1 /*
2  look_n_feel.cpp     MindForger thinking notebook
3 
4  Copyright (C) 2016-2020 Martin Dvorak <martin.dvorak@mindforger.com>
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License
8  as published by the Free Software Foundation; either version 2
9  of the License, or (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "look_n_feel.h"
20 
21 namespace m8r {
22 
23 using namespace std;
24 
LookAndFeels()25 LookAndFeels::LookAndFeels()
26     : config(Configuration::getInstance())
27 {
28     themeNames << UI_THEME_DARK << UI_THEME_LIGHT << UI_THEME_BLACK << UI_THEME_NATIVE;
29 }
30 
init(QApplication * mindforgerApplication)31 void LookAndFeels::init(QApplication* mindforgerApplication)
32 {
33     this->mindforgerApplication = mindforgerApplication;
34 }
35 
isThemeNameValid(const QString & themeName) const36 bool LookAndFeels::isThemeNameValid(const QString& themeName) const
37 {
38     if(!themeName.isEmpty() && themeNames.contains(themeName)) {
39         return true;
40     } else {
41         return false;
42     }
43 }
44 
setTheme(const QString & themeName)45 void LookAndFeels::setTheme(const QString& themeName)
46 {
47     if(UI_THEME_LIGHT == themeName.toStdString()) {
48         setLightTheme();
49     } else if(UI_THEME_DARK == themeName.toStdString()) {
50         setDarkTheme();
51     } else if(UI_THEME_BLACK == themeName.toStdString()) {
52         setBlackTheme();
53     } else if(UI_THEME_NATIVE == themeName.toStdString()) {
54         setNativeTheme();
55     }
56 }
57 
58 /*
59  * Built-in dark theme definition.
60  */
setDarkTheme()61 void LookAndFeels::setDarkTheme()
62 {
63     textColor = QString("#FFF");
64     backgroundColor =  QString("#353535");
65     highlightColor = QString("#008C00"); // RGB: 0, 140, 0
66 
67     editorBackgroundColor = backgroundColor;
68     editorLineNumbersForegroundColor = QString("#777777");
69     editorLineNumbersBackgroundColor = backgroundColor;
70 
71     editorBold.setRgb(0xFF,0xFF,0x00);
72     editorBolder.setRgb(0xFF,0xFF,0x00);
73     editorItalic.setRgb(0x00,0xAA,0x00);
74     editorItalicer.setRgb(0x00,0xAA,0x00);
75     editorStrikethrough.setRgb(0x00,0x00,0x00);
76     editorLink.setRgb(0x00,0xFF,0xFF);
77     editorList.setRgb(0x00,0x99,0x00);
78     editorCodeblock.setRgb(0x99,0x99,0x99);
79     editorHtmlTag.setRgb(0xAA,0x00,0xAA);
80     editorHtmlEntity.setRgb(0xAA,0x00,0xAA);
81     editorHtmlAttrName.setRgb(0xFF,0x00,0xFF);
82     editorHtmlAttrValue.setRgb(0x88,0x88,0x88);
83     editorHtmlComment.setRgb(0x66,0x66,0x66);
84 
85     cliTextColor = Qt::green;
86 
87     mindforgerApplication->setStyle(QStyleFactory::create("fusion"));
88     mindforgerApplication->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
89 
90     // Terminal green: QColor(0, 140, 0)
91     // Terminal blue : QColor(42, 130, 218)
92     palette.setColor(QPalette::Window, QColor(53,53,53));
93     palette.setColor(QPalette::WindowText, Qt::white);
94     palette.setColor(QPalette::Base, QColor(25,25,25));
95     palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
96     palette.setColor(QPalette::Text, Qt::white);
97     palette.setColor(QPalette::Button, QColor(53,53,53));
98     palette.setColor(QPalette::ButtonText, Qt::white);
99     palette.setColor(QPalette::BrightText, Qt::red);
100     palette.setColor(QPalette::Link, QColor(0, 140, 0));
101     palette.setColor(QPalette::Highlight, QColor(0, 140, 0));
102     palette.setColor(QPalette::HighlightedText, Qt::white);
103 
104     mindforgerApplication->setPalette(palette);
105 
106     // IMPROVE tooltips via palette does NOT work > CSS is used instead
107     mindforgerApplication->setStyleSheet(
108         "QToolTip { color: #ffffff; background-color: #008c00; border: 1px solid white; }"
109     );
110 
111     menuStylesheet = QString{
112         "QMenu::separator { background: #444; height: 1px; margin-left: 10px; margin-right: 10px; }"
113         "QMenuBar::item:disabled { color: #555; }"
114         "QMenu::item:disabled { color: #555; background: "}+backgroundColor+QString{"; }"};
115 }
116 
117 /*
118  * Built-in light theme definition.
119  */
setLightTheme()120 void LookAndFeels::setLightTheme()
121 {
122     textColor = QString("#000");
123     backgroundColor = QString("#FFF");
124     highlightColor = QString("#ED764D"); // RGB: 237, 118, 77
125 
126     editorBackgroundColor = QString("#FFF");
127     editorLineNumbersForegroundColor = QString("#BBBBBB");
128     editorLineNumbersBackgroundColor = QString("#EEEEEE");
129 
130     // magenta 0xBB,0x00,0xBB
131     // cyan 0x00,0x88,0x88
132     // blue 0x00,0x00,0xFF
133     // green 0x00,0x55,0x00
134 
135     editorBold.setRgb(0xFF,0x69,0x00);
136     editorBolder.setRgb(0xFF,0x69,0x00);
137     editorItalic.setRgb(0x55,0x00,0x55);
138     editorItalicer.setRgb(0x55,0x00,0x55);
139     editorStrikethrough.setRgb(0xAA,0xAA,0xAA);
140     editorLink.setRgb(0x00,0x00,0xFF);
141     editorList.setRgb(0x00,0x99,0x00);
142     editorCodeblock.setRgb(0x00,0x88,0x88);
143     editorHtmlTag.setRgb(0x00,0x00,0xFF);
144     editorHtmlEntity.setRgb(0x00,0x00,0xFF);
145     editorHtmlAttrName.setRgb(0x00,0x00,0xFF);
146     editorHtmlAttrValue.setRgb(0x88,0x88,0x88);
147     editorHtmlComment.setRgb(0xAA,0xAA,0xAA);
148 
149     cliTextColor = Qt::black;
150 
151     mindforgerApplication->setStyle(QStyleFactory::create("fusion"));
152 
153     // Ubuntu orange:
154     //   100% #E95420 QColor(221, 72, 20)
155     //    90% #EB6536 QColor(235, 101, 54)
156     //    80% #ED764D QColor(237, 118, 77)
157     palette.setColor(QPalette::Link, QColor(237, 118, 77));
158     palette.setColor(QPalette::Highlight, QColor(237, 118, 77));
159     palette.setColor(QPalette::HighlightedText, Qt::white);
160 
161     mindforgerApplication->setPalette(palette);
162 
163     mindforgerApplication->setStyleSheet("QToolTip { color: #ffffff; background-color: #ED764D; border: 1px solid white; }");
164 
165     menuStylesheet = QString("QMenu::separator { background: #ccc; height: 1px; margin-left: 10px; margin-right: 10px; }");
166 }
167 
setBlackTheme()168 void LookAndFeels::setBlackTheme()
169 {
170     textColor = QString("#FFF");
171     backgroundColor = QString("#000");
172     highlightColor = QString("#2A82DA"); // RGB: 42, 130, 218
173 
174     editorBackgroundColor = QString("#000");
175     editorLineNumbersForegroundColor = QString("#555555");
176     editorLineNumbersBackgroundColor = QString("#353535");
177 
178     editorBold.setRgb(0xFF,0xFF,0x00);
179     editorBolder.setRgb(0xFF,0xFF,0x00);
180     editorItalic.setRgb(0x00,0xAA,0x00);
181     editorItalicer.setRgb(0x00,0xAA,0x00);
182     editorStrikethrough.setRgb(0x00,0x00,0x00);
183     editorLink.setRgb(0x00,0xFF,0xFF);
184     editorList.setRgb(0x00,0x99,0x00);
185     editorCodeblock.setRgb(0x99,0x99,0x99);
186     editorHtmlTag.setRgb(0xAA,0x00,0xAA);
187     editorHtmlEntity.setRgb(0xAA,0x00,0xAA);
188     editorHtmlAttrName.setRgb(0xFF,0x00,0xFF);
189     editorHtmlAttrValue.setRgb(0x88,0x88,0x88);
190     editorHtmlComment.setRgb(0x66,0x66,0x66);
191 
192     cliTextColor = QColor(0x99,0xb1,0xff);
193 
194     /* The valid keys can be retrieved using the keys() function. Typically they include
195      * "windows" and "fusion". Depending on the platform, "windowsxp", "windowsvista" and
196      * "macintosh" may be available. Note that keys are case insensitive
197      */
198     mindforgerApplication->setStyle(QStyleFactory::create("fusion"));
199 
200     // Terminal green: QColor(0, 140, 0)
201     // Terminal blue : QColor(42, 130, 218)
202     palette.setColor(QPalette::Foreground, Qt::red);
203     palette.setColor(QPalette::Shadow, Qt::magenta);
204     palette.setColor(QPalette::BrightText, Qt::green);
205     palette.setColor(QPalette::Light, Qt::blue);
206     palette.setColor(QPalette::Midlight, Qt::yellow);
207     palette.setColor(QPalette::Mid, Qt::darkYellow);
208     palette.setColor(QPalette::Dark, Qt::darkRed);
209 
210     palette.setColor(QPalette::AlternateBase, Qt::black);
211     palette.setColor(QPalette::Base, QColor(20,20,20));
212     palette.setColor(QPalette::Text, Qt::white);
213     palette.setColor(QPalette::Window, Qt::black);
214     palette.setColor(QPalette::WindowText, Qt::white);
215     palette.setColor(QPalette::Button, QColor(10,10,10));
216     palette.setColor(QPalette::ButtonText, Qt::white);
217     palette.setColor(QPalette::ToolTipBase, Qt::white);
218     palette.setColor(QPalette::ToolTipText, Qt::white);
219 
220     palette.setColor(QPalette::Link, QColor(42,130,218));
221     palette.setColor(QPalette::Highlight, QColor(42, 130, 218));
222     palette.setColor(QPalette::HighlightedText, Qt::white);
223 
224     mindforgerApplication->setPalette(palette);
225 
226     // IMPROVE tooltips are set in two ways
227     mindforgerApplication->setStyleSheet("QToolTip { color: #ffffff; background-color: #000000; border: 1px solid white; }");
228 
229     menuStylesheet = QString{
230         "QMenu::separator { background: #444; height: 1px; margin-left: 10px; margin-right: 10px; }"
231         "QMenuBar::item:disabled { color: #555; }"
232         "QMenu::item:disabled { color: #555; background: "}+backgroundColor+QString{"; }"};
233 }
234 
setNativeTheme()235 void LookAndFeels::setNativeTheme()
236 {}
237 
isThemeNative() const238 bool LookAndFeels::isThemeNative() const
239 {
240     return UI_THEME_NATIVE == config.getUiThemeName();
241 }
242 
getHtmlTextColor()243 std::string& LookAndFeels::getHtmlTextColor()
244 {
245     static string dark{"#000"}, light{"#FFF"};
246 
247     if(config.isUiHtmlTheme()) {
248         if(config.getUiHtmlCssPath() == UI_HTML_THEME_CSS_LIGHT) {
249             // light CSS theme
250             return dark;
251         } else {
252             // dark CSS theme
253             return light;
254         }
255     } else {
256         if(config.getUiThemeName() == UI_THEME_LIGHT) {
257             // light RAW theme
258             return dark;
259         } else {
260             // dark RAW themes
261             return light;
262         }
263     }
264 }
265 
getHtmlBackgroundColor()266 std::string& LookAndFeels::getHtmlBackgroundColor()
267 {
268     static string dark{"#353535"}, light{"#FFF"};
269 
270     if(config.isUiHtmlTheme()) {
271         if(config.getUiHtmlCssPath() == UI_HTML_THEME_CSS_LIGHT) {
272             // light CSS theme
273             return light;
274         } else {
275             // dark CSS theme
276             return dark;
277         }
278     } else {
279         if(config.getUiThemeName() == UI_THEME_LIGHT) {
280             // light RAW theme
281             return light;
282         } else {
283             // dark RAW themes
284             return dark;
285         }
286     }
287 }
288 
289 
290 } // m8r namespace
291