Browse Source

Add free look and maid clothing toggles

habeebweeb 4 years ago
parent
commit
99e3ce00a0

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

@@ -87,7 +87,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             SetFaceValue(key, value ? max : 0f);
         }
 
-        public void SetControlValues()
+        public override void Update()
         {
             this.updating = true;
             TMorph morph = this.meidoManager.ActiveMeido.Maid.body0.Face.morph;

+ 256 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidDressingPane.cs

@@ -0,0 +1,256 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using static TBody;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    public class MaidDressingPane : BasePane
+    {
+        private MeidoManager meidoManager;
+        private Dictionary<SlotID, Toggle> ClothingToggles;
+        private Dictionary<SlotID, bool> LoadedSlots;
+        public enum Curl
+        {
+            front, back, shift
+        }
+        private static readonly SlotID[] clothingSlots = {
+            // main slots
+            SlotID.wear, SlotID.skirt, SlotID.bra, SlotID.panz, SlotID.headset, SlotID.megane,
+            SlotID.accUde, SlotID.glove, SlotID.accSenaka, SlotID.stkg, SlotID.shoes, SlotID.body,
+            // detailed slots
+            SlotID.accAshi, SlotID.accHana, SlotID.accHat, SlotID.accHeso, SlotID.accKamiSubL,
+            SlotID.accKamiSubR, SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_, SlotID.accKubi,
+            SlotID.accKubiwa, SlotID.accMiMiL, SlotID.accMiMiR, SlotID.accNipL, SlotID.accNipR,
+            SlotID.accShippo, SlotID.accXXX, 
+            // unused slots
+            // SlotID.mizugi, SlotID.onepiece, SlotID.accHead,
+        };
+
+        public static readonly SlotID[] bodySlots = {
+            SlotID.body, SlotID.head, SlotID.eye, SlotID.hairF, SlotID.hairR,
+            SlotID.hairS, SlotID.hairT, SlotID.hairAho, SlotID.chikubi, SlotID.underhair,
+            SlotID.moza, SlotID.accHa
+        };
+
+        private static readonly SlotID[] wearSlots = {
+            SlotID.wear, SlotID.mizugi, SlotID.onepiece
+        };
+
+        private static readonly SlotID[] headwearSlots = {
+            SlotID.headset, SlotID.accHat, SlotID.accKamiSubL,
+            SlotID.accKamiSubR, SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_
+        };
+
+        private Toggle detailedClothingToggle;
+        private Toggle curlingFrontToggle;
+        private Toggle curlingBackToggle;
+        private Toggle pantsuShiftToggle;
+        private bool detailedClothing = false;
+
+        public MaidDressingPane(MeidoManager meidoManager)
+        {
+            this.meidoManager = meidoManager;
+
+            ClothingToggles = new Dictionary<SlotID, Toggle>(clothingSlots.Length);
+            LoadedSlots = new Dictionary<SlotID, bool>(clothingSlots.Length);
+            foreach (SlotID slot in clothingSlots)
+            {
+                Toggle slotToggle = new Toggle(Translation.Get("clothing", slot.ToString()));
+                slotToggle.ControlEvent += (s, a) => ToggleClothing(slot, slotToggle.Value);
+                ClothingToggles.Add(slot, slotToggle);
+                LoadedSlots[slot] = true;
+            }
+
+            detailedClothingToggle = new Toggle(Translation.Get("clothing", "detail"));
+            detailedClothingToggle.ControlEvent += (s, a) => UpdateDetailedClothing();
+
+            curlingFrontToggle = new Toggle(Translation.Get("clothing", "curlingFront"));
+            curlingFrontToggle.ControlEvent += (s, a) => ToggleCurling(Curl.front, curlingFrontToggle.Value);
+            curlingBackToggle = new Toggle(Translation.Get("clothing", "curlingBack"));
+            curlingBackToggle.ControlEvent += (s, a) => ToggleCurling(Curl.back, curlingBackToggle.Value);
+            pantsuShiftToggle = new Toggle(Translation.Get("clothing", "shiftPanties"));
+            pantsuShiftToggle.ControlEvent += (s, a) => ToggleCurling(Curl.shift, pantsuShiftToggle.Value);
+
+            UpdateDetailedClothing();
+        }
+
+        public void ToggleClothing(SlotID slot, bool enabled)
+        {
+            if (this.updating) return;
+
+            if (slot == SlotID.body)
+            {
+                this.meidoManager.ActiveMeido.SetBodyMask(enabled);
+                return;
+            }
+
+            TBody body = this.meidoManager.ActiveMeido.Maid.body0;
+
+            if (!detailedClothing && slot == SlotID.headset)
+            {
+                this.updating = true;
+                foreach (SlotID wearSlot in headwearSlots)
+                {
+                    body.SetMask(wearSlot, enabled);
+                    ClothingToggles[wearSlot].Value = enabled;
+                }
+                this.updating = false;
+            }
+            else
+            {
+                if (slot == SlotID.wear)
+                {
+                    foreach (SlotID wearSlot in wearSlots)
+                    {
+                        body.SetMask(wearSlot, enabled);
+                    }
+                }
+                else if (slot == SlotID.megane)
+                {
+                    body.SetMask(SlotID.megane, enabled);
+                    body.SetMask(SlotID.accHead, enabled);
+                }
+                else body.SetMask(slot, enabled);
+            }
+        }
+
+        public void ToggleCurling(Curl curl, bool enabled)
+        {
+            if (updating) return;
+            Maid maid = this.meidoManager.ActiveMeido.Maid;
+            string[] name = curl == Curl.shift
+                ? new[] { "panz", "mizugi" }
+                : new[] { "skirt", "onepiece" };
+            if (enabled)
+            {
+                string action = curl == Curl.shift
+                    ? "パンツずらし"
+                    : curl == Curl.front
+                        ? "めくれスカート" : "めくれスカート後ろ";
+                maid.ItemChangeTemp(name[0], action);
+                maid.ItemChangeTemp(name[1], action);
+                this.updating = true;
+                if (curl == Curl.front && curlingBackToggle.Value)
+                {
+                    curlingBackToggle.Value = false;
+                }
+                else if (curl == Curl.back && curlingFrontToggle.Value)
+                {
+                    curlingFrontToggle.Value = false;
+                }
+                this.updating = false;
+            }
+            else
+            {
+                maid.ResetProp(name[0]);
+                maid.ResetProp(name[1]);
+            }
+            maid.AllProcProp();
+        }
+
+        public override void Update()
+        {
+            this.updating = true;
+            Maid maid = this.meidoManager.ActiveMeido.Maid;
+            TBody body = maid.body0;
+            foreach (SlotID clothingSlot in clothingSlots)
+            {
+                bool toggleValue;
+                bool hasSlot;
+                if (clothingSlot == SlotID.wear)
+                {
+                    toggleValue = body.GetMask(SlotID.wear) || body.GetMask(SlotID.mizugi)
+                        || body.GetMask(SlotID.onepiece);
+                    hasSlot = body.GetSlotLoaded(SlotID.wear) || body.GetSlotLoaded(SlotID.mizugi)
+                        || body.GetMask(SlotID.onepiece);
+                }
+                else if (clothingSlot == SlotID.megane)
+                {
+                    toggleValue = body.GetMask(SlotID.megane) || body.GetMask(SlotID.accHead);
+                    hasSlot = body.GetSlotLoaded(SlotID.megane) || body.GetSlotLoaded(SlotID.accHead);
+                }
+                else
+                {
+                    toggleValue = body.GetMask(clothingSlot);
+                    hasSlot = body.GetSlotLoaded(clothingSlot);
+                }
+
+                ClothingToggles[clothingSlot].Value = hasSlot ? toggleValue : false;
+                LoadedSlots[clothingSlot] = hasSlot;
+            }
+
+            curlingFrontToggle.Value = maid.IsItemChange("skirt", "めくれスカート")
+                || maid.IsItemChange("onepiece", "めくれスカート");
+
+            curlingBackToggle.Value = maid.IsItemChange("skirt", "めくれスカート後ろ")
+                || maid.IsItemChange("onepiece", "めくれスカート後ろ");
+
+            pantsuShiftToggle.Value = maid.IsItemChange("panz", "パンツずらし")
+                || maid.IsItemChange("mizugi", "パンツずらし");
+
+            this.updating = false;
+        }
+
+        private void DrawSlotGroup(params SlotID[] slots)
+        {
+            GUILayout.BeginHorizontal();
+            for (int i = 0; i < slots.Length; i++)
+            {
+                SlotID slot = slots[i];
+                if (!this.Enabled) GUI.enabled = false;
+                else GUI.enabled = LoadedSlots[slot];
+                ClothingToggles[slot].Draw();
+                if (i < slots.Length - 1) GUILayout.FlexibleSpace();
+            }
+            GUILayout.EndHorizontal();
+        }
+
+        private void UpdateDetailedClothing()
+        {
+            detailedClothing = detailedClothingToggle.Value;
+            ClothingToggles[SlotID.headset].Label = detailedClothing
+                ? Translation.Get("clothing", "headset")
+                : Translation.Get("clothing", "headwear");
+        }
+
+        public override void Draw(params GUILayoutOption[] layoutOptions)
+        {
+            this.Enabled = this.meidoManager.HasActiveMeido;
+
+            GUI.enabled = this.Enabled;
+            detailedClothingToggle.Draw();
+            MiscGUI.BlackLine();
+
+            DrawSlotGroup(SlotID.wear, SlotID.skirt);
+            DrawSlotGroup(SlotID.bra, SlotID.panz);
+            DrawSlotGroup(SlotID.headset, SlotID.megane);
+            DrawSlotGroup(SlotID.accUde, SlotID.glove, SlotID.accSenaka);
+            DrawSlotGroup(SlotID.stkg, SlotID.shoes, SlotID.body);
+
+            if (detailedClothing)
+            {
+                MiscGUI.BlackLine();
+                DrawSlotGroup(SlotID.accShippo, SlotID.accHat);
+                DrawSlotGroup(SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_);
+                DrawSlotGroup(SlotID.accKamiSubL, SlotID.accKamiSubR);
+                DrawSlotGroup(SlotID.accMiMiL, SlotID.accMiMiR, SlotID.accNipL, SlotID.accNipR);
+                DrawSlotGroup(SlotID.accHana, SlotID.accKubi, SlotID.accKubiwa);
+                DrawSlotGroup(SlotID.accHeso, SlotID.accAshi, SlotID.accXXX);
+            }
+
+            GUI.enabled = this.Enabled;
+
+            GUILayout.BeginHorizontal();
+            curlingFrontToggle.Draw();
+            GUILayout.FlexibleSpace();
+            curlingBackToggle.Draw();
+            GUILayout.FlexibleSpace();
+            pantsuShiftToggle.Draw();
+            GUILayout.FlexibleSpace();
+            GUILayout.EndHorizontal();
+        }
+    }
+}

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

