소스 검색

Add settings pane and key rebinding

Settings button is on the bottom right of the main window for all tabs.

All keys that MeidoPhotoStudio currently uses can be rebound except for
modifier keys (control, alt, shift). Controls can also be unbound.
habeebweeb 4 년 전
부모
커밋
91daeb4cfc

+ 28 - 0
COM3D2.MeidoPhotoStudio.Plugin/Config/MeidoPhotoStudio/Translations/en/translation.ui.json

@@ -384,5 +384,33 @@
         "initializing": "Initializing",
         "noMaids": "No Maids",
         "noProps": "No Props"
+    },
+    "controls": {
+        "activate": "Activate MPS",
+        "screenshot": "Screenshot",
+        "toggleUI": "Hide/Show UI",
+        "toggleMessage": "Message Box",
+        "meidoUndressing": "Undressing",
+        "cameraLayer": "Camera Layer",
+        "cameraReset": "Reset Camera",
+        "cameraSave": "Save Camera",
+        "cameraLoad": "Load Camera",
+        "dragSelect": "Select",
+        "dragDelete": "Delete",
+        "dragMove": "Move",
+        "dragRotate": "Rotate",
+        "dragScale": "Scale",
+        "dragFinger": "Show Fingers",
+        "saveScene": "Quick Save",
+        "loadScene": "Quick Load",
+        "openSceneManager": "Open Scene Manager"
+    },
+    "settingsHeaders": {
+        "controls": "Controls",
+        "controlsGeneral": "General",
+        "controlsMaids": "Maids",
+        "controlsCamera": "Camera",
+        "controlsDragPoint": "Drag Handles",
+        "controlsScene": "Scene Management"
     }
 }

+ 2 - 2
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Constants.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -33,7 +33,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public static readonly int dropdownWindowID = 777;
         public enum Window
         {
-            Call, Pose, Face, BG, BG2, Main, Message, Save, SaveModal
+            Call, Pose, Face, BG, BG2, Main, Message, Save, SaveModal, Settings
         }
         public enum Scene
         {

+ 6 - 6
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPoint.cs

@@ -92,12 +92,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         static DragPoint()
         {
-            InputManager.Register(MpsKey.DragSelect, KeyCode.A);
-            InputManager.Register(MpsKey.DragDelete, KeyCode.D);
-            InputManager.Register(MpsKey.DragMove, KeyCode.Z);
-            InputManager.Register(MpsKey.DragRotate, KeyCode.X);
-            InputManager.Register(MpsKey.DragScale, KeyCode.C);
-            InputManager.Register(MpsKey.DragFinger, KeyCode.Space);
+            InputManager.Register(MpsKey.DragSelect, KeyCode.A, "Select handle mode");
+            InputManager.Register(MpsKey.DragDelete, KeyCode.D, "Delete handle mode");
+            InputManager.Register(MpsKey.DragMove, KeyCode.Z, "Move handle mode");
+            InputManager.Register(MpsKey.DragRotate, KeyCode.X, "Rotate handle mode");
+            InputManager.Register(MpsKey.DragScale, KeyCode.C, "Scale handle mode");
+            InputManager.Register(MpsKey.DragFinger, KeyCode.Space, "Show finger handles");
         }
 
         private void Awake()

+ 54 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Controls/KeyRebindButton.cs

@@ -0,0 +1,54 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class KeyRebindButton : BaseControl
+    {
+        private Button button;
+        private bool listening = false;
+        private KeyCode keyCode;
+        public KeyCode KeyCode
+        {
+            get => keyCode;
+            set
+            {
+                keyCode = value;
+                button.Label = keyCode.ToString();
+            }
+        }
+        public KeyRebindButton(KeyCode code)
+        {
+            button = new Button(code.ToString());
+            button.ControlEvent += (s, a) => StartListening();
+        }
+
+        public void Draw(GUIStyle buttonStyle, params GUILayoutOption[] layoutOptions)
+        {
+            GUI.enabled = !listening && !InputManager.Listening;
+            button.Draw(buttonStyle, layoutOptions);
+            GUI.enabled = true;
+        }
+
+        public override void Draw(params GUILayoutOption[] layoutOptions)
+        {
+            GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
+            Draw(buttonStyle, layoutOptions);
+        }
+
+        private void StartListening()
+        {
+            listening = true;
+            InputManager.StartListening();
+            InputManager.KeyChange += KeyChange;
+        }
+
+        private void KeyChange(object sender, EventArgs args)
+        {
+            listening = false;
+            KeyCode = InputManager.CurrentKeyCode;
+            InputManager.KeyChange -= KeyChange;
+            OnControlEvent(EventArgs.Empty);
+        }
+    }
+}

