-
Notifications
You must be signed in to change notification settings - Fork 70
/
theme.lua
152 lines (123 loc) · 4.41 KB
/
theme.lua
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
-- This file is part of SUIT, copyright (c) 2016 Matthias Richter
local BASE = (...):match('(.-)[^%.]+$')
local theme = {}
theme.cornerRadius = 4
theme.color = {
normal = {bg = { 0.25, 0.25, 0.25}, fg = {0.73,0.73,0.73}},
hovered = {bg = { 0.19,0.6,0.73}, fg = {1,1,1}},
active = {bg = {1,0.6, 0}, fg = {1,1,1}}
}
-- 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