@@ -0,0 +1,52 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    public class MaidFaceLookPane : BasePane
+    {
+        private MeidoManager meidoManager;
+        private Slider lookXSlider;
+        private Slider lookYSlider;
+
+        public MaidFaceLookPane(MeidoManager meidoManager)
+        {
+            this.meidoManager = meidoManager;
+
+            this.lookXSlider = new Slider(Translation.Get("freeLook", "x"), -0.6f, 0.6f);
+            this.lookXSlider.ControlEvent += (s, a) => SetMaidLook();
+
+            this.lookYSlider = new Slider(Translation.Get("freeLook", "y"), 0.5f, -0.55f);
+            this.lookYSlider.ControlEvent += (s, a) => SetMaidLook();
+
+        }
+
+        public void SetMaidLook()
+        {
+            if (updating) return;
+
+            TBody body = this.meidoManager.ActiveMeido.Maid.body0;
+
+            bool isPlaying = this.meidoManager.ActiveMeido.Maid.GetAnimation().isPlaying;
+            body.offsetLookTarget = new Vector3(lookYSlider.Value * (isPlaying ? 1f : 0.6f), 1f, lookXSlider.Value);
+        }
+
+        public override void Update()
+        {
+            TBody body = this.meidoManager.ActiveMeido.Maid.body0;
+            this.updating = true;
+            this.lookXSlider.Value = body.offsetLookTarget.z;
+            this.lookYSlider.Value = body.offsetLookTarget.x;
+            this.updating = false;
+        }
+
+        public override void Draw(params GUILayoutOption[] layoutOptions)
+        {
+            GUI.enabled = this.Enabled;
+            GUILayout.BeginHorizontal();
+            lookXSlider.Draw();
+            lookYSlider.Draw();
+            GUILayout.EndHorizontal();
+        }
+    }
+}