+ 130 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/MainWindowPanes/SettingsWindowPane.cs

@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class SettingsWindowPane : BaseMainWindowPane
+    {
+        private Button reloadTranslationButton;
+        private KeyRebindButton[] rebindButtons;
+        private static readonly string[] actionTranslationKeys;
+        private static readonly string[] actionLabels;
+        private static readonly string[] headerTranslationKeys = {
+            "controls", "controlsGeneral", "controlsMaids", "controlsCamera", "controlsDragPoint", "controlsScene"
+        };
+        private static readonly Dictionary<string, string> headers = new Dictionary<string, string>();
+
+        static SettingsWindowPane()
+        {
+            actionTranslationKeys = Enum.GetNames(typeof(MpsKey))
+                .Select(action => char.ToLowerInvariant(action[0]) + action.Substring(1))
+                .ToArray();
+            actionLabels = new string[actionTranslationKeys.Length];
+        }
+
+        public SettingsWindowPane()
+        {
+            reloadTranslationButton = new Button("Reload Translation");
+            reloadTranslationButton.ControlEvent += (s, a) => Translation.ReinitializeTranslation();
+
+            rebindButtons = new KeyRebindButton[actionTranslationKeys.Length];
+
+            for (int i = 0; i < rebindButtons.Length; i++)
+            {
+                MpsKey action = (MpsKey)i;
+                KeyRebindButton button = new KeyRebindButton(KeyCode.None);
+                button.ControlEvent += (s, a) => InputManager.Rebind(action, button.KeyCode);
+                rebindButtons[i] = button;
+
+                actionLabels[i] = Translation.Get("controls", actionTranslationKeys[i]);
+            }
+
+            for (int i = 0; i < headerTranslationKeys.Length; i++)
+            {
+                headers[headerTranslationKeys[i]] = Translation.Get("settingsHeaders", headerTranslationKeys[i]);
+            }
+        }
+
+        protected override void ReloadTranslation()
+        {
+            for (int i = 0; i < rebindButtons.Length; i++)
+            {
+                actionLabels[i] = Translation.Get("controls", actionTranslationKeys[i]);
+            }
+
+            for (int i = 0; i < headerTranslationKeys.Length; i++)
+            {
+                headers[headerTranslationKeys[i]] = Translation.Get("settingsHeaders", headerTranslationKeys[i]);
+            }
+        }
+
+        public override void Draw()
+        {
+            scrollPos = GUILayout.BeginScrollView(scrollPos);
+
+            MiscGUI.Header(headers["controls"]);
+            MiscGUI.WhiteLine();
+
+            MiscGUI.Header(headers["controlsGeneral"]);
+            MiscGUI.WhiteLine();
+            for (MpsKey key = MpsKey.Activate; key <= MpsKey.ToggleMessage; key++)
+            {
+                DrawSetting(key);
+            }
+
+            MiscGUI.Header(headers["controlsMaids"]);
+            MiscGUI.WhiteLine();
+            DrawSetting(MpsKey.MeidoUndressing);
+
+            MiscGUI.Header(headers["controlsCamera"]);
+            MiscGUI.WhiteLine();
+            for (MpsKey key = MpsKey.CameraLayer; key <= MpsKey.CameraLoad; key++)
+            {
+                DrawSetting(key);
+            }
+
+            MiscGUI.Header(headers["controlsDragPoint"]);
+            MiscGUI.WhiteLine();
+            for (MpsKey key = MpsKey.DragSelect; key <= MpsKey.DragFinger; key++)
+            {
+                DrawSetting(key);
+            }
+
+            MiscGUI.Header(headers["controlsScene"]);
+            MiscGUI.WhiteLine();
+            for (MpsKey key = MpsKey.SaveScene; key <= MpsKey.OpenSceneManager; key++)
+            {
+                DrawSetting(key);
+            }
+
+            MiscGUI.WhiteLine();
+            reloadTranslationButton.Draw();
+            GUILayout.EndScrollView();
+        }
+
+        private void DrawSetting(MpsKey key)
+        {
+            int keyIndex = (int)key;
+            GUILayout.BeginHorizontal();
+            GUILayout.Label(actionLabels[keyIndex]);
+            GUILayout.FlexibleSpace();
+            rebindButtons[keyIndex].Draw(GUILayout.Width(90f));
+            if (GUILayout.Button("×", GUILayout.ExpandWidth(false)))
+            {
+                rebindButtons[keyIndex].KeyCode = KeyCode.None;
+                InputManager.Rebind(key, KeyCode.None);
+            }
+            GUILayout.EndHorizontal();
+        }
+
+        public override void UpdatePanes()
+        {
+            for (int i = 0; i < rebindButtons.Length; i++)
+            {
+                rebindButtons[i].KeyCode = InputManager.GetActionKey((MpsKey)i);
+            }
+        }
+    }
+}

