In a seemingly trivial setup, I encounter an undesired interplay between a selectable NSTextField and an NSColorPanel that I cannot get rid of and that drives me nuts.
Here’s the setup: Within one window, I have a selectable Multi-Line Label (de facto an NSTextField) and an NSColorWell.
The Color Well allows the user to color geometric objects in the GUI; it has nothing to do with text whatsoever. Of course, clicking on the color well activates it, i.e. brings up the shared NSColorPanel and connects the color well to it.
The Text Field is completely independent from the colored objects in the GUI and presents data to the user. It is read-only, i.e. not editable. Since the data is organized in columns, I use tabs for text formatting and the setAttributedStringValue:
method of NSTextField to display the data.
At first glimpse, everything works as you would expect in a such a trivial setup.
But here comes the rub: I want the user to be able to copy the data in the text field to process it elsewhere. Therefore, the NSTextField has to be selectable. And setting it to be selectable
is where the problems start:
When the user clicks on the selectable text field to select the text, the window’s field editor takes over, and as a consequence, all the tab settings of the attributed text are lost and the text gets mingled. The usual way to prevent this is to set the allowsEditingTextAttributes
property of the NSTextField to YES
. If I do this, the tab formatting is preserved when the user selects the text. But now the NSColorPanel (if visible) unintentionally also switches to the text color (always black), and if the color well is active (connected to the NSColorPanel), it will remain active, thereby changing the color of all geometric GUI objects to black. Ouch!
I have found no way to set the selectable
and allowsEditingTextAttributes
properties of NSTextField to YES
but still prevent it from communicating with the NSColorPanel.
The obvious alternative route would be to preserve the tab formatting for selected text even with allowsEditingTextAttributes
set to NO
(which would disconnect the color panel from the text field, as desired). But I’ve had no success with this approach either, although I do not really understand why:
My idea was to set the required tabs as the defaultParagraphStyle
of the field editor of the text field. So, I set up a customized field editor:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSArray *myTabs = @[
[[NSTextTab alloc] initWithType:NSRightTabStopType location:100],
[[NSTextTab alloc] initWithType:NSRightTabStopType location:200],
[[NSTextTab alloc] initWithType:NSRightTabStopType location:300]
];
NSMutableParagraphStyle *myParagraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
[myParagraphStyle setTabStops:myTabs];
myFieldEditor = [NSTextView new]; // myFieldEditor is an instance variable
[myFieldEditor setDefaultParagraphStyle:myParagraphStyle];
[window setDelegate:self];
[window fieldEditor:YES forObject:myTextField];
}
And activate it for the text field in the windowWillReturnFieldEditor:toObject:
delegate method:
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client
{
if (client == myTextField) return myFieldEditor;
return nil;
}
I even made sure that my custom field editor is indeed used by subclassing the NSTextFieldCell of my text field and logging the propagated field editor:
@implementation myTextFieldCell
- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj
{
NSTextView *newTextObj = (NSTextView*)[super setUpFieldEditorAttributes:textObj];
NSLog(@"STYLE: %@", [newTextObj defaultParagraphStyle]);
return newTextObj;
}
@end
Now, when I select the text in the text field, I get the following log output:
2017-11-02 11:51:07.432 Demo[94807:303] STYLE: Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (
100R,
200R,
300R
), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0.05, HeaderLevel 0
Which is exactly what is expected.
But still, the tab formatting disappears in the text field as soon as I select the text. I have no idea why this does not work.
So I’m stuck either way. If I set the allowsEditingTextAttributes
property of NSTextField to YES
, tab formatting is preserved when the text is selected, but my colored objects in the GUI unintentionally change to black. If I set the allowsEditingTextAttributes
property to NO
, the color panel behaves as it should, but the tab formatting is lost as soon as I select the text.
This is a very unfortunate case of Cocoa trying to be too smart and thereby making a completely trivial setup a huge issue.
Any ideas anyone?
setUpFieldEditorAttributes:
method ofmyTextFieldCell
to deactivate the color well (i.e. disconnect the color panel from the color well). This way, the color panel would change to black, but at least the colored GUI objects would not. But that’s not what I want; I want the color panel to stay connected to the color well, but not change to black. – Uli ZappeusesFontPanel
off. – WillekeusesFontPanel
would also switch off the color panel. But if so, that again raises the question why that wouldn’t work with the text view that is the field editor of the text field (which it doesn’t – just tested it). In short: customizing the field editor does not seem to have any effect at all, and I don’t know why. – Uli ZappeusesFontPanel
toNO
. Turns out I can still change the fonts in the text field with the Font Panel! So somehow customizing the field editor does not work, at least as I configure it, and it seems to me increasingly that this is at the heart of the issue. – Uli ZappeallowsEditingTextAttributes
property of NSTextField completely overwrites the field editor. If it’sYES
, I can edit fonts even withusesFontPanel
set toNO
in the field editor. If it’sNO
, I cannot edit fonts even withusesFontPanel
set toYES
in the field editor. And the same seems to be true for respecting the tab settings in the paragraph style. But then, what is the field editor good for in the first place? – Uli Zappe