Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mac OS X: How to force a Field Editor to scroll instead of wrap text?

I have a Cocoa, Document-based Mac OS X application.

One feature that I have in my app is a list of text items which can be double-clicked to edit. When the user double-clicks one of the text items, I place the current window's fieldEditor text field over the clicked text item to allow editing.

Everything is working fine except for one problem. I cannot figure out how to make the fieldEditor text field clip + scroll rather than wrap its text. Here's what it currently looks like:

enter image description here

See how the text is wrapping to a second line? I don't want that. I'd like it to remain one line which scrolls (and appears clipped).

Here's an example of it working correctly on a list item which has less text:

enter image description here

Here's what I'm trying in my view controller:

NSWindow *win = [listItemView window];
NSText *fieldEditor = [win fieldEditor:YES forObject:listItemView];
[fieldEditor setFont:[TDListItemView titleFont]];
[fieldEditor setAlignment:NSLeftTextAlignment];
[fieldEditor setDrawsBackground:YES];
[fieldEditor setBackgroundColor:[NSColor whiteColor]];
[fieldEditor setString:str];
[fieldEditor setDelegate:self];
[fieldEditor selectAll:nil];

if ([fieldEditor isKindOfClass:[NSTextView class]]) {
    NSTextView *tv = (NSTextView *)fieldEditor;
    NSMutableParagraphStyle *style = [[[tv defaultParagraphStyle] mutableCopy] autorelease];
    [style setLineBreakMode:NSLineBreakByClipping];
    [tv setDefaultParagraphStyle:style];
}

CGRect r = [self fieldEditorRectForBounds:[listItemView bounds] index:idx]; // height here is 10.0
[fieldEditor setFrame:r];
[fieldEditor setNeedsDisplay:YES];
[[self view] addSubview:fieldEditor];
[win makeFirstResponder:fieldEditor];

Notice that part in the middle: I check to see if this fieldEditor is an instance of NSTextView in order to call the setDefaultParagraphStyle: method on it. This is my attempt to get the fieldEditor to clip its text -- via the NSLineBreakByClipping value. It's not having any effect. And I'm not even sure this is what I should be doing to get the fieldEditor to scroll on one line.

Also note that the height of the rect which I compute in my -fieldEditorRectForBounds:index: method is correct, and is providing a rect which is correctly sized for a single line of text (14.0 pixels in this case).

What am I missing to make the fieldEditor display a single line of scrolled/clipped text?


I've also tried adding these lines in the middle section:

    [[tv textContainer] setHeightTracksTextView:YES];
    [[tv textContainer] setWidthTracksTextView:YES];

This has the desired effect of resizing the visible portion of the fieldEditor which is good. But the bad news is that it doesn't change the fact that the text is still wrapped, rather than clipped + scrolled. :(


This seems related to this constant:

NSStringDrawingUsesLineFragmentOrigin

which can be used in the options: argument of:

-[NSAttributedString drawWithRect:options:attributes:]

but in my case, I'm working from a NSText field editor, not an NSAttributedString. I can't figure out how to do this sort of thing with an NSText field editor.

like image 984
Todd Ditchendorf Avatar asked Oct 23 '22 03:10

Todd Ditchendorf


1 Answers

Hmmm ... NSTextView relies on an NSScrollView entirely for its scrolling behavior. I'm not sure if there's more to this that I'm not seeing, but it looks like the "historic" solution to your problem is either to:

Use A Different Control

You can use an editable NSTextField in its standard IB label configuration with editing enabled and scrolling selected as the behavior. It does all the heavy lifting for you already when configured properly - no need to mess around with the field editor directly.

...or to...

Cheat

Slap the field editor into an appropriately-sized and configured NSScrollView (allow only horizontal scroll; don't show the scrollers) dynamically, then remove the scroll view when finished editing.

like image 139
Joshua Nozzi Avatar answered Nov 02 '22 11:11

Joshua Nozzi