+ 23 - 12
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindow.cs

@@ -10,7 +10,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private LightManager lightManager;
         private Dictionary<Constants.Window, BaseMainWindowPane> windowPanes;
         private TabsPane tabsPane;
-        private Button ReloadTranslationButton;
+        private Button settingsButton;
         private BaseMainWindowPane currentWindowPane;
         public override Rect WindowRect
         {
@@ -49,10 +49,15 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             tabsPane = new TabsPane();
             tabsPane.TabChange += (s, a) => ChangeTab();
 
-            ReloadTranslationButton = new Button("Reload Translation");
-            ReloadTranslationButton.ControlEvent += (s, a) =>
+            settingsButton = new Button("Settings");
+            settingsButton.ControlEvent += (s, a) =>
             {
-                Translation.ReinitializeTranslation();
+                if (selectedWindow == Constants.Window.Settings) ChangeTab();
+                else
+                {
+                    settingsButton.Label = "Close";
+                    SetCurrentWindow(Constants.Window.Settings);
+                }
             };
         }
 
@@ -77,13 +82,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void ChangeTab()
         {
-            this.selectedWindow = (Constants.Window)tabsPane.SelectedTab;
-            SetCurrentWindow();
+            settingsButton.Label = "Settings";
+            SetCurrentWindow(tabsPane.SelectedTab);
         }
 
-        private void SetCurrentWindow()
+        private void SetCurrentWindow(Constants.Window window)
         {
             if (currentWindowPane != null) currentWindowPane.ActiveWindow = false;
+            selectedWindow = window;
             currentWindowPane = windowPanes[selectedWindow];
             currentWindowPane.ActiveWindow = true;
             currentWindowPane.UpdatePanes();
@@ -106,13 +112,18 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             GUILayout.FlexibleSpace();
 
-            ReloadTranslationButton.Draw();
-
-            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
-            labelStyle.fontSize = 10;
-            labelStyle.alignment = TextAnchor.LowerLeft;
+            GUIStyle labelStyle = new GUIStyle(GUI.skin.label)
+            {
+                fontSize = 10,
+                alignment = TextAnchor.LowerLeft
+            };
 
+            GUILayout.BeginHorizontal();
             GUILayout.Label(MeidoPhotoStudio.pluginString, labelStyle);
+            GUILayout.FlexibleSpace();
+            settingsButton.Draw(GUILayout.ExpandWidth(false));
+            GUILayout.EndHorizontal();
+
             GUI.DragWindow();
         }
 

+ 4 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EnvironmentManager.cs

