1guielement = class:new()
2
3function guielement:init(...)
4	local arg = {...}
5	self.active = true
6	self.priority = false
7	if arg[1] == "checkbox" then --checkbox(x, y, func, start)
8		self.type = arg[1]
9		self.x = arg[2]
10		self.y = arg[3]
11		self.func = arg[4]
12		if arg[5] or arg[5] == false then
13			self.var = arg[5]
14		else
15			self.var = true
16		end
17	elseif arg[1] == "dropdown" then --dropdown(x, y, width (in chars), func, start, {entries})
18		self.type = arg[1]
19		self.x = arg[2]
20		self.y = arg[3]
21		self.width = arg[4]
22		self.func = arg[5]
23		self.var = arg[6] or 1
24		self.entries = {}
25		for i = 7, #arg do
26			table.insert(self.entries, arg[i])
27		end
28		self.extended = false
29	elseif arg[1] == "rightclick" then --rightclick(x, y, width (in chars), func, start, {entries})
30		self.type = arg[1]
31		self.x = arg[2]
32		self.y = arg[3]
33		self.width = arg[4]
34		self.func = arg[5]
35		self.var = arg[6] or nil
36		self.entries = {}
37		for i = 7, #arg do
38			table.insert(self.entries, arg[i])
39		end
40		self.priority = true
41
42		if self.y > 112 then
43			self.direction = "up"
44		else
45			self.direction = "down"
46		end
47	elseif arg[1] == "button" then --button(x, y, text, func, space, arguments (in a table), height (in lines))
48		self.type = arg[1]
49		self.x = arg[2]
50		self.y = arg[3]
51		self.text = arg[4]
52		self.func = arg[5]
53		self.space = arg[6]
54		if type(arg[7]) ~= "table" then
55			self.arguments = {}
56		else
57			self.arguments = arg[7]
58		end
59		self.height = arg[8] or 1
60		self.width = arg[9] or string.len(self.text)*8
61
62		self.bordercolorhigh = {255, 255, 255}
63		self.bordercolor = {127, 127, 127}
64
65		self.fillcolor = {0, 0, 0}
66		self.textcolor = {255, 255, 255}
67	elseif arg[1] == "scrollbar" then --scrollbar(x, y, yrange, width, height, start)
68		self.type = arg[1]
69		self.x = arg[2]
70		self.y = arg[3]
71		self.range = arg[4]
72		self.width = arg[5]
73		self.height = arg[6]
74		self.value = arg[7] or 0
75		self.dir = arg[8] or "ver"
76
77		if self.dir == "ver" then
78			self.yrange = self.range - self.height
79		else
80			self.xrange = self.range - self.width
81		end
82
83		self.backgroundcolor = {127, 127, 127}
84		self.bordercolorhigh = {255, 255, 255}
85		self.bordercolor = {127, 127, 127}
86
87		self.fillcolor = {0, 0, 0}
88	elseif arg[1] == "input" then --input(x, y, width, enterfunc, start, maxlength)
89		self.type = arg[1]
90		self.x = arg[2]
91		self.y = arg[3]
92		self.width = arg[4]
93		self.func = arg[5]
94		self.value = arg[6] or ""
95		self.maxlength = arg[7] or 0
96		self.height = arg[8] or 1
97
98		self.timer = 0
99		self.cursorblink = true
100		self.inputting = false
101		self.cursorpos = string.len(self.value)+1
102		self.offset = 0
103
104		self.bordercolorhigh = {255, 255, 255}
105		self.bordercolor = {127, 127, 127}
106
107		self.fillcolor = {0, 0, 0}
108		self.textcolor = {255, 255, 255}
109	end
110end
111
112function guielement:update(dt)
113	if self.active then
114		if self.type == "scrollbar" then
115			if self.dragging then
116				if self.dir == "ver" then
117					local y = (love.mouse.getY()-self.draggingy) - self.y*scale
118					local actualyrange = self.yrange*scale
119
120					self.value = y / actualyrange
121					self.value = math.min(math.max(self.value, 0), 1) --clamp
122				else
123					local x = (love.mouse.getX()-self.draggingx) - self.x*scale
124					local actualxrange = self.xrange*scale
125
126					self.value = x / actualxrange
127					self.value = math.min(math.max(self.value, 0), 1) --clamp
128				end
129			end
130		elseif self.type == "input" then
131			self.timer = self.timer + dt
132			while self.timer > blinktime do
133				self.cursorblink = not self.cursorblink
134				self.timer = self.timer - blinktime
135			end
136		end
137	end
138end
139
140function guielement:draw()
141	love.graphics.setColor(255, 255, 255)
142	if self.type == "checkbox" then
143		local quad = 1
144		if self.var == true then
145			quad = 2
146		end
147		local high = 1
148		if self:inhighlight(love.mouse.getPosition()) then
149			high = 2
150		end
151
152		love.graphics.drawq(checkboximg, checkboxquad[high][quad], self.x*scale, self.y*scale, 0, scale, scale)
153	elseif self.type == "dropdown" then
154		local high = self:inhighlight(love.mouse.getPosition())
155
156		love.graphics.setColor(127, 127, 127)
157		if high then
158			love.graphics.setColor(255, 255, 255)
159		end
160
161		love.graphics.rectangle("fill", self.x*scale, self.y*scale, (3+self.width*8)*scale, 11*scale)
162		love.graphics.draw(dropdownarrowimg, (self.x+2+self.width*8)*scale, self.y*scale, 0, scale, scale)
163
164		love.graphics.setColor(0, 0, 0)
165		love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1)*scale, (1+self.width*8)*scale, 9*scale)
166
167		love.graphics.setColor(255, 255, 255)
168		if self.extended then
169			love.graphics.setColor(127, 127, 127)
170		end
171
172		properprint(self.entries[self.var], (self.x+1)*scale, (self.y+2)*scale)
173
174		if self.extended then
175			love.graphics.setColor(127, 127, 127)
176			if high then
177				love.graphics.setColor(255, 255, 255)
178			end
179
180			love.graphics.rectangle("fill", self.x*scale, (self.y+11)*scale, (13+self.width*8)*scale, (10*#self.entries)*scale)
181
182			for i = 1, #self.entries do
183				if high ~= i then
184					love.graphics.setColor(0, 0, 0)
185					love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1+i*10)*scale, (11+self.width*8)*scale, 9*scale)
186					love.graphics.setColor(255, 255, 255)
187					properprint(self.entries[i], (self.x+1)*scale, (self.y+2+10*i)*scale)
188				else
189					love.graphics.setColor(0, 0, 0)
190					properprint(self.entries[i], (self.x+1)*scale, (self.y+2+10*i)*scale)
191				end
192			end
193
194		end
195	elseif self.type == "rightclick" then
196		local high = self:inhighlight(love.mouse.getPosition())
197
198		love.graphics.setColor(255, 255, 255)
199
200		love.graphics.rectangle("fill", self.x*scale, self.y*scale, (3+self.width*8)*scale, 11*scale)
201
202		love.graphics.setColor(0, 0, 0)
203		love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1)*scale, (1+self.width*8)*scale, 9*scale)
204
205		love.graphics.setColor(255, 255, 255)
206
207		properprint(self.entries[1], (self.x+1)*scale, (self.y+2)*scale)
208
209		love.graphics.setColor(127, 127, 127)
210		if high then
211			love.graphics.setColor(255, 255, 255)
212		end
213
214		if self.direction == "down" then
215			love.graphics.rectangle("fill", self.x*scale, (self.y+11)*scale, (3+self.width*8)*scale, (10*(#self.entries-1))*scale)
216		else
217			love.graphics.rectangle("fill", self.x*scale, (self.y+10-(#self.entries)*10)*scale, (3+self.width*8)*scale, (10*(#self.entries-1))*scale)
218		end
219
220		for i = 2, #self.entries do
221			if high ~= i then
222				if self.var == self.entries[i] then
223					love.graphics.setColor(0, 127, 0)
224				else
225					love.graphics.setColor(0, 0, 0)
226				end
227				if self.direction == "down" then
228					love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1+(i-1)*10)*scale, (1+self.width*8)*scale, 9*scale)
229					love.graphics.setColor(255, 255, 255)
230					properprint(self.entries[i], (self.x+1)*scale, (self.y+2+10*(i-1))*scale)
231				else
232					love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1-(i-1)*10)*scale, (1+self.width*8)*scale, 9*scale)
233					love.graphics.setColor(255, 255, 255)
234					properprint(self.entries[i], (self.x+1)*scale, (self.y+2-10*(i-1))*scale)
235				end
236			else
237				if self.var == self.entries[i] then
238					love.graphics.setColor(0, 127, 0)
239				else
240					love.graphics.setColor(0, 0, 0)
241				end
242
243				if self.direction == "down" then
244					properprint(self.entries[i], (self.x+1)*scale, (self.y+2+10*(i-1))*scale)
245				else
246					properprint(self.entries[i], (self.x+1)*scale, (self.y+2-10*(i-1))*scale)
247				end
248			end
249		end
250
251	elseif self.type == "button" then
252		local high = self:inhighlight(love.mouse.getPosition())
253
254		love.graphics.setColor(self.bordercolor)
255		if high then
256			love.graphics.setColor(self.bordercolorhigh)
257		end
258
259		love.graphics.rectangle("fill", self.x*scale, self.y*scale, (3+self.width+self.space*2)*scale, (1+self.height*10+self.space*2)*scale)
260
261		love.graphics.setColor(self.fillcolor)
262		love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1)*scale, (1+self.width+self.space*2)*scale, (-1+self.height*10+self.space*2)*scale)
263
264		love.graphics.setColor(self.textcolor)
265		properprint(self.text, (self.x+1+self.space)*scale, (self.y+2+self.space)*scale)
266
267	elseif self.type == "scrollbar" then
268		if self.dir == "ver" then
269			local high = self:inhighlight(love.mouse.getPosition())
270
271			love.graphics.setColor(self.backgroundcolor)
272			love.graphics.rectangle("fill", self.x*scale, self.y*scale, self.width*scale, (self.yrange+self.height)*scale)
273
274			love.graphics.setColor(self.bordercolor)
275			if self.dragging or high then
276				love.graphics.setColor(self.bordercolorhigh)
277			end
278
279			love.graphics.rectangle("fill", self.x*scale, (self.y+self.yrange*self.value)*scale, (self.width)*scale, (self.height)*scale)
280
281			love.graphics.setColor(self.fillcolor)
282			love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1+self.yrange*self.value)*scale, (self.width-2)*scale, (self.height-2)*scale)
283		else
284			local high = self:inhighlight(love.mouse.getPosition())
285
286			love.graphics.setColor(self.backgroundcolor)
287			love.graphics.rectangle("fill", self.x*scale, self.y*scale, (self.xrange+self.width)*scale, self.height*scale)
288
289			love.graphics.setColor(self.bordercolor)
290			if self.dragging or high then
291				love.graphics.setColor(self.bordercolorhigh)
292			end
293
294			love.graphics.rectangle("fill", (self.x+self.xrange*self.value)*scale, self.y*scale, (self.width)*scale, (self.height)*scale)
295
296			love.graphics.setColor(self.fillcolor)
297			love.graphics.rectangle("fill", (self.x+1+self.xrange*self.value)*scale, (self.y+1)*scale, (self.width-2)*scale, (self.height-2)*scale)
298		end
299	elseif self.type == "input" then
300		local high = self:inhighlight(love.mouse.getPosition())
301
302		love.graphics.setColor(self.bordercolor)
303		if self.inputting or high then
304			love.graphics.setColor(self.bordercolorhigh)
305		end
306
307		love.graphics.rectangle("fill", self.x*scale, self.y*scale, (3+self.width*8+2)*scale, (1+self.height*10+2)*scale)
308
309		love.graphics.setColor(self.fillcolor)
310		love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1)*scale, (1+self.width*8+2)*scale, (-1+self.height*10+2)*scale)
311
312		love.graphics.setColor(self.textcolor)
313		--format string
314		local oldstring = self.value--string.sub(self.value, self.offset+1, self.offset+self.width)
315		local newstring = {}
316		for i = 1, string.len(oldstring), self.width do
317			if math.ceil(i/self.width) > self.height then
318				break
319			end
320			table.insert(newstring, string.sub(oldstring, i, i+self.width-1))
321		end
322
323		for i = 1, #newstring do
324			properprint(newstring[i], (self.x+2)*scale, (self.y+2+1+(i-1)*10)*scale)
325		end
326
327		--cursor
328		if self.height == 1 then
329			if self.inputting and self.cursorblink then
330				love.graphics.rectangle("fill", (self.x+2+(self.cursorpos-1-self.offset)*8)*scale, (self.y+10)*scale, 8*scale, 1*scale)
331			end
332		end
333	end
334	love.graphics.setColor(255, 255, 255)
335end
336
337function guielement:click(x, y, button)
338	if self.active then
339		if self.type == "checkbox" then
340			if self:inhighlight(x, y) then
341				self.func()
342			end
343		elseif self.type == "dropdown" then
344			if self.extended == false then
345				if self:inhighlight(x, y) then
346					self.extended = true
347					self.priority = true
348				end
349			else
350				local high = self:inhighlight(x, y)
351				self.extended = false
352				self.priority = false
353
354				if high then
355					if high ~= 0 then
356						self.func(high)
357					end
358					return true
359				end
360			end
361		elseif self.type == "rightclick" then
362			local high = self:inhighlight(x, y)
363
364			if high then
365				if high ~= 0 then
366					self.func(high)
367				end
368				return true
369			end
370		elseif self.type == "button" then
371			if self:inhighlight(x, y) and self.func then
372				self.func(unpack(self.arguments))
373			end
374		elseif self.type == "scrollbar" then
375			if self.dir == "ver" then
376				if self:inhighlight(x, y) then
377					self.dragging = true
378					self.draggingy = y-(self.y+self.yrange*self.value)*scale
379				end
380			else
381				if self:inhighlight(x, y) then
382					self.dragging = true
383					self.draggingx = x-(self.x+self.xrange*self.value)*scale
384				end
385			end
386			if button == "wd" then
387				self.value = math.min(1, self.value+0.2)
388			elseif button == "wu" then
389				self.value = math.max(0, self.value-0.2)
390			end
391		elseif self.type == "input" then
392			if self:inhighlight(x, y) then
393				self.inputting = true
394				self.timer = 0
395				self.cursorblink = true
396			else
397				self.inputting = false
398			end
399		end
400	end
401end
402
403function guielement:keypress(key)
404	if self.active then
405		if self.type == "input" then
406			if self.inputting then
407				if key == "-" or key == "," or key == ":" or key == ";" then
408					return
409				end
410				if key == "escape" then
411					self.inputting = false
412				elseif (key == "return" or key == "enter" or key == "kpenter") then
413					if self.func then
414						self:func()
415					else
416						self.inputting = false
417					end
418				elseif key == "backspace" then
419					self.value = string.sub(self.value, 1, string.len(self.value)-1)
420					if self.cursorpos > 1 and self.cursorpos > string.len(self.value)+1 then
421						self.cursorpos = self.cursorpos - 1
422					end
423					if self.offset > 0 and self.offset > string.len(self.value)-self.width then
424						self.offset = self.offset - 1
425					end
426				else
427					if string.len(self.value) < self.maxlength or self.maxlength == 0 then
428						local found = false
429						for i = 1, string.len(fontglyphs) do
430							if key == string.sub(fontglyphs, i, i) then
431								found = true
432								break
433							end
434						end
435
436						if found then
437							self.value = self.value .. key
438							if self.cursorpos ~= self.maxlength then
439								self.cursorpos = self.cursorpos + 1
440							end
441							if self.cursorpos > self.offset+self.width then
442								self.offset = self.offset + 1
443							end
444						end
445					end
446				end
447
448				return true
449			end
450		end
451	end
452end
453
454function guielement:unclick(x, y)
455	if self.active then
456		if self.type == "scrollbar" then
457			self.dragging = false
458		end
459	end
460end
461
462function guielement:inhighlight(x, y)
463	if self.type == "checkbox" then
464		if x >= self.x*scale and x < (self.x+9)*scale and y >= self.y*scale and y < (self.y+9)*scale then
465			return true
466		end
467	elseif self.type == "dropdown" then
468		if self.extended == false then
469			if x >= self.x*scale and x < (self.x+13+self.width*8)*scale and y >= self.y*scale and y < (self.y+11)*scale then
470				return true
471			end
472		else
473			if x >= self.x*scale and x < (self.x+13+self.width*8)*scale and y >= self.y*scale and y < (self.y+10*#self.entries+11)*scale then
474				--get which entry
475				return math.max(0, math.floor((y-(self.y+1)*scale) / (10*scale)))
476			end
477		end
478	elseif self.type == "rightclick" then
479		if self.direction == "down" then
480			if x >= self.x*scale and x < (self.x+3+self.width*8)*scale and y >= self.y*scale and y < (self.y+10*#self.entries+1)*scale then
481				--get which entry
482				return math.max(0, math.floor((y-(self.y+1)*scale) / (10*scale))+1)
483			end
484		else
485			if x >= self.x*scale and x < (self.x+3+self.width*8)*scale and y >= (self.y-10*(#self.entries-1))*scale and y < (self.y+11)*scale then
486				--get which entry
487				return math.max(0, math.floor((self.y*scale-y) / (10*scale))+2)
488			end
489		end
490	elseif self.type == "button" then
491		if x >= self.x*scale and x < (self.x+3+self.width+self.space*2)*scale and y >= self.y*scale and y < (self.y+1+self.height*10+self.space*2)*scale then
492			return true
493		end
494	elseif self.type == "scrollbar" then
495		if self.dir == "ver" then
496			if x >= self.x*scale and x < (self.x+self.width)*scale and y >= (self.y+self.yrange*self.value)*scale and y < (self.height+self.y+self.yrange*self.value)*scale then
497				return true
498			end
499		else
500			if x >= (self.x+self.xrange*self.value)*scale and x < (self.x+self.width+self.xrange*self.value)*scale and y >= self.y*scale and y < (self.height+self.y)*scale then
501				return true
502			end
503		end
504	elseif self.type == "input" then
505		if x >= self.x*scale and x < (self.x+3+self.width*8+2)*scale and y >= self.y*scale and y < (self.y+1+self.height*10+2)*scale then
506			return true
507		end
508	end
509
510	return false
511end