-- In Love 11.0, they updated `love.graphics.setColor` to be in a range from 0 to 1, rather than 0 to 255: https://love2d.org/wiki/love.graphics.setColor. As a result, the current SUIT default theme prints all white for all text input fields. The fix is to divide all of our current color settings by 255 if the major version is 11 or greater, and do nothing otherwise.
163 lines
4.7 KiB
Lua
163 lines
4.7 KiB
Lua
-- This file is part of SUIT, copyright (c) 2016 Matthias Richter
|
|
|
|
local BASE = (...):match('(.-)[^%.]+$')
|
|
|
|
local love = require 'love'
|
|
local theme = {}
|
|
theme.cornerRadius = 4
|
|
|
|
local divisor = love.getVersion() < 11 and 1 or 255
|
|
theme.color = {
|
|
normal = {
|
|
bg = { 66 / divisor, 66 / divisor, 66 / divisor},
|
|
fg = {188 / divisor, 188 / divisor, 188 / divisor}
|
|
},
|
|
hovered = {
|
|
bg = { 50 / divisor, 153 / divisor, 187 / divisor},
|
|
fg = {255 / divisor, 255 / divisor, 255 / divisor}
|
|
},
|
|
active = {
|
|
bg = {255 / divisor, 153 / divisor, 0 / divisor},
|
|
fg = {225 / divisor, 225 / divisor, 225 / divisor}
|
|
}
|
|
}
|
|
|
|
|
|
-- HELPER
|
|
function theme.getColorForState(opt)
|
|
local s = opt.state or "normal"
|
|
return (opt.color and opt.color[opt.state]) or theme.color[s]
|
|
end
|
|
|
|
function theme.drawBox(x,y,w,h, colors, cornerRadius)
|
|
colors = colors or theme.getColorForState(opt)
|
|
cornerRadius = cornerRadius or theme.cornerRadius
|
|
w = math.max(cornerRadius/2, w)
|
|
if h < cornerRadius/2 then
|
|
y,h = y - (cornerRadius - h), cornerRadius/2
|
|
end
|
|
|
|
love.graphics.setColor(colors.bg)
|
|
love.graphics.rectangle('fill', x,y, w,h, cornerRadius)
|
|
end
|
|
|
|
function theme.getVerticalOffsetForAlign(valign, font, h)
|
|
if valign == "top" then
|
|
return 0
|
|
elseif valign == "bottom" then
|
|
return h - font:getHeight()
|
|
end
|
|
-- else: "middle"
|
|
return (h - font:getHeight()) / 2
|
|
end
|
|
|
|
-- WIDGET VIEWS
|
|
function theme.Label(text, opt, x,y,w,h)
|
|
y = y + theme.getVerticalOffsetForAlign(opt.valign, opt.font, h)
|
|
|
|
love.graphics.setColor((opt.color and opt.color.normal or {}).fg or theme.color.normal.fg)
|
|
love.graphics.setFont(opt.font)
|
|
love.graphics.printf(text, x+2, y, w-4, opt.align or "center")
|
|
end
|
|
|
|
function theme.Button(text, opt, x,y,w,h)
|
|
local c = theme.getColorForState(opt)
|
|
|
|
theme.drawBox(x,y,w,h, c, opt.cornerRadius)
|
|
love.graphics.setColor(c.fg)
|
|
love.graphics.setFont(opt.font)
|
|
|
|
y = y + theme.getVerticalOffsetForAlign(opt.valign, opt.font, h)
|
|
love.graphics.printf(text, x+2, y, w-4, opt.align or "center")
|
|
end
|
|
|
|
function theme.Checkbox(chk, opt, x,y,w,h)
|
|
local c = theme.getColorForState(opt)
|
|
local th = opt.font:getHeight()
|
|
|
|
theme.drawBox(x+h/10,y+h/10,h*.8,h*.8, c, opt.cornerRadius)
|
|
love.graphics.setColor(c.fg)
|
|
if chk.checked then
|
|
love.graphics.setLineStyle('smooth')
|
|
love.graphics.setLineWidth(5)
|
|
love.graphics.setLineJoin("bevel")
|
|
love.graphics.line(x+h*.2,y+h*.55, x+h*.45,y+h*.75, x+h*.8,y+h*.2)
|
|
end
|
|
|
|
if chk.text then
|
|
love.graphics.setFont(opt.font)
|
|
y = y + theme.getVerticalOffsetForAlign(opt.valign, opt.font, h)
|
|
love.graphics.printf(chk.text, x + h, y, w - h, opt.align or "left")
|
|
end
|
|
end
|
|
|
|
function theme.Slider(fraction, opt, x,y,w,h)
|
|
local xb, yb, wb, hb -- size of the progress bar
|
|
local r = math.min(w,h) / 2.1
|
|
if opt.vertical then
|
|
x, w = x + w*.25, w*.5
|
|
xb, yb, wb, hb = x, y+h*(1-fraction), w, h*fraction
|
|
else
|
|
y, h = y + h*.25, h*.5
|
|
xb, yb, wb, hb = x,y, w*fraction, h
|
|
end
|
|
|
|
local c = theme.getColorForState(opt)
|
|
theme.drawBox(x,y,w,h, c, opt.cornerRadius)
|
|
theme.drawBox(xb,yb,wb,hb, {bg=c.fg}, opt.cornerRadius)
|
|
|
|
if opt.state ~= nil and opt.state ~= "normal" then
|
|
love.graphics.setColor((opt.color and opt.color.active or {}).fg or theme.color.active.fg)
|
|
if opt.vertical then
|
|
love.graphics.circle('fill', x+wb/2, yb, r)
|
|
else
|
|
love.graphics.circle('fill', x+wb, yb+hb/2, r)
|
|
end
|
|
end
|
|
end
|
|
|
|
function theme.Input(input, opt, x,y,w,h)
|
|
local utf8 = require 'utf8'
|
|
theme.drawBox(x,y,w,h, (opt.color and opt.color.normal) or theme.color.normal, opt.cornerRadius)
|
|
x = x + 3
|
|
w = w - 6
|
|
|
|
local th = opt.font:getHeight()
|
|
|
|
-- set scissors
|
|
local sx, sy, sw, sh = love.graphics.getScissor()
|
|
love.graphics.setScissor(x-1,y,w+2,h)
|
|
x = x - input.text_draw_offset
|
|
|
|
-- text
|
|
love.graphics.setColor((opt.color and opt.color.normal and opt.color.normal.fg) or theme.color.normal.fg)
|
|
love.graphics.setFont(opt.font)
|
|
love.graphics.print(input.text, x, y+(h-th)/2)
|
|
|
|
-- candidate text
|
|
local tw = opt.font:getWidth(input.text)
|
|
local ctw = opt.font:getWidth(input.candidate_text.text)
|
|
love.graphics.setColor((opt.color and opt.color.normal and opt.color.normal.fg) or theme.color.normal.fg)
|
|
love.graphics.print(input.candidate_text.text, x + tw, y+(h-th)/2)
|
|
|
|
-- candidate text rectangle box
|
|
love.graphics.rectangle("line", x + tw, y+(h-th)/2, ctw, th)
|
|
|
|
-- cursor
|
|
if opt.hasKeyboardFocus and (love.timer.getTime() % 1) > .5 then
|
|
local ct = input.candidate_text;
|
|
local ss = ct.text:sub(1, utf8.offset(ct.text, ct.start))
|
|
local ws = opt.font:getWidth(ss)
|
|
if ct.start == 0 then ws = 0 end
|
|
|
|
love.graphics.setLineWidth(1)
|
|
love.graphics.setLineStyle('rough')
|
|
love.graphics.line(x + opt.cursor_pos + ws, y + (h-th)/2,
|
|
x + opt.cursor_pos + ws, y + (h+th)/2)
|
|
end
|
|
|
|
-- reset scissor
|
|
love.graphics.setScissor(sx,sy,sw,sh)
|
|
end
|
|
|
|
return theme
|