@@ -56,10 +56,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         static EnvironmentManager()
         {
-            Input.Register(MpsKey.CameraLayer, KeyCode.Q);
-            Input.Register(MpsKey.CameraSave, KeyCode.S);
-            Input.Register(MpsKey.CameraLoad, KeyCode.A);
-            Input.Register(MpsKey.CameraReset, KeyCode.R);
+            Input.Register(MpsKey.CameraLayer, KeyCode.Q, "Camera control layer");
+            Input.Register(MpsKey.CameraSave, KeyCode.S, "Save camera transform");
+            Input.Register(MpsKey.CameraLoad, KeyCode.A, "Load camera transform");
+            Input.Register(MpsKey.CameraReset, KeyCode.R, "Reset camera transform");
         }
 
         public EnvironmentManager(MeidoManager meidoManager)

+ 48 - 8
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/InputManager.cs

@@ -2,21 +2,60 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
+using BepInEx.Configuration;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     internal class InputManager
     {
         private static InputListener inputListener;
+        private static readonly Dictionary<MpsKey, KeyCode> ActionKeys = new Dictionary<MpsKey, KeyCode>();
+        private static readonly Dictionary<MpsKey, ConfigEntry<KeyCode>> ConfigEntries
+            = new Dictionary<MpsKey, ConfigEntry<KeyCode>>();
         public static KeyCode CurrentKeyCode { get; private set; }
         public static bool Listening { get; private set; }
         public static event EventHandler KeyChange;
         public static bool Control => Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
         public static bool Alt => Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
         public static bool Shift => Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
-        private static readonly Dictionary<MpsKey, KeyCode> Actions = new Dictionary<MpsKey, KeyCode>();
+        public static readonly AcceptableValueBase controlRange;
+        public const KeyCode upperKeyCode = KeyCode.F15;
+        public const string configHeader = "Controls";
 
-        public static void Register(MpsKey action, KeyCode key) => Actions[action] = key;
+        static InputManager() => controlRange = new AcceptableValueRange<KeyCode>(default, upperKeyCode);
+
+        public static void Register(MpsKey action, KeyCode key, string description)
+        {
+            key = Clamp(key, default, upperKeyCode);
+            if (ConfigEntries.ContainsKey(action)) Rebind(action, key);
+            else
+            {
+                ConfigDescription configDescription = new ConfigDescription(description, controlRange);
+                ConfigEntries[action] = Configuration.Config.Bind(
+                    configHeader, action.ToString(), key, configDescription
+                );
+                key = ConfigEntries[action].Value;
+                ActionKeys[action] = key;
+            }
+        }
+
+        public static void Rebind(MpsKey action, KeyCode key)
+        {
+            key = Clamp(key, default, upperKeyCode);
+            if (ConfigEntries.ContainsKey(action)) ConfigEntries[action].Value = key;
+            ActionKeys[action] = key;
+        }
+
+        public static KeyCode Clamp(KeyCode value, KeyCode min, KeyCode max)
+        {
+            return value < min ? min : value > max ? max : value;
+        }
+
+        public static KeyCode GetActionKey(MpsKey action)
+        {
+            ActionKeys.TryGetValue(action, out KeyCode keyCode);
+            return keyCode;
+        }
 
         public static void StartListening()
         {
@@ -35,16 +74,18 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             inputListener.gameObject.SetActive(false);
             inputListener.KeyChange -= OnKeyChange;
             CurrentKeyCode = KeyCode.None;
+            Listening = false;
+            Input.ResetInputAxes();
         }
 
         public static bool GetKey(MpsKey action)
         {
-            return (Listening || !Actions.ContainsKey(action)) ? false : Input.GetKey(Actions[action]);
+            return !Listening && ActionKeys.ContainsKey(action) && Input.GetKey(ActionKeys[action]);
         }
 
         public static bool GetKeyDown(MpsKey action)
         {
-            return (Listening || !Actions.ContainsKey(action)) ? false : Input.GetKeyDown(Actions[action]);
+            return !Listening && ActionKeys.ContainsKey(action) && Input.GetKeyDown(ActionKeys[action]);
         }
 
         public static void Deactivate()
@@ -71,7 +112,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 keyCodes = Enum.GetValues(typeof(KeyCode))
                     .Cast<KeyCode>()
-                    .Where(keyCode => keyCode < KeyCode.Numlock)
+                    .Where(keyCode => keyCode <= upperKeyCode)
                     .ToArray();
             }
 