+ 108 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidPoseSelectorPane.cs

@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    public class MaidPoseSelectorPane : BasePane
+    {
+        private MeidoManager meidoManager;
+        private Button poseLeftButton;
+        private Button poseRightButton;
+        private Button poseGroupLeftButton;
+        private Button poseGroupRightButton;
+        private Dropdown poseGroupDropdown;
+        private Dropdown poseDropdown;
+        private string selectedPoseGroup;
+        private int selectedPose;
+
+        public MaidPoseSelectorPane(MeidoManager meidoManager)
+        {
+            this.meidoManager = meidoManager;
+
+            this.poseGroupDropdown = new Dropdown(Translation.GetList("poseGroupDropdown", Constants.PoseGroupList));
+            this.poseGroupDropdown.SelectionChange += ChangePoseGroup;
+
+            this.poseDropdown = new Dropdown(Constants.PoseDict[Constants.PoseGroupList[0]].ToArray());
+            this.poseDropdown.SelectionChange += ChangePose;
+
+            this.poseGroupLeftButton = new Button("<");
+            this.poseGroupLeftButton.ControlEvent += (s, a) => poseGroupDropdown.Step(-1);
+
+            this.poseGroupRightButton = new Button(">");
+            this.poseGroupRightButton.ControlEvent += (s, a) => poseGroupDropdown.Step(1);
+
+            this.poseLeftButton = new Button("<");
+            this.poseLeftButton.ControlEvent += (s, a) => poseDropdown.Step(-1);
+
+            this.poseRightButton = new Button(">");
+            this.poseRightButton.ControlEvent += (s, a) => poseDropdown.Step(1);
+        }
+
+        private void ChangePoseGroup(object sender, EventArgs args)
+        {
+            string newPoseGroup = Constants.PoseGroupList[this.poseGroupDropdown.SelectedItemIndex];
+            if (selectedPoseGroup == newPoseGroup)
+            {
+                this.poseDropdown.SelectedItemIndex = 0;
+            }
+            else
+            {
+                selectedPoseGroup = newPoseGroup;
+                if (this.poseGroupDropdown.SelectedItemIndex >= Constants.CustomPoseGroupsIndex)
+                {
+                    List<KeyValuePair<string, string>> pairList = Constants.CustomPoseDict[selectedPoseGroup];
+                    string[] poseList = pairList.Select(pair => pair.Key).ToArray();
+                    this.poseDropdown.SetDropdownItems(poseList);
+                }
+                else
+                {
+                    this.poseDropdown.SetDropdownItems(Constants.PoseDict[selectedPoseGroup].ToArray());
+                }
+            }
+        }
+
+        private void ChangePose(object sender, EventArgs args)
+        {
+            selectedPose = poseDropdown.SelectedItemIndex;
+            string poseName;
+            if (this.poseGroupDropdown.SelectedItemIndex >= Constants.CustomPoseGroupsIndex)
+                poseName = Constants.CustomPoseDict[selectedPoseGroup][selectedPose].Value;
+            else
+                poseName = Constants.PoseDict[selectedPoseGroup][selectedPose];
+
+            meidoManager.ActiveMeido.SetPose(poseName);
+        }
+
+        public override void Draw(params GUILayoutOption[] layoutOptions)
+        {
+            float arrowButtonSize = 30;
+            GUILayoutOption[] arrowLayoutOptions = {
+                GUILayout.Width(arrowButtonSize),
+                GUILayout.Height(arrowButtonSize)
+            };
+
+            float dropdownButtonHeight = arrowButtonSize;
+            float dropdownButtonWidth = 143f;
+            GUILayoutOption[] dropdownLayoutOptions = new GUILayoutOption[] {
+                GUILayout.Height(dropdownButtonHeight),
+                GUILayout.Width(dropdownButtonWidth)
+            };
+
+            GUI.enabled = meidoManager.HasActiveMeido;
+
+            GUILayout.BeginHorizontal();
+            this.poseGroupLeftButton.Draw(arrowLayoutOptions);
+            this.poseGroupDropdown.Draw(dropdownLayoutOptions);
+            this.poseGroupRightButton.Draw(arrowLayoutOptions);
+            GUILayout.EndHorizontal();
+
+            GUILayout.BeginHorizontal();
+            this.poseLeftButton.Draw(arrowLayoutOptions);
+            this.poseDropdown.Draw(dropdownLayoutOptions);
+            this.poseRightButton.Draw(arrowLayoutOptions);
+            GUILayout.EndHorizontal();
+        }
+    }
+}

