From 1865e7604a0af16c9b05748baac8bdc1375c11ef Mon Sep 17 00:00:00 2001 From: Falko Galperin Date: Fri, 15 Nov 2024 22:54:27 +0100 Subject: [PATCH] Move and slightly improve ConfirmDialog #683 This moves the ConfirmDialog out of the Drawable directories, since it is used in more situations than Drawable-specific menus. Additionally, some minor refactorings and improvements were made, notably: * The dialog is now more configurable. Specifically, the title, description, button texts, button icons, and button colors can all be set to custom values. There is also a pre-made configuration for delete confirmations. * The visuals of the dialog have been slightly changed. For example, the confirm button is now green by default, the dialog is slightly larger, there are icons on the buttons, and so on. * The dialog should now be able to handle differing text lengths better. * A static convenience method has been added to make it easier to ask the user confirmation questions. It suffices to call this static method on the class with the desired configuration (i.e., message etc.) and then await the result (see below), without the need for the caller to have access to a fitting GameObject for the dialog (or needing to handle destroying it). * The dialog has been turned into a `PlatformDependentComponent`. * A fade-in and fade-out animation has been implemented for the dialog. * Instead of utilizing callbacks, the method to show the dialog now leverages its asynchronous nature by simply waiting until the user made their choice, then returning a boolean indicating that choice. This should also more easily enable patterns such as early return, as is commonly done with the analogous `window.confirm()` method in Web development. --- .../UI/{Drawable => }/ConfirmDialog.prefab | 610 +++++++++++++++--- .../{Drawable => }/ConfirmDialog.prefab.meta | 0 .../SEE/Controls/Actions/ContextMenuAction.cs | 13 +- .../DebugAdapterProtocolManager.cs | 4 +- Assets/SEE/UI/Menu/ConfirmDialog.cs | 222 +++++++ Assets/SEE/UI/Menu/ConfirmDialog.cs.meta | 3 + .../SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs | 79 --- .../Menu/Drawable/ConfirmDialogMenu.cs.meta | 11 - .../DrawableWindowContextMenu.cs | 12 +- 9 files changed, 746 insertions(+), 208 deletions(-) rename Assets/Resources/Prefabs/UI/{Drawable => }/ConfirmDialog.prefab (80%) rename Assets/Resources/Prefabs/UI/{Drawable => }/ConfirmDialog.prefab.meta (100%) create mode 100644 Assets/SEE/UI/Menu/ConfirmDialog.cs create mode 100644 Assets/SEE/UI/Menu/ConfirmDialog.cs.meta delete mode 100644 Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs delete mode 100644 Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs.meta diff --git a/Assets/Resources/Prefabs/UI/Drawable/ConfirmDialog.prefab b/Assets/Resources/Prefabs/UI/ConfirmDialog.prefab similarity index 80% rename from Assets/Resources/Prefabs/UI/Drawable/ConfirmDialog.prefab rename to Assets/Resources/Prefabs/UI/ConfirmDialog.prefab index 136c3550a4..3b915de4d6 100644 --- a/Assets/Resources/Prefabs/UI/Drawable/ConfirmDialog.prefab +++ b/Assets/Resources/Prefabs/UI/ConfirmDialog.prefab @@ -1,5 +1,69 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &189312895703040459 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 491315681807423818} + - component: {fileID: 3763609878608328507} + m_Layer: 5 + m_Name: Texts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &491315681807423818 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189312895703040459} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2762970565581349884} + - {fileID: 1535639024858838830} + m_Father: {fileID: 4619280785831262312} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3763609878608328507 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189312895703040459} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 4 + m_Spacing: 10 + m_ChildForceExpandWidth: 0 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 1 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 --- !u!1 &472907478635077142 GameObject: m_ObjectHideFlags: 0 @@ -9,6 +73,7 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 4985421093549351610} + - component: {fileID: 130303167684898285} m_Layer: 5 m_Name: ConfirmDialog m_TagString: Untagged @@ -37,8 +102,20 @@ RectTransform: m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 300, y: 230} + m_SizeDelta: {x: 450, y: 230} m_Pivot: {x: 0.5, y: 0.5} +--- !u!225 &130303167684898285 +CanvasGroup: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 472907478635077142} + m_Enabled: 1 + m_Alpha: 1 + m_Interactable: 1 + m_BlocksRaycasts: 1 + m_IgnoreParentGroups: 0 --- !u!1 &979490588307293967 GameObject: m_ObjectHideFlags: 0 @@ -71,14 +148,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 1535639024858838830} + - {fileID: 491315681807423818} - {fileID: 8967378944806627992} m_Father: {fileID: 180024041207245043} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 125, y: 55} + m_SizeDelta: {x: 160, y: 55} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2786295064089808444 CanvasRenderer: @@ -103,20 +180,7 @@ MonoBehaviour: buttonText: Cancel clickEvent: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 0} - m_TargetAssemblyTypeName: SEE.Game.UI.HolisticMetrics.AddBoardSliderController, - SEE - m_MethodName: CreateBoard - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] hoverEvent: m_PersistentCalls: m_Calls: [] @@ -196,7 +260,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.43529412, g: 0.43137255, b: 0.43137255, a: 1} + m_Color: {r: 0.2901961, g: 0.30588236, b: 0.59607846, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -299,7 +363,7 @@ GameObject: - component: {fileID: 180024041207245043} - component: {fileID: 6238762571634008335} m_Layer: 5 - m_Name: Switch + m_Name: Buttons m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -324,7 +388,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} + m_SizeDelta: {x: 0, y: 80} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &6238762571634008335 MonoBehaviour: @@ -342,9 +406,9 @@ MonoBehaviour: m_Left: 20 m_Right: 20 m_Top: 15 - m_Bottom: 15 + m_Bottom: 10 m_ChildAlignment: 4 - m_Spacing: 10 + m_Spacing: 43.55 m_ChildForceExpandWidth: 0 m_ChildForceExpandHeight: 0 m_ChildControlWidth: 0 @@ -551,7 +615,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 300, y: 75} + m_SizeDelta: {x: 0, y: 86.51} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &3508249465455595637 CanvasRenderer: @@ -581,9 +645,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: 'Do you really want to delete the page? - - This action cannot be undone.' + m_text: Do you really want to do this? m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: 84dd14695854bbc43a5faa24fcf93d0d, type: 2} m_sharedMaterial: {fileID: 21261991626553910, guid: 84dd14695854bbc43a5faa24fcf93d0d, @@ -611,12 +673,12 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 18.35 + m_fontSize: 26 m_fontSizeBase: 22.5 m_fontWeight: 400 m_enableAutoSizing: 1 m_fontSizeMin: 16 - m_fontSizeMax: 72 + m_fontSizeMax: 26 m_fontStyle: 0 m_HorizontalAlignment: 2 m_VerticalAlignment: 512 @@ -690,8 +752,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -30} - m_SizeDelta: {x: 0, y: -60} + m_AnchoredPosition: {x: 0, y: -20} + m_SizeDelta: {x: 0, y: -40} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &7055449335591566390 CanvasRenderer: @@ -744,15 +806,15 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Padding: - m_Left: 0 - m_Right: 0 - m_Top: 0 + m_Left: 10 + m_Right: 10 + m_Top: 6 m_Bottom: 0 m_ChildAlignment: 0 m_Spacing: 0 m_ChildForceExpandWidth: 1 m_ChildForceExpandHeight: 1 - m_ChildControlWidth: 0 + m_ChildControlWidth: 1 m_ChildControlHeight: 0 m_ChildScaleWidth: 0 m_ChildScaleHeight: 0 @@ -789,14 +851,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - - {fileID: 1368585962797633345} + - {fileID: 7302236240568713709} - {fileID: 5915532368616297663} m_Father: {fileID: 180024041207245043} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 125, y: 55} + m_SizeDelta: {x: 160, y: 55} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &3736018421949878993 CanvasRenderer: @@ -821,27 +883,14 @@ MonoBehaviour: buttonText: Confirm clickEvent: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 0} - m_TargetAssemblyTypeName: SEE.Game.UI.HolisticMetrics.AddBoardSliderController, - SEE - m_MethodName: CreateBoard - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] hoverEvent: m_PersistentCalls: m_Calls: [] hoverSound: {fileID: 0} clickSound: {fileID: 0} buttonVar: {fileID: 0} - normalText: {fileID: 7665678077899908626} + normalText: {fileID: 3010408764763752967} soundSource: {fileID: 0} rippleParent: {fileID: 3491578728468766467} useCustomContent: 0 @@ -914,7 +963,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.43529412, g: 0.43137255, b: 0.43137255, a: 1} + m_Color: {r: 0.21176471, g: 0.6117647, b: 0.17254902, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -1156,7 +1205,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 60} + m_SizeDelta: {x: 0, y: 40} m_Pivot: {x: 0.5, y: 1} --- !u!222 &5500084886181934356 CanvasRenderer: @@ -1199,14 +1248,78 @@ MonoBehaviour: m_Top: 0 m_Bottom: 0 m_ChildAlignment: 4 - m_Spacing: 15 - m_ChildForceExpandWidth: 0 + m_Spacing: 20 + m_ChildForceExpandWidth: 1 m_ChildForceExpandHeight: 0 m_ChildControlWidth: 0 m_ChildControlHeight: 0 m_ChildScaleWidth: 0 m_ChildScaleHeight: 0 m_ReverseArrangement: 0 +--- !u!1 &7402863619967676152 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7302236240568713709} + - component: {fileID: 406482143824154937} + m_Layer: 5 + m_Name: Texts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7302236240568713709 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7402863619967676152} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8176715432835642386} + - {fileID: 2753530363709115625} + m_Father: {fileID: 5599443925521173053} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &406482143824154937 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7402863619967676152} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 4 + m_Spacing: 10 + m_ChildForceExpandWidth: 0 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 1 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 --- !u!1 &7413342215356150287 GameObject: m_ObjectHideFlags: 0 @@ -1218,6 +1331,7 @@ GameObject: - component: {fileID: 1535639024858838830} - component: {fileID: 9090477246577999013} - component: {fileID: 1825821336795976598} + - component: {fileID: 3123988764224439728} m_Layer: 5 m_Name: Text m_TagString: Untagged @@ -1237,12 +1351,12 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 4619280785831262312} + m_Father: {fileID: 491315681807423818} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 93.44, y: -27.5} + m_SizeDelta: {x: 71.98, y: 30.64} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &9090477246577999013 CanvasRenderer: @@ -1316,7 +1430,7 @@ MonoBehaviour: m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_enableWordWrapping: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} @@ -1342,7 +1456,21 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!1 &7664869957476801367 +--- !u!114 &3123988764224439728 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7413342215356150287} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 0 + m_VerticalFit: 0 +--- !u!1 &7702497847471518349 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -1350,9 +1478,10 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 1368585962797633345} - - component: {fileID: 1106347867249952345} - - component: {fileID: 7665678077899908626} + - component: {fileID: 2753530363709115625} + - component: {fileID: 3147329950783738952} + - component: {fileID: 3010408764763752967} + - component: {fileID: 1973223961053249612} m_Layer: 5 m_Name: Text m_TagString: Untagged @@ -1360,40 +1489,40 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!224 &1368585962797633345 +--- !u!224 &2753530363709115625 RectTransform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7664869957476801367} + m_GameObject: {fileID: 7702497847471518349} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 5599443925521173053} + m_Father: {fileID: 7302236240568713709} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 94.845, y: -27.5} + m_SizeDelta: {x: 87.94, y: 30.64} m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &1106347867249952345 +--- !u!222 &3147329950783738952 CanvasRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7664869957476801367} + m_GameObject: {fileID: 7702497847471518349} m_CullTransparentMesh: 0 ---- !u!114 &7665678077899908626 +--- !u!114 &3010408764763752967 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7664869957476801367} + m_GameObject: {fileID: 7702497847471518349} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} @@ -1451,7 +1580,7 @@ MonoBehaviour: m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_enableWordWrapping: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} @@ -1477,6 +1606,20 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &1973223961053249612 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7702497847471518349} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 0 + m_VerticalFit: 0 --- !u!1 &7757725893516098604 GameObject: m_ObjectHideFlags: 0 @@ -1516,7 +1659,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 30, y: 35} + m_SizeDelta: {x: 36.39, y: 35} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &7761948309818112666 CanvasRenderer: @@ -1541,20 +1684,7 @@ MonoBehaviour: buttonText: X clickEvent: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 0} - m_TargetAssemblyTypeName: SEE.Game.UI.HolisticMetrics.AddBoardSliderController, - SEE - m_MethodName: CreateBoard - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] hoverEvent: m_PersistentCalls: m_Calls: [] @@ -1686,7 +1816,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 175, y: 50} + m_SizeDelta: {x: 300, y: 50} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2902588927020717822 CanvasRenderer: @@ -1716,7 +1846,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: Confirm Dialog + m_text: Are you sure? m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: fa328c1ae3ffb6b4583cf371153b0be6, type: 2} m_sharedMaterial: {fileID: 21918420405216288, guid: fa328c1ae3ffb6b4583cf371153b0be6, @@ -1744,12 +1874,12 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 14 - m_fontSizeBase: 14 + m_fontSize: 30 + m_fontSizeBase: 29.5 m_fontWeight: 400 - m_enableAutoSizing: 0 + m_enableAutoSizing: 1 m_fontSizeMin: 18 - m_fontSizeMax: 72 + m_fontSizeMax: 30 m_fontStyle: 16 m_HorizontalAlignment: 2 m_VerticalAlignment: 512 @@ -1760,7 +1890,7 @@ MonoBehaviour: m_lineSpacingMax: 0 m_paragraphSpacing: 0 m_charWidthMaxAdj: 0 - m_enableWordWrapping: 1 + m_enableWordWrapping: 0 m_wordWrappingRatios: 0.4 m_overflowMode: 0 m_linkedTextComponent: {fileID: 0} @@ -1875,6 +2005,141 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_ShowMaskGraphic: 0 +--- !u!1 &8101876973254511969 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2762970565581349884} + - component: {fileID: 2559644166696375386} + - component: {fileID: 4409090642134081805} + m_Layer: 5 + m_Name: Icon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2762970565581349884 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8101876973254511969} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 491315681807423818} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 39.01, y: -27.5} + m_SizeDelta: {x: 16.88, y: 22.51} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2559644166696375386 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8101876973254511969} + m_CullTransparentMesh: 0 +--- !u!114 &4409090642134081805 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8101876973254511969} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: X + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 4ebb98a3c87fa521a888029274c92b79, type: 2} + m_sharedMaterial: {fileID: -8620075009897487826, guid: 4ebb98a3c87fa521a888029274c92b79, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 22.5 + m_fontSizeBase: 22.5 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 1 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &8484153070200510691 GameObject: m_ObjectHideFlags: 0 @@ -1942,8 +2207,8 @@ MonoBehaviour: m_Calls: [] m_text: X m_isRightToLeft: 0 - m_fontAsset: {fileID: 11400000, guid: 84dd14695854bbc43a5faa24fcf93d0d, type: 2} - m_sharedMaterial: {fileID: 21261991626553910, guid: 84dd14695854bbc43a5faa24fcf93d0d, + m_fontAsset: {fileID: 11400000, guid: 4ebb98a3c87fa521a888029274c92b79, type: 2} + m_sharedMaterial: {fileID: -8620075009897487826, guid: 4ebb98a3c87fa521a888029274c92b79, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} @@ -2022,7 +2287,7 @@ GameObject: - component: {fileID: 299736353203913646} - component: {fileID: 5150470231771594060} m_Layer: 5 - m_Name: Icon + m_Name: Icon (not shown) m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -2045,7 +2310,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 25, y: 25} + m_SizeDelta: {x: 30, y: 25} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &299736353203913646 CanvasRenderer: @@ -2062,7 +2327,7 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8724777390210691235} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: @@ -2075,7 +2340,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 1bb66208e276b0b499d31d402deefad0, type: 3} + m_Sprite: {fileID: 21300002, guid: 2a19aaadcf7844142a73ce60950ec353, type: 3} m_Type: 0 m_PreserveAspect: 1 m_FillCenter: 1 @@ -2085,3 +2350,138 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &9052633760965723713 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8176715432835642386} + - component: {fileID: 5015711401553908750} + - component: {fileID: 4359897939224999029} + m_Layer: 5 + m_Name: Icon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8176715432835642386 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9052633760965723713} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7302236240568713709} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 31.029999, y: -27.5} + m_SizeDelta: {x: 19.69, y: 22.51} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5015711401553908750 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9052633760965723713} + m_CullTransparentMesh: 0 +--- !u!114 &4359897939224999029 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9052633760965723713} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: \uf00c + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 4ebb98a3c87fa521a888029274c92b79, type: 2} + m_sharedMaterial: {fileID: -8620075009897487826, guid: 4ebb98a3c87fa521a888029274c92b79, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 22.5 + m_fontSizeBase: 22.5 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 1 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} diff --git a/Assets/Resources/Prefabs/UI/Drawable/ConfirmDialog.prefab.meta b/Assets/Resources/Prefabs/UI/ConfirmDialog.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/UI/Drawable/ConfirmDialog.prefab.meta rename to Assets/Resources/Prefabs/UI/ConfirmDialog.prefab.meta diff --git a/Assets/SEE/Controls/Actions/ContextMenuAction.cs b/Assets/SEE/Controls/Actions/ContextMenuAction.cs index 377ed0d43c..907d93adbc 100644 --- a/Assets/SEE/Controls/Actions/ContextMenuAction.cs +++ b/Assets/SEE/Controls/Actions/ContextMenuAction.cs @@ -15,7 +15,7 @@ using SEE.Game.City; using SEE.Utils.History; using SEE.GO.Menu; -using SEE.UI.Menu.Drawable; +using SEE.UI.Menu; using SEE.UI.Window.PropertyWindow; using SEE.XR; @@ -358,7 +358,7 @@ private static IEnumerable GetCommonOptions(PopupMenu popupMenu, entries.Add(new PopupMenuHeading("Source: " + source, Priority: int.MaxValue)); entries.Add(new PopupMenuHeading("Target: " + target, Priority: int.MaxValue)); } - entries.Add(new PopupMenuAction("Delete", DeleteElement, Icons.Trash, Priority: 0)); + entries.Add(new PopupMenuAction("Delete", () => DeleteElement().Forget(), Icons.Trash, Priority: 0)); entries.Add(new PopupMenuActionDoubleIcon("Inspect", () => { @@ -397,7 +397,7 @@ private static IEnumerable GetCommonOptions(PopupMenu popupMenu, return entries; - void DeleteElement() + async UniTaskVoid DeleteElement() { if (graphElement is Node node && node.IsRoot()) { @@ -414,8 +414,11 @@ void DeleteElement() } else { - ConfirmDialogMenu confirm = new($"Do you really want to delete the element {graphElement.ID}?\r\nThis action cannot be undone."); - confirm.ExecuteAfterConfirmAsync(() => graphElement.ItsGraph.RemoveElement(graphElement)).Forget(); + string message = $"Do you really want to delete the element {graphElement.ID}?\nThis action cannot be undone."; + if (await ConfirmDialog.ConfirmAsync(ConfirmConfiguration.Delete(message))) + { + graphElement.ItsGraph.RemoveElement(graphElement); + } } } diff --git a/Assets/SEE/UI/DebugAdapterProtocol/DebugAdapterProtocolManager.cs b/Assets/SEE/UI/DebugAdapterProtocol/DebugAdapterProtocolManager.cs index 1acb7a350b..7860510651 100644 --- a/Assets/SEE/UI/DebugAdapterProtocol/DebugAdapterProtocolManager.cs +++ b/Assets/SEE/UI/DebugAdapterProtocol/DebugAdapterProtocolManager.cs @@ -138,7 +138,7 @@ public static void Run() /// public static void OpenDebugAdapterConfig() { - GameObject go = new GameObject("Debug Adapter Configuration"); + GameObject go = new("Debug Adapter Configuration"); // create property group PropertyGroup group = go.gameObject.AddComponent(); @@ -224,7 +224,7 @@ void UpdateValues() /// public static void OpenLaunchConfig() { - GameObject go = new GameObject("Launch Request"); + GameObject go = new("Launch Request"); // create property group PropertyGroup group = go.AddComponent(); diff --git a/Assets/SEE/UI/Menu/ConfirmDialog.cs b/Assets/SEE/UI/Menu/ConfirmDialog.cs new file mode 100644 index 0000000000..98cda1b999 --- /dev/null +++ b/Assets/SEE/UI/Menu/ConfirmDialog.cs @@ -0,0 +1,222 @@ +using System; +using System.Threading; +using Cysharp.Threading.Tasks; +using DG.Tweening; +using Michsky.UI.ModernUIPack; +using SEE.GO; +using SEE.Utils; +using TMPro; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; + +namespace SEE.UI.Menu +{ + /// + /// Configuration for the confirm dialog. + /// + /// The description of the dialog, can be up to three lines long. + /// The title of the dialog displayed in the top bar. Should be kept short. + /// The text of the confirm button. + /// The text of the cancel button. + /// The icon of the confirm button, given as a FontAwesome character (see ). + /// The icon of the cancel button, given as a FontAwesome character (see ). + /// The color of the confirm button. Note that the text will be white, so choose a dark color. + public record ConfirmConfiguration( + string description, + string title = "Are you sure?", + string yesText = "Confirm", + string noText = "Cancel", + char yesIcon = Icons.Checkmark, + char noIcon = 'X', + Color? yesColor = null + ) + { + /// + /// A pre-made configuration for a delete dialog. + /// + /// The description of the dialog, can be up to three lines long. + /// A configuration for a delete dialog. + public static ConfirmConfiguration Delete(string description) + { + return new ConfirmConfiguration(description, title: "Really delete?", + yesText: "Delete", yesIcon: Icons.Trash, yesColor: Color.red.Darker()); + } + } + + /// + /// A simple configurable confirmation dialog with a "confirm" and a "cancel" button. + /// + public class ConfirmDialog : PlatformDependentComponent + { + /// + /// The duration of the fade animation in seconds. + /// + private const float AnimationDuration = 1.0f; + + /// + /// Prefab for the dialog. + /// + private static string DialogMenuPrefab => UIPrefabFolder + "ConfirmDialog"; + + /// + /// The default color of the confirm button. + /// + private static readonly Color DefaultColor = Color.green.Darker(); // Slightly darker green. + + /// + /// Whether the dialog should be destroyed after it is closed (and faded out). + /// + private bool OneTime; + + /// + /// The dialog menu game object. + /// + private GameObject Dialog { get; set; } + + /// + /// The canvas group of the dialog, used for fading in and out. + /// + private CanvasGroup CanvasGroup { get; set; } + + /// + /// The title of the dialog. + /// + private TextMeshProUGUI Title { get; set; } + + /// + /// The description of the dialog. + /// Can be up to three lines long. + /// + private TextMeshProUGUI Description { get; set; } + + /// + /// The negative/"cancel" button of the dialog. + /// + private ButtonManagerBasic NoButton { get; set; } + + /// + /// The positive/"confirm" button of the dialog. + /// + private ButtonManagerBasic YesButton { get; set; } + + /// + /// The image component of the controlling its color. + /// + private Image YesButtonImage { get; set; } + + /// + /// The TextMeshPro component for the icon of the . + /// + private TextMeshProUGUI NoIcon { get; set; } + + /// + /// The TextMeshPro component for the icon of the . + /// + private TextMeshProUGUI YesIcon { get; set; } + + /// + /// An event that is invoked when the user makes a choice in the dialog (including closing it). + /// + private UnityEvent OnChoiceMade { get; } = new(); + + /// + /// The game object under which the dialogs are instantiated. + /// + private static readonly Lazy dialogGameObject = new(() => new("ConfirmDialogs")); + + /// + /// The ongoing fade animation of the dialog, if any. + /// + private Tweener ExistingFade; + + /// + /// Initializes the dialog. + /// + protected override void StartDesktop() + { + Dialog = PrefabInstantiator.InstantiatePrefab(DialogMenuPrefab, Canvas.transform, false); + CanvasGroup = Dialog.MustGetComponent(); + NoButton = Dialog.transform.Find("Content/Buttons/Cancel").gameObject.MustGetComponent(); + NoIcon = NoButton.transform.Find("Texts/Icon").gameObject.MustGetComponent(); + YesButton = Dialog.transform.Find("Content/Buttons/Confirm").gameObject.MustGetComponent(); + YesIcon = YesButton.transform.Find("Texts/Icon").gameObject.MustGetComponent(); + YesButtonImage = YesButton.gameObject.MustGetComponent(); + Title = Dialog.transform.Find("Dragger/Text").gameObject.MustGetComponent(); + Description = Dialog.transform.Find("Content/Description").gameObject.MustGetComponent(); + ButtonManagerBasic CloseButton = Dialog.transform.Find("Dragger/CancelDragger").gameObject.MustGetComponent(); + + YesButton.clickEvent.AddListener(() => OnChoiceMade.Invoke(true)); + NoButton.clickEvent.AddListener(() => OnChoiceMade.Invoke(false)); + CloseButton.clickEvent.AddListener(() => OnChoiceMade.Invoke(false)); + OnChoiceMade.AddListener(_ => CloseMenu()); + } + + private void OnDestroy() + { + if (Dialog != null) + { + Destroyer.Destroy(Dialog); + } + } + + /// + /// Sets up the dialog with the given and fades it in. + /// + /// The configuration for the dialog. + private void ShowMenu(ConfirmConfiguration configuration) + { + Title.text = configuration.title; + Description.text = configuration.description; + YesButton.buttonText = configuration.yesText; + NoButton.buttonText = configuration.noText; + YesIcon.text = configuration.yesIcon.ToString(); + YesButtonImage.color = configuration.yesColor ?? DefaultColor; + NoIcon.text = configuration.noIcon.ToString(); + + Dialog.SetActive(true); + Dialog.transform.SetAsLastSibling(); + ExistingFade?.Kill(); + ExistingFade = CanvasGroup.DOFade(1f, AnimationDuration); + } + + /// + /// Closes the dialog by fading it out. + /// + private void CloseMenu() + { + ExistingFade?.Kill(); + ExistingFade = CanvasGroup.DOFade(0f, AnimationDuration).OnComplete(DisableMenu); + } + + /// + /// Disables/destroys the dialog after it has been faded out. + /// + private void DisableMenu() + { + if (OneTime) + { + Destroyer.Destroy(this); + } + else + { + Dialog.SetActive(false); + } + } + + /// + /// Shows a confirmation dialog with the given + /// and waits for the user to make a choice. Their choice is returned as a . + /// + /// The configuration for the dialog. + /// Whether the user confirmed the dialog. + public static async UniTask ConfirmAsync(ConfirmConfiguration configuration) + { + ConfirmDialog dialog = dialogGameObject.Value.AddComponent(); + dialog.OneTime = true; + await UniTask.WaitUntil(() => dialog.Dialog != null); // May need to wait for initialization. + dialog.ShowMenu(configuration); + return await dialog.OnChoiceMade.OnInvokeAsync(CancellationToken.None); + } + } +} diff --git a/Assets/SEE/UI/Menu/ConfirmDialog.cs.meta b/Assets/SEE/UI/Menu/ConfirmDialog.cs.meta new file mode 100644 index 0000000000..0d18dfe288 --- /dev/null +++ b/Assets/SEE/UI/Menu/ConfirmDialog.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5c29c87d6b544ee2b20d225feaf7b824 +timeCreated: 1731674969 \ No newline at end of file diff --git a/Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs b/Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs deleted file mode 100644 index 351ac13719..0000000000 --- a/Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Cysharp.Threading.Tasks; -using Michsky.UI.ModernUIPack; -using SEE.Game.Drawable; -using SEE.Utils; -using TMPro; -using UnityEngine.Events; - -namespace SEE.UI.Menu.Drawable -{ - /// - /// Class that provides a confirm dialog menu. - /// - public class ConfirmDialogMenu : Menu - { - /// - /// The prefab of the menu. - /// - private const string confirmMenuPrefab = "Prefabs/UI/Drawable/ConfirmDialog"; - - /// - /// Enables the dialog menu with given - /// - /// The text that should be displayed. - public ConfirmDialogMenu(string text) - { - Instantiate(confirmMenuPrefab); - - /// Initialize the buttons. - ButtonManagerBasic cancelDragger = GameFinder.FindChild(gameObject, "CancelDragger") - .GetComponent(); - cancelDragger.clickEvent.AddListener(() => - { - WasCanceled = true; - Destroyer.Destroy(gameObject); - }); - ButtonManagerBasic confirm = GameFinder.FindChild(gameObject, "Confirm") - .GetComponent(); - confirm.clickEvent.AddListener(() => - { - WasConfirmed = true; - Destroyer.Destroy(gameObject); - }); - ButtonManagerBasic cancel = GameFinder.FindChild(gameObject, "Cancel") - .GetComponent(); - cancel.clickEvent.AddListener(() => - { - WasCanceled = true; - Destroyer.Destroy(gameObject); - }); - TextMeshProUGUI description = GameFinder.FindChild(gameObject, "Description") - .GetComponent(); - description.text = text; - } - - /// - /// Executes the action after confirming the dialog. - /// - /// The action to be executed. - /// nothing, it waits until the dialog was confirmed or canceled. - public async UniTask ExecuteAfterConfirmAsync(UnityAction action) - { - await UniTask.WaitWhile(IsOpen); - if (WasConfirmed && !WasCanceled) - { - action.Invoke(); - } - } - - /// - /// True if the dialog was canceled. - /// - public bool WasCanceled { get; private set; } = false; - - /// - /// True if the dialog was confirmed. - /// - public bool WasConfirmed { get; private set; } = false; - } -} diff --git a/Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs.meta b/Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs.meta deleted file mode 100644 index 7f8de852e1..0000000000 --- a/Assets/SEE/UI/Menu/Drawable/ConfirmDialogMenu.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: adc603571c272134d8a543cd598647c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/SEE/UI/Window/DrawableManagerWindow/DrawableWindowContextMenu.cs b/Assets/SEE/UI/Window/DrawableManagerWindow/DrawableWindowContextMenu.cs index 2dd4b6d89b..76b05d7cf3 100644 --- a/Assets/SEE/UI/Window/DrawableManagerWindow/DrawableWindowContextMenu.cs +++ b/Assets/SEE/UI/Window/DrawableManagerWindow/DrawableWindowContextMenu.cs @@ -10,7 +10,7 @@ using SEE.Net.Actions.Drawable; using System.Linq; using Cysharp.Threading.Tasks; -using SEE.UI.Menu.Drawable; +using SEE.UI.Menu; namespace SEE.UI.Window.DrawableManagerWindow { @@ -410,7 +410,7 @@ PopupMenuAction CreatePopupEntries(int pageNumber) { if (removeIndicator) { - RemovePage(pageNumber); + RemovePage(pageNumber).Forget(); } else { @@ -439,16 +439,16 @@ void SetPage(int page) } /// Removes the page. - void RemovePage(int page) + async UniTaskVoid RemovePage(int page) { if (GameFinder.GetDrawableTypesOfPage(surface, page).Count > 0) { - ConfirmDialogMenu confirm = new($"Do you really want to delete the page {page}?\r\nThis action cannot be undone."); - confirm.ExecuteAfterConfirmAsync(() => + string deleteMessage = $"Do you really want to delete page {page}?\nThis action cannot be undone."; + if (await ConfirmDialog.ConfirmAsync(ConfirmConfiguration.Delete(deleteMessage))) { GameDrawableManager.RemovePage(surface, page); new SurfaceRemovePageNetAction(DrawableConfigManager.GetDrawableConfig(surface), page).Execute(); - }).Forget(); + } } else {