瀏覽代碼

New dock, fix horizontal and vertical child size, fix horizontal scroll

Jean-David Moisan 3 年之前
父節點
當前提交
c06bcfd018
共有 3 個文件被更改,包括 133 次插入6 次删除
  1. 127 0
      Source/Dock.cs
  2. 4 4
      Source/Horizontal.cs
  3. 2 2
      Source/Vertical.cs

+ 127 - 0
Source/Dock.cs

@@ -0,0 +1,127 @@
+using System.Runtime.CompilerServices;
+using Apos.Input;
+using Microsoft.Xna.Framework;
+using MonoGame.Extended;
+
+namespace Apos.Gui {
+    public class Dock : Component, IParent {
+        public Dock(int id, float left, float top, float right, float bottom) : base(id) {
+            DockLeft = left;
+            DockTop = top;
+            DockRight = right;
+            DockBottom = bottom;
+        }
+
+        public float DockLeft { get; set; }
+        public float DockTop { get; set; }
+        public float DockRight { get; set; }
+        public float DockBottom { get; set; }
+
+        public IComponent? Child { get; set; }
+
+        public override void UpdatePrefSize(GameTime gameTime) {
+            if (Child != null) {
+                Child.UpdatePrefSize(gameTime);
+
+                PrefWidth = DockRight - DockLeft;
+                PrefHeight = DockBottom - DockTop;
+            }
+        }
+        public override void UpdateSetup(GameTime gameTime) {
+            X = DockLeft;
+            Y = DockTop;
+
+            if (Child != null) {
+                Child.X = X;
+                Child.Y = Y;
+                Child.Width = MathHelper.Min(Width, Child.PrefWidth);
+                Child.Height = MathHelper.Min(Height, Child.PrefHeight);
+                Child.Clip = Child.Bounds.Intersection(Clip);
+
+                Child.UpdateSetup(gameTime);
+            }
+        }
+        public override void UpdateInput(GameTime gameTime) {
+            if (Child != null) {
+                Child.UpdateInput(gameTime);
+            }
+        }
+        public override void Draw(GameTime gameTime) {
+            GuiHelper.PushScissor(Clip);
+            GuiHelper.SpriteBatch.FillRectangle(Bounds, Color.Red * 0.2f);
+            GuiHelper.SpriteBatch.DrawRectangle(Bounds, Color.Blue, 2f);
+            GuiHelper.PopScissor();
+
+            if (Child != null) {
+                Child.Draw(gameTime);
+            }
+        }
+
+        public void Add(IComponent c) {
+            if (c != Child) {
+                if (Child != null) {
+                    Child.Parent = null;
+                }
+                Child = c;
+                Child.Parent = this;
+            }
+        }
+        public void Remove(IComponent c) {
+            if (Child == c) {
+                Child.Parent = null;
+                Child = null;
+            }
+        }
+        public void Reset() { }
+        public int NextIndex() => 0;
+
+        public override IComponent GetPrev() {
+            return Parent != null ? Parent.GetPrev(this) : Child != null ? Child : this;
+        }
+        public override IComponent GetNext() {
+            return Child != null ? Child : Parent != null ? Parent.GetNext(this) : this;
+        }
+        public virtual IComponent GetPrev(IComponent c) {
+            return this;
+        }
+        public virtual IComponent GetNext(IComponent c) {
+            return Parent != null ? Parent.GetNext(this) : this;
+        }
+
+        public virtual void SendToTop(IComponent c) {
+            Parent?.SendToTop(this);
+        }
+
+        public static new Dock Put(float left, float top, float right, float bottom, [CallerLineNumber] int id = 0, bool isAbsoluteId = false) {
+            // 1. Check if dock with id already exists.
+            //      a. If already exists. Get it.
+            //      b  If not, create it.
+            // 3. Push it on the stack.
+            // 4. Ping it.
+            id = GuiHelper.CurrentIMGUI.CreateId(id, isAbsoluteId);
+            GuiHelper.CurrentIMGUI.TryGetValue(id, out IComponent c);
+
+            Dock a;
+            if (c is Dock) {
+                a = (Dock)c;
+                a.DockLeft = left;
+                a.DockTop = top;
+                a.DockRight = right;
+                a.DockBottom = bottom;
+            } else {
+                a = new Dock(id, left, top, right, bottom);
+            }
+
+            IParent parent = GuiHelper.CurrentIMGUI.GrabParent(a);
+
+            if (a.LastPing != InputHelper.CurrentFrame) {
+                a.LastPing = InputHelper.CurrentFrame;
+                a.Index = parent.NextIndex();
+            }
+
+            GuiHelper.CurrentIMGUI.Push(a, 1);
+
+            return a;
+        }
+    }
+}

+ 4 - 4
Source/Horizontal.cs

@@ -61,8 +61,8 @@ namespace Apos.Gui {
         public override void UpdateSetup(GameTime gameTime) {
             // TODO: Keep current focus in view if it's in view?
 
-            if (_offsetXTween.B != ClampOffsetY(_offsetXTween.B)) {
-                SetOffset(_offsetXTween, ClampOffsetY(_offsetXTween.B));
+            if (_offsetXTween.B != ClampOffsetX(_offsetXTween.B)) {
+                SetOffset(_offsetXTween, ClampOffsetX(_offsetXTween.B));
             }
 
             _offsetX = _offsetXTween.Value;
@@ -76,9 +76,9 @@ namespace Apos.Gui {
                 c.X = currentX + X + OffsetX;
                 c.Y = Y + OffsetY;
                 c.Width = c.PrefWidth;
-                c.Height = c.PrefHeight;
+                c.Height = MathHelper.Min(c.PrefHeight, Height);
 
-                maxHeight = MathHelper.Max(c.PrefHeight, maxHeight);
+                maxHeight = MathHelper.Max(c.Height, maxHeight);
                 c.Clip = c.Bounds.Intersection(Clip);
 
                 c.UpdateSetup(gameTime);

+ 2 - 2
Source/Vertical.cs

@@ -75,10 +75,10 @@ namespace Apos.Gui {
             foreach (var c in _children) {
                 c.X = X + OffsetX;
                 c.Y = currentY + Y + OffsetY;
-                c.Width = c.PrefWidth;
+                c.Width = MathHelper.Min(c.PrefWidth, Width);
                 c.Height = c.PrefHeight;
 
-                maxWidth = MathHelper.Max(c.PrefWidth, maxWidth);
+                maxWidth = MathHelper.Max(c.Width, maxWidth);
                 c.Clip = c.Bounds.Intersection(Clip);
 
                 c.UpdateSetup(gameTime);