@@ -96,7 +137,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private class KeyChangeEventArgs : EventArgs
         {
             public KeyCode Key { get; }
-            public KeyChangeEventArgs(KeyCode key) => this.Key = key;
+            public KeyChangeEventArgs(KeyCode key) => Key = key;
         }
     }
 
@@ -109,8 +150,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         // Camera
         CameraLayer, CameraReset, CameraSave, CameraLoad,
         // Dragpoint
-        DragSelect, DragDelete, DragMove, DragRotate, DragScale,
-        DragFinger,
+        DragSelect, DragDelete, DragMove, DragRotate, DragScale, DragFinger,
         // Scene management
         SaveScene, LoadScene, OpenSceneManager
     }

+ 1 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MeidoManager.cs

@@ -47,10 +47,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
-        static MeidoManager()
-        {
-            InputManager.Register(MpsKey.MeidoUndressing, KeyCode.H);
-        }
+        static MeidoManager() => InputManager.Register(MpsKey.MeidoUndressing, KeyCode.H, "All maid undressing");
 
         public void ChangeMaid(int index)
         {

+ 2 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MessageWindowManager.cs

@@ -17,9 +17,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private string messageName;
         private string messageText;
 
+        static MessageWindowManager() => InputManager.Register(MpsKey.ToggleMessage, KeyCode.M, "Show/hide message box");
+
         public MessageWindowManager()
         {
-            InputManager.Register(MpsKey.ToggleMessage, KeyCode.M);
             sysRoot = GameObject.Find("__GameMain__/SystemUI Root");
             this.msgWnd = GameMain.Instance.MsgWnd;
             this.msgGameObject = sysRoot.transform.Find("MessageWindowPanel").gameObject;

+ 3 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/SceneManager.cs

@@ -69,9 +69,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 "Scene sorting mode"
             );
 
-            InputManager.Register(MpsKey.OpenSceneManager, KeyCode.F8);
-            InputManager.Register(MpsKey.SaveScene, KeyCode.S);
-            InputManager.Register(MpsKey.LoadScene, KeyCode.A);
+            Input.Register(MpsKey.OpenSceneManager, KeyCode.F8, "Hide/show scene manager");
+            Input.Register(MpsKey.SaveScene, KeyCode.S, "Quick save scene");
+            Input.Register(MpsKey.LoadScene, KeyCode.A, "Load quick saved scene");
         }
 
         public SceneManager(MeidoPhotoStudio meidoPhotoStudio)

+ 1 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/WindowManager.cs

@@ -13,10 +13,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             set => Windows[id] = value;
         }
 
-        public WindowManager()
-        {
-            InputManager.Register(MpsKey.ToggleUI, KeyCode.Tab);
-        }
+        public WindowManager() => InputManager.Register(MpsKey.ToggleUI, KeyCode.Tab, "Show/hide all UI");
 
         public void DrawWindow(BaseWindow window)
         {

+ 4 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MeidoPhotoStudio.cs

@@ -36,8 +36,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         static MeidoPhotoStudio()
         {
-            Input.Register(MpsKey.Screenshot, KeyCode.S);
-            Input.Register(MpsKey.Activate, KeyCode.F6);
+            Input.Register(MpsKey.Screenshot, KeyCode.S, "Take screenshot");
+            Input.Register(MpsKey.Activate, KeyCode.F6, "Activate/deactivate MeidoPhotoStudio");
         }
 
         private void Awake()
@@ -368,7 +368,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     [Constants.Window.BG] = new BGWindowPane(
                         environmentManager, lightManager, effectManager, sceneWindow
                     ),
-                    [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager)
+                    [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager),
+                    [Constants.Window.Settings] = new SettingsWindowPane()
                 },
                 [Constants.Window.Message] = new MessageWindow(messageWindowManager),
                 [Constants.Window.Save] = sceneWindow