diff --git a/Source/NimbleCommander/NimbleCommander/Core/Theming/ThemesManager.mm b/Source/NimbleCommander/NimbleCommander/Core/Theming/ThemesManager.mm index 539aca05a..4434822dd 100644 --- a/Source/NimbleCommander/NimbleCommander/Core/Theming/ThemesManager.mm +++ b/Source/NimbleCommander/NimbleCommander/Core/Theming/ThemesManager.mm @@ -7,7 +7,10 @@ #include #include #include +#include #include +#include +#include namespace nc { @@ -15,12 +18,20 @@ [[clang::no_destroy]] static std::shared_ptr g_CurrentTheme; -using TMN = ThemesManager::Notifications; +template +static constexpr auto make_array_n_impl(T &&value, std::index_sequence) +{ + return std::array, size>{(static_cast(indexes), value)..., std::forward(value)}; +} -using NotificationsMapping = - robin_hood::unordered_flat_map; +template +static constexpr auto make_array_n(T &&value) +{ + return make_array_n_impl(std::forward(value), std::make_index_sequence{}); +} -[[clang::no_destroy]] static const NotificationsMapping g_EntryToNotificationMapping = { +using TMN = ThemesManager::Notifications; +static constexpr std::pair g_EntryToNotificationMappingTable[] = { {"themeAppearance", TMN::Appearance}, {"filePanelsColoringRules_v1", TMN::FilePanelsGeneral}, {"filePanelsGeneralDropBorderColor", TMN::FilePanelsGeneral}, @@ -93,10 +104,26 @@ {"viewerFont", TMN::Viewer}, {"viewerOverlayColor", TMN::Viewer}, {"viewerTextColor", TMN::Viewer}, + {"viewerTextSyntaxCommentColor", TMN::Viewer}, + {"viewerTextSyntaxPreprocessorColor", TMN::Viewer}, + {"viewerTextSyntaxKeywordColor", TMN::Viewer}, + {"viewerTextSyntaxOperatorColor", TMN::Viewer}, + {"viewerTextSyntaxIdentifierColor", TMN::Viewer}, + {"viewerTextSyntaxNumberColor", TMN::Viewer}, + {"viewerTextSyntaxStringColor", TMN::Viewer}, {"viewerSelectionColor", TMN::Viewer}, {"viewerBackgroundColor", TMN::Viewer}, }; +static constinit const auto g_EntryToNotificationMapping = [] { + auto items = make_array_n( + std::pair(frozen::string(""), 0)); + for( size_t i = 0; i < std::size(g_EntryToNotificationMappingTable); ++i ) + items[i] = std::pair(g_EntryToNotificationMappingTable[i].first, + g_EntryToNotificationMappingTable[i].second); + return frozen::make_unordered_map(items); +}(); + static std::string MigrateThemeName(const std::string &_name); static std::optional ExtractThemeNameAppearance(const nc::config::Value &_doc); diff --git a/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTab.xib b/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTab.xib index fed848e5e..fabcfee96 100644 --- a/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTab.xib +++ b/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTab.xib @@ -1,8 +1,8 @@ - + - + @@ -50,7 +50,7 @@ - + @@ -120,13 +120,13 @@ @@ -198,8 +198,8 @@ - - - + + + diff --git a/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTabColoringRulesControl.xib b/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTabColoringRulesControl.xib index eeff7f519..46e784549 100644 --- a/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTabColoringRulesControl.xib +++ b/Source/NimbleCommander/NimbleCommander/Preferences/Base.lproj/PreferencesWindowThemesTabColoringRulesControl.xib @@ -1,8 +1,8 @@ - + - + @@ -20,13 +20,13 @@ - + - + - + @@ -48,7 +48,7 @@ - + @@ -80,7 +80,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -144,7 +144,7 @@ - + @@ -182,7 +182,7 @@ - + @@ -198,23 +198,23 @@ - + - + - + @@ -223,7 +223,7 @@ - - + + diff --git a/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesControls.mm b/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesControls.mm index 8361ea1a6..44da10a3f 100644 --- a/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesControls.mm +++ b/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesControls.mm @@ -76,8 +76,22 @@ - (id)initWithFrame:(NSRect)frameRect [self addConstraints:constraints]; }; add_visfmt(@"|[m_ColorWell(==40)]-[m_Description]-(>=0)-|"); - add_visfmt(@"V:|-(>=0@250)-[m_ColorWell(==18)]-(>=0@250)-|"); - add_visfmt(@"V:|-(==0)-[m_Description]-(==0)-|"); + add_visfmt(@"V:[m_ColorWell(==18)]"); + [self addConstraint:[NSLayoutConstraint constraintWithItem:m_ColorWell + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:m_Description + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; } return self; } @@ -370,7 +384,9 @@ - (NSView *)tableView:(NSTableView *) [[maybe_unused]] tableView { if( row >= static_cast(m_Rules.size()) ) return nil; + auto &r = m_Rules[row]; + if( [tableColumn.identifier isEqualToString:@"name"] ) { NSTextField *tf = [[NSTextField alloc] initWithFrame:NSRect()]; tf.stringValue = [NSString stringWithUTF8StdString:r.name]; @@ -385,14 +401,56 @@ - (NSView *)tableView:(NSTableView *) [[maybe_unused]] tableView cw.color = r.regular; cw.target = self; cw.action = @selector(onColorChanged:); - return cw; + cw.translatesAutoresizingMaskIntoConstraints = false; + NSTableCellView *cv = [[NSTableCellView alloc] initWithFrame:NSRect()]; + [cv addSubview:cw]; + [cv addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[cw(==18)]" + options:0 + metrics:nil + views:NSDictionaryOfVariableBindings(cw)]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:cw + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterX + multiplier:1. + constant:0.]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:cw + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; + return cv; } if( [tableColumn.identifier isEqualToString:@"focused"] ) { NSColorWell *cw = [[NSColorWell alloc] initWithFrame:NSRect()]; cw.color = r.focused; cw.target = self; cw.action = @selector(onColorChanged:); - return cw; + cw.translatesAutoresizingMaskIntoConstraints = false; + NSTableCellView *cv = [[NSTableCellView alloc] initWithFrame:NSRect()]; + [cv addSubview:cw]; + [cv addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[cw(==18)]" + options:0 + metrics:nil + views:NSDictionaryOfVariableBindings(cw)]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:cw + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterX + multiplier:1. + constant:0.]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:cw + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; + return cv; } if( [tableColumn.identifier isEqualToString:@"filter"] ) { NSButton *bt = [[NSButton alloc] initWithFrame:NSRect()]; @@ -402,8 +460,30 @@ - (NSView *)tableView:(NSTableView *) [[maybe_unused]] tableView static_cast(bt.cell).controlSize = NSControlSizeMini; bt.target = self; bt.action = @selector(onColoringFilterClicked:); - return bt; + bt.translatesAutoresizingMaskIntoConstraints = false; + NSTableCellView *cv = [[NSTableCellView alloc] initWithFrame:NSRect()]; + [cv addSubview:bt]; + [cv addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bt(==18)]" + options:0 + metrics:nil + views:NSDictionaryOfVariableBindings(bt)]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:bt + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterX + multiplier:1. + constant:0.]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:bt + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; + return cv; } + return nil; } diff --git a/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTab.mm b/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTab.mm index d52bef0d6..adb5bf29c 100644 --- a/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTab.mm +++ b/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTab.mm @@ -22,7 +22,7 @@ using namespace std::literals; using nc::ThemePersistence; -static NSTextField *SpawnSectionTitle(NSString *_title) +static NSTableCellView *SpawnSectionTitle(NSString *_title) { NSTextField *tf = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; tf.stringValue = _title; @@ -30,10 +30,25 @@ tf.editable = false; tf.drawsBackground = false; tf.font = [NSFont labelFontOfSize:13]; - return tf; -} - -static NSTextField *SpawnEntryTitle(NSString *_title) + tf.translatesAutoresizingMaskIntoConstraints = false; + NSTableCellView *cv = [[NSTableCellView alloc] initWithFrame:NSRect()]; + [cv addSubview:tf]; + [cv addConstraints:[NSLayoutConstraint + constraintsWithVisualFormat:@"H:|-(0)-[tf]-(0)-|" + options:0 + metrics:nil + views:NSDictionaryOfVariableBindings(tf)]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:tf + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; + return cv; +} + +static NSTableCellView *SpawnEntryTitle(NSString *_title) { NSTextField *tf = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; tf.stringValue = _title; @@ -42,7 +57,22 @@ tf.drawsBackground = false; tf.font = [NSFont labelFontOfSize:11]; tf.lineBreakMode = NSLineBreakByTruncatingTail; - return tf; + tf.translatesAutoresizingMaskIntoConstraints = false; + NSTableCellView *cv = [[NSTableCellView alloc] initWithFrame:NSRect()]; + [cv addSubview:tf]; + [cv addConstraints:[NSLayoutConstraint + constraintsWithVisualFormat:@"H:|-(0)-[tf]-(0)-|" + options:0 + metrics:nil + views:NSDictionaryOfVariableBindings(tf)]]; + [cv addConstraint:[NSLayoutConstraint constraintWithItem:tf + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:cv + attribute:NSLayoutAttributeCenterY + multiplier:1. + constant:0.]]; + return cv; } @interface PreferencesWindowThemesTab () @@ -382,7 +412,7 @@ - (CGFloat)outlineView:(NSOutlineView *) [[maybe_unused]] outlineView heightOfRo if( i.type == PreferencesWindowThemesTabItemType::ColoringRules ) return 140; - return 18; + return 20.; } - (void)loadSelectedDocument diff --git a/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTabModel.mm b/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTabModel.mm index 2cb1f0bf0..1c89ca4c5 100644 --- a/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTabModel.mm +++ b/Source/NimbleCommander/NimbleCommander/Preferences/PreferencesWindowThemesTabModel.mm @@ -149,6 +149,13 @@ - (instancetype)initWithTitle:(NSString *)_title andChildren:(NSArray *)_childre SpawnFontNode(@"Text font", "viewerFont"), SpawnColorNode(@"Overlay color", "viewerOverlayColor"), SpawnColorNode(@"Foreground color", "viewerTextColor"), + SpawnColorNode(@"Syntax color - keyword", "viewerTextSyntaxKeywordColor"), + SpawnColorNode(@"Syntax color - operator", "viewerTextSyntaxOperatorColor"), + SpawnColorNode(@"Syntax color - identifier", "viewerTextSyntaxIdentifierColor"), + SpawnColorNode(@"Syntax color - number", "viewerTextSyntaxNumberColor"), + SpawnColorNode(@"Syntax color - string", "viewerTextSyntaxStringColor"), + SpawnColorNode(@"Syntax color - comment", "viewerTextSyntaxCommentColor"), + SpawnColorNode(@"Syntax color - preprocessor", "viewerTextSyntaxPreprocessorColor"), SpawnColorNode(@"Selection color", "viewerSelectionColor"), SpawnColorNode(@"Background color", "viewerBackgroundColor") ];