Changing the cursor in an NSTextView - cocoa

I'm hoping this will be a relatively easy thing to do.
I am writing a Mac app that will be (mostly) a giant NSTextView. I would like to override the default text position cursor to a unique color/shape cursor. I don't have a lot of Quartz or general drawing experience but that's something I can look into more on my own.
What I'm primarily looking for is advice on the best way to implement this. Is it going to be a matter of overriding the drawRect function, calling the super, and then implementing my own draw code?
How would I find the appropriate location to draw that cursor? Is it contained within the drawRect's passed rect?

Essentially, you'll have to subclass the NSTextView and override some methods. The obvious one is
-(void)drawInsertionPointInRect:(NSRect)aRect color:(NSColor *)aColor turnedOn:(BOOL)flag
but that doesn't seem to entirely take care of it. Apparently, you also have to override a private method:
-(void)_drawInsertionPointInRect:(NSRect)arg1 color:(NSColor *)color
Look here for someone who's already trying to do this:
http://www.cocoadev.com/index.pl?CustomInsertionPoint

Related

How to draw a Cocoa focus ring without subclassing?

I'd like to draw a proper, modern animated focus ring around a control, which according to Q&A 1785, should be a simple matter of overriding the -drawFocusRingMask and -focusRingMaskBounds methods.
Trouble is, for this project I have to use Xojo, which can declare and invoke Cocoa methods, but doesn't give me any opportunity to actually create my own view subclass.
So, is there any way to get a proper focus ring without making an actual subclass? Some other methods, perhaps introduced after this 10.7 tech note, that get the job done? Or some sneaky way to inject a method into an existing class at runtime?
As one comment suggested, class_addMethod() would be right if you want to add an optional protocol method. The public macoslib project has some code that shows how to do that, just search for that name.
However, if the function is already implemented, then you cannot add another. In that case method swizzling is the solution. It's a common method to replace a selector'd function address with another, and then call the original one.
I don't seem to have an example in Xojo for that at hand, though.
Update
For standard Cocoa controls the simplest solution is to set the NSView property focusRingType accordingly (available in macoslib). Implementing drawFocusRingMask is only necessary for custom controls.

Custom drawing selection in NSTextView

I've got a NSTextView where I'd like to control drawing of the highlight/selection. Anyone know which method I have to overwrite so I can control what to draw in the selection rect?
You do not specify what you want to draw, so it's not easy to give you a straight answer.
If it's just an attributed string (Font, Style, Color, Background), you do not need anything fancy, just look for NSAttributedString. There are methods like -setSelectedTextAttributes: and the delegate method -textViewDidChangeSelection:
Generally, you should not subclass NSTextView if you don't have a very good reason to do so. You can do almost anything by just utilizing the usual delegation mechanisms.
If it's something very customized, there is a variety of possibilities depending on if you want to customize the selection (-setSelectedRange:) draw an overlay view (get the frame of the selectedRange) or mess around with the low level layout engine (-layoutManager). It really depends.
If you don't want to use the standard attributes to highlight text, eg by using an CALayer, you can get the rects containing the selection from the layoutManager of the NSTextView.

Implementing custom NSView in Cocoa on OS X

I am creating a Cocoa application wherein one view will contain the "hex dump" of the currently loaded document. Up until this point, I have been using a bog-standard (and very unappealing) NSTextField, but I am now looking for something more powerful.
I am a great fan of 0xED.app and would love to replicate its main "hex dump" view. How would I go about doing this?
I'm not necessarily after the eye-candy, but the ability to select a range of bytes without also selecting the offset or text columns. I am a loss as to where I would even begin to implement this effectively. Surely this is not drawn upon a blank canvas?
To get started and see how things basically work:
Subclass NSView.
Add an instance variable to hold your NSData.
Override drawRect:
Iterate your NSData
Use methods from NSString drawing AppKit additions to draw the bytes.
This approach will be slow for a large amount of data, but will give you a good handle on implementing a NSView subclass. After that, you'll want to improve the drawing performance by implementing something better than repeated calls to draw strings one at a time. You'll also want to implement overrides of methods like mouseDown: and keyDown: to handle input from the user to allow things like selecting a range of bytes.
That should get you started, once you have that going, I'd suggest asking follow up questions.
My guess is that it's probably accomplished using a NSTableView or subclass of it.
It might be a little tricky to get the correct text selection accomplished this way, but it's probably possible.
If you want to take a look at how a Cocoa interface is built you can use NibToXibConverter.
Download 0xED, right click on 0xED.app and select "Show Package Contents". Extract the Contents/Resources/English.lproj folder.
Run NibToXibConverter, browse to the folder extracted above, and put a tick next to "Decompile NIBs".
Select the "Convert" button and it will convert the NIBs to XIBs
Double click a XIB to open it in XCode and you can see how they are constructed
You will note that in the case of 0xED he is using a custom class (most likely a subclass of UIView with custom drawing as Jon Hess suggests).

Converting an NSComboBox to and NSTextField Easily

I have an NSComboBox and I was wondering if there is an easy way to convert it to an ordinary NSTextField? Considering NSCombBox is a subclass of NSTextField, I would think there is an easy way to turn this on/off but I can't figure it out.
They are two separate controls. You'll just have to swap one out for the other. If you're looking to do this in Interface Builder at design time, it's mind-numbingly simple. If you're looking to do this in code, it's not overly difficult (especially if you already have both controls created and configured somewhere in your XIB, like an off-screen view).
It might help to describe what you're trying to accomplish (ie, why you want to swap the controls). It's difficult to give a succinct answer without more information about your goals.

How do you create a custom themed NSButton?

How do you create a custom themed NSButton? I don't mean in a small way like changing the background color or changing from rounded edges to square edges. I want to replace the entire look and feel of the button. Is that even possible to do in Cocoa? Obviously I would have to subclass the NSButton class and go from there. Any help would be much appreciated.
Actually, you need to subclass NSButtonCell. You should read Apple's documentation on this to gain a better understanding of how they interact. You probably will still want to subclass NSButton so that it will use your NSButtonCell subclass, too.
For a button, most of the work is done in drawBezelWithFrame:inView:. If you want to alter the way the text or image is drawn, you would override drawTitle:withFrame:inView: and drawImage:withFrame:inView:.

Resources