diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/assets/details/bank/AssetDetailsBankCompositionControl.java b/prometeu-studio/src/main/java/p/studio/workspaces/assets/details/bank/AssetDetailsBankCompositionControl.java index c95ae378..f6380154 100644 --- a/prometeu-studio/src/main/java/p/studio/workspaces/assets/details/bank/AssetDetailsBankCompositionControl.java +++ b/prometeu-studio/src/main/java/p/studio/workspaces/assets/details/bank/AssetDetailsBankCompositionControl.java @@ -13,6 +13,11 @@ import p.studio.projects.ProjectReference; import p.studio.utilities.i18n.I18n; import p.studio.workspaces.assets.details.AssetDetailsUiSupport; import p.studio.workspaces.assets.messages.AssetWorkspaceDetailsViewState; +import p.studio.workspaces.assets.messages.events.StudioAssetBankCompositionAppliedEvent; +import p.studio.workspaces.assets.messages.events.StudioAssetBankCompositionApplyFailedEvent; +import p.studio.workspaces.assets.messages.events.StudioAssetBankCompositionApplyRequestedEvent; +import p.studio.workspaces.assets.messages.events.StudioAssetBankCompositionCapacityChangedEvent; +import p.studio.workspaces.assets.messages.events.StudioAssetBankCompositionDraftChangedEvent; import p.studio.workspaces.assets.messages.events.StudioAssetsDetailsViewStateChangedEvent; import p.studio.workspaces.framework.StudioSubscriptionBag; @@ -44,6 +49,7 @@ public final class AssetDetailsBankCompositionControl extends VBox implements St viewState = event.viewState(); coordinator.replaceDetails(viewState == null ? null : viewState.selectedAssetDetails()); render(); + publishStateNotifications(); })); } @@ -70,18 +76,22 @@ public final class AssetDetailsBankCompositionControl extends VBox implements St dualListView.setOnMoveToRight(items -> { coordinator.moveToSelected(items); render(); + publishStateNotifications(); }); dualListView.setOnMoveToLeft(items -> { coordinator.moveToAvailable(items); render(); + publishStateNotifications(); }); dualListView.setOnMoveUp(index -> { coordinator.moveUp(index); render(); + publishStateNotifications(); }); dualListView.setOnMoveDown(index -> { coordinator.moveDown(index); render(); + publishStateNotifications(); }); capacityMeter.setProgress(viewModel.capacityState().progress()); @@ -112,20 +122,56 @@ public final class AssetDetailsBankCompositionControl extends VBox implements St private void beginEdit() { coordinator.beginEdit(); render(); + publishStateNotifications(); } private void applyDraft() { - coordinator.apply(); - render(); + if (viewState == null || viewState.selectedAssetReference() == null) { + return; + } + workspaceBus.publish(new StudioAssetBankCompositionApplyRequestedEvent(viewState.selectedAssetReference())); + try { + coordinator.apply(); + render(); + publishStateNotifications(); + workspaceBus.publish(new StudioAssetBankCompositionAppliedEvent(viewState.selectedAssetReference())); + } catch (RuntimeException exception) { + workspaceBus.publish(new StudioAssetBankCompositionApplyFailedEvent( + viewState.selectedAssetReference(), + exception.getMessage())); + throw exception; + } } private void resetDraft() { coordinator.reset(); render(); + publishStateNotifications(); } private void cancelEdit() { coordinator.cancel(); render(); + publishStateNotifications(); + } + + private void publishStateNotifications() { + if (viewState == null || viewState.selectedAssetReference() == null || !coordinator.ready()) { + return; + } + final AssetDetailsBankCompositionViewModel viewModel = coordinator.viewModel(); + workspaceBus.publish(new StudioAssetBankCompositionDraftChangedEvent( + viewState.selectedAssetReference(), + viewModel.editing(), + viewModel.dirty(), + viewModel.availableFiles().size(), + viewModel.selectedFiles().size())); + workspaceBus.publish(new StudioAssetBankCompositionCapacityChangedEvent( + viewState.selectedAssetReference(), + viewModel.capacityState().progress(), + viewModel.capacityState().severity(), + viewModel.capacityState().blocked(), + viewModel.capacityState().labelText(), + viewModel.capacityState().hintText())); } } diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionAppliedEvent.java b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionAppliedEvent.java new file mode 100644 index 00000000..4371f5dc --- /dev/null +++ b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionAppliedEvent.java @@ -0,0 +1,13 @@ +package p.studio.workspaces.assets.messages.events; + +import p.packer.messages.AssetReference; +import p.studio.events.StudioEvent; + +import java.util.Objects; + +public record StudioAssetBankCompositionAppliedEvent( + AssetReference assetReference) implements StudioEvent { + public StudioAssetBankCompositionAppliedEvent { + Objects.requireNonNull(assetReference, "assetReference"); + } +} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionApplyFailedEvent.java b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionApplyFailedEvent.java new file mode 100644 index 00000000..e270d46d --- /dev/null +++ b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionApplyFailedEvent.java @@ -0,0 +1,15 @@ +package p.studio.workspaces.assets.messages.events; + +import p.packer.messages.AssetReference; +import p.studio.events.StudioEvent; + +import java.util.Objects; + +public record StudioAssetBankCompositionApplyFailedEvent( + AssetReference assetReference, + String message) implements StudioEvent { + public StudioAssetBankCompositionApplyFailedEvent { + Objects.requireNonNull(assetReference, "assetReference"); + message = Objects.requireNonNullElse(message, ""); + } +} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionApplyRequestedEvent.java b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionApplyRequestedEvent.java new file mode 100644 index 00000000..23797da8 --- /dev/null +++ b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionApplyRequestedEvent.java @@ -0,0 +1,13 @@ +package p.studio.workspaces.assets.messages.events; + +import p.packer.messages.AssetReference; +import p.studio.events.StudioEvent; + +import java.util.Objects; + +public record StudioAssetBankCompositionApplyRequestedEvent( + AssetReference assetReference) implements StudioEvent { + public StudioAssetBankCompositionApplyRequestedEvent { + Objects.requireNonNull(assetReference, "assetReference"); + } +} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionCapacityChangedEvent.java b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionCapacityChangedEvent.java new file mode 100644 index 00000000..adca2882 --- /dev/null +++ b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionCapacityChangedEvent.java @@ -0,0 +1,26 @@ +package p.studio.workspaces.assets.messages.events; + +import p.packer.messages.AssetReference; +import p.studio.controls.banks.StudioAssetCapacitySeverity; +import p.studio.events.StudioEvent; + +import java.util.Objects; + +public record StudioAssetBankCompositionCapacityChangedEvent( + AssetReference assetReference, + double progress, + StudioAssetCapacitySeverity severity, + boolean blocked, + String labelText, + String hintText) implements StudioEvent { + + public StudioAssetBankCompositionCapacityChangedEvent { + Objects.requireNonNull(assetReference, "assetReference"); + severity = severity == null ? StudioAssetCapacitySeverity.GREEN : severity; + if (progress < 0.0d || progress > 1.0d) { + throw new IllegalArgumentException("progress must be in the 0..1 range"); + } + labelText = Objects.requireNonNullElse(labelText, ""); + hintText = Objects.requireNonNullElse(hintText, ""); + } +} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionDraftChangedEvent.java b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionDraftChangedEvent.java new file mode 100644 index 00000000..e04e5504 --- /dev/null +++ b/prometeu-studio/src/main/java/p/studio/workspaces/assets/messages/events/StudioAssetBankCompositionDraftChangedEvent.java @@ -0,0 +1,21 @@ +package p.studio.workspaces.assets.messages.events; + +import p.packer.messages.AssetReference; +import p.studio.events.StudioEvent; + +import java.util.Objects; + +public record StudioAssetBankCompositionDraftChangedEvent( + AssetReference assetReference, + boolean editing, + boolean dirty, + int availableCount, + int selectedCount) implements StudioEvent { + + public StudioAssetBankCompositionDraftChangedEvent { + Objects.requireNonNull(assetReference, "assetReference"); + if (availableCount < 0 || selectedCount < 0) { + throw new IllegalArgumentException("counts must be non-negative"); + } + } +}