-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathtext_box.lua
238 lines (200 loc) · 7.22 KB
/
text_box.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
-- @author cedlemo
local setmetatable = setmetatable
local ipairs = ipairs
local math = math
local table = table
local type = type
local string = string
local color = require("gears.color")
local base = require("wibox.widget.base")
local helpers = require("blingbling.helpers")
local superproperties = require("blingbling.superproperties")
local lgi = require("lgi")
local pango = lgi.Pango
local pangocairo = lgi.PangoCairo
local util = require('awful.util')
---A text box.
--@module blingbling.text_box
local text_box = { mt = {} }
local data = setmetatable({}, { __mode = "k" })
---Fill all the widget with this color (default is transparent).
--@usage myt_box:set_background_color(string) -->"#rrggbbaa"
--@name set_background_color
--@class function
--@param t_box the value text box
--@param color a string "#rrggbbaa" or "#rrggbb"
---Fill the text area (text height/width + padding) background with this color (default is none).
--@usage myt_box:set_text_background_color(string) -->"#rrggbbaa"
--@name set_text_background_color
--@class function
--@param color a string "#rrggbbaa" or "#rrggbb"
---Set a border on the text area background (default is none ).
--@usage myt_box:set_text_background_border(string) -->"#rrggbbaa"
--@name set_text_background_border
--@class function
--@param color a string "#rrggbbaa" or "#rrggbb"
---Define the top and bottom margin for the text background .
--@usage myt_box:set_v_margin(integer)
--@name set_v_margin
--@class function
--@param t_box the value text box
--@param margin an integer for top and bottom margin
---Define the left and right margin for the text background.
--@usage myt_box:set_h_margin(integer)
--@name set_h_margin
--@class function
--@param t_box the value text box
--@param margin an integer for left and right margin
---Set rounded corners for background and text background.
--@usage myt_box:set_rounded_size(a) -> a in [0,1]
--@usage myt_box:set_rounded_size(b) -> b = { 0.2,0.3,0.4,0.7}
--@name set_rounded_size
--@class function
--@param t_box the value text box
--@param rounded_size float in [0,1] or a table of 4 float for each corners.
---Define the color of the text.
--@usage myt_box:set_text_color(string)
--@name set_text_color
--@class function
--@param t_box the value text box
--@param color a string "#rrggbb"
---Define the text font size.
--@usage myt_box:set_font_size(integer)
--@name set_font_size
--@class function
--@param t_box the value text box
--@param size the font size
local properties = { "width", "height", "h_margin", "v_margin",
"background_color",
"background_text_border", "text_background_color",
"rounded_size", "text_color", "font_size", "font"
}
-- Setup a pango layout for the given textbox and cairo context
local function setup_layout(t_box, width, height)
local layout = t_box._layout
layout.width = pango.units_from_double(width)
layout.height = pango.units_from_double(height)
end
local function draw( t_box, wibox, cr, width, height)
local props = helpers.load_properties(properties, data, t_box, superproperties)
local text = data[t_box].text
if type(props.font) ~= "string" and type(props.font) == "table" then
font = (props.font.family or "Sans") ..(props.font.slang or "normal") ..( props.font.weight or "normal")
end
layout = t_box._layout
cr:update_layout(layout)
local font_desc = pango.FontDescription.from_string(props.font .. " " .. props.font_size)
layout:set_font_description(font_desc)
layout.text = text
layout:set_markup("<span color='".. props.text_color .."'>"..text.."</span>" )
local _, logical = layout:get_pixel_extents()
setup_layout(t_box, width, height)
--Generate Background (background widget)
if data[t_box].background_color then
helpers.draw_rounded_corners_rectangle( cr,
0,
0,
width,
height,
props.background_color,
props.rounded_size)
end
--Draw nothing, or filled ( value background)
if data[t_box].text_background_color then
--draw rounded corner rectangle
helpers.draw_rounded_corners_rectangle( cr,
props.h_margin,
props.v_margin,
width - props.h_margin,
height - props.v_margin,
props.text_background_color,
props.rounded_size,
props.background_text_border
)
end
local x, y = 0
x = width / 2 - logical.width / 2
y = height / 2 - logical.height / 2
cr:move_to(x, y)
cr:show_layout(layout)
end
function text_box:fit( width, height)
setup_layout(self, width, height)
local _, logical = self._layout:get_pixel_extents()
if logical.width == 0 or logical.height == 0 then
return 0, 0
end
return logical.width, logical.height
end
--- Add a text to the t_box.
-- @usage myt_box:set_text(a_text)
-- @param t_box The t_box.
-- @param string a string.
local function set_text(t_box, string)
if not t_box then return end
local text = string or ""
data[t_box].text = text
t_box._layout.text = text
t_box:emit_signal("widget::updated")
return t_box
end
--- Set the t_box height.
-- @param height The height to set.
function text_box:set_height( height)
if height >= 5 then
data[self].height = height
self:emit_signal("widget::updated")
end
return self
end
--- Set the t_box width.
-- @param width The width to set.
function text_box:set_width( width)
if width >= 5 then
data[self].width = width
self:emit_signal("widget::updated")
end
return self
end
-- Build properties function
for _, prop in ipairs(properties) do
if not text_box["set_" .. prop] then
text_box["set_" .. prop] = function(t_box, value)
data[t_box][prop] = value
t_box:emit_signal("widget::updated")
return t_box
end
end
end
--- Create a t_box widget.
-- @param args Standard widget() arguments. You should add width and height
-- key to set t_box geometry.
-- @return A t_box widget.
function text_box.new(args)
local args = args or {}
local width = args.width or 5
local height = args.height or 5
if width < 5 or height < 5 then return end
local t_box = base.make_widget()
data[t_box] = {}
data[t_box].text = args.text or ""
for _, v in ipairs(properties) do
data[t_box][v] = args[v]
end
data[t_box].height = height
data[t_box].width = width
local ctx = pangocairo.font_map_get_default():create_context()
t_box._layout = pango.Layout.new(ctx)
-- Set methods
t_box.set_text = set_text
t_box.draw = draw
t_box.fit = text_box.fit
for _, prop in ipairs(properties) do
t_box["set_" .. prop] = text_box["set_" .. prop]
end
return t_box
end
function text_box.mt:__call(...)
return text_box.new(...)
end
return setmetatable(text_box, text_box.mt)