Skip to content

Commit 10650c4

Browse files
CSS consolidation and clean-up
1 parent 40fa2e9 commit 10650c4

9 files changed

Lines changed: 209 additions & 503 deletions

File tree

.stylelintrc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"ignoreFiles": ["src/main/resources/styles/**/*.css"],
3+
"rules": {}
4+
}

.vscode/settings.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,10 @@
55
"strings": "off",
66
"other": "off"
77
},
8-
"java.debug.settings.onBuildFailureProceed": true
8+
"java.debug.settings.onBuildFailureProceed": true,
9+
// Disable built-in CSS validation (not JavaFX aware) to suppress false positives
10+
"css.validate": false,
11+
// Keep stylelint enabled (it ignores JavaFX styles via .stylelintrc.json)
12+
"stylelint.enable": true,
13+
"stylelint.validate": ["css"]
914
}

THEMING.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Theming & Style Guide
2+
3+
This project centralizes JavaFX styling to reduce duplication and keep visual behavior consistent.
4+
5+
## Design Tokens (documented)
6+
7+
Because JavaFX CSS lacks native variables, tokens are documented (not enforced) in `global-theme.css`:
8+
9+
```text
10+
ORANGE_BASE_TOP #ffb066
11+
ORANGE_BASE_BOTTOM #ff8a33
12+
ORANGE_HOVER_TOP #ff8a33
13+
ORANGE_HOVER_BOTTOM #e56700
14+
ORANGE_ACTIVE_TOP #cc5800
15+
ORANGE_ACTIVE_BOTTOM #e56700
16+
LIGHT_BG_TOP #fcfcfc
17+
LIGHT_BG_BOTTOM #e9e9e9
18+
BORDER_LIGHT #c9c9c9
19+
HOVER_BG_TRANSLUCENT rgba(255,138,51,0.18)
20+
ARMED_BG_TRANSLUCENT rgba(255,138,51,0.32)
21+
FOCUS_RING rgba(255,138,51,0.6)
22+
```
23+
24+
Dark & high-contrast themes adapt these token intents.
25+
26+
## File Roles
27+
28+
- `global-theme.css`: Core component + icon button styling (single source of truth for hover/armed states).
29+
- `semantic-theme.css`: Domain / semantic containers (tree, panels, action bars) & subtle layout gradients.
30+
- `global-theme-*.css`: Variant overlays (dark, light override set, high contrast). Only put deltas here.
31+
- `fdd-canvas.css`: Canvas-specific layout/styling; avoids redefining global icon button states.
32+
33+
## Icon / Action Buttons
34+
35+
Use the classes:
36+
37+
- `fdd-icon-button` (button container base)
38+
- `fdd-action-button` (semantic grouping if needed)
39+
- `fdd-icon` (icon glyph fill/gradient)
40+
41+
Do NOT add per-screen hover overrides; adjust only in `global-theme.css`.
42+
43+
## Adding New Buttons
44+
45+
1. Create `Button b = new Button();`
46+
2. Add icon with `FontAwesomeIconView` and style class `fdd-icon`.
47+
3. `b.getStyleClass().addAll("fdd-action-button", "fdd-icon-button");`
48+
4. Optional semantic text color override: add a specific class (e.g. `export-button`) and declare only `-fx-text-fill` in a screen stylesheet.
49+
50+
## Theme Extension Steps
51+
52+
1. Document any new color in the token comment block in `global-theme.css`.
53+
2. Add adjusted values in dark/highcontrast variant files ONLY if different.
54+
3. Prefer gradients or translucent backgrounds to solid blocks for hover states.
55+
56+
## High Contrast Considerations
57+
58+
- Ensure focus rings remain visible (see `:focused` rule in high contrast file).
59+
- Keep sufficient contrast ratio (WCAG AA). Use the orange accent (#ff8a33) sparingly for focus / affordances.
60+
61+
## Cleanup Conventions
62+
63+
- When deprecating a style file, remove its load and delete the file rather than leaving empty placeholders.
64+
- Avoid wildcard `.button` rules; scope via class names to prevent style bleed.
65+
66+
## Future Ideas
67+
68+
- Build a small pre-process step (optional) to validate tokens.
69+
- Introduce a screenshot regression test harness for critical UI elements.

src/main/java/net/sourceforge/fddtools/ui/fx/FDDActionPanelFX.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,7 @@ public FDDActionPanelFX() {
3838
getStyleClass().add("fdd-action-panel");
3939
setPrefHeight(36);
4040
setMaxHeight(36);
41-
// Load custom stylesheet for improved look
42-
try {
43-
String css = getClass().getResource("/styles/action-panel.css").toExternalForm();
44-
getStylesheets().add(css);
45-
} catch (Exception ignore) { }
41+
// Styles now supplied by global-theme.css (action-panel.css deprecated)
4642
createButtons();
4743
createContextMenu();
4844
}

src/main/java/net/sourceforge/fddtools/ui/fx/FDDCanvasFX.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import javafx.scene.input.MouseButton;
2424
import javafx.scene.input.ZoomEvent;
2525
import javafx.scene.layout.*;
26+
import javafx.scene.layout.StackPane;
2627
import javafx.geometry.Orientation;
2728
import javafx.scene.paint.Color;
2829
import javafx.scene.text.Font;
@@ -199,31 +200,39 @@ private ToolBar createActionBar() {
199200
this.zoomSlider = zoomSlider;
200201

201202
// Create modern zoom buttons with FontAwesome icons and orange theme
202-
btnZoomOut = new Button();
203-
FontAwesomeIconView zoomOutIcon = new FontAwesomeIconView(FontAwesomeIcon.MINUS);
204-
zoomOutIcon.setGlyphSize(14);
205-
zoomOutIcon.getStyleClass().addAll("fdd-action-icon", "fdd-icon");
206-
btnZoomOut.setGraphic(zoomOutIcon);
203+
btnZoomOut = new Button();
204+
FontAwesomeIconView zoomOutIcon = new FontAwesomeIconView(FontAwesomeIcon.MINUS);
205+
zoomOutIcon.setSmooth(false); // disable text smoothing for crisper small glyph
206+
zoomOutIcon.setGlyphSize(16); // Option B: even glyph size for sharper pixel alignment
207+
zoomOutIcon.getStyleClass().addAll("fdd-action-icon", "fdd-icon");
208+
StackPane zoomOutWrap = new StackPane(zoomOutIcon); // Option A: snap to pixel wrapper
209+
zoomOutWrap.setSnapToPixel(true);
210+
btnZoomOut.setGraphic(zoomOutWrap);
207211
btnZoomOut.setMinWidth(32);
208212
btnZoomOut.setPrefWidth(32);
209213
btnZoomOut.setMinHeight(28);
210214
btnZoomOut.setPrefHeight(28);
211215
btnZoomOut.setOnAction(e -> zoomOut());
212216
btnZoomOut.setTooltip(new Tooltip("Zoom Out (Ctrl + Mouse Wheel or ⌘−)"));
213-
btnZoomOut.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "zoom-button", "zoom-out-button");
214-
215-
btnZoomIn = new Button();
216-
FontAwesomeIconView zoomInIcon = new FontAwesomeIconView(FontAwesomeIcon.PLUS);
217-
zoomInIcon.setGlyphSize(14);
218-
zoomInIcon.getStyleClass().addAll("fdd-action-icon", "fdd-icon");
219-
btnZoomIn.setGraphic(zoomInIcon);
217+
btnZoomOut.getStyleClass().addAll("fdd-action-button", "fdd-icon-button");
218+
btnZoomOut.setSnapToPixel(true); // ensure crisp rendering when armed
219+
220+
btnZoomIn = new Button();
221+
FontAwesomeIconView zoomInIcon = new FontAwesomeIconView(FontAwesomeIcon.PLUS);
222+
zoomInIcon.setSmooth(false); // disable smoothing for crisp edges
223+
zoomInIcon.setGlyphSize(16); // Option B: even glyph size
224+
zoomInIcon.getStyleClass().addAll("fdd-action-icon", "fdd-icon");
225+
StackPane zoomInWrap = new StackPane(zoomInIcon); // Option A wrapper
226+
zoomInWrap.setSnapToPixel(true);
227+
btnZoomIn.setGraphic(zoomInWrap);
220228
btnZoomIn.setMinWidth(32);
221229
btnZoomIn.setPrefWidth(32);
222230
btnZoomIn.setMinHeight(28);
223231
btnZoomIn.setPrefHeight(28);
224232
btnZoomIn.setOnAction(e -> zoomIn());
225233
btnZoomIn.setTooltip(new Tooltip("Zoom In (Ctrl + Mouse Wheel or ⌘+)"));
226-
btnZoomIn.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "zoom-button", "zoom-in-button");
234+
btnZoomIn.getStyleClass().addAll("fdd-action-button", "fdd-icon-button");
235+
btnZoomIn.setSnapToPixel(true); // ensure crisp rendering when armed
227236

