diff --git a/DungeonShooting_Godot/src/framework/ui/grid/IUiGrid.cs b/DungeonShooting_Godot/src/framework/ui/grid/IUiGrid.cs index 0fad5c1..ed184fe 100644 --- a/DungeonShooting_Godot/src/framework/ui/grid/IUiGrid.cs +++ b/DungeonShooting_Godot/src/framework/ui/grid/IUiGrid.cs @@ -1,4 +1,4 @@ - +using Godot; /// /// Ui网格组件基础接口, 无泛型 @@ -9,19 +9,25 @@ /// 当前选中的 Cell 索引 /// int SelectIndex { get; set; } - + /// /// 设置网格组件是否可见 /// bool Visible { get; set; } - + /// /// 当前网格组件数据大小 /// int Count { get; } + + /// + /// Godot 原生网格组件 + /// + GridContainer GridContainer { get; } /// - /// 触发点击 Cell + /// 触发 Cell 的点击事件 /// + /// cell的索引 void Click(int index); } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs index 8ddb33f..bc51bd0 100644 --- a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs +++ b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs @@ -12,7 +12,7 @@ public class UiGrid : IUiGrid where TUiCellNode : IUiCellNode { public bool IsDestroyed { get; private set; } - + public int SelectIndex { get => _selectIndex; @@ -31,6 +31,7 @@ return; } } + var prevIndex = _selectIndex; _selectIndex = newIndex; @@ -55,59 +56,71 @@ /// 选中的 Cell 包含的数据 /// public TData SelectData => _selectIndex >= 0 ? _cellList[_selectIndex].Data : default; - + public bool Visible { - get => _gridContainer.Visible; - set => _gridContainer.Visible = value; + get => GridContainer.Visible; + set => GridContainer.Visible = value; } public int Count => _cellList.Count; - + + public GridContainer GridContainer { get; private set; } + //模板对象 private TUiCellNode _template; + //模板大小 private Vector2 _size = Vector2.Zero; + //cell逻辑处理类 private Type _cellType; + //当前活动的cell池 private List> _cellList = new List>(); + //当前已被回收的cell池 private Stack> _cellPool = new Stack>(); - //godot原生网格组件 - private UiGridContainer _gridContainer; + //单个cell偏移 private Vector2I _cellOffset; + //列数 private int _columns; + //是否自动扩展列数 private bool _autoColumns; + //选中的cell索引 private int _selectIndex = -1; public UiGrid(TUiCellNode template, Type cellType) { - _gridContainer = new UiGridContainer(OnReady, OnProcess); - _gridContainer.Ready += OnReady; + GridContainer = new UiGridContainer(OnReady, OnProcess); + GridContainer.Ready += OnReady; _template = template; _cellType = cellType; var uiInstance = _template.GetUiInstance(); - uiInstance.AddSibling(_gridContainer); + uiInstance.AddSibling(GridContainer); uiInstance.GetParent().RemoveChild(uiInstance); if (uiInstance is Control control) { _size = control.Size; + if (control.CustomMinimumSize == Vector2.Zero) + { + control.CustomMinimumSize = _size; + } } } /// /// 设置每个 Cell 之间的偏移量 /// - public void SetCellOffset(Vector2I offset) + public void SetCellOffset(Vector2I offset) { _cellOffset = offset; - _gridContainer.AddThemeConstantOverride("h_separation", offset.X); - _gridContainer.AddThemeConstantOverride("v_separation", offset.Y); + GridContainer.AddThemeConstantOverride("h_separation", offset.X); + GridContainer.AddThemeConstantOverride("v_separation", offset.Y); } /// @@ -124,7 +137,7 @@ public void SetColumns(int columns) { _columns = columns; - _gridContainer.Columns = columns; + GridContainer.Columns = columns; } /// @@ -132,7 +145,7 @@ /// public int GetColumns() { - return _gridContainer.Columns; + return GridContainer.Columns; } /// @@ -145,13 +158,13 @@ _autoColumns = flag; if (_autoColumns) { - _gridContainer.Resized += OnGridResized; + GridContainer.Resized += OnGridResized; OnGridResized(); } else { - _gridContainer.Columns = _columns; - _gridContainer.Resized -= OnGridResized; + GridContainer.Columns = _columns; + GridContainer.Resized -= OnGridResized; } } } @@ -169,7 +182,7 @@ /// public void SetHorizontalExpand(bool flag) { - _gridContainer.SetHorizontalExpand(flag); + SetHorizontalExpand(GridContainer, flag); } /// @@ -177,7 +190,7 @@ /// public bool GetHorizontalExpand() { - return _gridContainer.GetHorizontalExpand(); + return GetHorizontalExpand(GridContainer); } /// @@ -240,7 +253,7 @@ do { var cell = GetCellInstance(); - _gridContainer.AddChild(cell.CellNode.GetUiInstance()); + GridContainer.AddChild(cell.CellNode.GetUiInstance()); } while (array.Length > _cellList.Count); } else if (array.Length < _cellList.Count) @@ -268,7 +281,7 @@ //取消选中 SelectIndex = -1; var cell = GetCellInstance(); - _gridContainer.AddChild(cell.CellNode.GetUiInstance()); + GridContainer.AddChild(cell.CellNode.GetUiInstance()); cell.SetData(data); } @@ -287,6 +300,7 @@ /// /// 移除指定索引的 Cell /// + /// public void RemoveByIndex(int index) { if (index < 0 || index >= _cellList.Count) @@ -299,6 +313,7 @@ //取消选中 SelectIndex = -1; } + var uiCell = _cellList[index]; _cellList.RemoveAt(index); ReclaimCellInstance(uiCell); @@ -324,14 +339,14 @@ ReclaimCellInstance(uiCell); } } - + public void Click(int index) { if (index < 0 || index >= _cellList.Count) { return; } - + _cellList[index].Click(); } @@ -345,6 +360,7 @@ { return; } + //这里记录 SelectIndex 是让排序后 SelectIndex 指向的 Cell 不变 var selectIndex = SelectIndex; var selectCell = GetCell(selectIndex); @@ -354,21 +370,24 @@ { selectIndex = _cellList.FindIndex(cell => cell == selectCell); } + //先移除所有节点 for (var i = 0; i < _cellList.Count; i++) { - _gridContainer.RemoveChild(_cellList[i].CellNode.GetUiInstance()); + GridContainer.RemoveChild(_cellList[i].CellNode.GetUiInstance()); } if (selectIndex >= 0) { _selectIndex = selectIndex; } + //以新的顺序加入GridContainer for (var i = 0; i < _cellList.Count; i++) { - _gridContainer.AddChild(_cellList[i].CellNode.GetUiInstance()); + GridContainer.AddChild(_cellList[i].CellNode.GetUiInstance()); } + //刷新Index for (var i = 0; i < _cellList.Count; i++) { @@ -376,7 +395,7 @@ cell.SetIndex(i); } } - + /// /// 销毁当前网格组件 /// @@ -401,23 +420,24 @@ _cellList = null; _cellPool = null; - _gridContainer.QueueFree(); + GridContainer.QueueFree(); } - + private void OnReady() { if (_template.GetUiInstance() is Control control) { - _gridContainer.Position = control.Position; + GridContainer.Position = control.Position; } } - + private void OnProcess(float delta) { if (IsDestroyed || !_template.GetUiPanel().IsOpen) { return; } + //调用 cell 更新 var uiCells = _cellPool.ToArray(); for (var i = 0; i < uiCells.Length; i++) @@ -458,23 +478,50 @@ private void ReclaimCellInstance(UiCell cell) { cell.SetEnable(false); - _gridContainer.RemoveChild(cell.CellNode.GetUiInstance()); + GridContainer.RemoveChild(cell.CellNode.GetUiInstance()); _cellPool.Push(cell); } private void OnGridResized() { - if (_autoColumns && _gridContainer != null) + if (_autoColumns && GridContainer != null) { - var width = _gridContainer.Size.X; + var width = GridContainer.Size.X; if (width <= _size.X + _cellOffset.X) { - _gridContainer.Columns = 1; + GridContainer.Columns = 1; } else { - _gridContainer.Columns = Mathf.FloorToInt(width / (_size.X + _cellOffset.X)); + GridContainer.Columns = Mathf.FloorToInt(width / (_size.X + _cellOffset.X)); } } } + + /// + /// 设置Ui布局方式是否横向扩展, 如果为 true, 则 GridContainer 的宽度会撑满父物体 + /// + private static void SetHorizontalExpand(Control control, bool flag) + { + if (flag) + { + control.LayoutMode = 1; + control.AnchorsPreset = (int)Control.LayoutPreset.TopWide; + control.SizeFlagsHorizontal |= Control.SizeFlags.Expand; + } + else if ((control.SizeFlagsHorizontal & Control.SizeFlags.Expand) != 0) + { + control.LayoutMode = 1; + control.AnchorsPreset = (int)Control.LayoutPreset.TopLeft; + control.SizeFlagsHorizontal ^= Control.SizeFlags.Expand; + } + } + + /// + /// 获取Ui布局方式是否横向扩展 + /// + private static bool GetHorizontalExpand(Control control) + { + return (control.SizeFlagsHorizontal & Control.SizeFlags.Expand) != 0; + } } \ No newline at end of file