diff --git a/Frameworks/OakTextView/src/GutterView.h b/Frameworks/OakTextView/src/GutterView.h index 58b94829..ed5c4439 100644 --- a/Frameworks/OakTextView/src/GutterView.h +++ b/Frameworks/OakTextView/src/GutterView.h @@ -36,9 +36,13 @@ struct GVLineRecord NSColor* foregroundColor; NSColor* backgroundColor; NSColor* iconColor; + NSColor* iconHoverColor; + NSColor* iconPressedColor; NSColor* selectionForegroundColor; NSColor* selectionBackgroundColor; NSColor* selectionIconColor; + NSColor* selectionIconHoverColor; + NSColor* selectionIconPressedColor; NSColor* selectionBorderColor; id delegate; std::vector columnDataSources; @@ -55,9 +59,13 @@ struct GVLineRecord @property (nonatomic, retain) NSColor* foregroundColor; @property (nonatomic, retain) NSColor* backgroundColor; @property (nonatomic, retain) NSColor* iconColor; +@property (nonatomic, retain) NSColor* iconHoverColor; +@property (nonatomic, retain) NSColor* iconPressedColor; @property (nonatomic, retain) NSColor* selectionForegroundColor; @property (nonatomic, retain) NSColor* selectionBackgroundColor; @property (nonatomic, retain) NSColor* selectionIconColor; +@property (nonatomic, retain) NSColor* selectionIconHoverColor; +@property (nonatomic, retain) NSColor* selectionIconPressedColor; @property (nonatomic, retain) NSColor* selectionBorderColor; - (void)setHighlightedRange:(std::string const&)str; - (void)reloadData:(id)sender; diff --git a/Frameworks/OakTextView/src/GutterView.mm b/Frameworks/OakTextView/src/GutterView.mm index 7afdc1f4..235caf09 100644 --- a/Frameworks/OakTextView/src/GutterView.mm +++ b/Frameworks/OakTextView/src/GutterView.mm @@ -88,15 +88,19 @@ struct data_source_t - (void)dealloc { D(DBF_GutterView, bug("\n");); - self.partnerView = nil; - self.lineNumberFont = nil; - self.foregroundColor = nil; - self.backgroundColor = nil; - self.iconColor = nil; - self.selectionForegroundColor = nil; - self.selectionBackgroundColor = nil; - self.selectionIconColor = nil; - self.selectionBorderColor = nil; + self.partnerView = nil; + self.lineNumberFont = nil; + self.foregroundColor = nil; + self.backgroundColor = nil; + self.iconColor = nil; + self.iconHoverColor = nil; + self.iconPressedColor = nil; + self.selectionForegroundColor = nil; + self.selectionBackgroundColor = nil; + self.selectionIconColor = nil; + self.selectionIconHoverColor = nil; + self.selectionIconPressedColor = nil; + self.selectionBorderColor = nil; iterate(it, columnDataSources) { if(it->datasource) @@ -353,7 +357,18 @@ static void DrawText (std::string const& text, CGRect const& rect, CGFloat basel [overlayImage lockFocus]; [image drawAdjustedAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0]; - [(selectedRow ? self.selectionIconColor : self.iconColor) set]; + if(selectedRow) + { + if(isHoveringRect && !isDownInRect) [self.selectionIconHoverColor set]; + else if(isHoveringRect && isDownInRect) [self.selectionIconPressedColor set]; + else [self.selectionIconColor set]; + } + else + { + if(isHoveringRect && !isDownInRect) [self.iconHoverColor set]; + else if(isHoveringRect && isDownInRect) [self.iconPressedColor set]; + else [self.iconColor set]; + } NSRectFillUsingOperation(NSMakeRect(0, 0, [image size].width, [image size].height), NSCompositeSourceAtop); [overlayImage unlockFocus]; diff --git a/Frameworks/OakTextView/src/OakDocumentView.mm b/Frameworks/OakTextView/src/OakDocumentView.mm index b70bd1bb..94eeab02 100644 --- a/Frameworks/OakTextView/src/OakDocumentView.mm +++ b/Frameworks/OakTextView/src/OakDocumentView.mm @@ -335,13 +335,17 @@ private: auto styles = [textView theme]->styles_for_scope(document->buffer().scope(0).left, NULL_STR, 0); self.gutterDividerColor = [NSColor tmColorWithCGColor:styles.gutterDivider()] ?: [NSColor grayColor]; - gutterView.foregroundColor = [NSColor tmColorWithCGColor:styles.gutterForeground()]; - gutterView.backgroundColor = [NSColor tmColorWithCGColor:styles.gutterBackground()]; - gutterView.iconColor = [NSColor tmColorWithCGColor:styles.gutterIcons()]; - gutterView.selectionForegroundColor = [NSColor tmColorWithCGColor:styles.gutterSelectionForeground()]; - gutterView.selectionBackgroundColor = [NSColor tmColorWithCGColor:styles.gutterSelectionBackground()]; - gutterView.selectionIconColor = [NSColor tmColorWithCGColor:styles.gutterSelectionIcons()]; - gutterView.selectionBorderColor = [NSColor tmColorWithCGColor:styles.gutterSelectionBorder()]; + gutterView.foregroundColor = [NSColor tmColorWithCGColor:styles.gutterForeground()]; + gutterView.backgroundColor = [NSColor tmColorWithCGColor:styles.gutterBackground()]; + gutterView.iconColor = [NSColor tmColorWithCGColor:styles.gutterIcons()]; + gutterView.iconHoverColor = [NSColor tmColorWithCGColor:styles.gutterIconsHover()]; + gutterView.iconPressedColor = [NSColor tmColorWithCGColor:styles.gutterIconsPressed()]; + gutterView.selectionForegroundColor = [NSColor tmColorWithCGColor:styles.gutterSelectionForeground()]; + gutterView.selectionBackgroundColor = [NSColor tmColorWithCGColor:styles.gutterSelectionBackground()]; + gutterView.selectionIconColor = [NSColor tmColorWithCGColor:styles.gutterSelectionIcons()]; + gutterView.selectionIconHoverColor = [NSColor tmColorWithCGColor:styles.gutterSelectionIconsHover()]; + gutterView.selectionIconPressedColor = [NSColor tmColorWithCGColor:styles.gutterSelectionIconsPressed()]; + gutterView.selectionBorderColor = [NSColor tmColorWithCGColor:styles.gutterSelectionBorder()]; gutterScrollView.backgroundColor = gutterView.backgroundColor; diff --git a/Frameworks/theme/src/theme.cc b/Frameworks/theme/src/theme.cc index 09a25589..a63f2b3f 100644 --- a/Frameworks/theme/src/theme.cc +++ b/Frameworks/theme/src/theme.cc @@ -27,21 +27,25 @@ theme_t::decomposed_style_t theme_t::parse_styles (plist::dictionary_t const& pl if(plist::get_key_path(plist, "scope", scopeSelector)) res.scope_selector = scopeSelector; - plist::get_key_path(plist, "settings.fontName", res.font_name); - get_key_path(plist, "settings.fontSize", res.font_size); - get_key_path(plist, "settings.foreground", res.foreground); - get_key_path(plist, "settings.background", res.background); - get_key_path(plist, "settings.gutterForeground", res.gutterForeground); - get_key_path(plist, "settings.gutterBackground", res.gutterBackground); - get_key_path(plist, "settings.gutterIcons", res.gutterIcons); - get_key_path(plist, "settings.gutterDivider", res.gutterDivider); - get_key_path(plist, "settings.gutterSelectionForeground", res.gutterSelectionForeground); - get_key_path(plist, "settings.gutterSelectionBackground", res.gutterSelectionBackground); - get_key_path(plist, "settings.gutterSelectionIcons", res.gutterSelectionIcons); - get_key_path(plist, "settings.gutterSelectionBorder", res.gutterSelectionBorder); - get_key_path(plist, "settings.caret", res.caret); - get_key_path(plist, "settings.selection", res.selection); - get_key_path(plist, "settings.invisibles", res.invisibles); + plist::get_key_path(plist, "settings.fontName", res.font_name); + get_key_path(plist, "settings.fontSize", res.font_size); + get_key_path(plist, "settings.foreground", res.foreground); + get_key_path(plist, "settings.background", res.background); + get_key_path(plist, "settings.gutterForeground", res.gutterForeground); + get_key_path(plist, "settings.gutterBackground", res.gutterBackground); + get_key_path(plist, "settings.gutterIcons", res.gutterIcons); + get_key_path(plist, "settings.gutterIconsHover", res.gutterIconsHover); + get_key_path(plist, "settings.gutterIconsPressed", res.gutterIconsPressed); + get_key_path(plist, "settings.gutterDivider", res.gutterDivider); + get_key_path(plist, "settings.gutterSelectionForeground", res.gutterSelectionForeground); + get_key_path(plist, "settings.gutterSelectionBackground", res.gutterSelectionBackground); + get_key_path(plist, "settings.gutterSelectionIcons", res.gutterSelectionIcons); + get_key_path(plist, "settings.gutterSelectionIconsHover", res.gutterSelectionIconsHover); + get_key_path(plist, "settings.gutterSelectionIconsPressed", res.gutterSelectionIconsPressed); + get_key_path(plist, "settings.gutterSelectionBorder", res.gutterSelectionBorder); + get_key_path(plist, "settings.caret", res.caret); + get_key_path(plist, "settings.selection", res.selection); + get_key_path(plist, "settings.invisibles", res.invisibles); bool flag; res.misspelled = plist::get_key_path(plist, "settings.misspelled", flag) ? (flag ? bool_true : bool_false) : bool_unset; @@ -211,20 +215,24 @@ styles_t const& theme_t::styles_for_scope (scope::context_t const& scope, std::s font.reset(newFont, CFRelease); } - cf::color_t foreground = base.foreground.is_blank() ? cf::color_t("#000000") : base.foreground; - cf::color_t background = base.background.is_blank() ? cf::color_t("#FFFFFF") : base.background; - cf::color_t gutterForeground = base.gutterForeground.is_blank() ? soften(foreground, 0.5) : base.gutterForeground; - cf::color_t gutterBackground = base.gutterBackground.is_blank() ? soften(background, 0.87) : base.gutterBackground; - cf::color_t gutterIcons = base.gutterIcons.is_blank() ? soften(foreground, 0.5) : base.gutterIcons; - cf::color_t gutterDivider = base.gutterDivider.is_blank() ? soften(foreground, 0.4) : base.gutterDivider; - cf::color_t gutterSelectionForeground = base.gutterSelectionForeground.is_blank() ? soften(foreground, 0.95) : base.gutterSelectionForeground; - cf::color_t gutterSelectionBackground = base.gutterSelectionBackground.is_blank() ? soften(background, 0.95) : base.gutterSelectionBackground; - cf::color_t gutterSelectionIcons = base.gutterSelectionIcons.is_blank() ? soften(foreground, 0.95) : base.gutterSelectionIcons; - cf::color_t gutterSelectionBorder = base.gutterSelectionBorder.is_blank() ? soften(foreground, 0.4) : base.gutterSelectionBorder; - cf::color_t selection = base.selection.is_blank() ? cf::color_t("#4D97FF54") : base.selection; - cf::color_t caret = base.caret.is_blank() ? cf::color_t("#000000") : base.caret; + cf::color_t foreground = base.foreground.is_blank() ? cf::color_t("#000000") : base.foreground; + cf::color_t background = base.background.is_blank() ? cf::color_t("#FFFFFF") : base.background; + cf::color_t gutterForeground = base.gutterForeground.is_blank() ? soften(foreground, 0.5) : base.gutterForeground; + cf::color_t gutterBackground = base.gutterBackground.is_blank() ? soften(background, 0.87) : base.gutterBackground; + cf::color_t gutterIcons = base.gutterIcons.is_blank() ? soften(foreground, 0.5) : base.gutterIcons; + cf::color_t gutterIconsHover = base.gutterIconsHover.is_blank() ? soften(foreground, 0.5) : base.gutterIconsHover; + cf::color_t gutterIconsPressed = base.gutterIconsPressed.is_blank() ? soften(foreground, 0.5) : base.gutterIconsPressed; + cf::color_t gutterDivider = base.gutterDivider.is_blank() ? soften(foreground, 0.4) : base.gutterDivider; + cf::color_t gutterSelectionForeground = base.gutterSelectionForeground.is_blank() ? soften(foreground, 0.95) : base.gutterSelectionForeground; + cf::color_t gutterSelectionBackground = base.gutterSelectionBackground.is_blank() ? soften(background, 0.95) : base.gutterSelectionBackground; + cf::color_t gutterSelectionIcons = base.gutterSelectionIcons.is_blank() ? soften(foreground, 0.95) : base.gutterSelectionIcons; + cf::color_t gutterSelectionIconsHover = base.gutterSelectionIconsHover.is_blank() ? soften(foreground, 0.95) : base.gutterSelectionIconsHover; + cf::color_t gutterSelectionIconsPressed = base.gutterSelectionIconsPressed.is_blank() ? soften(foreground, 0.95) : base.gutterSelectionIconsPressed; + cf::color_t gutterSelectionBorder = base.gutterSelectionBorder.is_blank() ? soften(foreground, 0.4) : base.gutterSelectionBorder; + cf::color_t selection = base.selection.is_blank() ? cf::color_t("#4D97FF54") : base.selection; + cf::color_t caret = base.caret.is_blank() ? cf::color_t("#000000") : base.caret; - styles_t res(foreground, background, gutterForeground, gutterBackground, gutterIcons, gutterDivider, gutterSelectionForeground, gutterSelectionBackground, gutterSelectionIcons, gutterSelectionBorder, selection, caret, font, base.underlined == bool_true, base.misspelled == bool_true); + styles_t res(foreground, background, gutterForeground, gutterBackground, gutterIcons, gutterIconsHover, gutterIconsPressed, gutterDivider, gutterSelectionForeground, gutterSelectionBackground, gutterSelectionIcons, gutterSelectionIconsHover, gutterSelectionIconsPressed, gutterSelectionBorder, selection, caret, font, base.underlined == bool_true, base.misspelled == bool_true); styles = _cache.insert(std::make_pair(key_t(scope, fontName, fontSize), res)).first; } return styles->second; @@ -316,19 +324,23 @@ theme_t::decomposed_style_t& theme_t::decomposed_style_t::operator+= (theme_t::d font_name = rhs.font_name == NULL_STR ? font_name : rhs.font_name; font_size = rhs.font_size > 0 ? rhs.font_size : font_size * fabs(rhs.font_size); - foreground = rhs.foreground.is_blank() ? foreground : rhs.foreground; - background = rhs.background.is_blank() ? background : blend(background, rhs.background); - gutterForeground = rhs.gutterForeground.is_blank() ? gutterForeground : rhs.gutterForeground; - gutterBackground = rhs.gutterBackground.is_blank() ? gutterBackground : rhs.gutterBackground; - gutterIcons = rhs.gutterIcons.is_blank() ? gutterIcons : rhs.gutterIcons; - gutterDivider = rhs.gutterDivider.is_blank() ? gutterDivider : rhs.gutterDivider; - gutterSelectionForeground = rhs.gutterSelectionForeground.is_blank() ? gutterSelectionForeground : rhs.gutterSelectionForeground; - gutterSelectionBackground = rhs.gutterSelectionBackground.is_blank() ? gutterSelectionBackground : rhs.gutterSelectionBackground; - gutterSelectionIcons = rhs.gutterSelectionIcons.is_blank() ? gutterSelectionIcons : rhs.gutterSelectionIcons; - gutterSelectionBorder = rhs.gutterSelectionBorder.is_blank() ? gutterSelectionBorder : rhs.gutterSelectionBorder; - caret = rhs.caret.is_blank() ? caret : rhs.caret; - selection = rhs.selection.is_blank() ? selection : rhs.selection; - invisibles = rhs.invisibles.is_blank() ? invisibles : rhs.invisibles; + foreground = rhs.foreground.is_blank() ? foreground : rhs.foreground; + background = rhs.background.is_blank() ? background : blend(background, rhs.background); + gutterForeground = rhs.gutterForeground.is_blank() ? gutterForeground : rhs.gutterForeground; + gutterBackground = rhs.gutterBackground.is_blank() ? gutterBackground : rhs.gutterBackground; + gutterIcons = rhs.gutterIcons.is_blank() ? gutterIcons : rhs.gutterIcons; + gutterIconsHover = rhs.gutterIconsHover.is_blank() ? gutterIconsHover : rhs.gutterIconsHover; + gutterIconsPressed = rhs.gutterIconsPressed.is_blank() ? gutterIconsPressed : rhs.gutterIconsPressed; + gutterDivider = rhs.gutterDivider.is_blank() ? gutterDivider : rhs.gutterDivider; + gutterSelectionForeground = rhs.gutterSelectionForeground.is_blank() ? gutterSelectionForeground : rhs.gutterSelectionForeground; + gutterSelectionBackground = rhs.gutterSelectionBackground.is_blank() ? gutterSelectionBackground : rhs.gutterSelectionBackground; + gutterSelectionIcons = rhs.gutterSelectionIcons.is_blank() ? gutterSelectionIcons : rhs.gutterSelectionIcons; + gutterSelectionIconsHover = rhs.gutterSelectionIconsHover.is_blank() ? gutterSelectionIconsHover : rhs.gutterSelectionIconsHover; + gutterSelectionIconsPressed = rhs.gutterSelectionIconsPressed.is_blank() ? gutterSelectionIconsPressed : rhs.gutterSelectionIconsPressed; + gutterSelectionBorder = rhs.gutterSelectionBorder.is_blank() ? gutterSelectionBorder : rhs.gutterSelectionBorder; + caret = rhs.caret.is_blank() ? caret : rhs.caret; + selection = rhs.selection.is_blank() ? selection : rhs.selection; + invisibles = rhs.invisibles.is_blank() ? invisibles : rhs.invisibles; bold = rhs.bold == bool_unset ? bold : rhs.bold; italic = rhs.italic == bool_unset ? italic : rhs.italic; diff --git a/Frameworks/theme/src/theme.h b/Frameworks/theme/src/theme.h index f18d55e5..82056c0d 100644 --- a/Frameworks/theme/src/theme.h +++ b/Frameworks/theme/src/theme.h @@ -9,23 +9,66 @@ typedef std::shared_ptr CTFontPtr; struct PUBLIC styles_t { - styles_t (cf::color_t const& foreground, cf::color_t const& background, cf::color_t const& gutterForeground, cf::color_t const& gutterBackground, cf::color_t const& gutterIcons, cf::color_t const& gutterDivider, cf::color_t const& gutterSelectionForeground, cf::color_t const& gutterSelectionBackground, cf::color_t const& gutterSelectionIcons, cf::color_t const& gutterSelectionBorder, cf::color_t const& selection, cf::color_t const& caret, CTFontPtr font, bool underlined, bool misspelled) : _foreground(foreground), _background(background), _gutterForeground(gutterForeground), _gutterBackground(gutterBackground), _gutterIcons(gutterIcons), _gutterDivider(gutterDivider), _gutterSelectionForeground(gutterSelectionForeground), _gutterSelectionBackground(gutterSelectionBackground), _gutterSelectionIcons(gutterSelectionIcons), _gutterSelectionBorder(gutterSelectionBorder), _selection(selection), _caret(caret), _font(font), _underlined(underlined), _misspelled(misspelled) { } + styles_t ( + cf::color_t const& foreground, + cf::color_t const& background, + cf::color_t const& gutterForeground, + cf::color_t const& gutterBackground, + cf::color_t const& gutterIcons, + cf::color_t const& gutterIconsHover, + cf::color_t const& gutterIconsPressed, + cf::color_t const& gutterDivider, + cf::color_t const& gutterSelectionForeground, + cf::color_t const& gutterSelectionBackground, + cf::color_t const& gutterSelectionIcons, + cf::color_t const& gutterSelectionIconsHover, + cf::color_t const& gutterSelectionIconsPressed, + cf::color_t const& gutterSelectionBorder, + cf::color_t const& selection, + cf::color_t const& caret, + CTFontPtr font, + bool underlined, + bool misspelled) + : + _foreground(foreground), + _background(background), + _gutterForeground(gutterForeground), + _gutterBackground(gutterBackground), + _gutterIcons(gutterIcons), + _gutterIconsHover(gutterIconsHover), + _gutterIconsPressed(gutterIconsPressed), + _gutterDivider(gutterDivider), + _gutterSelectionForeground(gutterSelectionForeground), + _gutterSelectionBackground(gutterSelectionBackground), + _gutterSelectionIcons(gutterSelectionIcons), + _gutterSelectionIconsHover(gutterSelectionIconsHover), + _gutterSelectionIconsPressed(gutterSelectionIconsPressed), + _gutterSelectionBorder(gutterSelectionBorder), + _selection(selection), + _caret(caret), + _font(font), + _underlined(underlined), + _misspelled(misspelled) { } - CGColorRef foreground () const { return _foreground; } - CGColorRef background () const { return _background; } - CGColorRef gutterForeground () const { return _gutterForeground; } - CGColorRef gutterBackground () const { return _gutterBackground; } - CGColorRef gutterIcons() const { return _gutterIcons; } - CGColorRef gutterDivider () const { return _gutterDivider; } - CGColorRef gutterSelectionForeground() const { return _gutterSelectionForeground; } - CGColorRef gutterSelectionBackground() const { return _gutterSelectionBackground; } - CGColorRef gutterSelectionIcons() const { return _gutterSelectionIcons; } - CGColorRef gutterSelectionBorder() const { return _gutterSelectionBorder; } - CGColorRef caret () const { return _caret; } - CGColorRef selection () const { return _selection; } - CTFontRef font () const { return _font.get(); } - bool underlined () const { return _underlined; } - bool misspelled () const { return _misspelled; } + CGColorRef foreground () const { return _foreground; } + CGColorRef background () const { return _background; } + CGColorRef gutterForeground () const { return _gutterForeground; } + CGColorRef gutterBackground () const { return _gutterBackground; } + CGColorRef gutterIcons() const { return _gutterIcons; } + CGColorRef gutterIconsHover() const { return _gutterIconsHover; } + CGColorRef gutterIconsPressed() const { return _gutterIconsPressed; } + CGColorRef gutterDivider () const { return _gutterDivider; } + CGColorRef gutterSelectionForeground() const { return _gutterSelectionForeground; } + CGColorRef gutterSelectionBackground() const { return _gutterSelectionBackground; } + CGColorRef gutterSelectionIcons() const { return _gutterSelectionIcons; } + CGColorRef gutterSelectionIconsHover() const { return _gutterSelectionIconsHover; } + CGColorRef gutterSelectionIconsPressed() const { return _gutterSelectionIconsPressed; } + CGColorRef gutterSelectionBorder() const { return _gutterSelectionBorder; } + CGColorRef caret () const { return _caret; } + CGColorRef selection () const { return _selection; } + CTFontRef font () const { return _font.get(); } + bool underlined () const { return _underlined; } + bool misspelled () const { return _misspelled; } private: cf::color_t _foreground; @@ -33,10 +76,14 @@ private: cf::color_t _gutterForeground; cf::color_t _gutterBackground; cf::color_t _gutterIcons; + cf::color_t _gutterIconsHover; + cf::color_t _gutterIconsPressed; cf::color_t _gutterDivider; cf::color_t _gutterSelectionForeground; cf::color_t _gutterSelectionBackground; cf::color_t _gutterSelectionIcons; + cf::color_t _gutterSelectionIconsHover; + cf::color_t _gutterSelectionIconsPressed; cf::color_t _gutterSelectionBorder; cf::color_t _selection; cf::color_t _caret; @@ -83,10 +130,14 @@ private: color_info_t gutterForeground; color_info_t gutterBackground; color_info_t gutterIcons; + color_info_t gutterIconsHover; + color_info_t gutterIconsPressed; color_info_t gutterDivider; color_info_t gutterSelectionForeground; color_info_t gutterSelectionBackground; color_info_t gutterSelectionIcons; + color_info_t gutterSelectionIconsHover; + color_info_t gutterSelectionIconsPressed; color_info_t gutterSelectionBorder; color_info_t caret; color_info_t selection;