View Javadoc
1   package de.spiritscorp.datasync.theme;
2   
3   /*-
4    * 		Data Sync
5    *
6    * 		Copyright ©   2022    The Spirit
7    * 		@email                        thespirit@spiritscorp.network
8    *
9    * 		This program is free software; you can redistribute it and/or modify
10   * 		it under the terms of the GNU General Public License as published by
11   * 		the Free Software Foundation; either version 3 of the License, or
12   * 		(at your option) any later version.
13   *
14   * 		This program is distributed in the hope that it will be useful,
15   * 		but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * 		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17   * 		See the GNU General Public License for more details.
18   *
19   * 		You should have received a copy of the GNU General Public License
20   * 		along with this program. If not, see <http://www.gnu.org/licenses/>.
21   */
22  
23  import javafx.scene.Scene;
24  
25  /**
26   * DarkSlateTheme provides a professional dark mode interface using slate and deep blue tones.
27   */
28  public class DarkSlateTheme implements AppTheme {
29  	// CHECKSTYLE:OFF
30  	@Override
31  	public void apply( Scene scene ) {
32  		scene.getRoot().setStyle( "-fx-font-size: 14; -fx-font-family: 'Comic Sans MS', 'Segoe UI'; -fx-background-color: #f4f6f9;" );
33  		final String css = """
34  				/* Global & Core Controls */
35  				.label {
36  				    -fx-text-fill: #202020;
37  				}
38  				.vbox, .hbox, .grid-pane {
39  				    -fx-background-color: #f4f6f9;
40  				}
41  
42  				/* Sidebar / ListView (Die linke Tabelle komplett überarbeitet) */
43  				.list-view {
44  				    -fx-background-color: #2c3e50; /* Dunkleres Blaugrau für die gesamte Sidebar */
45  				    -fx-border-color: #1a252f;
46  				    -fx-border-width: 0 1px 0 0; /* Trennlinie nach rechts */
47  				}
48  				.list-cell {
49  				    -fx-background-color: #2c3e50;
50  				    -fx-text-fill: #ecf0f1; /* Deutlich lesbareres, helles Grau/Weiß */
51  				    -fx-padding: 12px 16px;
52  				    -fx-border-color: #34495e;
53  				    -fx-border-width: 0 0 1px 0; /* Klare Untertrennung der Zeilen */
54  				}
55  				.list-cell:hover {
56  				    -fx-background-color: #34495e; /* Subtiler Hover-Effekt innerhalb der Sidebar */
57  				    -fx-text-fill: #ffffff;
58  				}
59  				.list-cell:selected {
60  				    -fx-background-color: #3498db; /* Kräftiges Navigations-Blau */
61  				    -fx-text-fill: #ffffff;
62  				    -fx-border-color: #2980b9;
63  				    -fx-font-weight: bold;
64  				}
65  
66  				/* Scroll Panes (Zentraler Viewport) */
67  				.scroll-pane, .scroll-pane .viewport{
68  				    -fx-background-color: #2c3e50;
69  				    -fx-background: #f4f6f9 !important;
70  					-fx-text-fill: #ffffff;
71  					-fx-border-color: #bdc3c7 !important; /* Rahmen um das Hauptfenster */
72  				    -fx-border-width: 1px !important;
73  				}
74  				.scroll-pane .label {
75  				    -fx-text-fill: #a0a0a0 !important;
76  				}
77  				.scroll-pane .scroll-bar:vertical, .scroll-pane .scroll-bar:horizontal {
78  				    -fx-background-color: #e2e6ea !important;
79  				}
80  				.scroll-pane .scroll-bar .thumb {
81  				    -fx-background-color: #bdc3c7 !important;
82  				    -fx-border-color: #95a5a6 !important;
83  				    -fx-background-radius: 4px !important;
84  				}
85  
86  				/* Buttons (Lesbarkeit maximiert durch blaugrauen Body & Rahmen) */
87  				.button {
88  				    -fx-background-color: #34495e;
89  				    -fx-text-fill: #ffffff !important;
90  				    -fx-border-color: #2c3e50;
91  				    -fx-border-width: 1px;
92  				    -fx-background-radius: 4px;
93  				    -fx-border-radius: 4px;
94  				    -fx-cursor: hand;
95  				    -fx-padding: 8px 16px;
96  				}
97  				.button:hover {
98  				    -fx-background-color: #415b76;
99  				    -fx-border-color: #3498db; /* Blaues Aufleuchten beim Hovern */
100 				}
101 
102 				/* Form Inputs & Dropdowns */
103 				.text-field, .combo-box, .text-area {
104 				    -fx-background-color: #ffffff;
105 				    -fx-text-fill: #2c3e50;
106 				    -fx-border-color: #bdc3c7; /* Klarer Rahmen für Textfelder */
107 				    -fx-border-width: 1px;
108 				    -fx-border-radius: 4px;
109 				    -fx-background-radius: 4px;
110 				}
111 				.text-field:focused, .combo-box:focused, .text-area:focused {
112 				    -fx-border-color: #3498db; /* Fokus-Blau */
113 				}
114 
115 				.text-area, .text-area .content {
116 				    -fx-background-color: #2c3e50;
117 				    -fx-text-fill: #ffffff !important;
118 				}
119 
120 				/* ComboBox Dropdown-Zellen */
121 				.combo-box:hover {
122 				    -fx-border-color: #3498db;
123 				}
124 				.combo-box .list-cell {
125 				    -fx-background-color: #ffffff !important;
126 				    -fx-text-fill: #2c3e50 !important;
127 				    -fx-border-width: 0;
128 				}
129 				.combo-box .list-cell:hover, .combo-box .list-cell:selected {
130 				    -fx-background-color: #3498db !important;
131 				    -fx-text-fill: #ffffff !important;
132 				}
133 
134 				/* CheckBox (Mehr Blau & klare Umrandung) */
135 				.check-box .box {
136 				    -fx-background-color: #ffffff;
137 				    -fx-border-color: #bdc3c7;
138 				    -fx-border-width: 1px;
139 				    -fx-background-radius: 3px;
140 				    -fx-border-radius: 3px;
141 				}
142 				.check-box:hover .box {
143 				    -fx-border-color: #3498db;
144 				}
145 				.check-box .text {
146 				    -fx-fill: #ffffff !important;
147 				}
148 				.check-box:selected .mark {
149 				    -fx-background-color: #3498db; /* Blaues Häkchen */
150 				}
151 
152 				/* Dropdown-Menü-Buttons & Kontextmenüs */
153 				 .menu-button, .menu-item {
154 				    -fx-background-color: #34495e;
155 				    -fx-text-fill: white;
156 				    -fx-border-color: #2c3e50;
157 				    -fx-background-radius: 4px;
158 				    -fx-border-radius: 4px;
159 				}
160 				.menu-button .label {
161 				    -fx-text-fill: #ffffff !important;
162 				}
163 				.menu-button:hover {
164 				    -fx-background-color: #415b76;
165 				    -fx-border-color: #3498db;
166 				}
167 				/* Wenn man die Maus über das geöffnete Menü bewegt */
168 				.menu-button:hover .label {
169 				    -fx-text-fill: #ffffff !important;
170 				}
171 				.context-menu {
172 				    -fx-background-color: #ffffff !important;
173 				    -fx-border-color: #bdc3c7 !important;
174 				    -fx-border-width: 1px !important;
175 				    -fx-padding: 5px !important;
176 				    -fx-border-radius: 4px !important;
177 				}
178 				.context-menu .menu-item {
179 				    -fx-background-color: #ffffff !important;
180 				}
181 				.context-menu .menu-item .label {
182 				    -fx-text-fill: #2c3e50 !important;
183 				}
184 				.context-menu .menu-item:focused, .context-menu .menu-item:hover {
185 				    -fx-background-color: #3498db !important;
186 				}
187 				.context-menu .menu-item:focused .label, .context-menu .menu-item:hover .label {
188 				    -fx-text-fill: #ffffff !important;
189 				}
190 				.context-menu .separator .line {
191 				    -fx-border-color: #bdc3c7 !important;
192 				}
193 
194 				.table-view {
195 				    -fx-background-color: #2c3e50;
196 				    -fx-border-color: #000000; /* Klarer blauer Außenrahmen */
197 				    -fx-border-width: 1px;
198 				}
199 				/* Tabellenkopf in hellem Navigations-Blau */
200 				.table-view .column-header, .table-view .filler {
201 				    -fx-background-color: #2c3e50;
202 				    -fx-border-color: #3498db; /* Etwas dunkleres Blau für die Spaltentrenner */
203 				}
204 				.table-view .column-header .label {
205 				    -fx-text-fill: #ffffff !important; /* Weiße Spaltenüberschriften */
206 				    -fx-font-weight: bold;
207 				}
208 				/* Die Tabellenzeilen selbst */
209 				.table-row-cell {
210 				    -fx-background-color: #ffffff;
211 				    -fx-text-fill: #2c3e50;
212 				    -fx-border-color: #e2e6ea; /* Subtile hellgraue Linien zwischen den Zeilen */
213 				    -fx-border-width: 0 0 1px 0;
214 				}
215 				/* Jede zweite Zeile leicht bläulich/grau absetzen für bessere Lesbarkeit */
216 				.table-row-cell:odd {
217 				    -fx-background-color: #f4f6f9;
218 				}
219 				/* Wenn eine Tabellenzeile ausgewählt ist */
220 				.table-row-cell:selected {
221 				    -fx-background-color: #2980b9;
222 				    -fx-text-fill: #ffffff !important;
223 				}
224 				.table-row-cell:selected .text {
225 				    -fx-fill: #ffffff !important;
226 				}
227 
228 				/* TabPane */
229 				.tab-pane .tab-header-area .tab-header-background {
230 				    -fx-background-color: #2c3e50;
231 				}
232 				.tab {
233 				    -fx-background-color: #34495e;
234 				    -fx-border-color: #2c3e50;
235 				    -fx-background-radius: 4px 4px 0 0;
236 				    -fx-border-radius: 4px 4px 0 0;
237 				}
238 				.tab:selected {
239 				    -fx-background-color: #3498db;
240 				}
241 				.tab:selected .tab-label {
242 				    -fx-text-fill: #ffffff !important;
243 				}
244 				.tab .tab-label {
245 				    -fx-text-fill: #b8c7ce;
246 				}
247 
248 				.progress-bar .track {
249 				    -fx-background-color: #e2e6ea;
250 				    -fx-border-color: #bdc3c7;
251 				    -fx-border-width: 1px;
252 				    -fx-background-radius: 4px;
253 				}
254 				.progress-bar .bar {
255 				    -fx-background-color: #3498db !important;
256 				    -fx-background-radius: 4px;
257 				    -fx-background-insets: 0;
258 				}
259 
260 				.dialog-pane {
261 				    -fx-background-color: #2c3e50 !important;
262 				    -fx-border-color: #bdc3c7 !important;
263 				    -fx-border-width: 1px !important;
264 				}
265 				.dialog-pane .header-panel {
266 				    -fx-background-color: #2c3e50 !important;
267 				    -fx-border-color: transparent !important;
268 				}
269 				.dialog-pane .content-panel, .dialog-pane .button-bar {
270 				    -fx-background-color: #2c3e50 !important;
271 				}
272 				.dialog-pane .label {
273 				    -fx-text-fill: #ffffff !important;
274 				}
275 				.dialog-pane .button {
276 				    -fx-background-color: #34495e !important;
277 				    -fx-text-fill: white !important;
278 				    -fx-border-color: #2c3e50 !important;
279 				    -fx-background-radius: 4px !important;
280 				    -fx-border-radius: 4px !important;
281 				}
282 				.dialog-pane .button:hover {
283 				    -fx-background-color: #3498db !important;
284 				    -fx-text-fill: #ffffff !important;
285 				}
286 				/* Status Signals */
287 				.status-success { -fx-text-fill: #27ae60; -fx-font-weight: bold; }
288 				.status-error   { -fx-text-fill: #c0392b; -fx-font-weight: bold; }
289 				.status-warning { -fx-text-fill: #f39c12; -fx-font-weight: bold; }
290 				""";
291 
292 		scene.getStylesheets().clear();
293 		scene.getStylesheets().add( "data:text/css," + css.replace( "\n", "" ).replace( " ", "%20" ) );
294 	}
295 	// CHECKSTYLE:OFF
296 
297 	@Override
298 	public String toString() {
299 		return getName();
300 	}
301 
302 	@Override
303 	public String getName() { return "Dark Slate"; }
304 }