From 55759c04e3d1d83d487488fe0f0e94514f696784 Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 20 Nov 2016 02:22:03 +0100 Subject: [PATCH] See #3446: the theme filenames now includes a code for version handling. The theme filename must use a template, that will be explained with this example: mytheme-GTK3-20_22.css Everything before -GTK3... is the theme (short) name, the [-GTK3-] is a mandatory part, 20 is the included version where support begins and 22 is the included version where the support ends. One of this two version parameters can be ommited (but not both of course), which make RT understand "is compatible from all version up to xx" (e.g. mytheme-GTK3-_22.css) or "is compatible from version yy and above" (e.g. mytheme-GTK3-20_.css) The RawTherapee-GTK3-_19.css comes 'as is' from the gtk3 branch and has still to be tuned. --- ...wTherapee.css => RawTherapee-GTK3-20_.css} | 0 rtdata/themes/RawTherapee-GTK3-_19.css | 448 ++++++++++++++++++ rtgui/main.cc | 9 +- rtgui/preferences.cc | 90 +++- rtgui/preferences.h | 19 +- 5 files changed, 551 insertions(+), 15 deletions(-) rename rtdata/themes/{RawTherapee.css => RawTherapee-GTK3-20_.css} (100%) create mode 100644 rtdata/themes/RawTherapee-GTK3-_19.css diff --git a/rtdata/themes/RawTherapee.css b/rtdata/themes/RawTherapee-GTK3-20_.css similarity index 100% rename from rtdata/themes/RawTherapee.css rename to rtdata/themes/RawTherapee-GTK3-20_.css diff --git a/rtdata/themes/RawTherapee-GTK3-_19.css b/rtdata/themes/RawTherapee-GTK3-_19.css new file mode 100644 index 000000000..e6eac9793 --- /dev/null +++ b/rtdata/themes/RawTherapee-GTK3-_19.css @@ -0,0 +1,448 @@ +/* + This file is part of RawTherapee. + + Copyright (c) 2015 DrSlony + Copyright (c) 2016 Hombre + + RawTherapee is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + RawTherapee is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with RawTherapee. If not, see . +*/ + +* { + color: #AAAAAA; +} + +.view:selected { + color: #262626; + background-color: #AAAAAA +} + +/* The Places and Dir browser panels */ +.view { + background-color: #262626; +} +/* The headers of these panels */ +.view .button { + background-color: #363636; + padding: 2px; +} + +.plainback { + background-color: #404040; +} + +GtkBox { + border-width: 0; + border-style: none; + border-radius: 0; + margin: 0; + padding: 0; +} + +GtkGrid { + margin: 2px; + padding: 0; + border-width: 0; + border-style: none; + border-radius: 0; +} + +/* Affects all frames except in the toolbox */ +GtkFrame { + border-width: 0; + border-color: #303030; + border-radius: 0; + border-style: solid; + /*border-style: none none none solid;*/ + padding: 4px; +} + +GtkFrame > GtkLabel { + color: #D8D8D8; +} + +#FileBrowser { + padding: 10px; + margin: 10px; +} + +/* Frames in Preferences */ +#PrefNotebook GtkFrame { + background-color: #3B3B3B; + border: 1px solid #505050; + border-radius: 4px; +} + +/* Frames in the toolbox. Not MyExpander frames. */ +GtkEventBox .frame { + border-color: #565656; +} + +/*.EditorTopPanel .button, .ToolBarPanelFileBrowser .button, .EditorZoomPanel .button {*/ +.button { + padding: 1px; + margin: 1px; +} + +/* Adjusters */ +.text-button { + padding: 0; +} + +/* Any text-button which is a real button, unlike Slider label */ +.text-button.button { + padding: 4px; +} + +.separator { + color: #363636; +} + +GtkProgressBar { + -GtkProgressBar-min-vertical-bar-width: 10; + -GtkProgressBar-min-horizontal-bar-height: 10; +} + +GtkDrawingArea { + border-radius: 0; + background-color: #363636; + border: 1px solid #252525; +} + +GtkDrawingArea:selected { + background-color: #565656; + border-radius: 10px; +} + +GtkImage { + padding: 1px; +} + +/* Vertical group of buttons in 1 column */ +GtkButton.Top { + border-radius: 10px 4px 0 0; + border-style: solid solid none solid; + margin-bottom: 0; +} +GtkButton.MiddleV { + border-radius: 0; + border-style: none solid none solid; + margin-top: 0; + margin-bottom: 0; +} +GtkButton.Bottom { + border-radius: 0 0 4px 4px; + border-style: none solid solid solid; + margin-top: 0; +} +/* end */ + +/* Horizontal group of buttons in 1 row */ +GtkButton.Left { + border-radius: 4px 0 0 4px; + border-style: solid none solid solid; + margin-right: 0; +} +GtkButton.MiddleH { + border-radius: 0; + border-style: solid none solid none; + margin-left: 0; + margin-right: 0; +} +GtkButton.Right { + border-radius: 0 4px 4px 0; + border-style: solid solid solid none; + margin-left: 0; +} +/* end */ + +/* [1.23[-][+]] */ +GtkEntry, GtkSpinButton { + padding: 1px; + background-color: #262626; +} + +GtkEntry:insensitive, GtkSpinButton:insensitive { + background-color: #363636; +} + +GtkEntry:hover, GtkSpinButton:hover { + background-color: #565656; +} + +GtkEntry:selected { + color: #262626; + background-color: #AAAAAA; +} + +/* Context menus */ +GtkMenu { + background-color: #262626; + color: #909090; +} + +/* Context menu item */ +.menuitem { + padding: 2px; +} + +#MyExpander { + margin: 10px; + padding: 5px; +} + +/* Tool background */ +#ExpanderBox { + background-color: #363636; + border-width: 1px; + border-style: solid; + border-radius: 4px; + border-color: #252525; + margin: 9px; + padding: 4px; +} + +#ExpanderBox GtkDrawingArea { + background-color: #363636; +} + +#ExpanderBox GtkFrame { + background-color: #3B3B3B; + border-style: solid; + border-width: 1px; + border-radius: 4px; + border-color: #313131; + margin: 3px; + padding: 2px; +} + +#ExpanderBox GtkFrame GtkDrawingArea { + background-color: #3B3B3B; +} + +#ExpanderBox GtkFrame GtkFrame { + background-color: #414141; + border: 1px solid #373737; + border-radius: 4px; + margin: 3px; + padding: 2px; +} + +#ExpanderBox GtkFrame GtkFrame GtkDrawingArea { + background-color: #414141; +} + +/* Sub-tool (MyExpander) background */ +#ExpanderBox2 { + background-color: #3B3B3B; + border: 1px solid #2A2A2A; + border-radius: 4px; + margin: 9px; + padding: 4px; +} + +#ExpanderBox2 GtkDrawingArea { + background-color: #3B3B3B; +} + +#ExpanderBox2 GtkFrame { + background-color: #414141; + border: 1px solid #373737; + border-radius: 4px; + margin: 3px; + padding: 2px; +} + +#ExpanderBox2 GtkFrame GtkDrawingArea { + background-color: #414141; +} + +#ExpanderBox2 GtkFrame GtkFrame { + background-color: #474747; + border: 1px solid #3D3D3D; + border-radius: 4px; + margin: 3px; + padding: 2px; +} + +#ExpanderBox2 GtkFrame GtkFrame GtkDrawingArea { + background-color: #474747; +} + +#MyExpanderTitle { + margin: 5px; + padding: 3px 1px 3px 1px; + font-size: 120%; +} +#MyExpanderTitle GtkLabel { + color: #CCCCCC; +} +#MyExpanderTitle:hover { + background-color: #202020; +} +#MyExpanderTitle GtkEventBox:hover GtkImage { + background-color: #202020; + border-radius: 3px; +} +#MyExpanderTitle:hover GtkLabel { + color: #D8D8D8; +} + +#ExpanderBox2 GtkSeparator, #ExpanderBox3 GtkSeparator { + color: #292929; +} + +/* Editor tab button */ +#MainNotebook > GtkGrid GtkLabel, #MainNotebook > GtkGrid GtkImage { + /* OK */ + padding: 1px; +} + +/* File Browser right side tabs - Toolbox, Inspector, Fast Export, Filter */ +GtkNotebook tab { + background-color: #383838; + border-width: 1px; + border-style: none; + border-color: #262626; + border-radius: 0; + padding: 3px; +} + +GtkNotebook tab:hover { + background-color: #505050; +} + +GtkNotebook tab:active { + border-width: 5px; + border-color: #989898; +} + +/* Get rid of shitty notebook header shadow */ +GtkNotebook.top tab { + border-bottom-style: solid; + padding-bottom: 8px; +} +GtkNotebook.right tab { + border-left-style: solid; + padding-left: 8px; +} +GtkNotebook.bottom tab { + border-top-style: solid; + padding-top: 8px; +} +GtkNotebook.left tab { + border-right-style: solid; + padding-right: 8px; +} + +/* Get rid of notebook frame border - too many borders */ +GtkNotebook.top.header, GtkNotebook.right.header, GtkNotebook.bottom.header, GtkNotebook.left.header { + box-shadow: none; + border-width: 1px; + border-color: #262626; + border-style: none; + border-radius: 0; + background-color: #383838; + padding: 0; +} +/* Get rid of notebook header border - too many borders */ +GtkNotebook.top.header { + /* OK */ + border-bottom-style: solid; +} +GtkNotebook.right.header { + /* OK */ + border-left-style: solid; +} +GtkNotebook.bottom.header { + /* OK */ + border-top-style: solid; +} +GtkNotebook.left.header { + /* OK */ + border-right-style: solid; +} +GtkNotebook.frame { + /* OK */ + border-radius: 0; + border-style: none; +} + +/* Pad notebooks, makes the other borders look nicer */ +GtkNotebook { + /* OK */ + background-color: #484848; + padding: 0; +} + + +#MainNotebook.header { + /* OK */ + background-color: #2A2A2A; +} +#MainNotebook > tab { + /* OK */ + background-color: #2A2A2A; +} +#MainNotebook > tab:hover { + /* OK */ + background-color: #505050; +} +#MainNotebook > tab:active { + /* OK */ + border-color: #989898; +} + +#RightNotebook.header { + /* OK */ + background-color: #2A2A2A; +} +#RightNotebook > tab { + /* OK */ + background-color: #2A2A2A; +} +#RightNotebook > tab:hover { + /* OK */ + background-color: #505050; +} +#RightNotebook > tab:active { + /* OK */ + border-color: #989898; +} + + +/* All tool panels have a frame except for Meta which unlike the rest is a notebook itself. + * So we use CSS to make it look like a frame. */ +#MetaPanelNotebook.frame { + border: 1px solid #262626; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top-width: 0; +} + +#MetaPanelNotebook.header { + border: 1px solid #262626; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-width: 0; + padding: 5px; + margin: 5px; +} + +.tooltip { + padding: 0; +} diff --git a/rtgui/main.cc b/rtgui/main.cc index 1933939f8..c984b4632 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -56,7 +56,6 @@ Glib::ustring creditsPath; Glib::ustring licensePath; Glib::ustring argv1; bool simpleEditor; -Glib::RefPtr cssForced; Glib::RefPtr cssRT; //Glib::Threads::Thread* mainThread; @@ -313,7 +312,13 @@ int main(int argc, char **argv) Glib::ustring filename = Glib::build_filename(argv0, "themes", options.theme + ".css"); if (!Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { - options.theme = "RawTherapee"; + options.theme = "RawTherapee-GTK"; + // We're not testing GTK_MAJOR_VERSION == 3 here, since this branch requires Gtk3 only + if (GTK_MINOR_VERSION < 20) { + options.theme = options.theme + "3-_19"; + } else { + options.theme = options.theme + "3-20_"; + } filename = Glib::build_filename(argv0, "themes", options.theme + ".css"); } cssRT = Gtk::CssProvider::create(); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 2be4cecd3..efc5d3972 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -41,6 +41,8 @@ Preferences::Preferences (RTWindow *rtwindow) , parent (rtwindow) , splash (nullptr) { + regex = Glib::Regex::create("^(.+)-GTK3-(\\d{1,2})?_(\\d{1,2})?\\.css$", Glib::RegexCompileFlags::REGEX_CASELESS); + moptions.copyFrom (&options); /* @@ -100,6 +102,19 @@ Preferences::~Preferences () options.preferencesHeight = get_height(); } +int Preferences::getThemeRowNumber(Glib::ustring& longThemeFName) +{ + + if (regex->match(longThemeFName + ".css", matchInfo)) { + for (size_t i=0 ; iset_active (0); - std::vector themes; - parseDir (argv0 + "/themes", themes, ".css"); + parseThemeDir (Glib::build_filename(argv0, "themes")); - for (size_t i = 0; i < themes.size(); i++) { - theme->append (themes[i]); + for (size_t i = 0; i < themeFNames.size(); i++) { + theme->append (themeFNames.at(i).shortFName); } themeGrid->attach_next_to(*themelab, Gtk::POS_LEFT, 1, 1); @@ -1337,6 +1351,59 @@ void Preferences::parseDir (Glib::ustring dirname, std::vector& i delete dir; } +void Preferences::parseThemeDir (Glib::ustring dirname) +{ + + if (dirname.empty()) { + return; + } + + // process directory + Glib::Dir* dir = nullptr; + + try { + dir = new Glib::Dir (dirname); + } catch (const Glib::Error& e) { + return; + } + + for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { + Glib::ustring fname = Glib::build_filename(dirname, *i); + Glib::ustring sname = *i; + + bool keepIt = false; + + // ignore directories and filter out unsupported theme + if (regex->match(sname, matchInfo) && !Glib::file_test (fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= 4) { + Glib::ustring fname2 = matchInfo.fetch(1); + Glib::ustring minMinor = matchInfo.fetch(2); + Glib::ustring maxMinor = matchInfo.fetch(3); + + if (!minMinor.empty()) { + guint64 minMinorVal = g_ascii_strtoll(minMinor.c_str(), 0, 0); + if ((guint64)GTK_MINOR_VERSION >= minMinorVal) { + keepIt = true; + } + } + if (!maxMinor.empty()) { + guint64 maxMinorVal = g_ascii_strtoll(maxMinor.c_str(), 0, 0); + if ((guint64)GTK_MINOR_VERSION <= maxMinorVal) { + keepIt = true; + } + } + if (keepIt) { + themeFNames.push_back(ThemeFilename(matchInfo.fetch(1), sname.substr(0, sname.size() - 4))); + } + } + } + std::sort(themeFNames.begin(), themeFNames.end(), [] (const ThemeFilename& firstDir, const ThemeFilename& secondDir) + { + return firstDir.longFName < secondDir.longFName; + }); + + delete dir; +} + void Preferences::storePreferences () { @@ -1369,7 +1436,7 @@ void Preferences::storePreferences () moptions.shadowThreshold = (int)shThresh->get_value (); moptions.language = languages->get_active_text (); moptions.languageAutoDetect = ckbLangAutoDetect->get_active (); - moptions.theme = theme->get_active_text (); + moptions.theme = themeFNames.at(theme->get_active_row_number ()).longFName; Gdk::RGBA cropCol = butCropCol->get_rgba(); moptions.cutOverlayBrush[0] = cropCol.get_red(); @@ -1585,7 +1652,8 @@ void Preferences::fillPreferences () ckbHistogramWorking->set_active (moptions.rtSettings.HistogramWorking); languages->set_active_text (moptions.language); ckbLangAutoDetect->set_active (moptions.languageAutoDetect); - theme->set_active_text (moptions.theme); + int themeNbr = getThemeRowNumber(moptions.theme); + theme->set_active (themeNbr==-1 ? 0 : themeNbr); Gdk::RGBA cropCol; cropCol.set_rgba(moptions.cutOverlayBrush[0], moptions.cutOverlayBrush[1], moptions.cutOverlayBrush[2]); @@ -1783,7 +1851,7 @@ void Preferences::okPressed () void Preferences::cancelPressed () { // set the initial theme back - if (theme->get_active_text() != options.theme) { + if (themeFNames.at(theme->get_active_row_number ()).longFName != options.theme) { RTImage::setPaths(options); RTImage::updateImages(); switchThemeTo(options.theme); @@ -1830,10 +1898,10 @@ void Preferences::aboutPressed () void Preferences::themeChanged () { - moptions.theme = theme->get_active_text (); + moptions.theme = themeFNames.at(theme->get_active_row_number ()).longFName; RTImage::setPaths(moptions); RTImage::updateImages(); - switchThemeTo(theme->get_active_text ()); + switchThemeTo(moptions.theme); } void Preferences::forRAWComboChanged () @@ -1961,10 +2029,12 @@ void Preferences::restoreValue() void Preferences::switchThemeTo(Glib::ustring newTheme) { - Glib::ustring filename(argv0 + "/themes/" + newTheme + ".css"); + Glib::ustring filename(Glib::build_filename(argv0, "themes", newTheme + ".css")); if (!css) { css = Gtk::CssProvider::create(); + Glib::RefPtr screen = Gdk::Screen::get_default(); + Gtk::StyleContext::add_provider_for_screen(screen, css, GTK_STYLE_PROVIDER_PRIORITY_USER); } try { diff --git a/rtgui/preferences.h b/rtgui/preferences.h index a1706f954..749b9669b 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -60,11 +60,21 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener add(addsetid); } }; + + class ThemeFilename + { + public: + Glib::ustring shortFName; + Glib::ustring longFName; + + ThemeFilename (Glib::ustring sfname, Glib::ustring lfname) : shortFName(sfname), longFName(lfname) {} + }; + Glib::RefPtr behModel; BehavColumns behavColumns; - - -protected: + std::vector themeFNames; + Glib::RefPtr regex; + Glib::MatchInfo matchInfo; Splash* splash; ProfileStoreComboBox* rprofiles; Gtk::TreeIter currRawRow; // :) @@ -198,6 +208,7 @@ protected: void fillPreferences (); void storePreferences (); void parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext); + void parseThemeDir (Glib::ustring dirname); void updateDFinfos (); void updateFFinfos (); void workflowUpdate(); @@ -210,6 +221,8 @@ protected: void switchThemeTo (Glib::ustring newTheme); bool splashClosed(GdkEventAny* event); + int getThemeRowNumber(Glib::ustring& longThemeFName); + void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); Gtk::Widget* getProcParamsPanel ();