228237
// Modern control buttons with better icons/text
229238
btnReset = new Button("100%");
@@ -233,7 +242,8 @@ private ToolBar createActionBar() {
233242
btnReset.setPrefHeight(28);
234243
btnReset.setOnAction(e -> resetZoom());
235244
btnReset.setTooltip(new Tooltip("Reset to 100% (⌘0)"));
236-
btnReset.getStyleClass().addAll("zoom-button", "reset-button");
245+
// Make reset visually consistent: treat as icon/button variant with same border/hover
246+
btnReset.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "reset-button");
237247

238248
btnFit = new Button();
239249
FontAwesomeIconView fitIcon = new FontAwesomeIconView(FontAwesomeIcon.ARROWS_ALT);
@@ -246,7 +256,7 @@ private ToolBar createActionBar() {
246256
btnFit.setPrefHeight(28);
247257
btnFit.setOnAction(e -> fitToWindow());
248258
btnFit.setTooltip(new Tooltip("Fit to Window"));
249-
btnFit.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "zoom-button", "fit-button");
259+
btnFit.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "fit-button");
250260

251261
// Group zoom buttons in a contained group
252262
HBox zoomButtons = new HBox(2);
@@ -282,7 +292,7 @@ private ToolBar createActionBar() {
282292
saveButton.setPrefHeight(32);
283293
saveButton.setOnAction(e -> saveImage());
284294
saveButton.setTooltip(new Tooltip("Save as Image (⌘S)"));
285-
saveButton.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "action-button", "save-button");
295+
saveButton.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "save-button");
286296

