diff options
author | Neil Hodgson <nyamatongwe@gmail.com> | 2021-05-10 23:02:05 +1000 |
---|---|---|
committer | Neil Hodgson <nyamatongwe@gmail.com> | 2021-05-10 23:02:05 +1000 |
commit | 7b98798ee4047aec150927d3b5fc6a75f78e0273 (patch) | |
tree | c1b72ac86262d57c968bd9c0e091777a7732f0f2 | |
parent | 8497317864816c0f7a4b5baf3229c7a3336f55d8 (diff) | |
download | scintilla-mirror-7b98798ee4047aec150927d3b5fc6a75f78e0273.tar.gz |
Implement UpdateBaseElements on Cocoa to update colours to match current system
settings. Trigger UpdateBaseElements when system settings change.
This makes Scintilla (by default) track the correct tint to show as the
selection background.
-rw-r--r-- | cocoa/ScintillaCocoa.h | 2 | ||||
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 56 | ||||
-rw-r--r-- | cocoa/ScintillaView.mm | 25 |
3 files changed, 83 insertions, 0 deletions
diff --git a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h index d07ffe758..f99c39770 100644 --- a/cocoa/ScintillaCocoa.h +++ b/cocoa/ScintillaCocoa.h @@ -247,6 +247,8 @@ public: void SetFirstResponder(bool isFirstResponder_); void ActiveStateChanged(bool isActive_); void SetFocusActiveState(); + void UpdateBaseElements() override; + void WindowWillMove(); // Find indicator diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index c4569144e..602ca30d6 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -2525,6 +2525,62 @@ void ScintillaCocoa::SetFocusActiveState() { //-------------------------------------------------------------------------------------------------- +namespace { + +/** + * Convert from an NSColor into a ColourAlpha + */ +ColourAlpha ColourFromNSColor(NSColor *value) { + return ColourAlpha(static_cast<unsigned int>(value.redComponent * componentMaximum), + static_cast<unsigned int>(value.greenComponent * componentMaximum), + static_cast<unsigned int>(value.blueComponent * componentMaximum), + static_cast<unsigned int>(value.alphaComponent * componentMaximum)); +} + +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Update ViewStyle::elementBaseColours to match system preferences. + */ +void ScintillaCocoa::UpdateBaseElements() { + NSView *content = ContentView(); + NSAppearance *saved = [NSAppearance currentAppearance]; + [NSAppearance setCurrentAppearance:content.effectiveAppearance]; + + bool changed = false; + if (@available(macOS 10.14, *)) { + NSColor *textBack = [NSColor.textBackgroundColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + NSColor *noFocusBack = [NSColor.unemphasizedSelectedTextBackgroundColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + if (vs.selection.layer == Layer::base) { + NSColor *selBack = [NSColor.selectedTextBackgroundColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + // Additional selection: blend with text background to make weaker version. + NSColor *modified = [selBack blendedColorWithFraction:0.5 ofColor:textBack]; + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_BACK, ColourFromNSColor(selBack)); + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_ADDITIONAL_BACK, ColourFromNSColor(modified)) || changed; + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_NO_FOCUS_BACK, ColourFromNSColor(noFocusBack)) || changed; + } else { + // Less translucent colour used in dark mode as otherwise less visible + const int alpha = textBack.brightnessComponent > 0.5 ? 0x40 : 0x60; + // Make a translucent colour that approximates selectedTextBackgroundColor + NSColor *accent = [NSColor.controlAccentColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + const ColourAlpha colourAccent = ColourFromNSColor(accent); + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_BACK, ColourAlpha(colourAccent, alpha)); + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_ADDITIONAL_BACK, ColourAlpha(colourAccent, alpha/2)) || changed; + changed = vs.SetElementBase(SC_ELEMENT_SELECTION_NO_FOCUS_BACK, ColourAlpha(ColourFromNSColor(noFocusBack), alpha)) || changed; + + } + } + if (changed) { + Redraw(); + } + + [NSAppearance setCurrentAppearance:saved]; +} + +//-------------------------------------------------------------------------------------------------- + /** * When the window is about to move, the calltip and autcoimpletion stay in the same spot, * so cancel them. diff --git a/cocoa/ScintillaView.mm b/cocoa/ScintillaView.mm index 593722c1e..f878a7a6b 100644 --- a/cocoa/ScintillaView.mm +++ b/cocoa/ScintillaView.mm @@ -338,6 +338,17 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) { //-------------------------------------------------------------------------------------------------- /** + * Gets called by the runtime when the effective appearance changes. + */ +- (void) viewDidChangeEffectiveAppearance { + if (mOwner.backend) { + mOwner.backend->UpdateBaseElements(); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** * Gets called by the runtime when the view needs repainting. */ - (void) drawRect: (NSRect) rect { @@ -1454,11 +1465,18 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) { name: NSWindowWillMoveNotification object: self.window]; + [center addObserver: self + selector: @selector(defaultsDidChange:) + name: NSSystemColorsDidChangeNotification + object: self.window]; + [scrollView.contentView setPostsBoundsChangedNotifications: YES]; [center addObserver: self selector: @selector(scrollerAction:) name: NSViewBoundsDidChangeNotification object: scrollView.contentView]; + + mBackend->UpdateBaseElements(); } return self; } @@ -1498,6 +1516,13 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) { //-------------------------------------------------------------------------------------------------- +- (void) defaultsDidChange: (NSNotification *) note { +#pragma unused(note) + mBackend->UpdateBaseElements(); +} + +//-------------------------------------------------------------------------------------------------- + - (void) viewDidMoveToWindow { [super viewDidMoveToWindow]; |