فهرست منبع

Refactor almost everything

oof
habeebweeb 4 سال پیش
والد
کامیت
76a6bc3d4e
35فایلهای تغییر یافته به همراه778 افزوده شده و 642 حذف شده
  1. 17 5
      COM3D2.MeidoPhotoStudio.Plugin/Config/MeidoPhotoStudio/translations.en.json
  2. 10 1
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Constants.cs
  3. 7 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Controls/DropDown.cs
  4. 1 1
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/BackgroundSelectorPane.cs
  5. 3 5
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/PropsPane.cs
  6. 7 3
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BasePane.cs
  7. 7 7
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/CallWindowPanes/MaidSelectorPane.cs
  8. 2 2
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/FaceWindowPanes/MaidFaceSliderPane.cs
  9. 4 4
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/Background2Window.cs
  10. 34 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/MainWindowPanes/BGWindowPane.cs
  11. 9 6
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidCallWindow.cs
  12. 14 26
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidFaceWindow.cs
  13. 20 32
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidPoseWindow.cs
  14. 12 15
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/OtherPanes/MaidSwitcherPane.cs
  15. 11 10
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/OtherPanes/TabsPane.cs
  16. 5 3
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidDressingPane.cs
  17. 3 3
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidFaceLookPane.cs
  18. 3 8
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidIKPane.cs
  19. 5 4
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidPoseSelectorPane.cs
  20. 0 25
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/BaseMainWindow.cs
  21. 33 4
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/BaseWindow.cs
  22. 17 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/BaseWindowPane.cs
  23. 125 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindow.cs
  24. 0 27
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/BackgroundWindow.cs
  25. 47 6
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/OtherWindows/MessageWindow.cs
  26. 100 75
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/DragPointManager.cs
  27. 1 1
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EffectManager.cs
  28. 32 18
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EnvironmentManager.cs
  29. 72 94
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MeidoManager.cs
  30. 4 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MessageWindowManager.cs
  31. 1 4
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/PropManager.cs
  32. 44 122
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/WindowManager.cs
  33. 2 1
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragHead.cs
  34. 59 38
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/Meido.cs
  35. 67 92
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MeidoPhotoStudio.cs

+ 17 - 5
COM3D2.MeidoPhotoStudio.Plugin/Config/MeidoPhotoStudio/translations.en.json

@@ -1073,16 +1073,28 @@
         "bg": "BG"
     },
     "lights": {
-        "labelNormal": "Norm",
-        "labelSpot": "Spot",
-        "labelPoint": "Point",
-        "labelColor": "Color",
         "x": "Light X",
         "y": "Light Y",
-        "brightness": "Brightness",
+        "intensity": "Brightness",
         "range": "Range",
+        "spot": "Spot Angle",
         "shadow": "Shadow"
     },