+ 5 - 9
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidFaceWindow.cs

@@ -60,7 +60,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             MaidSwitcherPane.Draw();
 
-            bool previousState = GUI.enabled;
             GUI.enabled = this.meidoManager.HasActiveMeido;
 
             GUILayout.BeginHorizontal();
@@ -74,30 +73,27 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.maidFaceSliderPane.Draw();
 
             GUILayout.EndScrollView();
-
-            GUI.enabled = previousState;
         }
 
         private void UpdateFace()
         {
-            if (this.meidoManager.HasActiveMeido)
+            if (!this.meidoManager.HasActiveMeido) return;
+            if (TabsPane.SelectedTab == Constants.Window.Face)
             {
                 this.meidoManager.ActiveMeido.Maid.boMabataki = false;
                 this.meidoManager.ActiveMeido.Maid.body0.Face.morph.EyeMabataki = 0f;
-                this.maidFaceSliderPane.SetControlValues();
+                this.maidFaceSliderPane.Update();
             }
         }
 
         private void SelectMeido(object sender, MeidoChangeEventArgs args)
         {
-            if (TabsPane.SelectedTab == Constants.Window.Face)
-                UpdateFace();
+            UpdateFace();
         }
 
         private void ChangeTab(object sender, EventArgs args)
         {
-            if (TabsPane.SelectedTab == Constants.Window.Face)
-                UpdateFace();
+            UpdateFace();
         }
     }
 }

