Mixing graphics in NSTextView? - cocoa

I thought I read somewhere that there is a way to embed drawings or other non-text in a text view, but I can't find anything about it in the Apple documentation. Can anyone point me in the right direction? I'm trying to build an editor, not just a view. I'm imagining a special character in the underlying text, and based on text attributes, it would reserves some blank space in the text layout. ? Or maybe I need to layout blocks myself, using NSTextContainers and a custom NSView to flow text around graphics?

Take a look into the NSTextAttachment and NSTextAttachmentCell. You can do your own custom drawing when you subclass the NSTextAttachmentCell.
Apple docs: Text Attachment Programming Topics

Related

How to control the size of image attachments in a NSTextView

By default, in a NSTextView, image attachments are displayed at their actual resolution. For large images, this results in having only a small portion of the image displayed in the view. This doesn't look good and the user has to do lots of scrolling to enter text after the image.
For example, in the window below, you can't tell much about the image in the text view.
So the question is: how to scale down image attachments, so that they fit in the NSTextView?
You can find a few solutions for this on the internet, based on subclassing NSTextAttachmentCell, but by doing so, you lose a number of good behaviors provided for free by the NSTextView, like the creation of annotations in an attached image.
Actually there is a much simpler solution: to use a NSLayoutManager property named defaultAttachmentScaling that does exactly what we want.
In your code, set this property as in:
myTextView.layoutManager.defaultAttachmentScaling = NSImageScaleProportionallyDown;
and this is it: large images are now scaled to match the width of the text view.
For detailed information on this property, I suggest you read the comments in the header file NSLayoutManager.h.
Note for iOS developers: unfortunately, this property is not available on iOS.

How to translate between user mouse coordinates and PDFDocument coordinates?

I'm working on an app for Macintosh. I want to have the user be able to click inside a PDF rendered onscreen and have an annotation appear where they clicked (or selected). Should/can I use PDFKit for this? I looked at the classes, but PDFSelection seems to deal with text, not coordinates. Specifically, I want to know which classes I should use to achieve this. I've read the PDFKit programming guide, but I'm still not quite clear as to the path forward.
Apple provides sample code, PDF Annotation Editor, its description is:
This sample application uses PDF Kit to examine, edit, and create PDF annotations. It has an inspector panel that shows various attributes of supported annotations. The inspector allows users to edit those values. Additionally, annotations can be created and the code demonstrates how to use PDF Kit to do this. Also, the sample code demonstrates subclassing of PDFAnnotationStamp in order to override the draw method and draw your own custom annotation content. Finally, the sample code demonstrates subclassing PDFView in order to overlay your own content over the PDF content being displayed.
This would appear to answer your questions, in particular look at mouseDown in PDFEditView.
HTH

How to change the spacing between letters in a NSFont?

I'm trying to change the letter spacing in a NSFont (such as Gill Sans). Is this possible or will I need to load my own custom font?
Though I suppose fonts might specify some kerning hints, kerning is really an attribute of rendered text. So the answer to your question depends on how you're going to render your text to the screen.
If you're using NSAttributedString, you can look at the NSKernAttributeName attribute (see the Constants section in the documentation. If you're using CoreText and CFAttributedString, you can look at the kCTKernAttributeName attribute (see the Constants section in the documentation.
If you're using something else to render text, then the answer (if there is one; not all text rendering methods support advanced customization) will be dependent on that something else.

Cocoa: Creating a Custom Text View

In a nutshell, I don't want raw text, or even rich text. I want to load an xml document, which has metadata for sections of text, and I want to display that metadata in a drawer when I click on a given text section. A hyperlink is a good example; obviously trivial to do in a web app, but while I'm not that experienced with mac dev, I can't seem to find an easy way to accomplish this with cocoa.
Any suggestions as to general strategy? There doesn't seem to be an HTML view built in to Interface builder or I'd mess with that.
I'm not entirely clear on what you're trying to do. It sounds like you want to load an XML document, display the text, and display various metadata when certain bits of text are selected.
If that's the case, you should read about the Cocoa Text System. The NSTextStorage class is a subclass of NSMutableAttributedString, and you can apply arbitrary attributes to any range of text. When the selection changes, you can get the attributes in the selected range and use that to update your drawer. (By the way, drawers are really on their way out. I'd suggest a different user interface. NSSplitView-based interfaces are much more in vogue these days.)
Of course, to build up the NSTextStorage, you'd need to parse the XML with NSXMLDocument or NSXMLParser, but you'd get much more control and it would look more "Cocoa-like".
You could use a WebView, which is the Safari renderer, but I think you'd have a hard time getting it to display text the way you want. Safari has never been great at rendering XML without XSLT.

How to set g:text style to bold font in a Windows Gadget?

I'm developing a Vista/Win7 Desktop Gadget that uses a translucent g:background (doc) area with g:text (doc) on top. I'm adding the text via addTextObject (doc), and this all works as expected.
However, I can't figure out how to set that text to bold style. There doesn't seem to be a way to do this directly via the exposed properties that I can see, and I can't use regular text + CSS in this case due to the fact this text is placed onto a g:background object.
I have also tried specifying a bold font directly, such as Arial Bold (doesn't work) instead of Arial (works).
So how can this be done?
Edit: I have tried setting font-weight:bold for both the body and the g:background object that parents my text; no luck.
See Flip Calendar, by Jonathan Abbott. His code is usually well commented so maybe you can get some ideas from that.
EDIT
The source of my information was from the early days of Vista Beta 2 where that was the official word from MS. I also found the following response to a thread on the MSDN forums regarding the Flip Calendar gadget itself:
http://social.msdn.microsoft.com/Forums/en-US/sidebargadfetdevelopment/thread/841e9d5e-32e9-453f-bd0e-dc5a4e607c33/
The gadget has options for setting bold font on the day of the month (a g:text object) but on closer inspection it doesn't work. Sorry about that. The MS guys have been known to be wrong as well on one or more occasions. I can honestly say that I don't use the g:text object.
This means your only (well, non activex route) option is VML text, which provides a lot of flexibility on layout. However, you will have to place it on a fully opaque area of the gadget which is probably why you wanted to use the addTextObject in the first place. Gary Beene's site really helped me out when I was getting started, but it doesn't go into any detail on the v:textbox element and the v:textpath element, though the MSDN documentation goes into enough detail on these.
If you need to place the text on a non-fully opaque area of the gadget, then you could still go the VML route and place an image behind the text that acts as a shadow, starting out fully opaque and fading to fully transparent. This is how Microsoft does text in window title bars with aero enabled.
Alternatively, you could create an ActiveXObject that draws the text you need in the font you want and saves the image to a temporary file in the gadget folder. Then you set that to the src of an addImageObject. I've done something similar in a gadget and it's fast enough not to be noticeable. You can also set min/max dimensions so shrinking/stretching to fit becomes a breeze.

Resources