+    "lightsPane": {
+        "header": "Lights",
+        "add": "+",
+        "delete": "Del",
+        "reset": "Reset",
+        "clear": "Clear",
+        "color": "Color",
+        "disable": "Disable"
+    },
+    "lightType": {
+        "main": "Main",
+        "normal": "Normal",
+        "spot": "Spot",
+        "point": "Point"
+    },
     "effectBloom": {
         "strength": "Strength",
         "blur": "Blur",

+ 10 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Constants.cs

@@ -22,7 +22,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public static readonly int dropdownWindowID = 777;
         public enum Window
         {
-            Call, Pose, Face, BG, BG2, Message, Save, SaveModal
+            Call, Pose, Face, BG, BG2, Main, Message, Save, SaveModal
         }
         public enum Scene
         {
@@ -385,6 +385,15 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
+        private static void InitializeHandItems()
+        {
+            List<string> handItems = new List<string>(
+                GameUty.MenuFiles.Where(menu => menu.StartsWith("handiteml") || menu.StartsWith("handitemr"))
+            );
+
+            WriteToFile("mm_hand_items", handItems);
+        }
+
         private static CsvParser OpenCsvParser(string nei, AFileSystemBase fs)
         {
             try

+ 7 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Controls/DropDown.cs

@@ -245,6 +245,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public static void HandleDropdown()
         {
             dropdownWindow = GUI.Window(Constants.dropdownWindowID, dropdownWindow, GUIFunc, "", windowStyle);
+            if (Input.mouseScrollDelta.y != 0f)
+            {
+                if (Visible && dropdownWindow.Contains(Event.current.mousePosition))
+                {
+                    Input.ResetInputAxes();
+                }
+            }
         }
 
         private static void GUIFunc(int id)

+ 1 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/BackgroundSelectorPane.cs

@@ -61,7 +61,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             updating = false;
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             float arrowButtonSize = 30;
             GUILayoutOption[] arrowLayoutOptions = {

+ 3 - 5
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/PropsPane.cs

@@ -4,7 +4,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     class PropsPane : BasePane
     {
-        private EnvironmentManager environmentManager;
         private PropManager propManager;
         private Dropdown otherDoguDropdown;
         private Dropdown doguDropdown;
@@ -15,10 +14,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private Button nextOtherDoguButton;
         private Button prevOtherDoguButton;
 
-        public PropsPane(EnvironmentManager environmentManager)
+        public PropsPane(PropManager propManager)
         {
-            this.environmentManager = environmentManager;
-            this.propManager = this.environmentManager.PropManager;
+            this.propManager = propManager;
 
             this.doguDropdown = new Dropdown(Translation.GetArray("props1Dropdown", Constants.DoguList));
 
@@ -58,7 +56,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.otherDoguDropdown.SetDropdownItems(Translation.GetArray("props2Dropdown", Constants.OtherDoguList));
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             float arrowButtonSize = 30;
             GUILayoutOption[] arrowLayoutOptions = {

+ 7 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BasePane.cs

@@ -3,17 +3,17 @@ using System.Collections.Generic;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    public abstract class BasePane : BaseControl
+    public abstract class BasePane
     {
         protected List<BaseControl> Controls { get; set; }
-        protected List<BasePane> Panes { get; set; }
         protected bool updating = false;
+        public virtual bool Visible { get; set; }
+        public bool Enabled { get; set; }
 
         public BasePane()
         {
             Translation.ReloadTranslationEvent += OnReloadTranslation;
             Controls = new List<BaseControl>();
-            Panes = new List<BasePane>();
         }
 
         ~BasePane()
@@ -27,5 +27,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         }
 
         protected virtual void ReloadTranslation() { }
+
+        public virtual void UpdatePane() { }
+
+        public virtual void Draw() { }
     }
 }

+ 7 - 7
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/CallWindowPanes/MaidSelectorPane.cs

@@ -16,11 +16,11 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.meidoManager = meidoManager;
             selectedMaidList = new List<int>();
             clearMaidsButton = new Button(Translation.Get("maidCallWindow", "clearButton"));
-            clearMaidsButton.ControlEvent += (s, a) => selectedMaidList.Clear();
+            clearMaidsButton.ControlEvent += (s, a) => this.meidoManager.SelectMeidoList.Clear();
             Controls.Add(clearMaidsButton);
 
             callMaidsButton = new Button(Translation.Get("maidCallWindow", "callButton"));
-            callMaidsButton.ControlEvent += (s, a) => this.meidoManager.OnBeginCallMeidos(this.selectedMaidList);
+            callMaidsButton.ControlEvent += (s, a) => this.meidoManager.CallMeidos();
             Controls.Add(callMaidsButton);
         }
 
@@ -30,7 +30,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             callMaidsButton.Label = Translation.Get("maidCallWindow", "callButton");
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             clearMaidsButton.Draw();
             callMaidsButton.Draw();
@@ -54,17 +54,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 Meido meido = meidoManager.meidos[i];
                 float y = i * buttonHeight;
-                bool selectedMaid = selectedMaidList.Contains(i);
+                bool selectedMaid = this.meidoManager.SelectMeidoList.Contains(i);
 
                 if (GUI.Button(new Rect(0, y, buttonWidth, buttonHeight), ""))
                 {
-                    if (selectedMaid) selectedMaidList.Remove(i);
-                    else selectedMaidList.Add(i);
+                    if (selectedMaid) this.meidoManager.SelectMeidoList.Remove(i);
+                    else this.meidoManager.SelectMeidoList.Add(i);
                 }
 
                 if (selectedMaid)
                 {
-                    int selectedIndex = selectedMaidList.IndexOf(i) + 1;
+                    int selectedIndex = this.meidoManager.SelectMeidoList.IndexOf(i) + 1;
                     GUI.DrawTexture(new Rect(5, y + 5, buttonWidth - 10, buttonHeight - 10), Texture2D.whiteTexture);
                     GUI.Label(
                         new Rect(0, y + 5, buttonWidth - 10, buttonHeight), selectedIndex.ToString(), selectLabelStyle

+ 2 - 2
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/FaceWindowPanes/MaidFaceSliderPane.cs

@@ -129,7 +129,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             SetFaceValue(key, value ? max : 0f);
         }
 
-        public override void Update()
+        public override void UpdatePane()
         {
             this.updating = true;
             TMorph morph = this.meidoManager.ActiveMeido.Maid.body0.Face.morph;
@@ -160,7 +160,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.updating = false;
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             for (int i = 0; i < faceKeys.Length; i += 2)
             {

+ 4 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/Background2Window.cs

@@ -1,17 +1,17 @@
-using System.Collections;
+using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    public class Background2Window : BaseMainWindow
+    public class BG2WindowPane : BaseWindowPane
     {
         EnvironmentManager environmentManager;
-        public Background2Window(EnvironmentManager environmentManager)
+        public BG2WindowPane(EnvironmentManager environmentManager)
         {
             this.environmentManager = environmentManager;
         }
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
 
             GUILayout.Label("bg2");

+ 34 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/MainWindowPanes/BGWindowPane.cs

@@ -0,0 +1,34 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    public class BGWindowPane : BaseWindowPane
+    {
+        private BackgroundSelectorPane backgroundSelectorPane;
+        private PropsPane propsPane;
+        // private LightsPane lightsPane;
+
+        public BGWindowPane(EnvironmentManager environmentManager)
+        {
+            this.backgroundSelectorPane = new BackgroundSelectorPane(environmentManager);
+            this.propsPane = new PropsPane(environmentManager.PropManager);
+            // this.lightsPane = new LightsPane(environmentManager.LightManager);
+        }
+        public override void Draw()
+        {
+            this.backgroundSelectorPane.Draw();
+            this.propsPane.Draw();
+            // this.lightsPane.Draw();
+        }
+
+        public override void UpdatePanes()
+        {
+            if (ActiveWindow)
+            {
+                this.propsPane.UpdatePane();
+                // this.lightsPane.UpdatePane();
+            }
+        }
+    }
+}

+ 9 - 6
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidCallWindow.cs

@@ -1,17 +1,15 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    public class MaidCallWindow : BaseMainWindow
+    public class CallWindowPane : BaseWindowPane
     {
         private MeidoManager meidoManager;
         private MaidSelectorPane maidSelectorPane;
         private Button placementButton;
         private Button placementOKButton;
-        public MaidCallWindow(MeidoManager meidoManager) : base()
+
+        public CallWindowPane(MeidoManager meidoManager)
         {
             this.meidoManager = meidoManager;
             placementButton = new Button(Translation.Get("placementDropdown", "normal"));
@@ -31,7 +29,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             placementOKButton.Label = Translation.Get("maidCallWindow", "okButton");
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void UpdatePanes()
+        {
+            maidSelectorPane.UpdatePane();
+        }
+
+        public override void Draw()
         {
             GUILayout.BeginHorizontal();
             placementButton.Draw(GUILayout.Width(150));

+ 14 - 26
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidFaceWindow.cs

@@ -1,25 +1,23 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
+using System;
 using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    public class MaidFaceWindow : BaseMainWindow
+    public class FaceWindowPane : BaseWindowPane
     {
         private MeidoManager meidoManager;
         private MaidFaceSliderPane maidFaceSliderPane;
+        private MaidSwitcherPane maidSwitcherPane;
         private Dropdown faceBlendDropdown;
         private Button facePrevButton;
         private Button faceNextButton;
 
-        public MaidFaceWindow(MeidoManager meidoManager)
+        public FaceWindowPane(MeidoManager meidoManager, MaidSwitcherPane maidSwitcherPane)
         {
             this.meidoManager = meidoManager;
-            this.meidoManager.SelectMeido += SelectMeido;
+            // this.meidoManager.UpdateMeido += UpdateMeido;
 
-            TabsPane.TabChange += ChangeTab;
+            this.maidSwitcherPane = maidSwitcherPane;
 
             this.maidFaceSliderPane = new MaidFaceSliderPane(this.meidoManager);
 
@@ -31,7 +29,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 if (updating) return;
                 string faceBlend = Constants.FaceBlendList[this.faceBlendDropdown.SelectedItemIndex];
                 this.meidoManager.ActiveMeido.SetFaceBlend(faceBlend);
-                this.UpdateFace();
+                this.UpdatePanes();
             };
 
             this.facePrevButton = new Button("<");
@@ -41,11 +39,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.faceNextButton.ControlEvent += (s, a) => this.faceBlendDropdown.Step(1);
         }
 
-        ~MaidFaceWindow()
-        {
-            TabsPane.TabChange -= ChangeTab;
-        }
-
         protected override void ReloadTranslation()
         {
             updating = true;
@@ -55,7 +48,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             updating = false;
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             float arrowButtonSize = 30;
             GUILayoutOption[] arrowLayoutOptions = {
@@ -70,7 +63,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 GUILayout.Width(dropdownButtonWidth)
             };
 
-            MaidSwitcherPane.Draw();
+            this.maidSwitcherPane.Draw();
 
             GUI.enabled = this.meidoManager.HasActiveMeido;
 
@@ -87,25 +80,20 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             GUILayout.EndScrollView();
         }
 
-        private void UpdateFace()
+        public override void UpdatePanes()
         {
             if (!this.meidoManager.HasActiveMeido) return;
-            if (TabsPane.SelectedTab == Constants.Window.Face)
+            if (ActiveWindow)
             {
                 this.meidoManager.ActiveMeido.Maid.boMabataki = false;
                 this.meidoManager.ActiveMeido.Maid.body0.Face.morph.EyeMabataki = 0f;
-                this.maidFaceSliderPane.Update();
+                this.maidFaceSliderPane.UpdatePane();
             }
         }
 
-        private void SelectMeido(object sender, MeidoChangeEventArgs args)
-        {
-            UpdateFace();
-        }
-
-        private void ChangeTab(object sender, EventArgs args)
+        private void UpdateMeido(object sender, EventArgs args)
         {
-            UpdateFace();
+            UpdatePanes();
         }
     }
 }

+ 20 - 32
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidPoseWindow.cs

@@ -1,24 +1,25 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
+using System;
 using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    public class MaidPoseWindow : BaseMainWindow
+    public class PoseWindowPane : BaseWindowPane
     {
         private MeidoManager meidoManager;
         private MaidPoseSelectorPane maidPosePane;
+        private MaidSwitcherPane maidSwitcherPane;
         private MaidFaceLookPane maidFaceLookPane;
         private MaidDressingPane maidDressingPane;
         private MaidIKPane maidIKPane;
         private Toggle freeLookToggle;
-        public MaidPoseWindow(MeidoManager meidoManager)
+
+        public PoseWindowPane(MeidoManager meidoManager, MaidSwitcherPane maidSwitcherPane)
         {
             this.meidoManager = meidoManager;
-            this.meidoManager.SelectMeido += (s, a) => UpdatePanes();
-            this.meidoManager.FreeLookChange += (s, a) => UpdatePanes();
+            this.maidSwitcherPane = maidSwitcherPane;
+
+            // this.meidoManager.UpdateMeido += UpdateMeido;
+            // this.meidoManager.FreeLookChange += UpdateMeido;
 
             this.maidPosePane = new MaidPoseSelectorPane(meidoManager);
             this.maidFaceLookPane = new MaidFaceLookPane(meidoManager);
@@ -28,25 +29,18 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             this.maidIKPane = new MaidIKPane(meidoManager);
 
-            TabsPane.TabChange += OnTabChange;
-
             this.freeLookToggle = new Toggle(Translation.Get("freeLook", "freeLookToggle"), false);
             this.freeLookToggle.ControlEvent += (s, a) => SetMaidFreeLook();
         }
 
-        ~MaidPoseWindow()
-        {
-            TabsPane.TabChange -= OnTabChange;
-        }
-
         protected override void ReloadTranslation()
         {
             this.freeLookToggle.Label = Translation.Get("freeLook", "freeLookToggle");
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
-            MaidSwitcherPane.Draw();
+            this.maidSwitcherPane.Draw();
             maidPosePane.Draw();
 
             this.scrollPos = GUILayout.BeginScrollView(this.scrollPos);
@@ -73,31 +67,25 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.meidoManager.ActiveMeido.IsFreeLook = this.freeLookToggle.Value;
         }
 
-        private void UpdatePanes()
+        public override void UpdatePanes()
         {
-            if (this.meidoManager.ActiveMeido == null)
-            {
-                this.updating = true;
-                this.freeLookToggle.Value = false;
-                this.updating = false;
-                return;
-            }
+            if (this.meidoManager.ActiveMeido == null) return;
 
-            if (TabsPane.SelectedTab == Constants.Window.Pose)
+            if (ActiveWindow)
             {
                 this.updating = true;
                 this.freeLookToggle.Value = this.meidoManager.ActiveMeido?.IsFreeLook ?? false;
                 this.updating = false;
-                maidPosePane.Update();
-                maidFaceLookPane.Update();
-                maidDressingPane.Update();
-                maidIKPane.Update();
+                maidPosePane.UpdatePane();
+                maidFaceLookPane.UpdatePane();
+                maidDressingPane.UpdatePane();
+                maidIKPane.UpdatePane();
             }
         }
 
-        private void OnTabChange(object sender, EventArgs args)
+        private void UpdateMeido(object sender, EventArgs args)
         {
-            UpdatePanes();
+            this.UpdatePanes();
         }
     }
 }

+ 12 - 15
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/OtherPanes/MaidSwitcherPane.cs

@@ -5,13 +5,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     public class MaidSwitcherPane : BasePane
     {
-        public static MeidoManager meidoManager;
-        private static Button PreviousButton;
-        private static Button NextButton;
-        public static event EventHandler<MeidoChangeEventArgs> MaidChange;
-        private static int SelectedMeido => meidoManager.SelectedMeido;
-        static MaidSwitcherPane()
+        private MeidoManager meidoManager;
+        private Button PreviousButton;
+        private Button NextButton;
+        private int SelectedMeido => meidoManager.SelectedMeido;
+        public MaidSwitcherPane(MeidoManager meidoManager)
         {
+            this.meidoManager = meidoManager;
             PreviousButton = new Button("<");
             PreviousButton.ControlEvent += (s, a) => ChangeMaid(-1);
 
@@ -19,7 +19,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             NextButton.ControlEvent += (s, a) => ChangeMaid(1);
         }
 
-        public static void Draw()
+        public override void Draw()
         {
             GUIStyle boxStyle = new GUIStyle(GUI.skin.box);
             GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
@@ -54,16 +54,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             GUILayout.EndHorizontal();
         }
 
-        private static void ChangeMaid(int dir)
+        private void ChangeMaid(int dir)
         {
             dir = (int)Mathf.Sign(dir);
-            int selected = Utility.Wrap(SelectedMeido + dir, 0, meidoManager.ActiveMeidoList.Count);
-            OnMaidChange(new MeidoChangeEventArgs(selected));
-        }
-
-        private static void OnMaidChange(MeidoChangeEventArgs args)
-        {
-            MaidChange?.Invoke(null, args);
+            int selected = Utility.Wrap(
+                this.meidoManager.SelectedMeido + dir, 0, this.meidoManager.ActiveMeidoList.Count
+            );
+            this.meidoManager.ChangeMaid(selected);
         }
     }
 }

+ 11 - 10
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/OtherPanes/TabsPane.cs

@@ -5,39 +5,40 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     public class TabsPane : BasePane
     {
-        private static SelectionGrid Tabs;
-        private static Constants.Window selectedTab;
-        public static Constants.Window SelectedTab
+        private SelectionGrid Tabs;
+        private Constants.Window selectedTab;
+        public Constants.Window SelectedTab
         {
             get => selectedTab;
             set => Tabs.SelectedItem = (int)value;
 
         }
-        public static event EventHandler TabChange;
-        private static new bool updating;
-        private static readonly string[] tabNames = { "call", "pose", "face", "bg", "bg2" };
-        static TabsPane()
+        public event EventHandler TabChange;
+        private new bool updating;
+        private readonly string[] tabNames = { "call", "pose", "face", "bg", "bg2" };
+
+        public TabsPane()
         {
             Translation.ReloadTranslationEvent += (s, a) => ReloadTranslation();
             Tabs = new SelectionGrid(Translation.GetArray("tabs", tabNames));
             Tabs.ControlEvent += (s, a) => OnChangeTab();
         }
 
-        protected static new void ReloadTranslation()
+        protected override void ReloadTranslation()
         {
             updating = true;
             Tabs.SetItems(Translation.GetArray("tabs", tabNames), Tabs.SelectedItem);
             updating = false;
         }
 
-        private static void OnChangeTab()
+        private void OnChangeTab()
         {
             if (updating) return;
             selectedTab = (Constants.Window)Tabs.SelectedItem;
             TabChange?.Invoke(null, EventArgs.Empty);
         }
 
-        public static void Draw()
+        public override void Draw()
         {
             Tabs.Draw(GUILayout.ExpandWidth(false));
             MiscGUI.BlackLine();

+ 5 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidDressingPane.cs

@@ -174,10 +174,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             maid.AllProcProp();
         }
 
-        public override void Update()
+        public override void UpdatePane()
         {
             if (!this.meidoManager.HasActiveMeido) return;
+
             this.updating = true;
+
             Maid maid = this.meidoManager.ActiveMeido.Maid;
             TBody body = maid.body0;
             foreach (SlotID clothingSlot in clothingSlots)
@@ -249,10 +251,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             ClothingToggles[SlotID.headset].Label = detailedClothing
                 ? Translation.Get("clothing", "headset")
                 : Translation.Get("clothing", "headwear");
-            Update();
+            UpdatePane();
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             this.Enabled = this.meidoManager.HasActiveMeido;
 

+ 3 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidFaceLookPane.cs

@@ -12,7 +12,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public MaidFaceLookPane(MeidoManager meidoManager)
         {
             this.meidoManager = meidoManager;
-            this.meidoManager.AnimeChange += (s, a) => SetBounds();
+            // this.meidoManager.AnimeChange += (s, a) => SetBounds();
 
             this.lookXSlider = new Slider(Translation.Get("freeLook", "x"), -0.6f, 0.6f);
             this.lookXSlider.ControlEvent += (s, a) => SetMaidLook();
@@ -48,7 +48,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.lookYSlider.SetBounds(left, right);
         }
 
-        public override void Update()
+        public override void UpdatePane()
         {
             TBody body = this.meidoManager.ActiveMeido.Maid.body0;
             this.updating = true;
@@ -58,7 +58,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.updating = false;
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             GUI.enabled = this.meidoManager.HasActiveMeido && this.meidoManager.ActiveMeido.IsFreeLook;
             GUILayout.BeginHorizontal();

+ 3 - 8
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidIKPane.cs

@@ -16,11 +16,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public MaidIKPane(MeidoManager meidoManager)
         {
             this.meidoManager = meidoManager;
-            this.meidoManager.AnimeChange += (s, a) =>
-            {
-                if (!this.meidoManager.HasActiveMeido) return;
-                if (TabsPane.SelectedTab == Constants.Window.Pose) Update();
-            };
 
             this.ikToggle = new Toggle(Translation.Get("maidPoseWindow", "ikToggle"), true);
             this.ikToggle.ControlEvent += (s, a) => SetIK(IKToggle.IK, this.ikToggle.Value);
@@ -42,12 +37,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private void SetIK(IKToggle toggle, bool value)
         {
             if (updating) return;
-            if (toggle == IKToggle.IK) this.meidoManager.ActiveMeido.SetIKActive(value);
+            if (toggle == IKToggle.IK) this.meidoManager.ActiveMeido.IsIK = value;
             else if (toggle == IKToggle.Release) this.meidoManager.ActiveMeido.IsStop = false;
             else if (toggle == IKToggle.Bone) this.meidoManager.ActiveMeido.IsBone = value;
         }
 
-        public override void Update()
+        public override void UpdatePane()
         {
             this.updating = true;
             this.ikToggle.Value = this.meidoManager.ActiveMeido.IsIK;
@@ -56,7 +51,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.updating = false;
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             bool active = this.meidoManager.HasActiveMeido;
 

+ 5 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidPoseSelectorPane.cs

@@ -49,6 +49,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             this.poseRightButton = new Button(">");
             this.poseRightButton.ControlEvent += (s, a) => poseDropdown.Step(1);
+
+            selectedPoseGroup = Constants.PoseGroupList[this.poseGroupDropdown.SelectedItemIndex];
         }
 
         protected override void ReloadTranslation()
@@ -71,7 +73,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void ChangePoseGroup(object sender, EventArgs args)
         {
-            if (updating) return;
             string newPoseGroup = Constants.PoseGroupList[this.poseGroupDropdown.SelectedItemIndex];
             if (selectedPoseGroup == newPoseGroup)
             {
@@ -124,16 +125,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             return poseList.Select((kvp, i) => $"{i + 1}:{kvp.Key}").ToArray();
         }
 
-        public override void Update()
+        public override void UpdatePane()
         {
             this.updating = true;
-            PoseInfo poseInfo = this.meidoManager.ActiveMeido.poseInfo;
+            PoseInfo poseInfo = this.meidoManager.ActiveMeido.CachedPose;
             this.poseGroupDropdown.SelectedItemIndex = poseInfo.PoseGroupIndex;
             this.poseDropdown.SelectedItemIndex = poseInfo.PoseIndex;
             this.updating = false;
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Draw()
         {
             float arrowButtonSize = 30;
             GUILayoutOption[] arrowLayoutOptions = {

+ 0 - 25
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/BaseMainWindow.cs

@@ -1,25 +0,0 @@
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    public abstract class BaseMainWindow : BaseWindow
-    {
-        public BaseMainWindow() : base() { }
-        public override void OnGUI(int id)
-        {
-            TabsPane.Draw();
-
-            Draw();
-
-            GUI.enabled = true;
-
-            GUILayout.FlexibleSpace();
-            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
-            labelStyle.fontSize = 10;
-            labelStyle.alignment = TextAnchor.LowerLeft;
-
-            GUILayout.Label("MeidoPhotoStudio 1.0.0", labelStyle);
-            GUI.DragWindow();
-        }
-    }
-}

+ 33 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/BaseWindow.cs

@@ -4,11 +4,40 @@ using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    public abstract class BaseWindow : BasePane
+    public abstract class BaseWindow : BaseWindowPane
     {
-        protected Vector2 scrollPos;
-        public BaseWindow() : base() { }
-        public virtual void OnGUI(int id)
+        private static int id = 765;
+        private static int ID { get => id++; }
+        public readonly int windowID;
+        protected Rect windowRect;
+        public abstract Rect WindowRect { get; set; }
+
+        public BaseWindow() : base()
+        {
+            windowID = ID;
+        }
+
+        protected virtual void HandleZoom()
+        {
+            if (Input.mouseScrollDelta.y != 0f)
+            {
+                if (Visible && WindowRect.Contains(Event.current.mousePosition))
+                {
+                    Input.ResetInputAxes();
+                }
+            }
+        }
+
+        public virtual void Update()
+        {
+            HandleZoom();
+        }
+
+        public virtual void Activate() { }
+
+        public virtual void Deactivate() { }
+
+        public virtual void GUIFunc(int id)
         {
             Draw();
             GUI.DragWindow();

+ 17 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/BaseWindowPane.cs

@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    public abstract class BaseWindowPane : BasePane
+    {
+        protected List<BasePane> Panes = new List<BasePane>();
+        protected Vector2 scrollPos;
+        public bool ActiveWindow { get; set; }
+
+        public virtual void UpdatePanes()
+        {
+            foreach (BasePane pane in Panes) pane.UpdatePane();
+        }
+    }
+}

+ 125 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindow.cs

@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    public class MainWindow : BaseWindow
+    {
+        private MeidoManager meidoManager;
+        private Dictionary<Constants.Window, BaseWindowPane> windowPanes;
+        private TabsPane tabsPane;
+        private Button ReloadTranslationButton;
+        private BaseWindowPane currentWindowPane;
+        public override Rect WindowRect
+        {
+            get
+            {
+                windowRect.width = 230f;
+                windowRect.height = Screen.height * 0.8f;
+                windowRect.x = Mathf.Clamp(windowRect.x, 0, Screen.width - windowRect.width);
+                windowRect.y = Mathf.Clamp(windowRect.y, -windowRect.height + 30, Screen.height - 50);
+                return windowRect;
+            }
+            set => windowRect = value;
+        }
+        private Constants.Window selectedWindow = Constants.Window.Call;
+
+        public BaseWindowPane this[Constants.Window id]
+        {
+            get => windowPanes[id];
+            set => AddWindow(id, value);
+        }
+
+        public MainWindow(MeidoManager meidoManager) : base()
+        {
+            this.meidoManager = meidoManager;
+            this.meidoManager.UpdateMeido += UpdateMeido;
+
+            windowPanes = new Dictionary<Constants.Window, BaseWindowPane>();
+            windowRect = new Rect(Screen.width, Screen.height * 0.08f, 230f, Screen.height * 0.8f);
+
+            tabsPane = new TabsPane();
+            tabsPane.TabChange += (s, a) => ChangeTab();
+
+            ReloadTranslationButton = new Button("Reload Translation");
+            ReloadTranslationButton.ControlEvent += (s, a) =>
+            {
+                Translation.ReloadTranslation();
+            };
+        }
+
+        public override void Activate()
+        {
+            this.updating = true;
+            tabsPane.SelectedTab = Constants.Window.Call;
+            this.updating = false;
+            this.Visible = true;
+        }
+
+        public void AddWindow(Constants.Window id, BaseWindowPane window)
+        {
+            if (windowPanes.ContainsKey(id))
+            {
+                Panes.Remove(windowPanes[id]);
+            }
+            windowPanes[id] = window;
+            Panes.Add(windowPanes[id]);
+        }
+
+        private void ChangeTab()
+        {
+            this.selectedWindow = (Constants.Window)tabsPane.SelectedTab;
+            SetCurrentWindow();
+        }
+
+        private void SetCurrentWindow()
+        {
+            if (currentWindowPane != null) currentWindowPane.ActiveWindow = false;
+            currentWindowPane = windowPanes[selectedWindow];
+            currentWindowPane.ActiveWindow = true;
+            currentWindowPane.UpdatePanes();
+        }
+
+        public override void Update()
+        {
+            base.Update();
+            if (Input.GetKeyDown(KeyCode.Tab))
+            {
+                this.Visible = !this.Visible;
+            }
+        }
+
+        public override void Draw()
+        {
+            tabsPane.Draw();
+
+            currentWindowPane?.Draw();
+
+            GUI.enabled = true;
+
+            GUILayout.FlexibleSpace();
+
+            ReloadTranslationButton.Draw();
+
+            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
+            labelStyle.fontSize = 10;
+            labelStyle.alignment = TextAnchor.LowerLeft;
+
+            GUILayout.Label("MeidoPhotoStudio 1.0.0", labelStyle);
+            GUI.DragWindow();
+        }
+
+
+        private void UpdateMeido(object sender, MeidoUpdateEventArgs args)
+        {
+            if (args.FromMeido)
+            {
+                Constants.Window newWindow = args.IsBody ? Constants.Window.Pose : Constants.Window.Face;
+                if (this.selectedWindow == newWindow) currentWindowPane.UpdatePanes();
+                else tabsPane.SelectedTab = newWindow;
+            }
+            else currentWindowPane.UpdatePanes();
+        }
+    }
+}

+ 0 - 27
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/BackgroundWindow.cs

@@ -1,27 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    public class BackgroundWindow : BaseMainWindow
-    {
-        private EnvironmentManager environmentManager;
-        private BackgroundSelectorPane backgroundSelectorPane;
-        private PropsPane propsPane;
-
-        public BackgroundWindow(EnvironmentManager environmentManager)
-        {
-            this.environmentManager = environmentManager;
-            this.backgroundSelectorPane = new BackgroundSelectorPane(this.environmentManager);
-            this.propsPane = new PropsPane(this.environmentManager);
-        }
-
-        public override void Draw(params GUILayoutOption[] layoutOptions)
-        {
-            this.backgroundSelectorPane.Draw();
-            this.propsPane.Draw();
-        }
-    }
-}

+ 47 - 6
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/OtherWindows/MessageWindow.cs

@@ -5,16 +5,37 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     public class MessageWindow : BaseWindow
     {
-        MessageWindowManager messageWindowManager;
-        TextField nameTextField;
-        Slider fontSizeSlider;
-        TextArea messageTextArea;
-        Button okButton;
+        private MessageWindowManager messageWindowManager;
+        private TextField nameTextField;
+        private Slider fontSizeSlider;
+        private TextArea messageTextArea;
+        private Button okButton;
+        public override Rect WindowRect
+        {
+            get
+            {
+                windowRect.width = Mathf.Clamp(Screen.width * 0.4f, 440, Mathf.Infinity);
+                windowRect.height = Mathf.Clamp(Screen.height * 0.15f, 150, Mathf.Infinity);
+                windowRect.x = Mathf.Clamp(
+                    windowRect.x,
+                    -windowRect.width + Utility.GetPix(20),
+                    Screen.width - Utility.GetPix(20)
+                );
+                windowRect.y = Mathf.Clamp(
+                    windowRect.y,
+                    -windowRect.height + Utility.GetPix(20),
+                    Screen.height - Utility.GetPix(20)
+                );
+                return windowRect;
+            }
+            set => windowRect = value;
+        }
         private int fontSize = 25;
         private bool showingMessage = false;
 
         public MessageWindow(MessageWindowManager messageWindowManager) : base()
         {
+            windowRect = new Rect(Screen.width / 2f - 220f, Screen.height - 150f, 440f, 150f);
             this.messageWindowManager = messageWindowManager;
             nameTextField = new TextField();
             Controls.Add(nameTextField);
@@ -57,7 +78,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             messageWindowManager.ShowMessage(nameTextField.Value, messageTextArea.Value);
         }
 
-        public override void Draw(params GUILayoutOption[] layoutOptions)
+        public override void Update()
+        {
+            base.Update();
+            if (Input.GetKeyDown(KeyCode.M))
+            {
+                this.ToggleVisibility();
+            }
+        }
+
+        public override void Draw()
         {
             GUILayout.BeginHorizontal();
             GUILayout.Label("Name", GUILayout.ExpandWidth(false));
@@ -73,5 +103,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             messageTextArea.Draw(GUILayout.MinHeight(90));
             okButton.Draw(GUILayout.ExpandWidth(false), GUILayout.Width(30));
         }
+
+        public override void Deactivate()
+        {
+            if (showingMessage)
+            {
+                messageWindowManager.CloseMessagePanel();
+                showingMessage = false;
+            }
+
+            Visible = false;
+        }
     }
 }

+ 100 - 75
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/DragPointManager.cs

@@ -124,10 +124,29 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private Dictionary<Bone, Transform> BoneTransform;
         private IKMode ikMode;
         private IKMode ikModeOld = IKMode.None;
-        public event EventHandler<MeidoChangeEventArgs> SelectMaid;
-        public bool Initialized { get; private set; }
-        public bool Active { get; set; }
-        public bool IsBone { get; set; }
+        public event EventHandler<MeidoUpdateEventArgs> SelectMaid;
+        private bool active = false;
+        public bool Active
+        {
+            get => active;
+            set
+            {
+                if (this.active == value) return;
+                this.active = value;
+                this.SetActive(this.active);
+            }
+        }
+        private bool isBone = false;
+        public bool IsBone
+        {
+            get => isBone;
+            set
+            {
+                if (this.isBone == value) return;
+                this.isBone = value;
+                this.SetBoneMode(this.isBone);
+            }
+        }
         private static bool cubeActive = false;
 
         public DragPointManager(Meido meido)
@@ -137,47 +156,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.meido.BodyLoad += Initialize;
         }
 
-        public void Initialize(object sender, EventArgs args)
-        {
-            if (Initialized) return;
-
-            Initialized = true;
-            InitializeBones();
-            InitializeDragPoints();
-            SetActive(true);
-            meido.BodyLoad -= Initialize;
-        }
-
-        public void Deactivate()
+        public void Destroy()
         {
             foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
             {
                 GameObject.Destroy(dragPoint.Value.gameObject);
             }
-            DragPoint.Clear();
             BoneTransform.Clear();
-            Initialized = false;
-            this.Active = false;
-        }
-
-        public void SetActive(bool active)
-        {
-            this.Active = active;
-            if (this.Active)
-            {
-                ikMode = ikModeOld = IKMode.None;
-                UpdateIK();
-            }
-            else
-            {
-                foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-                {
-                    dragPoint.Value.gameObject.SetActive(false);
-                }
-                DragPoint[Bone.Head].SetDragProp(false, true, false);
-                DragPoint[Bone.Body].SetDragProp(false, true, false);
-                DragPoint[Bone.Cube].SetDragProp(false, true, true);
-            }
+            DragPoint.Clear();
         }
 
         public void Update()
@@ -221,9 +207,52 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             ikModeOld = ikMode;
         }
 
+        private void Initialize(object sender, EventArgs args)
+        {
+            meido.BodyLoad -= Initialize;
+            InitializeBones();
+            InitializeDragPoints();
+            this.Active = true;
+            this.SetBoneMode(false);
+        }
+
+        private void SetBoneMode(bool active)
+        {
+            foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
+            {
+                dragPoint.Value.IsBone = this.IsBone;
+                if (!this.IsBone)
+                {
+                    dragPoint.Value.SetDragProp(false, true, dragPoint.Key >= Bone.Finger0L);
+                }
+            }
+            UpdateIK();
+        }
+
+        private void SetActive(bool active)
+        {
+            if (active)
+            {
+                ikMode = ikModeOld = IKMode.None;
+                ((DragHead)DragPoint[Bone.Head]).IsIK = true;
+                UpdateIK();
+            }
+            else
+            {
+                foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
+                {
+                    dragPoint.Value.gameObject.SetActive(false);
+                }
+                ((DragHead)DragPoint[Bone.Head]).IsIK = false;
+                DragPoint[Bone.Head].SetDragProp(false, true, false);
+                DragPoint[Bone.Body].SetDragProp(false, true, false);
+                DragPoint[Bone.Cube].SetDragProp(false, true, true);
+            }
+        }
+
         private void UpdateIK()
         {
-            if (Active)
+            if (this.Active)
             {
                 if (this.IsBone) UpdateBoneIK();
                 else
@@ -285,6 +314,26 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
+        private void OnSelectFace(object sender, EventArgs args)
+        {
+            OnMeidoSelect(new MeidoUpdateEventArgs(meido.ActiveSlot, true, false));
+        }
+
+        private void OnSelectBody(object sender, EventArgs args)
+        {
+            OnMeidoSelect(new MeidoUpdateEventArgs(meido.ActiveSlot, true, true));
+        }
+
+        private void OnSetDragPointScale(object sender, EventArgs args)
+        {
+            this.SetDragPointScale(maid.transform.localScale.x);
+        }
+
+        private void OnMeidoSelect(MeidoUpdateEventArgs args)
+        {
+            SelectMaid?.Invoke(this, args);
+        }
+
         private void SetDragPointScale(float scale)
         {
             foreach (KeyValuePair<Bone, BaseDrag> kvp in DragPoint)
@@ -294,20 +343,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
-        public void BoneModeActive(bool active)
-        {
-            this.IsBone = active;
-            foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-            {
-                dragPoint.Value.IsBone = this.IsBone;
-                if (!this.IsBone)
-                {
-                    dragPoint.Value.SetDragProp(false, true, dragPoint.Key >= Bone.Finger0L);
-                }
-            }
-            SetActive(true);
-        }
-
         // TODO: Rework this a little to reduce number of needed BaseDrag derived components
         private void InitializeDragPoints()
         {
@@ -367,8 +402,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     () => maid.transform.position,
                     () => maid.transform.eulerAngles
                 );
-            DragBody dragCube = DragPoint[Bone.Cube] as DragBody;
-            dragCube.Scale += (s, a) => SetDragPointScale(maid.transform.localScale.x);
+            DragBody dragCube = (DragBody)DragPoint[Bone.Cube];
+            dragCube.Scale += OnSetDragPointScale;
             dragCube.DragPointVisible = true;
 
             // Body Dragpoint
@@ -387,9 +422,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                         BoneTransform[Bone.Spine0a].transform.eulerAngles.z + 90f
                     )
             );
-            DragBody dragBody = DragPoint[Bone.Body] as DragBody;
-            dragBody.Select += (s, e) => OnMeidoSelect(new MeidoChangeEventArgs(meido.ActiveSlot, true));
-            dragBody.Scale += (s, a) => SetDragPointScale(maid.transform.localScale.x);
+            DragBody dragBody = (DragBody)DragPoint[Bone.Body];
+            dragBody.Select += OnSelectBody;
+            dragBody.Scale += OnSetDragPointScale;
 
             // Head Dragpoint
             DragPoint[Bone.Head] =
@@ -408,8 +443,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
                 )
             );
-            DragHead dragHead = DragPoint[Bone.Head] as DragHead;
-            dragHead.Select += (s, a) => OnMeidoSelect(new MeidoChangeEventArgs(meido.ActiveSlot, true, false));
+            DragHead dragHead = (DragHead)DragPoint[Bone.Head];
+            dragHead.Select += OnSelectFace;
 
             // Torso Dragpoint
             DragPoint[Bone.Torso] =
@@ -423,7 +458,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 BoneTransform[Bone.Spine0a],
                 BoneTransform[Bone.Spine]
             };
-            DragTorso dragTorso = DragPoint[Bone.Torso] as DragTorso;
+            DragTorso dragTorso = (DragTorso)DragPoint[Bone.Torso];
             dragTorso.Initialize(spineParts, meido,
                 () => new Vector3(
                     spineTrans1.position.x,
@@ -443,7 +478,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 .AddComponent<DragPelvis>();
             Transform pelvisTrans = BoneTransform[Bone.Pelvis];
             Transform spineTrans = BoneTransform[Bone.Spine];
-            DragPelvis dragPelvis = DragPoint[Bone.Pelvis] as DragPelvis;
+            DragPelvis dragPelvis = (DragPelvis)DragPoint[Bone.Pelvis];
             dragPelvis.Initialize(BoneTransform[Bone.Pelvis], meido,
                 () => new Vector3(
                     pelvisTrans.position.x,
@@ -466,7 +501,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 BoneTransform[Bone.MuneL],
                 BoneTransform[Bone.MuneSubL]
             };
-            DragMune dragMuneL = DragPoint[Bone.MuneL] as DragMune;
+            DragMune dragMuneL = (DragMune)DragPoint[Bone.MuneL];
             dragMuneL.Initialize(muneIKChainL, meido,
                 () => (BoneTransform[Bone.MuneL].position + BoneTransform[Bone.MuneSubL].position) / 2f,
                 () => Vector3.zero
@@ -481,7 +516,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 BoneTransform[Bone.MuneR],
                 BoneTransform[Bone.MuneSubR]
             };
-            DragMune dragMuneR = DragPoint[Bone.MuneR] as DragMune;
+            DragMune dragMuneR = (DragMune)DragPoint[Bone.MuneR];
             dragMuneR.Initialize(muneIKChainR, meido,
                 () => (BoneTransform[Bone.MuneR].position + BoneTransform[Bone.MuneSubR].position) / 2f,
                 () => Vector3.zero
@@ -701,16 +736,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             };
         }
 
-        private void OnMeidoSelect(MeidoChangeEventArgs args)
-        {
-            SelectMaid?.Invoke(this, args);
-        }
-
-        private void OnDragEvent(object sender, EventArgs args)
-        {
-            this.meido.IsStop = true;
-        }
-
         private struct DragInfo
         {
             public Bone Bone { get; private set; }

+ 1 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EffectManager.cs

@@ -12,7 +12,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         }
 
-        public void Initialize()
+        public void Activate()
         {
 
         }

+ 32 - 18
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EnvironmentManager.cs

@@ -4,23 +4,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     public class EnvironmentManager
     {
-        public PropManager PropManager { get; private set; }
-        public LightManager LightManager { get; private set; }
-        public EffectManager EffectManager { get; private set; }
         private GameObject cameraObject;
         private Camera subCamera;
         private GameObject bgObject;
         private Transform bg;
         private CameraInfo cameraInfo;
+        public LightManager LightManager { get; set; }
+        public PropManager PropManager { get; set; }
+        public EffectManager EffectManager { get; set; }
 
-        public EnvironmentManager(PropManager propManager, LightManager lightManager, EffectManager effectManager)
-        {
-            this.PropManager = propManager;
-            this.LightManager = lightManager;
-            this.EffectManager = effectManager;
-        }
-
-        public void Initialize()
+        public void Activate()
         {
             bgObject = GameObject.Find("__GameMain__/BG");
             bg = bgObject.transform;
@@ -28,12 +21,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             cameraObject = new GameObject("subCamera");
             subCamera = cameraObject.AddComponent<Camera>();
             subCamera.CopyFrom(Camera.main);
-            cameraObject.SetActive(true);
             subCamera.clearFlags = CameraClearFlags.Depth;
             subCamera.cullingMask = 256;
             subCamera.depth = 1f;
             subCamera.transform.parent = GameMain.Instance.MainCamera.transform;
 
+            cameraObject.SetActive(true);
+
             bgObject.SetActive(true);
             GameMain.Instance.BgMgr.ChangeBg("Theater");
 
@@ -42,17 +36,38 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 Utility.GetFieldValue<CameraMain, UltimateOrbitCamera>(GameMain.Instance.MainCamera, "m_UOCamera");
             UOCamera.enabled = true;
 
-            GameMain.Instance.MainLight.Reset();
-            GameMain.Instance.CharacterMgr.ResetCharaPosAll();
-
             ResetCamera();
             SaveCameraInfo();
+
+            PropManager.Activate();
+            // LightManager.Activate();
+            // EffectManager.Activate();
         }
 
         public void Deactivate()
         {
             GameObject.Destroy(cameraObject);
             GameObject.Destroy(subCamera);
+
+            PropManager.Deactivate();
+            // LightManager.Deactivate();
+            // EffectManager.Deactivate();
+
+            bool isNight = GameMain.Instance.CharacterMgr.status.GetFlag("時間帯") == 3;
+
+            if (isNight)
+            {
+                GameMain.Instance.BgMgr.ChangeBg("ShinShitsumu_ChairRot_Night");
+            }
+            else
+            {
+                GameMain.Instance.BgMgr.ChangeBg("ShinShitsumu_ChairRot");
+            }
+
+            GameMain.Instance.MainCamera.Reset(CameraMain.CameraType.Target, true);
+            GameMain.Instance.MainCamera.SetTargetPos(new Vector3(0.5609447f, 1.380762f, -1.382336f), true);
+            GameMain.Instance.MainCamera.SetDistance(1.6f, true);
+            GameMain.Instance.MainCamera.SetAroundAngle(new Vector2(245.5691f, 6.273283f), true);
         }
 
         public void Update()
@@ -76,7 +91,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
 
             PropManager.Update();
-            LightManager.Update();
+            // LightManager.Update();
+            // EffectManager.Update();
         }
 
         public void ChangeBackground(string assetName, bool creative = false)
@@ -118,8 +134,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             cameraMain.SetTargetPos(new Vector3(0f, 0.9f, 0f), true);
             cameraMain.SetDistance(3f, true);
         }
-
-
     }
 
     public struct CameraInfo

+ 72 - 94
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MeidoManager.cs

@@ -10,15 +10,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private static CharacterMgr characterMgr = GameMain.Instance.CharacterMgr;
         private int undress = 0;
         public Meido[] meidos { get; private set; }
-        public List<Meido> ActiveMeidoList { get; private set; }
-        public Meido ActiveMeido => ActiveMeidoList.Count > 0 ? ActiveMeidoList[selectedMeido] : null;
+        public List<int> SelectMeidoList { get; private set; } = new List<int>();
+        public List<Meido> ActiveMeidoList { get; private set; } = new List<Meido>();
+        public Meido ActiveMeido => ActiveMeidoList.Count > 0 ? ActiveMeidoList[SelectedMeido] : null;
         public bool HasActiveMeido => ActiveMeido != null;
         public int numberOfMeidos;
-        public event EventHandler<MeidoChangeEventArgs> SelectMeido;
+        public event EventHandler<MeidoUpdateEventArgs> UpdateMeido;
         public event EventHandler EndCallMeidos;
         public event EventHandler BeginCallMeidos;
-        public event EventHandler AnimeChange;
-        public event EventHandler FreeLookChange;
         private int selectedMeido = 0;
         public int SelectedMeido
         {
@@ -31,34 +30,38 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 foreach (Meido meido in ActiveMeidoList)
                 {
-                    if (meido.Maid.IsBusy)
-                    {
-                        Debug.Log(meido.NameEN + " is busy!");
-                        return true;
-                    }
+                    if (meido.Maid.IsBusy) return true;
                 }
                 return false;
             }
         }
 
-        public MeidoManager()
+        public void ChangeMaid(int index)
         {
+            OnUpdateMeido(null, new MeidoUpdateEventArgs(index));
+        }
+
+        public void Activate()
+        {
+            GameMain.Instance.CharacterMgr.ResetCharaPosAll();
             numberOfMeidos = characterMgr.GetStockMaidCount();
-            ActiveMeidoList = new List<Meido>();
             meidos = new Meido[numberOfMeidos];
 
-            MaidSwitcherPane.MaidChange += ChangeMeido;
-            MaidSwitcherPane.meidoManager = this;
-
             for (int stockMaidIndex = 0; stockMaidIndex < numberOfMeidos; stockMaidIndex++)
             {
                 meidos[stockMaidIndex] = new Meido(stockMaidIndex);
             }
         }
 
-        ~MeidoManager()
+        public void Deactivate()
         {
-            MaidSwitcherPane.MaidChange -= ChangeMeido;
+            foreach (Meido meido in meidos)
+            {
+                meido.UpdateMeido -= OnUpdateMeido;
+                meido.Deactivate();
+            }
+            SelectMeidoList.Clear();
+            ActiveMeidoList.Clear();
         }
 
         public void Update()
@@ -71,6 +74,33 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
+        public void CallMeidos()
+        {
+            this.BeginCallMeidos?.Invoke(this, EventArgs.Empty);
+            GameMain.Instance.MainCamera.FadeOut(0.01f, false, () =>
+            {
+                UnloadMeidos();
+
+                foreach (int slot in this.SelectMeidoList)
+                {
+                    Meido meido = meidos[slot];
+                    ActiveMeidoList.Add(meido);
+                    meido.BodyLoad += OnEndCallMeidos;
+                    meido.UpdateMeido += OnUpdateMeido;
+                }
+
+                for (int i = 0; i < ActiveMeidoList.Count; i++)
+                {
+                    Meido meido = ActiveMeidoList[i];
+                    meido.Load(i, this.SelectMeidoList[i]);
+                }
+
+                SelectedMeido = 0;
+
+                if (this.SelectMeidoList.Count == 0) OnEndCallMeidos(this, EventArgs.Empty);
+            }, false);
+        }
+
         private void UndressAll()
         {
             if (!HasActiveMeido) return;
@@ -87,86 +117,24 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 activeMeido.SetMaskMode(maskMode);
             }
-            OnSelectMeido(new MeidoChangeEventArgs(SelectedMeido));
+
+            this.UpdateMeido?.Invoke(ActiveMeido, new MeidoUpdateEventArgs(SelectedMeido));
         }
 
-        public void UnloadMeidos()
+        private void UnloadMeidos()
         {
             foreach (Meido meido in ActiveMeidoList)
             {
-                meido.SelectMeido -= ChangeMeido;
-                meido.BodyLoad -= OnEndCallMeidos;
-                meido.AnimeChange -= OnAnimeChangeEvent;
-                meido.FreeLookChange -= OnFreeLookChangeEvent;
+                meido.UpdateMeido -= OnUpdateMeido;
                 meido.Unload();
             }
             ActiveMeidoList.Clear();
         }
 
-        public void Deactivate()
+        private void OnUpdateMeido(object sender, MeidoUpdateEventArgs args)
         {
-            foreach (Meido meido in meidos)
-            {
-                meido.SelectMeido -= ChangeMeido;
-                meido.BodyLoad -= OnEndCallMeidos;
-                meido.AnimeChange -= OnAnimeChangeEvent;
-                meido.FreeLookChange -= OnFreeLookChangeEvent;
-                meido.Deactivate();
-            }
-            ActiveMeidoList.Clear();
-        }
-
-        public void CallMeidos(List<int> selectedMaids)
-        {
-            UnloadMeidos();
-
-            foreach (int slot in selectedMaids)
-            {
-                Meido meido = meidos[slot];
-                ActiveMeidoList.Add(meido);
-                meido.SelectMeido += ChangeMeido;
-                meido.BodyLoad += OnEndCallMeidos;
-                meido.AnimeChange += OnAnimeChangeEvent;
-                meido.FreeLookChange += OnFreeLookChangeEvent;
-            }
-
-            for (int i = 0; i < ActiveMeidoList.Count; i++)
-            {
-                Meido meido = ActiveMeidoList[i];
-                meido.Load(i, selectedMaids[i]);
-            }
-
-            SelectedMeido = 0;
-            OnSelectMeido(new MeidoChangeEventArgs(SelectedMeido));
-
-            if (selectedMaids.Count == 0) OnEndCallMeidos(this, EventArgs.Empty);
-        }
-
-        private void OnAnimeChangeEvent(object sender, EventArgs args)
-        {
-            this.AnimeChange?.Invoke(this.ActiveMeido, EventArgs.Empty);
-        }
-
-        private void OnFreeLookChangeEvent(object sender, EventArgs args)
-        {
-            this.FreeLookChange?.Invoke(this.ActiveMeido, args);
-        }
-
-        private void OnSelectMeido(MeidoChangeEventArgs args)
-        {
-            SelectMeido?.Invoke(this, args);
-        }
-
-        private void ChangeMeido(object sender, MeidoChangeEventArgs args)
-        {
-            SelectedMeido = args.selected;
-            OnSelectMeido(args);
-        }
-
-        public void OnBeginCallMeidos(List<int> selectList)
-        {
-            this.BeginCallMeidos?.Invoke(this, EventArgs.Empty);
-            GameMain.Instance.MainCamera.FadeOut(0.01f, false, () => CallMeidos(selectList), false);
+            if (!args.IsEmpty) this.SelectedMeido = args.SelectedMeido;
+            this.UpdateMeido?.Invoke(ActiveMeido, args);
         }
 
         private void OnEndCallMeidos(object sender, EventArgs args)
@@ -182,16 +150,26 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
     }
-    public class MeidoChangeEventArgs : EventArgs
+
+    public class MeidoUpdateEventArgs : EventArgs
     {
-        public int selected;
-        public bool isBody;
-        public bool fromMeido = false;
-        public MeidoChangeEventArgs(int selected, bool fromMaid = false, bool isBody = true)
+        public static new MeidoUpdateEventArgs Empty { get; } = new MeidoUpdateEventArgs(-1);
+        public bool IsEmpty
+        {
+            get
+            {
+                return (this == MeidoUpdateEventArgs.Empty) ||
+                    (this.SelectedMeido == -1 && !this.FromMeido && !this.IsBody);
+            }
+        }
+        public int SelectedMeido { get; }
+        public bool IsBody { get; }
+        public bool FromMeido { get; } = false;
+        public MeidoUpdateEventArgs(int meidoIndex, bool fromMaid = false, bool isBody = true)
         {
-            this.selected = selected;
-            this.isBody = isBody;
-            this.fromMeido = fromMaid;
+            this.SelectedMeido = meidoIndex;
+            this.IsBody = isBody;
+            this.FromMeido = fromMaid;
         }
     }
 }

+ 4 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MessageWindowManager.cs

@@ -24,6 +24,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 .GetComponent<UILabel>();
             Utility.SetFieldValue<MessageClass, UILabel>(this.msgClass, "message_label_", this.msgLabel);
             Utility.SetFieldValue<MessageClass, UILabel>(this.msgClass, "name_label_", this.nameLabel);
+        }
+
+        public void Activate()
+        {
             SetPhotoMessageWindowActive(true);
         }
 

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

@@ -18,10 +18,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             None, Move, Rotate, Scale, Delete, Other
         }
 
-        public PropManager()
-        {
-
-        }
+        public void Activate() { }
 
         public void Deactivate()
         {

+ 44 - 122
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/WindowManager.cs

@@ -4,167 +4,89 @@ using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    using Window = Constants.Window;
+    using static Constants;
     public class WindowManager
     {
-        private Dictionary<Window, BaseWindow> Windows;
-        private static Window currentWindow = Window.Call;
-        private static Window CurrentWindow
+        private Dictionary<Window, BaseWindow> Windows = new Dictionary<Window, BaseWindow>();
+        private List<BaseWindow> WindowList = new List<BaseWindow>();
+        public BaseWindow this[Window id]
         {
-            get => currentWindow;
+            get => Windows[id];
             set
             {
-                if (value > Window.BG2) currentWindow = Window.BG2;
-                else if (value < Window.Call) currentWindow = Window.Call;
-                else currentWindow = value;
+                Windows[id] = value;
+                WindowList.Add(Windows[id]);
             }
         }
-        private Rect mainWindowRect;
-        private Rect messageWindowRect;
-        private MeidoManager meidoManager;
-        private bool initializeWindows = false;
-        public bool MainWindowVisible { get; set; }
-        public bool MessageWindowVisible
+
+        public bool AddWindow(Window id, BaseWindow window)
         {
-            get => Windows[Window.Message].Visible;
-            set
+            if (!this.Windows.ContainsKey(id))
             {
-                Windows[Window.Message].Visible = value;
+                this.Windows[id] = window;
+                this.WindowList.Add(window);
+                return true;
             }
+            return false;
         }
-        public bool DropdownVisible
+
+        public bool RemoveWindow(Window id)
         {
-            get => DropdownHelper.Visible;
-            set
+            if (Windows.ContainsKey(id))
             {
-                DropdownHelper.Visible = value;
+                WindowList.Remove(Windows[id]);
+                Windows.Remove(id);
+                return true;
             }
-        }
-        public WindowManager(
-            MeidoManager meidoManager,
-            EnvironmentManager environmentManager,
-            MessageWindowManager messageWindowManager
-        )
-        {
-            TabsPane.TabChange += ChangeTab;
-            this.meidoManager = meidoManager;
-            this.meidoManager.SelectMeido += MeidoSelect;
-
-            mainWindowRect.y = Screen.height * 0.08f;
-            mainWindowRect.x = Screen.width;
-            Windows = new Dictionary<Window, BaseWindow>()
-            {
-                [Window.Call] = new MaidCallWindow(meidoManager),
-                [Window.Pose] = new MaidPoseWindow(meidoManager),
-                [Window.Face] = new MaidFaceWindow(meidoManager),
-                [Window.BG] = new BackgroundWindow(environmentManager),
-                [Window.BG2] = new Background2Window(environmentManager),
-                [Window.Message] = new MessageWindow(messageWindowManager)
-            };
-            Windows[Window.Message].Visible = false;
+            return false;
         }
 
-        ~WindowManager()
+        public void DrawWindow(Window id)
         {
-            TabsPane.TabChange -= ChangeTab;
+            DrawWindow(Windows[id]);
         }
 
-        private void MeidoSelect(object sender, MeidoChangeEventArgs args)
+        public void DrawWindow(BaseWindow window)
         {
-            if (args.fromMeido)
-                TabsPane.SelectedTab = args.isBody ? Window.Pose : Window.Face;
-        }
+            if (window.Visible)
+            {
+                GUIStyle windowStyle = new GUIStyle(GUI.skin.box);
+                window.WindowRect = GUI.Window(window.windowID, window.WindowRect, window.GUIFunc, "", windowStyle);
+            }
 
-        private void ChangeTab(object sender, EventArgs args)
-        {
-            CurrentWindow = TabsPane.SelectedTab;
+            if (DropdownHelper.Visible) DropdownHelper.HandleDropdown();
         }
 
-        public void Update()
+        public void DrawWindows()
         {
-            if (Input.GetKeyDown(KeyCode.M))
-            {
-                (Windows[Window.Message] as MessageWindow).ToggleVisibility();
-            }
-
-            if (Input.GetKeyDown(KeyCode.Tab))
+            foreach (BaseWindow window in WindowList)
             {
-                MainWindowVisible = !MainWindowVisible;
+                DrawWindow(window);
             }
-
-            HandleZoom();
         }
 
-        private void HandleZoom()
+        public void Update()
         {
-            bool mainWindowVisible = MainWindowVisible;
-            bool dropdownVisible = DropdownVisible;
-            bool messageWindowVisible = MessageWindowVisible;
-            if (mainWindowVisible || dropdownVisible || messageWindowVisible)
+            foreach (BaseWindow window in WindowList)
             {
-                if (Input.mouseScrollDelta.y != 0f)
-                {
-                    Vector2 mousePos = Event.current.mousePosition;
-                    if (mainWindowVisible && mainWindowRect.Contains(mousePos)
-                        || dropdownVisible && DropdownHelper.dropdownWindow.Contains(mousePos)
-                        || messageWindowVisible && messageWindowRect.Contains(mousePos)
-                    )
-                    {
-                        GameMain.Instance.MainCamera.SetControl(false);
-                        Input.ResetInputAxes();
-                    }
-
-                }
+                window.Update();
             }
         }
 
-        public void OnGUI()
+        public void Activate()
         {
-            GUIStyle windowStyle = new GUIStyle(GUI.skin.box);
-            GameMain.Instance.MainCamera.SetControl(true);
-
-            if (MainWindowVisible)
+            foreach (BaseWindow window in WindowList)
             {
-                mainWindowRect.width = 230;
-                mainWindowRect.height = Screen.height * 0.8f;
-
-                mainWindowRect.x = Mathf.Clamp(mainWindowRect.x, 0, Screen.width - mainWindowRect.width);
-                mainWindowRect.y = Mathf.Clamp(mainWindowRect.y, -mainWindowRect.height + 30, Screen.height - 50);
-
-                mainWindowRect = GUI.Window(
-                    Constants.mainWindowID, mainWindowRect, Windows[CurrentWindow].OnGUI, "", windowStyle
-                );
+                window.Activate();
             }
+        }
 
-            if (MessageWindowVisible)
+        public void Deactivate()
+        {
+            foreach (BaseWindow window in WindowList)
             {
-                messageWindowRect.width = Mathf.Clamp(Screen.width * 0.4f, 440, Mathf.Infinity);
-                messageWindowRect.height = Mathf.Clamp(Screen.height * 0.15f, 150, Mathf.Infinity);
-
-                messageWindowRect.x = Mathf.Clamp(
-                    messageWindowRect.x,
-                    -messageWindowRect.width + Utility.GetPix(20),
-                    Screen.width - Utility.GetPix(20)
-                );
-                messageWindowRect.y = Mathf.Clamp(
-                    messageWindowRect.y,
-                    -messageWindowRect.height + Utility.GetPix(20),
-                    Screen.height - Utility.GetPix(20)
-                );
-
-                if (!initializeWindows)
-                {
-                    messageWindowRect.x = Screen.width / 2 - messageWindowRect.width / 2;
-                    messageWindowRect.y = Screen.height - messageWindowRect.height;
-                    initializeWindows = true;
-                }
-
-                messageWindowRect = GUI.Window(
-                    Constants.messageWindowID, messageWindowRect, Windows[Window.Message].OnGUI, "", windowStyle
-                );
+                window.Deactivate();
             }
-
-            if (DropdownVisible) DropdownHelper.HandleDropdown();
         }
     }
 }

+ 2 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragHead.cs

@@ -13,6 +13,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private Vector3 defEyeRotR;
         private Vector3 mousePosOther;
         public event EventHandler Select;
+        public bool IsIK { get; set; }
 
         public DragHead Initialize(Transform head, Meido meido, Func<Vector3> posFunc, Func<Vector3> rotFunc)
         {
@@ -83,7 +84,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         protected override void Drag()
         {
-            if ((CurrentDragType == DragType.None || CurrentDragType == DragType.Select) || IsBone) return;
+            if (!IsIK || (CurrentDragType == DragType.None || CurrentDragType == DragType.Select) || IsBone) return;
 
             if (!(CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY))
             {

+ 59 - 38
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/Meido.cs

@@ -8,9 +8,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     public class Meido
     {
+        private const int MAX_MAIDS = 12;
         private static CharacterMgr characterMgr = GameMain.Instance.CharacterMgr;
         public readonly int stockNo;
-        public readonly PoseInfo defaultPose = new PoseInfo(0, 0, "pose_taiki_f");
+        public static readonly PoseInfo defaultPose = new PoseInfo(0, 0, "pose_taiki_f");
         public Maid Maid { get; private set; }
         public Texture2D Image { get; private set; }
         public string FirstName { get; private set; }
@@ -19,31 +20,46 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public string NameEN => $"{FirstName}\n{LastName}";
         public int ActiveSlot { get; private set; }
         private DragPointManager dragPointManager;
-        public event EventHandler<MeidoChangeEventArgs> SelectMeido;
+        public event EventHandler<MeidoUpdateEventArgs> UpdateMeido;
         public event EventHandler BodyLoad;
-        public event EventHandler AnimeChange;
-        public event EventHandler FreeLookChange;
         private bool isLoading = false;
-        public bool IsIK { get; private set; }
+        public bool IsIK
+        {
+            get => dragPointManager?.Active ?? false;
+            set
+            {
+                if (dragPointManager == null || value == dragPointManager.Active) return;
+                else dragPointManager.Active = value;
+            }
+        }
         private bool isFreeLook;
         public bool IsFreeLook
         {
             get => isFreeLook;
             set
             {
+                if (this.isFreeLook == value) return;
                 this.isFreeLook = value;
                 Maid.body0.trsLookTarget = this.isFreeLook ? null : GameMain.Instance.MainCamera.transform;
-                this.FreeLookChange?.Invoke(this, EventArgs.Empty);
+                this.UpdateMeido?.Invoke(this, MeidoUpdateEventArgs.Empty);
             }
         }
         public bool IsStop
         {
-            get => !Maid.GetAnimation().isPlaying;
+            get
+            {
+                if (!Maid.body0.isLoadedBody) return true;
+                else return !Maid.GetAnimation().isPlaying;
+            }
             set
             {
-                if (!value) this.SetPose(this.poseInfo.PoseName);
-                else Maid.GetAnimation().Stop();
-                this.AnimeChange?.Invoke(this, EventArgs.Empty);
+                if (!Maid.body0.isLoadedBody || value == !Maid.GetAnimation().isPlaying) return;
+                else
+                {
+                    if (value) Maid.GetAnimation().Stop();
+                    else this.SetPose(this.CachedPose.PoseName);
+                    this.UpdateMeido?.Invoke(this, MeidoUpdateEventArgs.Empty);
+                }
             }
         }
         private bool isBone = false;
@@ -52,8 +68,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             get => isBone;
             set
             {
+                if (this.isBone == value) return;
                 this.isBone = value;
-                this.dragPointManager?.BoneModeActive(this.isBone);
+                if (this.dragPointManager != null) this.dragPointManager.IsBone = this.isBone;
+                this.UpdateMeido?.Invoke(this, MeidoUpdateEventArgs.Empty);
             }
         }
         public bool Visible
@@ -61,7 +79,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             get => Maid.Visible;
             set => Maid.Visible = value;
         }
-        public PoseInfo poseInfo;
+        private PoseInfo cachedPose;
+        public PoseInfo CachedPose
+        {
+            get => cachedPose;
+            private set => cachedPose = value;
+        }
 
         public Meido(int stockMaidIndex)
         {
@@ -70,7 +93,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.Image = Maid.GetThumIcon();
             this.FirstName = Maid.status.firstName;
             this.LastName = Maid.status.lastName;
-            this.poseInfo = defaultPose;
+            this.CachedPose = defaultPose;
             // I don't know why I put this here. Must've fixed something with proc loading
             Maid.boAllProcPropBUSY = false;
         }
@@ -86,6 +109,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
                 return;
             }
+
             dragPointManager.Update();
         }
 
@@ -98,7 +122,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             if (!Maid.body0.isLoadedBody)
             {
-                if (activeSlot >= 12)
+                if (activeSlot >= MAX_MAIDS)
                 {
                     Maid.DutPropAll();
                     Maid.AllProcPropSeqStart();
@@ -117,11 +141,11 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             if (dragPointManager == null)
             {
                 dragPointManager = new DragPointManager(this);
-                dragPointManager.SelectMaid += (sender, meidoChangeArgs) => OnMeidoSelect(meidoChangeArgs);
+                dragPointManager.SelectMaid += OnMeidoSelect;
             }
             else
             {
-                dragPointManager.SetActive(true);
+                dragPointManager.Active = true;
 
                 this.IsIK = true;
                 this.IsStop = false;
@@ -153,7 +177,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             Maid.Visible = false;
 
-            dragPointManager?.SetActive(false);
+            if (dragPointManager != null) dragPointManager.Active = false;
+
             this.IsIK = false;
             this.IsStop = false;
             this.IsBone = false;
@@ -162,20 +187,25 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public void Deactivate()
         {
             Unload();
-            dragPointManager?.Deactivate();
+            if (dragPointManager != null)
+            {
+                dragPointManager.Destroy();
+                dragPointManager.SelectMaid -= OnMeidoSelect;
+            }
+
             Maid.SetPos(Vector3.zero);
             Maid.SetRot(Vector3.zero);
             Maid.SetPosOffset(Vector3.zero);
             Maid.body0.SetBoneHitHeightY(0f);
 
-            Maid.Visible = false;
-            Maid.ActiveSlotNo = -1;
             Maid.DelPrefabAll();
+
+            Maid.ActiveSlotNo = -1;
         }
 
         public void SetPose(PoseInfo poseInfo)
         {
-            this.poseInfo = poseInfo;
+            this.CachedPose = poseInfo;
             SetPose(poseInfo.PoseName);
         }
 
@@ -216,7 +246,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public void SetMune(bool drag = false)
         {
-            bool isMomiOrPaizuri = poseInfo.PoseName.Contains("_momi") || poseInfo.PoseName.Contains("paizuri_");
+            bool isMomiOrPaizuri = CachedPose.PoseName.Contains("_momi") || CachedPose.PoseName.Contains("paizuri_");
             float onL = (drag || isMomiOrPaizuri) ? 0f : 1f;
             Maid.body0.MuneYureL(onL);
             Maid.body0.MuneYureR(onL);
@@ -282,16 +312,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             body.FixVisibleFlag(false);
         }
 
-        public void SetIKActive(bool active)
-        {
-            this.IsIK = active;
-            if (dragPointManager == null) this.IsIK = false;
-            else
-            {
-                dragPointManager.SetActive(this.IsIK);
-            }
-        }
-
         private void OnBodyLoad()
         {
             BodyLoad?.Invoke(this, EventArgs.Empty);
@@ -301,18 +321,18 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.IsBone = false;
         }
 
-        private void OnMeidoSelect(MeidoChangeEventArgs args)
+        private void OnMeidoSelect(object sender, MeidoUpdateEventArgs args)
         {
-            SelectMeido?.Invoke(this, args);
+            UpdateMeido?.Invoke(this, args);
         }
     }
 
     public struct PoseInfo
     {
-        public int PoseGroupIndex { get; private set; }
-        public int PoseIndex { get; private set; }
-        public string PoseName { get; private set; }
-        public bool IsCustomPose { get; private set; }
+        public int PoseGroupIndex { get; }
+        public int PoseIndex { get; }
+        public string PoseName { get; }
+        public bool IsCustomPose { get; }
         public PoseInfo(int poseGroup, int pose, string poseName, bool isCustomPose = false)
         {
             this.PoseGroupIndex = poseGroup;
@@ -320,5 +340,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.PoseName = poseName;
             this.IsCustomPose = isCustomPose;
         }
+        public override string ToString() => $"pose group: {PoseGroupIndex}, pose index: {PoseIndex}, pose name: {PoseName}, is custom: {IsCustomPose}";
     }
 }

+ 67 - 92
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MeidoPhotoStudio.cs

@@ -1,4 +1,5 @@
 using System.Linq;
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.IO;
@@ -16,10 +17,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private WindowManager windowManager;
         private MeidoManager meidoManager;
         private EnvironmentManager environmentManager;
-        private MessageWindowManager messageWindowManager;
         private PropManager propManager;
-        private LightManager lightManager;
-        private EffectManager effectManager;
+        // private LightManager lightManager;
+        // private EffectManager effectManager;
+        private MessageWindowManager messageWindowManager;
         private Constants.Scene currentScene;
         private bool initialized = false;
         private bool isActive = false;
@@ -45,15 +46,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 if (Input.GetKeyDown(KeyCode.F6))
                 {
-                    if (!initialized)
-                    {
-                        Initialize();
-                        windowManager.MainWindowVisible = true;
-                    }
-                    else
-                    {
-                        ReturnToMenu();
-                    }
+                    if (isActive) Deactivate();
+                    else Activate();
                 }
 
                 if (isActive)
@@ -65,8 +59,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     }
 
                     meidoManager.Update();
-                    windowManager.Update();
                     environmentManager.Update();
+                    windowManager.Update();
                 }
             }
         }
