File size: 6,432 Bytes
b6a38d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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