• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: A Thousand Newbie Questions...
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A Thousand Newbie Questions...


  • Subject: Re: A Thousand Newbie Questions...
  • From: Douglas Davidson <email@hidden>
  • Date: Mon, 8 Oct 2001 12:10:30 -0700

On Sunday, October 7, 2001, at 09:56 PM, email@hidden wrote:

Next, I figured I could just subclass NSTextView, and override some it's methods, creating, in effect an NSCodeView, that could be re-used by anyone ( god love open-source ). I've created several of those stupid text editors described in a hundred tutorials, but I'm failing to see a way to send the NSTextView a formatting command. I looked at ProjectCenter ( a GNUStep application) source, and they seem to be doing something really strange with NSScanner and a textView, but this doesn't seem like it would be the way to go.

Charles Jolley responded with an excellent summary of attributes on text in Cocoa, so I won't repeat any of that here. That should get you through taking some text, and some set of rules, and coloring the text based on those rules. Here I want to discuss a different question: once you have the text colored and displayed in a text view, if you then let the user loose to go ahead and edit it, how do you keep the coloring up to date?

There are a number of different ways you could do this. Probably the least invasive way of hooking into the text system to do this would be to act as your NSTextView's delegate. You will then get a message,

- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString;
// Delegate only. If characters are changing, replacementString is what will replace the affectedCharRange. If attributes only are changing, replacementString will be nil.

whenever the user changes the text, by one means or another. That should give you enough information to figure out what has changed, and to redo your coloring, potentially limiting your calculations to the minimum necessary. Note that you will get this call before the change actually takes place, and you have the opportunity to veto it by returning NO if you like. After the change takes place, you will get

- (void)textDidChange:(NSNotification *)notification; /* Any keyDown or paste which changes the contents causes this */

(defined in the superclass, in NSText.h).

If you are doing with with an NSTextView subclass, on the other hand, you can override the methods

- (BOOL)shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString;
- (void)didChangeText;

to hook in at the same places. Keep in mind that these methods are called whenever the user does something that causes the text to change; if some other piece of code programmatically changes the text, they will not be called.

If you want to find out whenever the text changes, by whatever means, you could work at a lower level--for example, with NSLayoutManager or NSTextStorage. NSTextStorage is a mutable attributed string subclass that has the additional feature of notifying whenever it changes. The text storage's delegate will get

- (void)textStorageWillProcessEditing:(NSNotification *)notification; /* Delegate can change the characters or attributes */
- (void)textStorageDidProcessEditing:(NSNotification *)notification; /* Delegate can change the attributes */

whenever the text storage changes--you can determine what is changing with editedMask, editedRange, and changeInLength. Others can register for the NSTextStorageWillProcessEditingNotification or NSTextStorageDidProcessEditingNotification to do the same thing--see TextEdit for an example.

A layout manager will get

- (void)textStorage:(NSTextStorage *)str edited:(unsigned)editedMask range:(NSRange)newCharRange changeInLength:(int)delta invalidatedRange:(NSRange)invalidatedCharRange;
// Sent from processEditing in NSTextStorage. newCharRange is the range in the final string which was explicitly edited. invalidatedRange includes stuff which was changed as a result of attribute fixing. invalidatedRange is either equal to newCharRange or larger. Layout managers should not change the contents of the text storage during the execution of this message.

when its text storage changes. The layout manager should not change the text storage itself, but it could certainly set temporary attributes on itself.

Douglas Davidson


References: 
 >A Thousand Newbie Questions... (From: email@hidden)

  • Prev by Date: Re: Cocoa newbie frustration
  • Next by Date: OpenGL unwarranted slowdown?
  • Previous by thread: Re: A Thousand Newbie Questions...
  • Next by thread: NSMatrix Opacity ?
  • Index(es):
    • Date
    • Thread