@@ -81,7 +75,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 UTY.GetChildObject(GameMain.Instance.gameObject, "SystemUI Root/SystemDialog", false);
             GameObject sysShortcut =
                 UTY.GetChildObject(GameMain.Instance.gameObject, "SystemUI Root/SystemShortcut", false);
-            if (editUI != null) editUI.SetActive(false);
+            editUI.SetActive(false);
             fpsViewer.SetActive(false);
             sysDialog.SetActive(false);
             sysShortcut.SetActive(false);
@@ -93,7 +87,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 Meido meido = activeMeidoList[i];
                 isIK[i] = meido.IsIK;
-                if (meido.IsIK) meido.SetIKActive(false);
+                if (meido.IsIK) meido.IsIK = false;
             }
 
             GizmoRender.UIVisible = false;
@@ -111,7 +105,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             // Show UI and dragpoints
             uiActive = true;
-            if (editUI != null) editUI.SetActive(true);
+            editUI.SetActive(true);
             fpsViewer.SetActive(GameMain.Instance.CMSystem.ViewFps);
             sysDialog.SetActive(true);
             sysShortcut.SetActive(true);
@@ -119,112 +113,93 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             for (int i = 0; i < activeMeidoList.Count; i++)
             {
                 Meido meido = activeMeidoList[i];
-                if (isIK[i]) meido.SetIKActive(true);
+                if (isIK[i]) meido.IsIK = true;
             }
 
             GizmoRender.UIVisible = true;
         }