+ 43 - 79
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Windows/MainWindows/MaidPoseWindow.cs

@@ -9,111 +9,75 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
     public class MaidPoseWindow : BaseMainWindow
     {
         private MeidoManager meidoManager;
-        private Button poseLeftButton;
-        private Button poseRightButton;
-        private Button poseGroupLeftButton;
-        private Button poseGroupRightButton;
-        private Dropdown poseGroupDropdown;
-        private Dropdown poseDropdown;
-        private string selectedPoseGroup;
-        private int selectedPose;
+        private MaidPoseSelectorPane poseSelectorPane;
+        private MaidFaceLookPane maidFaceLookPane;
+        private MaidDressingPane maidDressingPane;
+        private Toggle freeLookToggle;
         public MaidPoseWindow(MeidoManager meidoManager)
         {
             this.meidoManager = meidoManager;
-            this.meidoManager.SelectMeido += SelectMeido;
+            this.meidoManager.SelectMeido += OnMeidoSelect;
 
-            this.poseGroupDropdown = new Dropdown(Translation.GetList("poseGroupDropdown", Constants.PoseGroupList));
-            this.poseGroupDropdown.SelectionChange += ChangePoseGroup;
+            this.poseSelectorPane = new MaidPoseSelectorPane(meidoManager);
+            this.maidFaceLookPane = new MaidFaceLookPane(meidoManager);
+            this.maidFaceLookPane.Enabled = false;
 
-            this.poseDropdown = new Dropdown(Constants.PoseDict[Constants.PoseGroupList[0]].ToArray());
-            this.poseDropdown.SelectionChange += ChangePose;
+            this.maidDressingPane = new MaidDressingPane(meidoManager);
 
-            this.poseGroupLeftButton = new Button("<");
-            this.poseGroupLeftButton.ControlEvent += (s, a) => poseGroupDropdown.Step(-1);
+            TabsPane.TabChange += OnTabChange;
 
-            this.poseGroupRightButton = new Button(">");
-            this.poseGroupRightButton.ControlEvent += (s, a) => poseGroupDropdown.Step(1);
-
-            this.poseLeftButton = new Button("<");
-            this.poseLeftButton.ControlEvent += (s, a) => poseDropdown.Step(-1);
-
-            this.poseRightButton = new Button(">");
-            this.poseRightButton.ControlEvent += (s, a) => poseDropdown.Step(1);
-        }
-
-        private void ChangePoseGroup(object sender, EventArgs args)
-        {
-            string newPoseGroup = Constants.PoseGroupList[this.poseGroupDropdown.SelectedItemIndex];
-            if (selectedPoseGroup == newPoseGroup)
-            {
-                this.poseDropdown.SelectedItemIndex = 0;
-            }
-            else
+            this.freeLookToggle = new Toggle(Translation.Get("freeLook", "freeLookToggle"), false);
+            this.freeLookToggle.ControlEvent += (s, a) =>
             {
-                selectedPoseGroup = newPoseGroup;
-                if (this.poseGroupDropdown.SelectedItemIndex >= Constants.CustomPoseGroupsIndex)
-                {
-                    List<KeyValuePair<string, string>> pairList = Constants.CustomPoseDict[selectedPoseGroup];
-                    string[] poseList = pairList.Select(pair => pair.Key).ToArray();
-                    this.poseDropdown.SetDropdownItems(poseList);
-                }
-                else
-                {
-                    this.poseDropdown.SetDropdownItems(Constants.PoseDict[selectedPoseGroup].ToArray());
-                }
-            }
+                TBody body = this.meidoManager.ActiveMeido.Maid.body0;
+                body.trsLookTarget = this.freeLookToggle.Value ? null : GameMain.Instance.MainCamera.transform;
+                this.maidFaceLookPane.Enabled = this.freeLookToggle.Value;
+                if (this.freeLookToggle.Value) this.maidFaceLookPane.SetMaidLook();
+            };
         }
 
