litong 发表于 2024-1-10 23:36:39

一个简单的UI库

源代码 UITest.zip(22.22 KB, 下载次数: 29)2022-5-4 03:27 上传
点击文件名下载附件





代码summary:

namespace UI
{
    abstract class Element
    {
      public int X, Y, DX, DY;
      public CachedVar<int> FullX, FullY;
      public CachedVar<int> MouseX, MouseY;
      public CachedVar<bool> MouseInside, MouseInsideTmp;
      public bool Visible, Enabled;
      public CachedVar<bool> TrueVisible, TrueEnabled;

      public Element Parent; // controls
      public List<Element> Children = new List<Element>(); // forms

      public CachedVar<bool> OnMouseButtonDown, OnMouseButtonUp, OnMouseButtonDownTmp;

      public Element(int x, int y, int dx, int dy)
      {
            X = x;
            Y = y;
            DX = dx;
            DY = dy;

            FullX = new CachedVar<int>(() => Parent == null ? X : Parent.X + X);
            FullY = new CachedVar<int>(() => Parent == null ? Y : Parent.Y + Y);

            MouseX = new CachedVar<int>(() => Core.TheCore.MouseX - (Parent == null ? 0 : Parent.X) - X);
            MouseY = new CachedVar<int>(() => Core.TheCore.MouseY - (Parent == null ? 0 : Parent.Y) - Y);

            MouseInside = new CachedVar<bool>(() =>
                {
                  if (MouseX.v() < 0 || MouseX.v() >= DX || MouseY.v() < 0 || MouseY.v() >= DY
                        || (!TrueVisible.v()))
                        return false;
                  // truely visible:
                  if (Parent == null) // a form
                  {
                        for (int i = Core.TheCore.Root.Count - 1; i >= 0; i--)
                        {
                            Element e = Core.TheCore.Root<i>;
                            if (e == this)
                              break;
                            else
                              if (e.MouseX.v() >= 0 && e.MouseX.v() < e.DX && e.MouseY.v() >= 0 && e.MouseY.v() < e.DY
                                    && e.TrueVisible.v())
                                    return false;
                        }
                        for (int i = Children.Count - 1; i >= 0; i--)
                        {
                            Element e = Children<i>;
                            if (e.MouseX.v() >= 0 && e.MouseX.v() < e.DX && e.MouseY.v() >= 0 && e.MouseY.v() < e.DY
                              && e.TrueVisible.v())
                              return false;
                        }
                        return MouseX.v() >= 0 && MouseX.v() < DX && MouseY.v() >= 0 && MouseY.v() < DY;
                  }
                  else // a control
                  {
                        for (int i = Core.TheCore.Root.Count - 1; i >= 0; i--)
                        {
                            Element e = Core.TheCore.Root<i>;
                            if (e == Parent)
                              break;
                            else
                              if (e.MouseX.v() >= 0 && e.MouseX.v() < e.DX && e.MouseY.v() >= 0 && e.MouseY.v() < e.DY
                                    && e.TrueVisible.v())
                                    return false;
                        }
                        return MouseX.v() >= 0 && MouseX.v() < DX && MouseY.v() >= 0 && MouseY.v() < DY;                        
                  }
                });

            MouseInsideTmp = new CachedVar<bool>(() =>
                {
                  if (MouseX.v() < 0 || MouseX.v() >= DX || MouseY.v() < 0 || MouseY.v() >= DY
                           || (!TrueVisible.v()))
                        return false;
                  // truely visible:
                  if (Parent == null) // a form
                  {
                        for (int i = Core.TheCore.Root.Count - 1; i >= 0; i--)
                        {
                            Element e = Core.TheCore.Root<i>;
                            if (e == this)
                              return MouseX.v() >= 0 && MouseX.v() < DX && MouseY.v() >= 0 && MouseY.v() < DY;
                            else
                              if (e.MouseX.v() >= 0 && e.MouseX.v() < e.DX && e.MouseY.v() >= 0 && e.MouseY.v() < e.DY
                                    && e.TrueVisible.v())
                                    return false;
                        }
                        return false;
                  }
                  else // a control
                        return MouseInside.v();
                });

            Visible = true;
            Enabled = true;

            TrueVisible = new CachedVar<bool>(() => (Parent == null ? true : Parent.Visible) && Visible);
            TrueEnabled = new CachedVar<bool>(() => (Parent == null ? true : Parent.Enabled) && Enabled);

            OnMouseButtonDown = new CachedVar<bool>(() => (TrueEnabled.v() && MouseInside.v()) ? Core.TheCore.MouseButtonDown : false);
            OnMouseButtonUp = new CachedVar<bool>(() => (TrueEnabled.v() && MouseInside.v()) ? Core.TheCore.MouseButtonUp : false);
            OnMouseButtonDownTmp = new CachedVar<bool>(() => (TrueEnabled.v() && MouseInsideTmp.v()) ? Core.TheCore.MouseButtonDown : false);
      }

      public abstract Element Update(); // returns a form to be bringed to the top
      public abstract void Render(Surface backSurface);
    }

    class Core
    {
      public static Core TheCore;

      public int DX, DY;

      public int MouseDX, MouseDY, MouseDZ, MouseX, MouseY;
      public bool MouseLeftButton, MouseRightButton, MouseMiddleButton;
      public bool MouseButtonDown, MouseButtonUp;

      public List<Element> Root = new List<Element>();

      public Core(int dx, int dy)
      {
            DX = dx;
            DY = dy;
      }

      public void Update()
      {
            List<Element> tmps = new List<Element>();
            foreach (Element e in Root)
            {
                Element tmp = e.Update();
                if (tmp != null)
                  tmps.Add(tmp);

                foreach (Element f in e.Children)
                  f.Update();
            }
            foreach (Element tmp in tmps)
            {
                Root.Remove(tmp);
                Root.Add(tmp);
            }
      }

      public void Render(Surface backSurface)
      {
            foreach (Element e in Root)
            {
                if (e.TrueVisible.v())
                  e.Render(backSurface);

                foreach (Element f in e.Children)
                  if (f.TrueVisible.v())
                        f.Render(backSurface);
            }
      }
    }
页: [1]
查看完整版本: 一个简单的UI库