Everything in this page that isn’t owned by someone else is in the public domain. That means there’s no copyright, and you can do what you want. Okay, in the USA there’s an automatic copyright that’s implied by writing, so I guess I have to say explicitely that this is public domain.

Line Number No-Wrap Text

About

This demo shows how I’ve manipulated NSTextView in order to

  1. display line numbers
  2. turn word-wrapping on or off

The demo and the class are probably slightly misnamed, since JSDTextView would seem to indicate an NSView subclass. This is not the case. JSDTextView is actually an NSView subclass the builds the NSTextView by hand, including the enclosing NSScrollView instance.

To implement the view in a nib, make sure IB knows about the JSDTextView.h file (i.e., drag it to your nib). You can then put a CustomView on your window or view, and change its custom class to JSDTextView. Explore the header file for useful functions. Default instantiation in the program will show line numbers and will not wrap text.

The downside to this approach is that you lose most of the IB configurability of an NSTextView. Oh well; it’s easy to do in code. Just remember that the real NSTextView properties and methods are buried one level lower, i.e., use [[instance textView] methodName] to work with the real NSTextView instance. Again, look at the header file to see what else could be useful.

Someday if there’s interest and I have time, I could expose more of the buried instance-properties and write an Interface Builder palette for this class. After all, I need a good excuse to write one someday, and that’s the only unused chapter in my Hillegas book!

What’s Involved

JSDText.h/.m
This is the component proper. The JSDTextView class is the principle class; you should ignore the others and regard them as private unless you need some functionality therein.
AppDelegate.h/.m
This serves as the application delegate for the demo, but isn’t really used as a delegate. It answers to the two check boxes to control the demo’s word wrapping and line numbering.
MainMenu.nib
Contains the main window as well as well as menus and other goodies MainMenu.nib usually does.

Why This is For You

I hope to save you the trouble and time that it took me to figure out how to do this. Good luck!

Thanks!

I’d like to give especial thanks to Koen van der Drift <kvddrift@earthlink.net>, without whose code I wouldn’t have gotten line numbering to work at all!

FAQ’s (not literally FAQ’s yet, but preemptive)

Why isn’t line number one (1) shown on a new, blank JSDTextView instance until you type something?

The real answer is that NSLayoutManager hasn’t drawn any glyphs on that line, thus there’s no simple way to ascertain the coordinates to draw the line number. The answer I’m inclined to say is that I think this is proper behavior because until there’s text there, there’s no line that exists, not even a carriage return. As soon as you type a single character, you now have a line.

Okay, aside from the first line, why isn’t the line number shown when the cursor is on a new line all by itself at the end of the text?

I’d have to say the same reason as above, i.e., there’s no glyph and hence no coordinate to draw the line number. But I still think that this is proper behavior, for the same reasons above.

Go to the downloads area, or download it now.

Views from Nibs

About

This demo simply shows how you can go about loading assembled views from a Nib file into an existing window. There are two big reasons I can think of that you would want to do this:

  1. This gives you the advantage of designing (for example) a single “main window” from which you can load multiple “subviews” on a dynamic basis. This could work similar to an NSTabView whereby a single window can display multiple subviews. This is also similar to Interface Builder’s “Info Window” where using the pop-up menu changes the page dynamically.
  2. You can design “super controls” out of existing control and put them in a single nib with their own complex controller class, and then use/instantiate this “super control” on as many separate windows as you want. For example, you could define a table that uses a constant datasource with associated form controls on the same view, with all of the logic in the controller. You can then use this entire codebase on any other forms with very simple instantiation.

What’s Involved

AppDelegate.h/.m
This serves as the application delegate and actually contains the logic for swapping the nib-views in and out.
MainMenu.nib
Contains the main window as well as well as menus and other goodies MainMenu.nib usually does.
View1.nib and View2.nib
Contain the views that will be swapped in the main window program.
View1Controller.h/.m and View2Controller.h/.m
Contain the respective controller classes (View1 and View2) that make this work. Each controller class has some simple controller logic just to demonstrate them.

Why This is For You

I hope to save you the trouble and time that it took me to figure out how to do this. The Apple mailing list archives at http://cocoa.mamasam.com are a great resource, but for this particular task (and this particular Cocoa newbie) it was like wading through mud. Good luck!

Go to the downloads area, or download it now.