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 ();