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.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import p.studio.controls.lifecycle.StudioControlLifecycle;
import p.studio.controls.lifecycle.StudioControlLifecycleSupport;
@ -13,6 +14,7 @@ import java.util.Objects;
public final class StudioRightUtilityPanelControl extends BorderPane implements StudioControlLifecycle {
public StudioRightUtilityPanelControl(
Node headerContent,
ObservableValue<String> activityTitle,
Node activityContent) {
StudioControlLifecycleSupport.install(this, this);
@ -26,7 +28,13 @@ public final class StudioRightUtilityPanelControl extends BorderPane implements
final TabPane tabs = new TabPane(activityTab);
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) {

View File

@ -1,34 +1,62 @@
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.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import p.studio.Container;
import p.studio.controls.lifecycle.StudioControlLifecycle;
import p.studio.controls.lifecycle.StudioControlLifecycleSupport;
import p.studio.utilities.i18n.I18n;
import java.util.Objects;
public final class StudioRunSurfaceControl extends HBox implements StudioControlLifecycle {
private final BooleanProperty running = new SimpleBooleanProperty(false);
public StudioRunSurfaceControl() {
StudioControlLifecycleSupport.install(this, this);
getStyleClass().add("studio-run-surface");
setSpacing(8);
setAlignment(Pos.CENTER_RIGHT);
setAlignment(Pos.CENTER_LEFT);
getChildren().addAll(
createButton(Container.i18n().bind(I18n.TOOLBAR_PLAY), () -> { }),
createButton(Container.i18n().bind(I18n.TOOLBAR_STOP), () -> { }),
createButton(Container.i18n().bind(I18n.TOOLBAR_EXPORT), () -> { }));
final Label icon = new Label();
icon.getStyleClass().add("studio-run-toggle-icon");
icon.textProperty().bind(Bindings.when(running).then("\u25A0").otherwise("\u25B6"));
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) {
final Button button = new Button();
button.getStyleClass().add("studio-run-button");
button.textProperty().bind(Objects.requireNonNull(text, "text"));
button.setOnAction(ignored -> Objects.requireNonNull(action, "action").run());
return button;
public boolean isRunning() {
return running.get();
}
public BooleanProperty runningProperty() {
return running;
}
}

View File

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

View File

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

View File

@ -11,25 +11,9 @@
-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 {
-fx-alignment: center-right;
-fx-padding: 6 0 6 0;
-fx-alignment: center;
-fx-padding: 12 12 0 12;
}
.studio-shell-menu-bar {
@ -63,10 +47,67 @@
-fx-border-width: 0 0 0 1;
}
.studio-right-utility-layout {
-fx-padding: 0 0 10 0;
}
.studio-right-utility-tabs {
-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 {
-fx-text-fill: #d4d4d4;
-fx-padding: 16;