287297
printButton = new Button();
288298
FontAwesomeIconView printIcon = new FontAwesomeIconView(FontAwesomeIcon.PRINT);
@@ -296,7 +306,7 @@ private ToolBar createActionBar() {
296306
printButton.setPrefHeight(32);
297307
printButton.setOnAction(e -> printImage());
298308
printButton.setTooltip(new Tooltip("Print (⌘P)"));
299-
printButton.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "action-button", "print-button");
309+
printButton.getStyleClass().addAll("fdd-action-button", "fdd-icon-button", "print-button");
300310

301311
// Create spacer to push action buttons to the right
302312
Region spacer = new Region();
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1 @@
1-
/* Action panel now leverages global-theme unified classes */
2-
.fdd-action-panel { background-color:#fcfcfc; -fx-background-color: linear-gradient(to bottom,#fcfcfc,#e9e9e9); border-color:#c9c9c9; -fx-border-color:#c9c9c9; border-width:1px 0 0 0; -fx-border-width:1 0 0 0; padding:4px; -fx-padding:4; }
3-
.fdd-action-button { background-color:transparent; -fx-background-color: transparent; cursor:pointer; -fx-cursor:hand; padding:4px; -fx-padding:4; -fx-background-radius:6; -fx-border-radius:6; border-radius:6; }
4-
.fdd-action-button:hover { background-color:rgba(255,138,51,0.10); -fx-background-color: rgba(255,138,51,0.18); }
5-
.fdd-action-button:armed { background-color:rgba(255,138,51,0.25); -fx-background-color: rgba(255,138,51,0.32); }
6-
.fdd-action-icon { -fx-fill: linear-gradient(to bottom,#ffb066,#ff8a33); fill: linear-gradient(to bottom,#ffb066,#ff8a33); }
7-
.fdd-action-button:hover .fdd-action-icon { -fx-fill: linear-gradient(to bottom,#ff8a33,#e56700); fill: linear-gradient(to bottom,#ff8a33,#e56700); }
8-
.fdd-action-button:armed .fdd-action-icon { -fx-fill: linear-gradient(to bottom,#cc5800,#e56700); fill: linear-gradient(to bottom,#cc5800,#e56700); }
1+
/* Deprecated: action panel styles migrated into global-theme.css (kept empty for backward imports). */

0 commit comments

Comments
 (0)