From 73dc62da054cbc18afc694f803ebff7fe24f4eca Mon Sep 17 00:00:00 2001 From: chai Date: Sat, 13 Nov 2021 17:29:45 +0800 Subject: * split --- .../GameLab/Editor/Window/ContainerWindow.lua | 22 +++- Data/Libraries/GameLab/Editor/Window/GUIWindow.lua | 23 ++-- .../GameLab/Editor/Window/SplitWindow.lua | 130 ++++++++++++++------- 3 files changed, 122 insertions(+), 53 deletions(-) (limited to 'Data/Libraries') diff --git a/Data/Libraries/GameLab/Editor/Window/ContainerWindow.lua b/Data/Libraries/GameLab/Editor/Window/ContainerWindow.lua index caf3b37..1e75cdc 100644 --- a/Data/Libraries/GameLab/Editor/Window/ContainerWindow.lua +++ b/Data/Libraries/GameLab/Editor/Window/ContainerWindow.lua @@ -1,10 +1,13 @@ +local Debug = require("GameLab.Debug") +local Rect = require("GameLab.Engine.Math.Rect") + local NativeContainWidow = GameLab.Editor.Window.Internal.ContainerWindow local Window = GameLab.Editor.Window local ContainerWindow = GameLab.GlobalClass("GameLab.Editor.Window.ContainerWindow") ContainerWindow.Ctor = function(self, position, showMode, min, max) - self.m_Native = NativeContainWidow.New(position, showMode, min, max) + self.m_Native = NativeContainWidow.New(self, position, showMode, min, max) self.m_RootSplitWindow = Window.SplitWindow.New(Window.ESplitMode.Horizontal) end @@ -32,4 +35,21 @@ ContainerWindow.GetHeight = function(self) return self:GetSize().y end +ContainerWindow.OnSizeChanged = function(self) + if self.m_Native == nil then + return + end + local pos = self:GetSize() + local position = Rect.New() + position.x = 0 + position.y = 0 + position.width = pos.x + position.height = pos.y + self.m_RootSplitWindow:SetPosition(position) +end + +ContainerWindow.SetRootSplitWindow = function(self, sp) + self.m_RootSplitWindow = sp +end + return ContainerWindow \ No newline at end of file diff --git a/Data/Libraries/GameLab/Editor/Window/GUIWindow.lua b/Data/Libraries/GameLab/Editor/Window/GUIWindow.lua index 6f6335b..51ee128 100644 --- a/Data/Libraries/GameLab/Editor/Window/GUIWindow.lua +++ b/Data/Libraries/GameLab/Editor/Window/GUIWindow.lua @@ -1,13 +1,13 @@ local GUIWindow = GameLab.GlobalClass("GameLab.Editor.Window.GUIWindow") local NativeGUIWindow = GameLab.Editor.Window.Internal.GUIWindow -local inspect = require("inspect") -local Debug = require("GameLab.Debug") -local GL = require("GameLab.Engine.GL") -local Math = require("GameLab.Engine.Math") -local Rendering = require("GameLab.Engine.Rendering") -local Utils = require("GameLab.Utils") -local Events = require("GameLab.Events") +local inspect = require "inspect" +local Debug = require "GameLab.Debug" +local GL = require "GameLab.Engine.GL" +local Math = require "GameLab.Engine.Math" +local Rendering = require "GameLab.Engine.Rendering" +local Utils = require "GameLab.Utils" +local Events = require "GameLab.Events" local Rect = Math.Rect local Event = Events.Event @@ -17,7 +17,8 @@ local i = 0 local col = { {1, 0, 0, 1}, {1, 1, 0, 1}, - {1, 0, 1, 1}, + {0, 0, 1, 1}, + {0, 1, 1, 1}, } GUIWindow.Ctor = function(self) @@ -42,7 +43,7 @@ end GUIWindow.SetPosition = function(self, pos) self.m_Position:Set(pos) - self.m_Native:SetPosition(pos) + self.m_Native:SetPosition({pos.x, pos.y, pos.width, pos.height}) end GUIWindow.GetPosition = function(self) @@ -58,9 +59,9 @@ GUIWindow.OnGUI = function(self) local event = Event.current - if self.m_SplitWindow then + if self.m_SplitWindow ~= nil and event ~= nil then local e = Events.CopyEvent(event) - e.mousePosition:Add(self.m_Position:GetPosition()) + e.mousePosition:Add(self.m_Position:GetPosition()) -- 坐标转换到全局containerWindow的坐标 self.m_SplitWindow:DoSplit(e) end end diff --git a/Data/Libraries/GameLab/Editor/Window/SplitWindow.lua b/Data/Libraries/GameLab/Editor/Window/SplitWindow.lua index 9dd6446..8f126a9 100644 --- a/Data/Libraries/GameLab/Editor/Window/SplitWindow.lua +++ b/Data/Libraries/GameLab/Editor/Window/SplitWindow.lua @@ -1,31 +1,38 @@ local Debug = GameLab.Debug local EEventType = GameLab.Events.EEventType -local Rect = require("GameLab.Engine.Math.Rect") -local GUI = require("GameLab.Engine.GUI") +local Math = require "GameLab.Engine.Math" +local GUI = require "GameLab.Engine.GUI" +local inspect = require "inspect" + +local Rect = Math.Rect local Splitter = GameLab.Class("GameLab.Editor.Window.Internal.Splitter") Splitter.Ctor = function(self, value) - self.size = 10 + self.size = 20 self.value = value -- [0-1] 位置 end --- 抽象的窗口,用来处理布局 -local SplitWindow = GameLab.GlobalClass("GameLab.Editor.Window.SplitWindow") - local ESplitMode = GameLab.GlobalEnum("GameLab.Editor.Window.ESplitMode", { "Horizontal", -- 水平划分 "Vertical", -- 垂直划分 }) +-- 布局状态 +local SplitState = { + currentSplitter = nil +} + +-- 抽象的窗口,用来处理布局 +local SplitWindow = GameLab.GlobalClass("GameLab.Editor.Window.SplitWindow") + SplitWindow.Ctor = function(self, mode, splitter) + self.m_ContainerWindow = nil self.m_SplitMode = mode self.m_Parent = nil -- 父节点是一个split window或者空 - self.m_SubSplit = {} -- 子节点也是split windows - self.m_GUIWindow = {} -- 不包含subSplit的有一个GUIWindow + self.m_SubWindows = {} -- 子窗口,可以是SplitWindow或GUIWindow self.m_Splitter = {} - self.m_CurSplitter = nil - self.m_ContainerWindow = nil + self.m_Position = Rect.New() if splitter ~= nil and type(splitter) == "table" then for _, v in ipairs(splitter) do local sp = Splitter.New(v) @@ -43,50 +50,86 @@ SplitWindow.DoSplit = function(self, event) local id = GUI.GetControlID() if event.type == EEventType.MouseDown then - + local bHandled = false + for i, sp in ipairs(self.m_Splitter) do + local rect = Rect.New() + if self.m_SplitMode == ESplitMode.Horizontal then + local x = sp.value * self.m_Position.width + self.m_Position.x - sp.size / 2 + local w = sp.size + rect.x = x + rect.y = self.m_Position.y + rect.width = w + rect.height = self.m_Position.height + else + local y = sp.value * self.m_Position.height + self.m_Position.y - sp.size / 2 + local h = sp.size + rect.x = self.m_Position.x + rect.y = y + rect.width = self.m_Position.width + rect.height = h + end + if rect:Contains(event.mousePosition) then + SplitState.currentSplitter = sp + GUI.SetHotControl(id) + bHandled = true + break + end + end elseif event.type == EEventType.MouseDrag then - + local hot = GUI.GetHotControl() + if hot == id then + local splitter = SplitState.currentSplitter + if splitter ~= nil then + local mousePos = event.mousePosition + mousePos.x = mousePos.x - self.m_Position.x + mousePos.y = mousePos.y - self.m_Position.y + if self.m_SplitMode == ESplitMode.Horizontal then + splitter.value = mousePos.x / self.m_Position.width + else + splitter.value = mousePos.y / self.m_Position.height + end + splitter.value = Math.Clamp(splitter.value, 0, 1) + self:SetPosition(self.m_Position) + end + end elseif event.type == EEventType.MouseUp then - + if GUI.GetHotControl() == id then + SplitState.currentSplitter = nil + end end end --- 返回在containerWindow下的像素大小和位置 -SplitWindow.GetPosition = function(self) - local position = Rect.New() - local parent = self.GetParent - if parent == nil then --最顶层的split window - position.x = 0 - position.y = 0 - position.width = self.m_ContainerWindow:GetWidth() - position.height = self.m_ContainerWindow:GetHeight() - return position - end - local parentPos = parent:GetPosition() - local index = self:GetIndexOfParent() - -- 前后的splitter - local prev = index > 1 and parent.m_Splitter[index - 1] or nil - local next = index <= #parent.m_Splitter and parent.m_Splitter[index] or nil - local offset = prev ~= nil and prev.value or 0 - local pv = offset - local nv = next ~= nil and next.value or 1 - local size = nv - pv - position:CopyFrom(parentPos) - if parent.m_SplitMode == ESplitMode.Horizontal then - position.x = position.x + offset - position.width = position.width * size - else - position.y = position.y + offset - position.height = position.height * size +-- 设置在containerwindow中的位置和大小 +SplitWindow.SetPosition = function(self, position) + self.m_Position:CopyFrom(position) + for i, subWindow in ipairs(self.m_SubWindows) do + local prev = i > 1 and self.m_Splitter[i-1].value or 0 + local next = i <= #self.m_Splitter and self.m_Splitter[i].value or 1 + local pos = Rect.New() + pos:CopyFrom(position) + if self.m_SplitMode == ESplitMode.Horizontal then + pos.x = pos.x + prev * position.width + pos.width = position.width * (next - prev) + else + pos.y = pos.y + prev * position.height + pos.height = position.height * (next - prev) + end + subWindow:SetPosition(pos) end end +SplitWindow.GetPosition = function(self) + local pos = Rect.New() + pos:CopyFrom(self.m_Position) + return pos +end + -- 返回guiWnd SplitWindow.GetIndexOfParent = function(self) if self.m_Parent == nil then return 1 end - for i, sp in ipairs(self.m_Parent.m_SubSplit) do + for i, sp in ipairs(self.m_Parent.m_SubWindows) do if sp == self then return i end @@ -97,4 +140,9 @@ SplitWindow.GetParent = function(self) return self.m_Parent end +SplitWindow.AddSubWindow = function(self, subWindow) + table.insert(self.m_SubWindows, subWindow) + subWindow.m_Parent = self +end + return SplitWindow \ No newline at end of file -- cgit v1.1-26-g67d0