mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-10-19 13:53:01 +02:00
Use one base font size and a per-profile startup design
JavaFX picks a 13px default font on macOS and Linux but 12px on Windows, so labels in fixed-size controls were cut off outside Windows. Both stylesheets now set 12px on the root. Each operator profile now chooses light or dark mode for startup on the GUI settings tab. The Windows menu entries remain a quick switch for the running session. All windows, including the update window and the top candidates list, follow the design, and the main window no longer starts light while the station map starts dark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
27c093b108
commit
1dfd8bf46b
12 files changed
+117
-42
No files matched your search
@@ -133,6 +133,9 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
private On4KstConnectionState lastDisplayedConnectionState;
|
||||
private String lastDisplayedConnectionDetail = "";
|
||||
|
||||
/** Scenes whose stylesheet follows the light/dark design switch. */
|
||||
private final List<Scene> themedScenes = new ArrayList<>();
|
||||
|
||||
private final Button btnBandUpgradeIndicator = new Button("BAND+");
|
||||
private final Tooltip tipBandUpgradeIndicator = new Tooltip();
|
||||
private Timeline bandUpgradeBlinkTimeline;
|
||||
@@ -4589,7 +4592,10 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
root.setCenter(listView);
|
||||
root.setBottom(new Label("Double-click a candidate to select it."));
|
||||
|
||||
stage.setScene(new Scene(root, 360, 500));
|
||||
Scene candidatesScene = new Scene(root, 360, 500);
|
||||
registerThemedScene(candidatesScene);
|
||||
stage.setOnHidden(event -> themedScenes.remove(candidatesScene));
|
||||
stage.setScene(candidatesScene);
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@@ -5621,21 +5627,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
window30.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
|
||||
System.out.println("KST4ContestApp, info: switching to dark mode");
|
||||
|
||||
scn_ChatwindowMainScene.getStylesheets().clear();
|
||||
clusterAndQSOMonScene.getStylesheets().clear();
|
||||
settingsScene.getStylesheets().clear();
|
||||
setUserAgentStylesheet(null);
|
||||
|
||||
scn_ChatwindowMainScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING);
|
||||
clusterAndQSOMonScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING);
|
||||
settingsScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING);
|
||||
|
||||
chatcontroller.getChatPreferences().setGUI_darkModeActive(true);
|
||||
if (stationMapBridge != null) {
|
||||
stationMapBridge.applyThemeFromPreferences(); //dark mode for the map
|
||||
}
|
||||
// quick switch for this session only, the startup design is set per profile in the GUI options
|
||||
applyTheme(true);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5643,21 +5636,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
window40.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
|
||||
System.out.println("KST4ContestApp, info: switching to default mode");
|
||||
|
||||
scn_ChatwindowMainScene.getStylesheets().clear();
|
||||
clusterAndQSOMonScene.getStylesheets().clear();
|
||||
settingsScene.getStylesheets().clear();
|
||||
setUserAgentStylesheet(null);
|
||||
|
||||
scn_ChatwindowMainScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
clusterAndQSOMonScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
settingsScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
chatcontroller.getChatPreferences().setGUI_darkModeActive(false);
|
||||
|
||||
if (stationMapBridge != null) {
|
||||
stationMapBridge.applyThemeFromPreferences();
|
||||
}
|
||||
// quick switch for this session only, the startup design is set per profile in the GUI options
|
||||
applyTheme(false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5779,6 +5759,43 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
return menubar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a scene whose stylesheet follows the light/dark design switch and
|
||||
* applies the currently active design to it.
|
||||
*/
|
||||
private void registerThemedScene(Scene scene) {
|
||||
if (scene == null) {
|
||||
return;
|
||||
}
|
||||
themedScenes.add(scene);
|
||||
applyThemeStylesheet(scene, chatcontroller.getChatPreferences().isGUI_darkModeActive());
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches all registered windows and the station map to the dark or light design
|
||||
* for the running session. The per-profile startup design is not changed here.
|
||||
*/
|
||||
private void applyTheme(boolean darkMode) {
|
||||
LOGGER.info("Switching GUI design to " + (darkMode ? "dark" : "light") + " mode");
|
||||
|
||||
chatcontroller.getChatPreferences().setGUI_darkModeActive(darkMode);
|
||||
setUserAgentStylesheet(null);
|
||||
|
||||
for (Scene scene : themedScenes) {
|
||||
applyThemeStylesheet(scene, darkMode);
|
||||
}
|
||||
|
||||
if (stationMapBridge != null) {
|
||||
stationMapBridge.applyThemeFromPreferences();
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyThemeStylesheet(Scene scene, boolean darkMode) {
|
||||
scene.getStylesheets().setAll(darkMode
|
||||
? ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING
|
||||
: ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Sked warning Initializing and functional section
|
||||
@@ -6975,6 +6992,9 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
activeOperatorProfile.getWorkedDatabaseRelativeFileName(),
|
||||
activeOperatorProfile.isSeedWorkedDatabaseFromResource());
|
||||
layoutAutosave = new LayoutAutosave(chatcontroller.getChatPreferences());
|
||||
// Every profile starts with its own configured design; the menu quick switch only lasts for the session.
|
||||
chatcontroller.getChatPreferences().setGUI_darkModeActive(
|
||||
chatcontroller.getChatPreferences().isGUI_darkModeActiveByDefault());
|
||||
messageVariableResolver = new MessageVariableResolver(chatcontroller.getChatPreferences());
|
||||
chatcontroller.setStatusListener(this); //callback interface for updating Thread events in visual
|
||||
|
||||
@@ -7109,7 +7129,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
screenAwareMainSceneSizeHW[0]
|
||||
);
|
||||
|
||||
scn_ChatwindowMainScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
registerThemedScene(scn_ChatwindowMainScene);
|
||||
|
||||
|
||||
|
||||
@@ -9123,7 +9143,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
|
||||
clusterAndQSOMonScene = new Scene(pnl_directedMSGWin, chatcontroller.getChatPreferences().getGUIclusterAndQSOMonStage_SceneSizeHW()[0], chatcontroller.getChatPreferences().getGUIclusterAndQSOMonStage_SceneSizeHW()[1]);
|
||||
clusterAndQSOMonScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
registerThemedScene(clusterAndQSOMonScene);
|
||||
|
||||
clusterAndQSOMonScene.heightProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
@@ -9251,6 +9271,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
System.out.println("SRVR Version: " + chatcontroller.getUpdateInformation().getLatestVersionNumberOnServer() + " // installed version " + ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER);
|
||||
|
||||
stage_updateStage.setScene(new Scene(vbxUpdateWindow, chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[0], chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[1]));
|
||||
registerThemedScene(stage_updateStage.getScene());
|
||||
stage_updateStage.getScene().widthProperty().addListener((observable, oldValue, newValue) -> {
|
||||
chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[0] = newValue.doubleValue();
|
||||
requestLayoutSave();
|
||||
@@ -11944,6 +11965,33 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
grdPnlGuiOptions.add(lblShowFreshCallHint, 0, 6);
|
||||
grdPnlGuiOptions.add(chkBxShowFreshCallHint, 1, 6);
|
||||
|
||||
// Startup design of this operator profile; the Windows menu only switches for the session.
|
||||
grdPnlGuiOptions.add(generateLabeledSeparator(100, "Design"), 0, 7, 2, 1);
|
||||
|
||||
ToggleGroup guiOptions_tglGrpDesign = new ToggleGroup();
|
||||
RadioButton designLightModeRB = new RadioButton("Light mode ");
|
||||
designLightModeRB.setToggleGroup(guiOptions_tglGrpDesign);
|
||||
RadioButton designDarkModeRB = new RadioButton("Dark mode ");
|
||||
designDarkModeRB.setToggleGroup(guiOptions_tglGrpDesign);
|
||||
|
||||
if (chatcontroller.getChatPreferences().isGUI_darkModeActiveByDefault()) {
|
||||
designDarkModeRB.setSelected(true);
|
||||
} else {
|
||||
designLightModeRB.setSelected(true);
|
||||
}
|
||||
|
||||
guiOptions_tglGrpDesign.selectedToggleProperty().addListener((obs, oldToggle, newToggle) -> {
|
||||
if (newToggle == null) {
|
||||
return;
|
||||
}
|
||||
boolean darkMode = newToggle == designDarkModeRB;
|
||||
chatcontroller.getChatPreferences().setGUI_darkModeActiveByDefault(darkMode);
|
||||
applyTheme(darkMode);
|
||||
});
|
||||
|
||||
grdPnlGuiOptions.add(new Label("Design at startup of this profile:"), 0, 8);
|
||||
grdPnlGuiOptions.add(new HBox(designLightModeRB, designDarkModeRB), 1, 8);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12260,7 +12308,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
// VBox vBox = new VBox(tabPaneOptions);
|
||||
settingsScene = new Scene(optionsPanel, chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[0], chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[1]);
|
||||
settingsScene.getStylesheets().add(ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT);
|
||||
registerThemedScene(settingsScene);
|
||||
settingsScene.widthProperty().addListener((observable, oldValue, newValue) -> {
|
||||
chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[0] = newValue.doubleValue();
|
||||
requestLayoutSave();
|
||||
|
||||
@@ -90,6 +90,8 @@ public final class OperatorProfilePickerDialog {
|
||||
profileListView,
|
||||
buttonRow);
|
||||
dialogContent.setPadding(new Insets(15));
|
||||
// No application stylesheet yet: use the same base font size as the main windows.
|
||||
dialogContent.setStyle("-fx-font-size: 12px;");
|
||||
|
||||
dialogStage.setScene(new Scene(dialogContent, 380, 280));
|
||||
profileListView.requestFocus();
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
.root {
|
||||
/* Same base font size on all platforms: macOS/Linux default to 13px, Windows to 12px. */
|
||||
-fx-font-size: 12px;
|
||||
}
|
||||
|
||||
.button:pressed {
|
||||
-fx-border-color: #ff0000;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
.root {
|
||||
/* Same base font size on all platforms: macOS/Linux default to 13px, Windows to 12px. */
|
||||
-fx-font-size: 12px;
|
||||
-fx-accent: #1e74c6;
|
||||
-fx-focus-color: -fx-accent;
|
||||
-fx-base: #373e43;
|
||||
|
||||
Reference in new issue
Block a user