Improved multi-line entry on macOS

- Proper bg and fg colors on Dark Mode (Mojave)
- No use of NSRegularControlSize (deprecated 10.12)
- Keeps styling between typed characters and scripted characters
(SetEntry/Append)
This commit is contained in:
Francisco Requena 2018-11-28 18:33:30 +01:00
parent 7138276ccf
commit 49667b21d8
1 changed files with 26 additions and 15 deletions

View File

@ -6,6 +6,8 @@
// see also http://stackoverflow.com/questions/24210153/nstextview-not-properly-resizing-with-auto-layout and http://stackoverflow.com/questions/11237622/using-autolayout-with-expanding-nstextviews // see also http://stackoverflow.com/questions/24210153/nstextview-not-properly-resizing-with-auto-layout and http://stackoverflow.com/questions/11237622/using-autolayout-with-expanding-nstextviews
@interface intrinsicSizeTextView : NSTextView { @interface intrinsicSizeTextView : NSTextView {
uiMultilineEntry *libui_e; uiMultilineEntry *libui_e;
NSDictionary *strAttrs;
NSFont *font;
} }
- (id)initWithFrame:(NSRect)r e:(uiMultilineEntry *)e; - (id)initWithFrame:(NSRect)r e:(uiMultilineEntry *)e;
@end @end
@ -25,8 +27,13 @@ struct uiMultilineEntry {
- (id)initWithFrame:(NSRect)r e:(uiMultilineEntry *)e - (id)initWithFrame:(NSRect)r e:(uiMultilineEntry *)e
{ {
self = [super initWithFrame:r]; self = [super initWithFrame:r];
if (self) if (self) {
self->libui_e = e; self->libui_e = e;
self->font = [NSFont controlContentFontOfSize:0];
self->strAttrs = [NSDictionary
dictionaryWithObjects:@[font, [NSColor controlTextColor]]
forKeys:@[NSFontAttributeName, NSForegroundColorAttributeName]];
}
return self; return self;
} }
@ -51,6 +58,16 @@ struct uiMultilineEntry {
(*(self->libui_e->onChanged))(self->libui_e, self->libui_e->onChangedData); (*(self->libui_e->onChanged))(self->libui_e, self->libui_e->onChangedData);
} }
-(NSDictionary *)stringAttributes
{
return self->strAttrs;
}
-(NSFont *)font
{
return self->font;
}
@end @end
uiDarwinControlAllDefaultsExceptDestroy(uiMultilineEntry, sv) uiDarwinControlAllDefaultsExceptDestroy(uiMultilineEntry, sv)
@ -79,6 +96,9 @@ void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text)
{ {
[[e->tv textStorage] replaceCharactersInRange:NSMakeRange(0, [[e->tv string] length]) [[e->tv textStorage] replaceCharactersInRange:NSMakeRange(0, [[e->tv string] length])
withString:uiprivToNSString(text)]; withString:uiprivToNSString(text)];
[[e->tv textStorage] setAttributes:[e->tv stringAttributes] range:NSMakeRange(0, [[e->tv string] length])];
// must be called explicitly according to the documentation of shouldChangeTextInRange:replacementString: // must be called explicitly according to the documentation of shouldChangeTextInRange:replacementString:
e->changing = YES; e->changing = YES;
[e->tv didChangeText]; [e->tv didChangeText];
@ -90,6 +110,9 @@ void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text)
{ {
[[e->tv textStorage] replaceCharactersInRange:NSMakeRange([[e->tv string] length], 0) [[e->tv textStorage] replaceCharactersInRange:NSMakeRange([[e->tv string] length], 0)
withString:uiprivToNSString(text)]; withString:uiprivToNSString(text)];
[[e->tv textStorage] setAttributes:[e->tv stringAttributes] range:NSMakeRange(0, [[e->tv string] length])];
e->changing = YES; e->changing = YES;
[e->tv didChangeText]; [e->tv didChangeText];
e->changing = NO; e->changing = NO;
@ -119,7 +142,6 @@ void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly)
static uiMultilineEntry *finishMultilineEntry(BOOL hscroll) static uiMultilineEntry *finishMultilineEntry(BOOL hscroll)
{ {
uiMultilineEntry *e; uiMultilineEntry *e;
NSFont *font;
uiprivScrollViewCreateParams p; uiprivScrollViewCreateParams p;
uiDarwinNewControl(uiMultilineEntry, e); uiDarwinNewControl(uiMultilineEntry, e);
@ -129,8 +151,6 @@ static uiMultilineEntry *finishMultilineEntry(BOOL hscroll)
// verified against Interface Builder for a sufficiently customized text view // verified against Interface Builder for a sufficiently customized text view
// NSText properties: // NSText properties:
// this is what Interface Builder sets the background color to
[e->tv setBackgroundColor:[NSColor colorWithCalibratedWhite:1.0 alpha:1.0]];
[e->tv setDrawsBackground:YES]; [e->tv setDrawsBackground:YES];
[e->tv setEditable:YES]; [e->tv setEditable:YES];
[e->tv setSelectable:YES]; [e->tv setSelectable:YES];
@ -159,8 +179,6 @@ static uiMultilineEntry *finishMultilineEntry(BOOL hscroll)
[e->tv setUsesRuler:NO]; [e->tv setUsesRuler:NO];
[e->tv setUsesInspectorBar:NO]; [e->tv setUsesInspectorBar:NO];
[e->tv setSelectionGranularity:NSSelectByCharacter]; [e->tv setSelectionGranularity:NSSelectByCharacter];
// there is a dedicated named insertion point color but oh well
[e->tv setInsertionPointColor:[NSColor controlTextColor]];
// typing attributes is nil; keep default (we change it below for fonts though) // typing attributes is nil; keep default (we change it below for fonts though)
[e->tv setSmartInsertDeleteEnabled:NO]; [e->tv setSmartInsertDeleteEnabled:NO];
[e->tv setContinuousSpellCheckingEnabled:NO]; [e->tv setContinuousSpellCheckingEnabled:NO];
@ -199,18 +217,11 @@ static uiMultilineEntry *finishMultilineEntry(BOOL hscroll)
[[e->tv textContainer] setContainerSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)]; [[e->tv textContainer] setContainerSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)];
// don't use uiDarwinSetControlFont() directly; we have to do a little extra work to set the font // don't use uiDarwinSetControlFont() directly; we have to do a little extra work to set the font
font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; [e->tv setTypingAttributes:[e->tv stringAttributes]];
[e->tv setTypingAttributes:[NSDictionary [e->tv setFont:[e->tv font]];
dictionaryWithObject:font
forKey:NSFontAttributeName]];
// e->tv font from Interface Builder is nil, but setFont:nil throws an exception
// let's just set it to the standard control font anyway, just to be safe
[e->tv setFont:font];
memset(&p, 0, sizeof (uiprivScrollViewCreateParams)); memset(&p, 0, sizeof (uiprivScrollViewCreateParams));
p.DocumentView = e->tv; p.DocumentView = e->tv;
// this is what Interface Builder sets it to
p.BackgroundColor = [NSColor colorWithCalibratedWhite:1.0 alpha:1.0];
p.DrawsBackground = YES; p.DrawsBackground = YES;
p.Bordered = YES; p.Bordered = YES;
p.HScroll = hscroll; p.HScroll = hscroll;