+
         private void OnGUI()
         {
             if (uiActive)
             {
-                windowManager.OnGUI();
+                windowManager.DrawWindows();
             }
         }
+
         private void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode)
         {
             currentScene = (Constants.Scene)scene.buildIndex;
-        }
-        private void ReturnToMenu()
-        {
-            if (meidoManager.IsBusy) return;
-            meidoManager.Deactivate();
-            environmentManager.Deactivate();
-            messageWindowManager.Deactivate();
 
-            isActive = false;
-            uiActive = false;
-            initialized = false;
-            windowManager.MainWindowVisible = false;
-            GameMain.Instance.SoundMgr.PlayBGM("bgm009.ogg", 1f, true);
-            GameObject go = GameObject.Find("UI Root").transform.Find("DailyPanel").gameObject;
-            go.SetActive(true);
-            bool isNight = GameMain.Instance.CharacterMgr.status.GetFlag("時間帯") == 3;
-
-            if (isNight)
-            {
-                GameMain.Instance.BgMgr.ChangeBg("ShinShitsumu_ChairRot_Night");
-            }
-            else
+            if (currentScene == Constants.Scene.Daily)
             {
-                GameMain.Instance.BgMgr.ChangeBg("ShinShitsumu_ChairRot");
+                if (!initialized) Initialize();
             }
-
-            GameMain.Instance.MainCamera.Reset(CameraMain.CameraType.Target, true);
-            GameMain.Instance.MainCamera.SetTargetPos(new Vector3(0.5609447f, 1.380762f, -1.382336f), true);
-            GameMain.Instance.MainCamera.SetDistance(1.6f, true);
-            GameMain.Instance.MainCamera.SetAroundAngle(new Vector2(245.5691f, 6.273283f), true);
         }
 
         private void Initialize()
         {
-            TabsPane.SelectedTab = Constants.Window.Call;
-            initialized = true;
-            meidoManager = new MeidoManager();
-
-            meidoManager.BeginCallMeidos += (s, a) => this.uiActive = false;
-            meidoManager.EndCallMeidos += (s, a) => this.uiActive = true;
+            if (initialized) return;
 
-            lightManager = new LightManager();
+            meidoManager = new MeidoManager();
             propManager = new PropManager();
-            effectManager = new EffectManager();
-            environmentManager = new EnvironmentManager(propManager, lightManager, effectManager);
+            // lightManager = new LightManager();
+            environmentManager = new EnvironmentManager()
+            {
+                PropManager = propManager,
+                // LightManager = lightManager
+            };
+
             messageWindowManager = new MessageWindowManager();
-            windowManager = new WindowManager(meidoManager, environmentManager, messageWindowManager);
 
-            environmentManager.Initialize();
+            MaidSwitcherPane maidSwitcherPane = new MaidSwitcherPane(meidoManager);
 
-            isActive = true;
+            windowManager = new WindowManager()
+            {
+                [Constants.Window.Main] = new MainWindow(meidoManager)
+                {
+                    [Constants.Window.Call] = new CallWindowPane(meidoManager),
+                    [Constants.Window.Pose] = new PoseWindowPane(meidoManager, maidSwitcherPane),
+                    [Constants.Window.Face] = new FaceWindowPane(meidoManager, maidSwitcherPane),
+                    [Constants.Window.BG] = new BGWindowPane(environmentManager),
+                    [Constants.Window.BG2] = new BG2WindowPane(environmentManager)
+                },
+                [Constants.Window.Message] = new MessageWindow(messageWindowManager)
+            };
+
+            meidoManager.BeginCallMeidos += (s, a) => uiActive = false;
+            meidoManager.EndCallMeidos += (s, a) => uiActive = true;
+        }
+
+        private void Activate()
+        {
             uiActive = true;
+            isActive = true;
 
-            #region maid stuff
-            // if (maid)
-            // {
-            //     maid.StopKuchipakuPattern();
-            //     maid.body0.trsLookTarget = GameMain.Instance.MainCamera.transform;
-
-            //     if (maid.Visible && maid.body0.isLoadedBody)
-            //     {
-            //         maid.CrossFade("pose_taiki_f.anm", false, true, false, 0f);
-            //         maid.SetAutoTwistAll(true);
-            //         maid.body0.MuneYureL(1f);
-            //         maid.body0.MuneYureR(1f);
-            //         maid.body0.jbMuneL.enabled = true;
-            //         maid.body0.jbMuneR.enabled = true;
-            //     }
-
-            //     maid.body0.SetMask(TBody.SlotID.wear, true);
-            //     maid.body0.SetMask(TBody.SlotID.skirt, true);
-            //     maid.body0.SetMask(TBody.SlotID.bra, true);
-            //     maid.body0.SetMask(TBody.SlotID.panz, true);
-            //     maid.body0.SetMask(TBody.SlotID.mizugi, true);
-            //     maid.body0.SetMask(TBody.SlotID.onepiece, true);
-            //     if (maid.body0.isLoadedBody)
-            //     {
-            //         for (int i = 0; i < maid.body0.goSlot.Count; i++)
-            //         {
-            //             List<THair1> fieldValue = Utility.GetFieldValue<TBoneHair_, List<THair1>>(maid.body0.goSlot[i].bonehair, "hair1list");
-            //             for (int j = 0; j < fieldValue.Count; ++j)
-            //             {
-            //                 fieldValue[j].SoftG = new Vector3(0.0f, -3f / 1000f, 0.0f);
-            //             }
-            //         }
-            //     }
-            // }
-            #endregion
+            meidoManager.Activate();
+            environmentManager.Activate();
+            windowManager.Activate();
+            messageWindowManager.Activate();
 
             GameObject dailyPanel = GameObject.Find("UI Root").transform.Find("DailyPanel").gameObject;
             dailyPanel.SetActive(false);
         }
+
+        private void Deactivate()
+        {
+            if (meidoManager.IsBusy) return;
+
+            uiActive = false;
+            isActive = false;
+
+            meidoManager.Deactivate();
+            environmentManager.Deactivate();
+            messageWindowManager.Deactivate();
+            windowManager.Deactivate();
+
+            // GameMain.Instance.SoundMgr.PlayBGM("bgm009.ogg", 1f, true);
+            GameObject dailyPanel = GameObject.Find("UI Root").transform.Find("DailyPanel").gameObject;
+            dailyPanel.SetActive(true);
+        }
     }
 }