1 package de.spiritscorp.datasync.gui;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import javafx.application.Application;
24 import javafx.application.Platform;
25 import javafx.collections.FXCollections;
26 import javafx.collections.ObservableList;
27 import javafx.scene.Node;
28 import javafx.scene.Scene;
29 import javafx.scene.control.Label;
30 import javafx.scene.control.Separator;
31 import javafx.scene.control.TextArea;
32 import javafx.scene.image.Image;
33 import javafx.scene.layout.BorderPane;
34 import javafx.scene.layout.VBox;
35 import javafx.stage.Stage;
36
37 import org.kordamp.ikonli.Ikon;
38 import org.kordamp.ikonli.javafx.FontIcon;
39
40 import de.spiritscorp.datasync.Main;
41 import de.spiritscorp.datasync.controller.MainViewController;
42 import de.spiritscorp.datasync.controller.SyncJobContext;
43 import de.spiritscorp.datasync.controller.ViewController;
44 import de.spiritscorp.datasync.io.Debug;
45 import de.spiritscorp.datasync.io.PreferenceManager;
46 import de.spiritscorp.datasync.theme.AppTheme;
47 import de.spiritscorp.datasync.theme.DarkSlateTheme;
48 import de.spiritscorp.datasync.theme.MatrixTerminalTheme;
49 import de.spiritscorp.datasync.theme.NordicLightTheme;
50
51
52
53
54
55
56
57 public class Gui extends Application {
58
59
60 public static final int INFO_DELAY = 4;
61 static final String CSS_BUTTON_ICON = "button-icon";
62 private static final int ICON_SIZE = 20;
63
64 private final ObservableList<SyncJobContext> jobList = FXCollections.observableArrayList();
65 private ViewController controller;
66
67 private final ObservableList<AppTheme> availableThemes = FXCollections.observableArrayList(
68 new DarkSlateTheme(),
69 new MatrixTerminalTheme(),
70 new NordicLightTheme() );
71 private AppTheme currentTheme = availableThemes.getFirst();
72
73 private Scene mainScene;
74 private SidebarView sidebarView;
75 private WorkspaceView workspaceView;
76 private SyncJobContext currentActiveJob;
77 private Stage windowStage;
78
79
80
81
82 public enum ViewState {
83
84
85
86 MONITOR,
87
88
89
90
91 SETTINGS,
92
93
94
95
96 INFO
97 }
98
99 private ViewState currentViewState = ViewState.MONITOR;
100
101
102
103
104
105
106
107
108 public static FontIcon createIcon( final Ikon ikon ) {
109 final FontIcon icon = new FontIcon( ikon );
110 icon.setIconSize( ICON_SIZE );
111 return icon;
112 }
113
114 @Override
115 public void start( final Stage primaryStage ) {
116 this.windowStage = primaryStage;
117 this.controller = new MainViewController( this );
118 this.controller.registerNativeShutdownHook();
119
120 PreferenceManager prefMan = PreferenceManager.getInstance();
121 AppTheme theme = prefMan.getTheme();
122 if( theme instanceof DarkSlateTheme ) {
123 this.currentTheme = availableThemes.get( 0 );
124 }else if( theme instanceof MatrixTerminalTheme ) {
125 this.currentTheme = availableThemes.get( 1 );
126 }else if( theme instanceof NordicLightTheme ) {
127 this.currentTheme = availableThemes.get( 2 );
128 }
129 prefMan.setTheme( currentTheme );
130
131 primaryStage.setTitle( "DataSync Advanced Management Platform" );
132 primaryStage.getIcons().add( new Image( getClass().getResourceAsStream( "/icons/16x16.png" ) ) );
133 Platform.setImplicitExit( false );
134 primaryStage.setOnCloseRequest( _ -> {
135 Debug.printDebug( "[Info] Window hidden. Application processing stays active in background." );
136 controller.runInBackground( false );
137 } );
138 sidebarView = new SidebarView( this, controller );
139 workspaceView = new WorkspaceView( this, controller );
140
141 final BorderPane mainLayout = new BorderPane();
142 mainLayout.setLeft( sidebarView );
143 mainLayout.setCenter( workspaceView );
144
145 mainScene = new Scene( mainLayout, 1350, 800 );
146 if( !getJobList().isEmpty() ) {
147 sidebarView.getSidebarListView().getSelectionModel().select( 0 );
148 }
149 currentTheme.apply( mainScene );
150
151 primaryStage.setScene( mainScene );
152 if( Main.isFirstStart() ) {
153 controller.runInBackground( Main.isFirstStart() );
154 }else {
155 primaryStage.show();
156 }
157 }
158
159
160
161
162
163
164 public void setViewState( final ViewState state ) {
165 this.currentViewState = state;
166 if( state == ViewState.INFO ) {
167 workspaceView.refreshView( state, null );
168 workspaceView.displayCustomViewNode( buildAboutInfoNode() );
169 }else {
170 workspaceView.refreshView( currentViewState, currentActiveJob );
171 }
172 }
173
174
175
176
177
178
179 public void setCurrentActiveJob( final SyncJobContext job ) {
180 this.currentActiveJob = job;
181 workspaceView.bindJob( job );
182 if( this.currentViewState == ViewState.INFO ) {
183 workspaceView.displayCustomViewNode( buildAboutInfoNode() );
184 }else {
185 workspaceView.refreshView( currentViewState, job );
186 }
187 }
188
189
190
191
192
193
194 public void changeTheme( final AppTheme newTheme ) {
195 if( newTheme != null && mainScene != null ) {
196 this.currentTheme = newTheme;
197
198 mainScene.getStylesheets().clear();
199 this.currentTheme.apply( mainScene );
200 }
201 }
202
203
204
205
206
207
208
209
210 public void showStatusNotification( final String message, final NotifyStatus notifyStatus, final int durationSec ) {
211 if( workspaceView != null ) {
212 workspaceView.displayTemporaryStatus( message, notifyStatus, durationSec );
213 }
214 }
215
216
217
218
219
220
221
222 public void setInitialJobConfigurations( final ObservableList<SyncJobContext> jobList ) {
223 this.jobList.clear();
224 this.jobList.addAll( jobList );
225 }
226
227
228
229
230
231
232 public ObservableList<SyncJobContext> getJobList() { return jobList; }
233
234
235
236
237
238
239 public Stage getWindowStage() { return windowStage; }
240
241
242
243
244
245
246 public ObservableList<AppTheme> getAvailableThemes() { return availableThemes; }
247
248
249
250
251
252
253 public AppTheme getCurrentTheme() { return currentTheme; }
254
255 public boolean isShowing() { return windowStage.isShowing(); }
256
257
258
259
260 private Node buildAboutInfoNode() {
261 final VBox infoBox = new VBox( 10 );
262 infoBox.getStyleClass().addAll( "info-box" );
263 final Label appTitle = new Label( "DataSync Core Engine" );
264 appTitle.getStyleClass().addAll( "app-title-label" );
265 final Label version = new Label( "Programmversion: " + Main.VERSION );
266 final Label vendor = new Label( "Lizenznehmer / Entwickler: Tom Spirit" );
267 final Label copyright = new Label( "Copyright: Licensed under GNU GPL v3.0 Copyleft System." );
268 final Separator sep = new Separator();
269 final TextArea legalText = new TextArea(
270 """
271 This program is free software; you can redistribute it and/or modify
272 it under the terms of the GNU General Public License as published by
273 the Free Software Foundation; either version 3 of the License.
274
275 This program is distributed in the hope that it will be useful, without any warranty.
276 """ );
277 legalText.setEditable( false );
278 legalText.setPrefHeight( 150 );
279 legalText.getStyleClass().addAll( "legalText" );
280
281 infoBox.getChildren().addAll( appTitle, version, vendor, copyright, sep, legalText );
282 return infoBox;
283 }
284 }