| DefineClass.XSizeControl = { | |
| __parents = { "XWindow" }, | |
| properties = { | |
| { category = "Visual", id = "LeftSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize03.tga" }, | |
| { category = "Visual", id = "RightSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize03.tga" }, | |
| { category = "Visual", id = "TopSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize04.tga" }, | |
| { category = "Visual", id = "BottomSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize04.tga" }, | |
| { category = "Visual", id = "TopLeftSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize02.tga" }, | |
| { category = "Visual", id = "TopRightSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize01.tga" }, | |
| { category = "Visual", id = "BottomLeftSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize01.tga" }, | |
| { category = "Visual", id = "BottomRightSizeCursor", editor = "ui_image", force_extension = ".tga", default = "CommonAssets/UI/Controls/resize02.tga" }, | |
| }, | |
| BorderWidth = 5, | |
| BorderColor = RGBA(0, 0, 0, 0), | |
| Dock = "ignore", | |
| HandleMouse = true, | |
| ZOrder = -1, | |
| size_region = false, | |
| size_cursor = false, | |
| box_at_drag_start = false, | |
| pt_at_drag_start = false, | |
| } | |
| function XSizeControl:UpdateLayout() | |
| local parent_box = self.parent.box | |
| self:SetBox(parent_box:minx(), parent_box:miny(), parent_box:sizex(), parent_box:sizey()) | |
| end | |
| function XSizeControl:PointInWindow(pt) | |
| if pt and self.window_state ~= "destroying" and self.visible then | |
| local bbox = self.box | |
| local border = self.BorderWidth | |
| if pt:InBox(bbox) then | |
| if not pt:InBox(box(bbox:minx() + border, bbox:miny() + border, bbox:maxx() - border, bbox:maxy() - border)) then | |
| return true | |
| end | |
| end | |
| end | |
| end | |
| function XSizeControl:ResolveSizeMoveRegion(pt) | |
| local border_width = self.BorderWidth | |
| local bbox = self.box | |
| if pt:InBox(sizebox(bbox:minx(), bbox:miny(), border_width, border_width)) then | |
| return "topleft", self.TopLeftSizeCursor | |
| elseif pt:InBox(sizebox(bbox:maxx() - border_width, bbox:miny(), border_width, border_width)) then | |
| return "topright", self.TopRightSizeCursor | |
| elseif pt:InBox(sizebox(bbox:maxx() - border_width, bbox:maxy() - border_width, border_width, border_width)) then | |
| return "bottomright", self.BottomRightSizeCursor | |
| elseif pt:InBox(sizebox(bbox:minx(), bbox:maxy() - border_width, border_width, border_width)) then | |
| return "bottomleft", self.BottomLeftSizeCursor | |
| else | |
| local center = self.box:Center() | |
| local diff = pt - center | |
| local x_percent = MulDivRound(diff:x(), 1000, self.box:sizex()) | |
| local y_percent = MulDivRound(diff:y(), 1000, self.box:sizey()) | |
| if abs(x_percent) < abs(y_percent) then | |
| if y_percent > 0 then | |
| return "bottom", self.BottomSizeCursor | |
| else | |
| return "top", self.TopSizeCursor | |
| end | |
| else | |
| if x_percent > 0 then | |
| return "right", self.RightSizeCursor | |
| else | |
| return "left", self.LeftSizeCursor | |
| end | |
| end | |
| end | |
| end | |
| function XSizeControl:GetMouseTarget(pt) | |
| if self.size_cursor then | |
| return self, self.size_cursor | |
| else | |
| local _, cursor_image = self:ResolveSizeMoveRegion(pt) | |
| return self, cursor_image | |
| end | |
| end | |
| function XSizeControl:OnMouseButtonDown(pt, button) | |
| if button == "L" then | |
| self.parent:SetDock("ignore") | |
| self:SetFocus() | |
| self.desktop:SetMouseCapture(self) | |
| self.box_at_drag_start = self.box | |
| self.pt_at_drag_start = pt | |
| self.size_region, self.size_cursor = self:ResolveSizeMoveRegion(pt) | |
| self:OnMousePos(pt) | |
| end | |
| end | |
| function XSizeControl:OnMouseButtonUp(pt, button) | |
| if button == "L" then | |
| self:OnMousePos(pt) | |
| self.desktop:SetMouseCapture() | |
| self.size_region = false | |
| self.size_cursor = false | |
| return "break" | |
| end | |
| end | |
| function XSizeControl:OnMousePos(pt) | |
| if self.desktop:GetMouseCapture() ~= self then return "break" end | |
| local old_box = self.box_at_drag_start | |
| local old_pt = self.pt_at_drag_start | |
| local side = self.size_region | |
| local min_width = self.parent.MinWidth | |
| local max_width = self.parent.MaxWidth | |
| local min_height = self.parent.MinHeight | |
| local max_height = self.parent.MaxHeight | |
| local diff = pt - old_pt | |
| local new_box | |
| if side == "left" then | |
| local width = Clamp(old_box:sizex() - diff:x(), min_width, max_width) | |
| new_box = box(old_box:maxx() - width, old_box:miny(), old_box:maxx(), old_box:maxy()) | |
| elseif side == "right" then | |
| local width = Clamp(old_box:sizex() + diff:x(), min_width, max_width) | |
| new_box = box(old_box:minx(), old_box:miny(), old_box:minx() + width, old_box:maxy()) | |
| elseif side == "bottom" then | |
| local height = Clamp(old_box:sizey() + diff:y(), min_height, max_height) | |
| new_box = box(old_box:minx(), old_box:miny(), old_box:maxx(), old_box:miny() + height) | |
| elseif side == "top" then | |
| local height = Clamp(old_box:sizey() - diff:y(), min_height, max_height) | |
| new_box = box(old_box:minx(), old_box:maxy() - height, old_box:maxx(), old_box:maxy()) | |
| elseif side == "topleft" then | |
| local height = Clamp(old_box:sizey() - diff:y(), min_height, max_height) | |
| local width = Clamp(old_box:sizex() - diff:x(), min_width, max_width) | |
| new_box = box(old_box:maxx() - width, old_box:maxy() - height, old_box:maxx(), old_box:maxy()) | |
| elseif side == "topright" then | |
| local height = Clamp(old_box:sizey() - diff:y(), min_height, max_height) | |
| local width = Clamp(old_box:sizex() + diff:x(), min_width, max_width) | |
| new_box = box(old_box:minx(), old_box:maxy() - height, old_box:minx() + width, old_box:maxy()) | |
| elseif side == "bottomleft" then | |
| local height = Clamp(old_box:sizey() + diff:y(), min_height, max_height) | |
| local width = Clamp(old_box:sizex() - diff:x(), min_width, max_width) | |
| new_box = box(old_box:maxx() - width, old_box:miny(), old_box:maxx(), old_box:miny() + height) | |
| elseif side == "bottomright" then | |
| local height = Clamp(old_box:sizey() + diff:y(), min_height, max_height) | |
| local width = Clamp(old_box:sizex() + diff:x(), min_width, max_width) | |
| new_box = box(old_box:minx(), old_box:miny(), old_box:minx() + width, old_box:miny() + height) | |
| end | |
| if new_box and new_box:IsValid() then | |
| self.parent:SetBox(new_box:minx(), new_box:miny(), new_box:sizex(), new_box:sizey()) | |
| end | |
| return "break" | |
| end |