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