-        private void ChangePose(object sender, EventArgs args)
+        ~MaidPoseWindow()
         {
-            selectedPose = poseDropdown.SelectedItemIndex;
-            string poseName;
-            if (this.poseGroupDropdown.SelectedItemIndex >= Constants.CustomPoseGroupsIndex)
-                poseName = Constants.CustomPoseDict[selectedPoseGroup][selectedPose].Value;
-            else
-                poseName = Constants.PoseDict[selectedPoseGroup][selectedPose];
-
-            meidoManager.ActiveMeido.SetPose(poseName);
+            TabsPane.TabChange -= OnTabChange;
         }
 
         public override void Draw(params GUILayoutOption[] layoutOptions)
         {
-            float arrowButtonSize = 30;
-            GUILayoutOption[] arrowLayoutOptions = {
-                GUILayout.Width(arrowButtonSize),
-                GUILayout.Height(arrowButtonSize)
-            };
-
-            float dropdownButtonHeight = arrowButtonSize;
-            float dropdownButtonWidth = 143f;
-            GUILayoutOption[] dropdownLayoutOptions = new GUILayoutOption[] {
-                GUILayout.Height(dropdownButtonHeight),
-                GUILayout.Width(dropdownButtonWidth)
-            };
-
             MaidSwitcherPane.Draw();
+            poseSelectorPane.Draw();
 
-            bool previousState = GUI.enabled;
-            GUI.enabled = meidoManager.HasActiveMeido;
+            GUILayout.BeginScrollView(this.scrollPos);
 
             GUILayout.BeginHorizontal();
-            this.poseGroupLeftButton.Draw(arrowLayoutOptions);
-            this.poseGroupDropdown.Draw(dropdownLayoutOptions);
-            this.poseGroupRightButton.Draw(arrowLayoutOptions);
+            GUI.enabled = this.meidoManager.HasActiveMeido;
+            freeLookToggle.Draw();
             GUILayout.EndHorizontal();
 
-            GUILayout.BeginHorizontal();
-            this.poseLeftButton.Draw(arrowLayoutOptions);
-            this.poseDropdown.Draw(dropdownLayoutOptions);
-            this.poseRightButton.Draw(arrowLayoutOptions);
-            GUILayout.EndHorizontal();
+            maidFaceLookPane.Draw();
+
+            maidDressingPane.Draw();
+            GUILayout.EndScrollView();
+        }
 
-            GUI.enabled = previousState;
+        private void UpdatePanes()
+        {
+            if (!this.meidoManager.HasActiveMeido) return;
+
+            if (TabsPane.SelectedTab == Constants.Window.Pose)
+            {
+                maidFaceLookPane.Update();
+                maidDressingPane.Update();
+            }
         }
 
-        private void SelectMeido(object sender, EventArgs args)
+        private void OnMeidoSelect(object sender, MeidoChangeEventArgs args)
         {
+            UpdatePanes();
+        }
 
+        private void OnTabChange(object sender, EventArgs args)
+        {
+            UpdatePanes();
         }
     }
 }