myspace / CommonLua /X /XSizeControl.lua
sirnii's picture
Upload 1816 files
b6a38d7 verified
raw
history blame
6.43 kB
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