update shell

This commit is contained in:
bQUARKz 2026-03-11 15:54:50 +00:00
parent dea0ef0d6a
commit 6f105b11ab
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 117 additions and 42 deletions

View File

@ -6,6 +6,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.control.TabPane; import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import p.studio.controls.lifecycle.StudioControlLifecycle; import p.studio.controls.lifecycle.StudioControlLifecycle;
import p.studio.controls.lifecycle.StudioControlLifecycleSupport; import p.studio.controls.lifecycle.StudioControlLifecycleSupport;
@ -13,6 +14,7 @@ import java.util.Objects;
public final class StudioRightUtilityPanelControl extends BorderPane implements StudioControlLifecycle { public final class StudioRightUtilityPanelControl extends BorderPane implements StudioControlLifecycle {
public StudioRightUtilityPanelControl( public StudioRightUtilityPanelControl(
Node headerContent,
ObservableValue<String> activityTitle, ObservableValue<String> activityTitle,
Node activityContent) { Node activityContent) {
StudioControlLifecycleSupport.install(this, this); StudioControlLifecycleSupport.install(this, this);
@ -26,7 +28,13 @@ public final class StudioRightUtilityPanelControl extends BorderPane implements
final TabPane tabs = new TabPane(activityTab); final TabPane tabs = new TabPane(activityTab);
tabs.getStyleClass().add("studio-right-utility-tabs"); tabs.getStyleClass().add("studio-right-utility-tabs");
setCenter(tabs); final VBox layout = new VBox(10);
layout.getStyleClass().add("studio-right-utility-layout");
if (headerContent != null) {
layout.getChildren().add(headerContent);
}
layout.getChildren().add(tabs);
setCenter(layout);
} }
public static Label createPlaceholderContent(ObservableValue<String> text) { public static Label createPlaceholderContent(ObservableValue<String> text) {

View File

@ -1,34 +1,62 @@
package p.studio.controls.shell; package p.studio.controls.shell;
import javafx.beans.value.ObservableValue; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import p.studio.Container; import p.studio.Container;
import p.studio.controls.lifecycle.StudioControlLifecycle; import p.studio.controls.lifecycle.StudioControlLifecycle;
import p.studio.controls.lifecycle.StudioControlLifecycleSupport; import p.studio.controls.lifecycle.StudioControlLifecycleSupport;
import p.studio.utilities.i18n.I18n; import p.studio.utilities.i18n.I18n;
import java.util.Objects;
public final class StudioRunSurfaceControl extends HBox implements StudioControlLifecycle { public final class StudioRunSurfaceControl extends HBox implements StudioControlLifecycle {
private final BooleanProperty running = new SimpleBooleanProperty(false);
public StudioRunSurfaceControl() { public StudioRunSurfaceControl() {
StudioControlLifecycleSupport.install(this, this); StudioControlLifecycleSupport.install(this, this);
getStyleClass().add("studio-run-surface"); getStyleClass().add("studio-run-surface");
setSpacing(8); setSpacing(8);
setAlignment(Pos.CENTER_RIGHT); setAlignment(Pos.CENTER_LEFT);
getChildren().addAll( final Label icon = new Label();
createButton(Container.i18n().bind(I18n.TOOLBAR_PLAY), () -> { }), icon.getStyleClass().add("studio-run-toggle-icon");
createButton(Container.i18n().bind(I18n.TOOLBAR_STOP), () -> { }), icon.textProperty().bind(Bindings.when(running).then("\u25A0").otherwise("\u25B6"));
createButton(Container.i18n().bind(I18n.TOOLBAR_EXPORT), () -> { }));
final StackPane iconShell = new StackPane(icon);
iconShell.getStyleClass().add("studio-run-toggle-icon-shell");
final Label text = new Label();
text.getStyleClass().add("studio-run-toggle-text");
text.textProperty().bind(Bindings.createStringBinding(
() -> Container.i18n().text(running.get() ? I18n.TOOLBAR_STOP : I18n.TOOLBAR_PLAY),
running));
final HBox content = new HBox(8, iconShell, text);
content.setAlignment(Pos.CENTER_LEFT);
final Button toggleButton = new Button();
toggleButton.getStyleClass().add("studio-run-toggle-button");
toggleButton.graphicProperty().set(content);
toggleButton.setOnAction(ignored -> running.set(!running.get()));
running.addListener((ignored, oldValue, newValue) -> {
toggleButton.getStyleClass().removeAll("studio-run-toggle-play", "studio-run-toggle-stop");
toggleButton.getStyleClass().add(newValue ? "studio-run-toggle-stop" : "studio-run-toggle-play");
});
toggleButton.getStyleClass().add("studio-run-toggle-play");
getChildren().add(toggleButton);
} }
private Button createButton(ObservableValue<String> text, Runnable action) { public boolean isRunning() {
final Button button = new Button(); return running.get();
button.getStyleClass().add("studio-run-button"); }
button.textProperty().bind(Objects.requireNonNull(text, "text"));
button.setOnAction(ignored -> Objects.requireNonNull(action, "action").run()); public BooleanProperty runningProperty() {
return button; return running;
} }
} }

View File

@ -5,13 +5,10 @@ import javafx.scene.layout.BorderPane;
import p.studio.controls.lifecycle.StudioControlLifecycle; import p.studio.controls.lifecycle.StudioControlLifecycle;
import p.studio.controls.lifecycle.StudioControlLifecycleSupport; import p.studio.controls.lifecycle.StudioControlLifecycleSupport;
import java.util.Objects;
public final class StudioShellTopBarControl extends BorderPane implements StudioControlLifecycle { public final class StudioShellTopBarControl extends BorderPane implements StudioControlLifecycle {
public StudioShellTopBarControl(Node menuBar, Node runSurface) { public StudioShellTopBarControl(Node menuBar) {
StudioControlLifecycleSupport.install(this, this); StudioControlLifecycleSupport.install(this, this);
getStyleClass().add("studio-shell-top-bar"); getStyleClass().add("studio-shell-top-bar");
setLeft(Objects.requireNonNull(menuBar, "menuBar")); setLeft(menuBar);
setRight(Objects.requireNonNull(runSurface, "runSurface"));
} }
} }

View File

@ -22,7 +22,7 @@ public final class MainView extends BorderPane {
this.projectReference = projectReference; this.projectReference = projectReference;
final var menuBar = new StudioShellMenuBarControl(); final var menuBar = new StudioShellMenuBarControl();
final var runSurface = new StudioRunSurfaceControl(); final var runSurface = new StudioRunSurfaceControl();
setTop(new StudioShellTopBarControl(menuBar, runSurface)); setTop(new StudioShellTopBarControl(menuBar));
host.register(new EditorWorkspace()); host.register(new EditorWorkspace());
host.register(new PlaceholderWorkspace(WorkspaceId.ASSETS, I18n.WORKSPACE_ASSETS, "Assets")); host.register(new PlaceholderWorkspace(WorkspaceId.ASSETS, I18n.WORKSPACE_ASSETS, "Assets"));
@ -31,8 +31,8 @@ public final class MainView extends BorderPane {
final var workspaceRail = new StudioWorkspaceRailControl<>( final var workspaceRail = new StudioWorkspaceRailControl<>(
List.of( List.of(
new StudioWorkspaceRailItem<>(WorkspaceId.EDITOR, "📝", Container.i18n().bind(I18n.WORKSPACE_CODE)),
new StudioWorkspaceRailItem<>(WorkspaceId.ASSETS, "📦", Container.i18n().bind(I18n.WORKSPACE_ASSETS)), new StudioWorkspaceRailItem<>(WorkspaceId.ASSETS, "📦", Container.i18n().bind(I18n.WORKSPACE_ASSETS)),
new StudioWorkspaceRailItem<>(WorkspaceId.EDITOR, "📝", Container.i18n().bind(I18n.WORKSPACE_CODE)),
new StudioWorkspaceRailItem<>(WorkspaceId.DEBUG, "🎮", Container.i18n().bind(I18n.WORKSPACE_DEBUG)), new StudioWorkspaceRailItem<>(WorkspaceId.DEBUG, "🎮", Container.i18n().bind(I18n.WORKSPACE_DEBUG)),
new StudioWorkspaceRailItem<>(WorkspaceId.SHIPPER, "⚙️", Container.i18n().bind(I18n.WORKSPACE_SHIPPER)) new StudioWorkspaceRailItem<>(WorkspaceId.SHIPPER, "⚙️", Container.i18n().bind(I18n.WORKSPACE_SHIPPER))
), ),
@ -40,12 +40,13 @@ public final class MainView extends BorderPane {
setLeft(workspaceRail); setLeft(workspaceRail);
setCenter(host); setCenter(host);
setRight(new StudioRightUtilityPanelControl( setRight(new StudioRightUtilityPanelControl(
runSurface,
Container.i18n().bind(I18n.SHELL_ACTIVITY), Container.i18n().bind(I18n.SHELL_ACTIVITY),
StudioRightUtilityPanelControl.createPlaceholderContent(Container.i18n().bind(I18n.SHELL_ACTIVITY)))); StudioRightUtilityPanelControl.createPlaceholderContent(Container.i18n().bind(I18n.SHELL_ACTIVITY))));
// default // default
workspaceRail.select(WorkspaceId.EDITOR); workspaceRail.select(WorkspaceId.ASSETS);
showWorkspace(WorkspaceId.EDITOR); showWorkspace(WorkspaceId.ASSETS);
} }
public ProjectReference projectReference() { public ProjectReference projectReference() {

View File

@ -11,25 +11,9 @@
-fx-padding: 0 12 0 0; -fx-padding: 0 12 0 0;
} }
.studio-run-button {
-fx-background-color: transparent;
-fx-text-fill: #d4d4d4;
-fx-font-size: 14px;
-fx-padding: 6 10 6 10;
-fx-background-radius: 6;
}
.studio-run-button:hover {
-fx-background-color: #2a2d2e;
}
.studio-run-button:pressed {
-fx-background-color: #37373d;
}
.studio-run-surface { .studio-run-surface {
-fx-alignment: center-right; -fx-alignment: center;
-fx-padding: 6 0 6 0; -fx-padding: 12 12 0 12;
} }
.studio-shell-menu-bar { .studio-shell-menu-bar {
@ -63,10 +47,67 @@
-fx-border-width: 0 0 0 1; -fx-border-width: 0 0 0 1;
} }
.studio-right-utility-layout {
-fx-padding: 0 0 10 0;
}
.studio-right-utility-tabs { .studio-right-utility-tabs {
-fx-background-color: transparent; -fx-background-color: transparent;
} }
.studio-run-toggle-button {
-fx-background-radius: 10;
-fx-padding: 10 14 10 14;
-fx-cursor: hand;
-fx-border-radius: 10;
-fx-border-width: 1;
}
.studio-run-toggle-button:hover {
-fx-opacity: 0.95;
}
.studio-run-toggle-button:pressed {
-fx-opacity: 0.85;
}
.studio-run-toggle-play {
-fx-background-color: #173322;
-fx-border-color: #2f8f59;
}
.studio-run-toggle-stop {
-fx-background-color: #3a1719;
-fx-border-color: #c24a54;
}
.studio-run-toggle-icon-shell {
-fx-min-width: 24;
-fx-min-height: 24;
-fx-pref-width: 24;
-fx-pref-height: 24;
-fx-alignment: center;
}
.studio-run-toggle-icon {
-fx-font-size: 15px;
-fx-font-weight: bold;
}
.studio-run-toggle-play .studio-run-toggle-icon {
-fx-text-fill: #48d17c;
}
.studio-run-toggle-stop .studio-run-toggle-icon {
-fx-text-fill: #ff5d66;
}
.studio-run-toggle-text {
-fx-text-fill: #f7fbff;
-fx-font-size: 13px;
-fx-font-weight: bold;
}
.studio-utility-placeholder { .studio-utility-placeholder {
-fx-text-fill: #d4d4d4; -fx-text-fill: #d4d4d4;
-fx-padding: 16; -fx-padding: 16;