Merge commit 'fd9244d4ebd549e8b4d3de055e3cf378f9142596' as 'core'
This commit is contained in:
commit
25bdcd3335
|
@ -0,0 +1,245 @@
|
|||
local c = {}
|
||||
|
||||
local _STRING_GSUB = string.gsub
|
||||
local _STRING_CHAR = string.char
|
||||
local _STRING_FIND = string.find
|
||||
local _STRING_SUB = string.sub
|
||||
local _TABLE_CONCAT = table.concat
|
||||
local _MATH_FLOOR = math.floor
|
||||
local _PAIRS = pairs
|
||||
local _TONUMBER = tonumber
|
||||
|
||||
local decode -- to ref this before definition
|
||||
|
||||
local decode_scanWhitespace = function(s, startPos)
|
||||
local whitespace = " \n\r\t"
|
||||
local stringLen = #s
|
||||
|
||||
while (_STRING_FIND(whitespace, _STRING_SUB(s, startPos, startPos), 1, true) and
|
||||
startPos <= stringLen) do
|
||||
startPos = startPos + 1
|
||||
end
|
||||
return startPos
|
||||
end
|
||||
|
||||
local decode_scanArray = function(s, startPos)
|
||||
local array = {}
|
||||
local stringLen = #s
|
||||
|
||||
--~ assert(_STRING_SUB(s, startPos, startPos) == '[',
|
||||
--~ 'decode_scanArray called but array does not start at position ' .. startPos ..
|
||||
--~ ' in string:\n'..s )
|
||||
|
||||
startPos = startPos + 1
|
||||
|
||||
repeat
|
||||
startPos = decode_scanWhitespace(s, startPos)
|
||||
--~ assert(startPos <= stringLen, 'JSON String ended unexpectedly scanning array.')
|
||||
|
||||
local curChar = _STRING_SUB(s,startPos,startPos)
|
||||
|
||||
if (curChar == ']') then
|
||||
return array, startPos + 1
|
||||
end
|
||||
|
||||
if (curChar == ',') then
|
||||
startPos = decode_scanWhitespace(s, startPos + 1)
|
||||
end
|
||||
|
||||
--~ assert(startPos <= stringLen, 'JSON String ended unexpectedly scanning array.')
|
||||
object, startPos = decode(s, startPos)
|
||||
array[#array + 1] = object
|
||||
until false
|
||||
end
|
||||
|
||||
local decode_scanComment = function(s, startPos)
|
||||
--~ assert(_STRING_SUB(s, startPos, startPos + 1) == '/*',
|
||||
--~ "decode_scanComment called but comment does not start at position " .. startPos)
|
||||
|
||||
local endPos = _STRING_FIND(s, '*/', startPos + 2)
|
||||
--~ assert(endPos ~= nil, "Unterminated comment in string at " .. startPos)
|
||||
return endPos + 2
|
||||
end
|
||||
|
||||
local decode_scanConstant = function(s, startPos)
|
||||
local consts = {["true"] = true, ["false"] = false, ["null"] = nil}
|
||||
local constNames = {"true", "false", "null"}
|
||||
|
||||
for _, k in _PAIRS(constNames) do
|
||||
if _STRING_SUB(s, startPos, startPos + #k - 1 ) == k then
|
||||
return consts[k], startPos + #k
|
||||
end
|
||||
end
|
||||
--~ assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' ..
|
||||
--~ startPos)
|
||||
end
|
||||
|
||||
local decode_scanNumber = function(s, startPos)
|
||||
local endPos = startPos + 1
|
||||
local stringLen = #s
|
||||
local acceptableChars = "+-0123456789.e"
|
||||
|
||||
while (_STRING_FIND(acceptableChars, _STRING_SUB(s, endPos, endPos), 1, true)
|
||||
and endPos <= stringLen) do
|
||||
endPos = endPos + 1
|
||||
end
|
||||
|
||||
local numberString = _STRING_GSUB(_STRING_SUB(s, startPos, endPos - 1), '+', '')
|
||||
return _TONUMBER(numberString), endPos
|
||||
end
|
||||
|
||||
local decode_scanObject = function(s, startPos)
|
||||
local object = {}
|
||||
local stringLen = #s
|
||||
local key, value
|
||||
|
||||
--~ assert(_STRING_SUB(s, startPos, startPos) == '{',
|
||||
--~ 'decode_scanObject called but object does not start at position ' .. startPos ..
|
||||
--~ ' in string:\n' .. s)
|
||||
|
||||
startPos = startPos + 1
|
||||
|
||||
repeat
|
||||
startPos = decode_scanWhitespace(s, startPos)
|
||||
|
||||
--~ assert(startPos <= stringLen, 'JSON string ended unexpectedly while scanning object.')
|
||||
|
||||
local curChar = _STRING_SUB(s, startPos, startPos)
|
||||
|
||||
if (curChar == '}') then
|
||||
return object, startPos + 1
|
||||
end
|
||||
|
||||
if (curChar == ',') then
|
||||
startPos = decode_scanWhitespace(s, startPos + 1)
|
||||
end
|
||||
|
||||
--~ assert(startPos <= stringLen, 'JSON string ended unexpectedly scanning object.')
|
||||
|
||||
-- Scan the key
|
||||
key, startPos = decode(s, startPos)
|
||||
|
||||
--~ assert(startPos <= stringLen,
|
||||
--~ 'JSON string ended unexpectedly searching for value of key ' .. key)
|
||||
|
||||
startPos = decode_scanWhitespace(s, startPos)
|
||||
|
||||
--~ assert(startPos <= stringLen,
|
||||
--~ 'JSON string ended unexpectedly searching for value of key ' .. key)
|
||||
|
||||
--~ assert(_STRING_SUB(s, startPos, startPos) == ':',
|
||||
--~ 'JSON object key-value assignment mal-formed at ' .. startPos)
|
||||
|
||||
startPos = decode_scanWhitespace(s, startPos + 1)
|
||||
|
||||
--~ assert(startPos <= stringLen,
|
||||
--~ 'JSON string ended unexpectedly searching for value of key ' .. key)
|
||||
|
||||
value, startPos = decode(s, startPos)
|
||||
|
||||
object[key] = value
|
||||
until false
|
||||
end
|
||||
|
||||
local escapeSequences = {
|
||||
["\\t"] = "\t",
|
||||
["\\f"] = "\f",
|
||||
["\\r"] = "\r",
|
||||
["\\n"] = "\n",
|
||||
["\\b"] = "\b"
|
||||
}
|
||||
|
||||
setmetatable(escapeSequences, {__index = function(t, k) return _STRING_SUB(k, 2) end})--skip "\"
|
||||
|
||||
local decode_scanString = function (s, startPos)
|
||||
--~ assert(startPos, 'decode_scanString(..) called without start position')
|
||||
|
||||
local startChar = _STRING_SUB(s, startPos, startPos)
|
||||
|
||||
--~ assert(startChar == [["]] or startChar == [[']],
|
||||
--~ 'decode_scanString called for a non-string')
|
||||
|
||||
local t = {}
|
||||
local i, j = startPos, startPos
|
||||
|
||||
while _STRING_FIND(s, startChar, j + 1) ~= j + 1 do
|
||||
local oldj = j
|
||||
local x, y = _STRING_FIND(s, startChar, oldj + 1)
|
||||
|
||||
i, j = _STRING_FIND(s, "\\.", j + 1)
|
||||
|
||||
if not i or x < i then i, j = x, y - 1 end
|
||||
|
||||
--~ table.insert(t, _STRING_SUB(s, oldj + 1, i - 1))
|
||||
t[#t + 1] = _STRING_SUB(s, oldj + 1, i - 1)
|
||||
|
||||
if _STRING_SUB(s, i, j) == "\\u" then
|
||||
local a = _STRING_SUB(s, j + 1, j + 4)
|
||||
local n = _TONUMBER(a, 16)
|
||||
local x
|
||||
|
||||
j = j + 4
|
||||
|
||||
--~ assert(n, "String decoding failed: bad Unicode escape " .. a .. " at position " ..
|
||||
--~ i .. " : " .. j)
|
||||
|
||||
if n < 0x80 then
|
||||
x = _STRING_CHAR(n % 0x80)
|
||||
elseif n < 0x800 then
|
||||
x = _STRING_CHAR(0xC0 + (_MATH_FLOOR(n / 64) % 0x20), 0x80 + (n % 0x40))
|
||||
else
|
||||
x = _STRING_CHAR(0xE0 + (_MATH_FLOOR(n / 4096) % 0x10), 0x80 +
|
||||
(_MATH_FLOOR(n / 64) % 0x40), 0x80 + (n % 0x40))
|
||||
end
|
||||
|
||||
--~ table.insert(t, x)
|
||||
t[#t + 1] = x
|
||||
else
|
||||
--~ table.insert(t, escapeSequences[_STRING_SUB(s, i, j)])
|
||||
t[#t + 1] = escapeSequences[_STRING_SUB(s, i, j)]
|
||||
end
|
||||
end
|
||||
--~ table.insert(t, _STRING_SUB(j, j + 1))
|
||||
t[#t + 1] = _STRING_SUB(j, j + 1)
|
||||
|
||||
--~ assert(_STRING_FIND(s, startChar, j + 1), "String decoding failed: missing closing " ..
|
||||
--~ startChar .. " at position " .. j .. "(for string at position " .. startPos .. ")")
|
||||
|
||||
return _TABLE_CONCAT(t, ""), j + 2
|
||||
end
|
||||
|
||||
decode = function(s, startPos)
|
||||
startPos = startPos or 1
|
||||
startPos = decode_scanWhitespace(s, startPos)
|
||||
|
||||
--~ assert(startPos <= #s,
|
||||
--~ 'Unterminated JSON encoded object found at position in [' .. s .. ']')
|
||||
|
||||
local curChar = _STRING_SUB(s, startPos, startPos)
|
||||
|
||||
if curChar == '{' then
|
||||
return decode_scanObject(s, startPos)
|
||||
end
|
||||
|
||||
if curChar == '[' then
|
||||
return decode_scanArray(s, startPos)
|
||||
end
|
||||
|
||||
if _STRING_FIND("+-0123456789.e", curChar, 1, true) then
|
||||
return decode_scanNumber(s, startPos)
|
||||
end
|
||||
|
||||
if curChar == [["]] or curChar == [[']] then
|
||||
return decode_scanString(s, startPos)
|
||||
end
|
||||
|
||||
if _STRING_SUB(s, startPos, startPos + 1) == '/*' then
|
||||
return decode(s, decode_scanComment(s, startPos))
|
||||
end
|
||||
|
||||
return decode_scanConstant(s, startPos)
|
||||
end
|
||||
|
||||
c.decode = decode
|
||||
|
||||
return c
|
|
@ -0,0 +1,176 @@
|
|||
local c = {}
|
||||
|
||||
local _PAIRS = pairs
|
||||
local _TYPE = type
|
||||
local _TONUMBER = tonumber
|
||||
local _TOSTRING = tostring
|
||||
local _IO_POPEN = io.popen
|
||||
local _IO_OPEN = io.open
|
||||
local _MATH_FLOOR = math.floor
|
||||
local _MATH_CEIL = math.ceil
|
||||
local _STRING_SUB = string.sub
|
||||
local _STRING_GSUB = string.gsub
|
||||
local _STRING_MATCH = string.match
|
||||
local _STRING_FORMAT = string.format
|
||||
local _STRING_UPPER = string.upper
|
||||
local _CONKY_PARSE = conky_parse
|
||||
local _SELECT = select
|
||||
local _SETMETATABLE = setmetatable
|
||||
|
||||
local copy_table = function(t)
|
||||
local s = {}
|
||||
for i, v in _PAIRS(t) do s[i] = _TYPE(v) == 'table' and copy_table(v) or v end
|
||||
return s
|
||||
end
|
||||
|
||||
local round = function(x, places)
|
||||
local m = 10 ^ (places or 0)
|
||||
if x >= 0 then
|
||||
return _MATH_FLOOR(x * m + 0.5) / m
|
||||
else
|
||||
return _MATH_CEIL(x * m - 0.5) / m
|
||||
end
|
||||
end
|
||||
|
||||
local get_bytes_power = function(unit)
|
||||
if unit == 'KiB' then return 10
|
||||
elseif unit == 'MiB' then return 20
|
||||
elseif unit == 'GiB' then return 30
|
||||
elseif unit == 'TiB' then return 40
|
||||
else return 0
|
||||
end
|
||||
end
|
||||
|
||||
local convert_bytes = function(x, old_unit, new_unit)
|
||||
if old_unit == new_unit then
|
||||
return _TONUMBER(x)
|
||||
else
|
||||
return x * 2 ^ (get_bytes_power(old_unit) - get_bytes_power(new_unit))
|
||||
end
|
||||
end
|
||||
|
||||
local round_to_string = function(x, places)
|
||||
places = places or 0
|
||||
local y = round(x, places)
|
||||
if places > 0 then return _STRING_FORMAT('%.'..places..'f', y) else return _TOSTRING(y) end
|
||||
end
|
||||
|
||||
local precision_round_to_string = function(x, sig_fig)
|
||||
sig_fig = sig_fig or 4
|
||||
if x < 10 then return round_to_string(x, sig_fig - 1)
|
||||
elseif x < 100 then return round_to_string(x, sig_fig - 2)
|
||||
elseif x < 1000 then return round_to_string(x, sig_fig - 3)
|
||||
else return round_to_string(x, sig_fig - 4)
|
||||
end
|
||||
end
|
||||
|
||||
local read_entire_file = function(file, regex, mode)
|
||||
if not file then return '' end
|
||||
local str = file:read(mode or '*a')
|
||||
file:close()
|
||||
if not str then return '' end
|
||||
if regex then return _STRING_MATCH(str, regex) or '' else return str end
|
||||
end
|
||||
|
||||
local conky = function(expr, regex)
|
||||
local ans = _CONKY_PARSE(expr)
|
||||
if regex then return _STRING_MATCH(ans, regex) or '' else return ans end
|
||||
end
|
||||
|
||||
local precision_convert_bytes = function(val, old_unit, new_unit, sig_fig)
|
||||
return precision_round_to_string(convert_bytes(val, old_unit, new_unit), sig_fig)
|
||||
end
|
||||
|
||||
local get_unit = function(bytes)
|
||||
if bytes < 1024 then return 'B'
|
||||
elseif bytes < 1048576 then return 'KiB'
|
||||
elseif bytes < 1073741824 then return 'MiB'
|
||||
else return 'GiB'
|
||||
end
|
||||
end
|
||||
|
||||
local get_unit_base_K = function(kilobytes)
|
||||
if kilobytes < 1024 then return 'KiB'
|
||||
elseif kilobytes < 1048576 then return 'MiB'
|
||||
elseif kilobytes < 1073741824 then return 'GiB'
|
||||
else return 'TiB'
|
||||
end
|
||||
end
|
||||
|
||||
local parse_unit = function(str)
|
||||
return _STRING_MATCH(str, '^([%d%p]-)(%a+)')
|
||||
end
|
||||
|
||||
local char_count = function(str, char)
|
||||
return _SELECT(2, _STRING_GSUB(str, char, char))
|
||||
end
|
||||
|
||||
local line_count = function(str)
|
||||
return char_count(str, '\n')
|
||||
end
|
||||
|
||||
local execute_cmd = function(cmd, regex, mode)
|
||||
return read_entire_file(_IO_POPEN(cmd), regex, mode)
|
||||
end
|
||||
|
||||
local read_file = function(path, regex, mode)
|
||||
return read_entire_file(_IO_OPEN(path, 'rb'), regex, mode)
|
||||
end
|
||||
|
||||
local write_file = function(path, str)
|
||||
local file = _IO_OPEN(path, 'w+')
|
||||
if file then
|
||||
file:write(str)
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
local conky_numeric = function(expr, regex)
|
||||
return _TONUMBER(conky(expr, regex)) or 0
|
||||
end
|
||||
|
||||
local memoize = function(f)
|
||||
local mem = {} -- memoizing table
|
||||
_SETMETATABLE(mem, {__mode = "kv"}) -- make it weak
|
||||
return function (x) -- new version of ’f’, with memoizing
|
||||
local r = mem[x]
|
||||
if not r then -- no previous result?
|
||||
r = f(x) -- calls original function
|
||||
mem[x] = r -- store result for reuse
|
||||
end
|
||||
return r
|
||||
end
|
||||
end
|
||||
|
||||
local convert_unix_time = function(unix_time, frmt)
|
||||
local cmd = 'date -d @'..unix_time
|
||||
if frmt then cmd = cmd..' +\''..frmt..'\'' end
|
||||
return _STRING_MATCH(execute_cmd(cmd), '(.-)\n')
|
||||
end
|
||||
|
||||
local capitalize_each_word = function(str)
|
||||
return _STRING_SUB(_STRING_GSUB(" "..str, "%W%l", _STRING_UPPER), 2)
|
||||
end
|
||||
|
||||
c.round = round
|
||||
c.get_bytes_power = get_bytes_power
|
||||
c.convert_bytes = convert_bytes
|
||||
c.copy_table = copy_table
|
||||
c.conky = conky
|
||||
c.round_to_string = round_to_string
|
||||
c.precision_round_to_string = precision_round_to_string
|
||||
c.precision_convert_bytes = precision_convert_bytes
|
||||
c.get_unit = get_unit
|
||||
c.get_unit_base_K = get_unit_base_K
|
||||
c.parse_unit = parse_unit
|
||||
c.char_count = char_count
|
||||
c.line_count = line_count
|
||||
c.execute_cmd = execute_cmd
|
||||
c.read_file = read_file
|
||||
c.write_file = write_file
|
||||
c.conky_numeric = conky_numeric
|
||||
c.memoize = memoize
|
||||
c.convert_unix_time = convert_unix_time
|
||||
c.capitalize_each_word = capitalize_each_word
|
||||
|
||||
return c
|
|
@ -0,0 +1,55 @@
|
|||
local c = {}
|
||||
|
||||
local Gradient = require 'Gradient'
|
||||
|
||||
local _CAIRO_PATTERN_CREATE_RGBA = cairo_pattern_create_rgba
|
||||
|
||||
--Color(hex_rgba, [force_alpha])
|
||||
local init = function(arg)
|
||||
|
||||
local hex_rgba = arg.hex_rgba
|
||||
|
||||
local obj = {
|
||||
r = ((hex_rgba / 0x1000000) % 0x100) / 255.,
|
||||
g = ((hex_rgba / 0x10000) % 0x100) / 255.,
|
||||
b = ((hex_rgba / 0x100) % 0x100) / 255.,
|
||||
a = arg.force_alpha or (hex_rgba % 0x100) / 255.
|
||||
}
|
||||
obj.userdata = _CAIRO_PATTERN_CREATE_RGBA(obj.r, obj.g, obj.b, obj.a)
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
--ColorStop(hex_rgba, stop, [force_alpha])
|
||||
local initColorStop = function(arg)
|
||||
|
||||
local obj = init{
|
||||
hex_rgba = arg.hex_rgba,
|
||||
force_alpha = arg.force_alpha
|
||||
}
|
||||
|
||||
obj.stop = arg.stop
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
--Gradient([p1], [p2], [r0], [r1], ... color stops)
|
||||
local initGradient = function(arg)
|
||||
|
||||
local obj = {
|
||||
color_stops = {},
|
||||
ptype = 'Gradient'
|
||||
}
|
||||
|
||||
for i = 1, #arg do obj.color_stops[i] = arg[i] end
|
||||
|
||||
Gradient(obj, arg.p1, arg.p2, arg.r1, arg.r2)
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
c.init = init
|
||||
c.ColorStop = initColorStop
|
||||
c.Gradient = initGradient
|
||||
|
||||
return c
|
|
@ -0,0 +1,20 @@
|
|||
local _CAIRO_PATTERN_CREATE_RADIAL = cairo_pattern_create_radial
|
||||
local _CAIRO_PATTERN_CREATE_LINEAR = cairo_pattern_create_linear
|
||||
local _CAIRO_PATTERN_ADD_COLOR_STOP_RGBA = cairo_pattern_add_color_stop_rgba
|
||||
local _PAIRS = pairs
|
||||
|
||||
local set_dimensions = function(gradient, p1, p2, r1, r2)
|
||||
if p1 and p2 then
|
||||
local pattern = (r1 and r2) and
|
||||
_CAIRO_PATTERN_CREATE_RADIAL(p1.x, p1.y, r1, p2.x, p2.y, r2) or
|
||||
_CAIRO_PATTERN_CREATE_LINEAR(p1.x, p1.y, p2.x, p2.y)
|
||||
|
||||
for _, color_stop in _PAIRS(gradient.color_stops) do
|
||||
_CAIRO_PATTERN_ADD_COLOR_STOP_RGBA(pattern, color_stop.stop, color_stop.r,
|
||||
color_stop.g, color_stop.b, color_stop.a)
|
||||
end
|
||||
gradient.userdata = pattern
|
||||
end
|
||||
end
|
||||
|
||||
return set_dimensions
|
|
@ -0,0 +1,58 @@
|
|||
local c = {}
|
||||
|
||||
local Gradient = require 'Gradient'
|
||||
local schema = require 'default_patterns'
|
||||
|
||||
local _TONUMBER = tonumber
|
||||
local _STRING_SUB = string.sub
|
||||
|
||||
--Pattern(pattern, [p1], [p2], [r1], [r2], [key])
|
||||
local initPattern = function(arg)
|
||||
|
||||
local pattern = arg.pattern
|
||||
local p1 = arg.p1
|
||||
local p2 = arg.p2
|
||||
local r1 = arg.r1
|
||||
local r2 = arg.r2
|
||||
|
||||
if p1 and p2 and pattern and pattern.ptype == 'Gradient' then
|
||||
Gradient(pattern, p1, p2, r1, r2)
|
||||
end
|
||||
|
||||
return pattern.userdata
|
||||
end
|
||||
|
||||
--Critical([critical_pattern], [critical_limit], [p1], [p2], [r1], [r2])
|
||||
|
||||
local CRITICAL_PATTERN = schema.red
|
||||
local CRITICAL_LIMIT = '>80'
|
||||
|
||||
local CRITICAL_CREATE_FUNCTION = function(limit)
|
||||
local compare = limit and _STRING_SUB(limit, 1, 1)
|
||||
local value = limit and _TONUMBER(_STRING_SUB(limit, 2))
|
||||
|
||||
if compare == '>' then return function(n) return (n > value) end end
|
||||
if compare == '<' then return function(n) return (n < value) end end
|
||||
return function(n) return nil end --if no limit then return dummy
|
||||
end
|
||||
|
||||
local initCritical = function(arg)
|
||||
|
||||
local obj = {
|
||||
source = initPattern{
|
||||
pattern = arg.critical_pattern or CRITICAL_PATTERN,
|
||||
p1 = arg.p1,
|
||||
p2 = arg.p2,
|
||||
r1 = arg.r1,
|
||||
r2 = arg.r2,
|
||||
},
|
||||
enabled = CRITICAL_CREATE_FUNCTION(arg.critical_limit or CRITICAL_LIMIT)
|
||||
}
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
c.Pattern = initPattern
|
||||
c.Critical = initCritical
|
||||
|
||||
return c
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
local cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1366, 768)
|
||||
local CR = cairo_create(cs)
|
||||
cairo_surface_destroy(cs)
|
||||
|
||||
return CR
|
|
@ -0,0 +1,31 @@
|
|||
local c = {}
|
||||
|
||||
local _CR = require 'CR'
|
||||
|
||||
local _CAIRO_NEW_PATH = cairo_new_path
|
||||
local _CAIRO_ARC = cairo_arc
|
||||
local _CAIRO_COPY_PATH = cairo_copy_path
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_APPEND_PATH(cr, obj.path)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, obj.thickness)
|
||||
_CAIRO_SET_LINE_CAP(cr, obj.cap)
|
||||
_CAIRO_SET_SOURCE(cr, obj.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
local create_path = function(x, y, radius, theta0, theta1)
|
||||
_CAIRO_NEW_PATH(_CR)
|
||||
_CAIRO_ARC(_CR, x, y, radius, theta0, theta1)
|
||||
return _CAIRO_COPY_PATH(_CR)
|
||||
end
|
||||
|
||||
c.draw = draw
|
||||
c.create_path = create_path
|
||||
|
||||
return c
|
|
@ -0,0 +1,34 @@
|
|||
local c = {}
|
||||
|
||||
local Dial = require 'Dial'
|
||||
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
|
||||
local set = function(obj, index, percent)
|
||||
Dial.set(obj.dials[index], percent)
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
local dials = obj.dials
|
||||
_CAIRO_SET_LINE_WIDTH(cr, dials[1].thickness)
|
||||
_CAIRO_SET_LINE_CAP(cr, dials[1].cap)
|
||||
|
||||
for i = 1, #dials do
|
||||
local current_dial = dials[i]
|
||||
_CAIRO_SET_SOURCE(cr, current_dial.source)
|
||||
_CAIRO_APPEND_PATH(cr, current_dial.path)
|
||||
_CAIRO_STROKE(cr)
|
||||
_CAIRO_SET_SOURCE(cr, current_dial.current_source)
|
||||
_CAIRO_APPEND_PATH(cr, current_dial.dial_path)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,30 @@
|
|||
local c = {}
|
||||
|
||||
local Arc = require 'Arc'
|
||||
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
|
||||
local set = function(obj, percent)
|
||||
obj.percent = percent
|
||||
obj.dial_path = obj._make_dial_path(percent)
|
||||
|
||||
if obj.critical.enabled(obj.percent) then
|
||||
obj.current_source = obj.critical.source
|
||||
else
|
||||
obj.current_source = obj.indicator_source
|
||||
end
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
Arc.draw(obj, cr)
|
||||
_CAIRO_SET_SOURCE(cr, obj.current_source)
|
||||
_CAIRO_APPEND_PATH(cr, obj.dial_path)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,31 @@
|
|||
local c = {}
|
||||
|
||||
local _IMLIB_LOAD_IMAGE = imlib_load_image
|
||||
local _IMLIB_CONTEXT_SET_IMAGE = imlib_context_set_image
|
||||
local _IMLIB_RENDER_IMAGE_ON_DRAWABLE = imlib_render_image_on_drawable
|
||||
local _IMLIB_FREE_IMAGE = imlib_free_image
|
||||
local _IMLIB_IMAGE_GET_WIDTH = imlib_image_get_width
|
||||
local _IMLIB_IMAGE_GET_HEIGHT = imlib_image_get_height
|
||||
|
||||
local set = function(obj, path)
|
||||
local img = _IMLIB_LOAD_IMAGE(path)
|
||||
_IMLIB_CONTEXT_SET_IMAGE(img)
|
||||
|
||||
obj.width = _IMLIB_IMAGE_GET_WIDTH()
|
||||
obj.height = _IMLIB_IMAGE_GET_HEIGHT()
|
||||
obj.path = path
|
||||
|
||||
_IMLIB_FREE_IMAGE()
|
||||
end
|
||||
|
||||
local draw = function(obj)
|
||||
local img = _IMLIB_LOAD_IMAGE(obj.path)
|
||||
_IMLIB_CONTEXT_SET_IMAGE(img)
|
||||
_IMLIB_RENDER_IMAGE_ON_DRAWABLE(obj.x, obj.y)
|
||||
_IMLIB_FREE_IMAGE()
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,31 @@
|
|||
local c = {}
|
||||
|
||||
local _IMLIB_LOAD_IMAGE = imlib_load_image
|
||||
local _IMLIB_CONTEXT_SET_IMAGE = imlib_context_set_image
|
||||
local _IMLIB_RENDER_IMAGE_ON_DRAWABLE_AT_SIZE = imlib_render_image_on_drawable_at_size
|
||||
local _IMLIB_FREE_IMAGE = imlib_free_image
|
||||
local _IMLIB_IMAGE_GET_WIDTH = imlib_image_get_width
|
||||
local _IMLIB_IMAGE_GET_HEIGHT = imlib_image_get_height
|
||||
|
||||
local set = function(obj, path)
|
||||
local img = _IMLIB_LOAD_IMAGE(path)
|
||||
_IMLIB_CONTEXT_SET_IMAGE(img)
|
||||
|
||||
obj.img_width = _IMLIB_IMAGE_GET_WIDTH()
|
||||
obj.img_height = _IMLIB_IMAGE_GET_HEIGHT()
|
||||
obj.path = path
|
||||
|
||||
_IMLIB_FREE_IMAGE()
|
||||
end
|
||||
|
||||
local draw = function(obj)
|
||||
local img = _IMLIB_LOAD_IMAGE(obj.path)
|
||||
_IMLIB_CONTEXT_SET_IMAGE(img)
|
||||
_IMLIB_RENDER_IMAGE_ON_DRAWABLE_AT_SIZE(obj.x, obj.y, obj.width, obj.height)
|
||||
_IMLIB_FREE_IMAGE()
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,110 @@
|
|||
local c = {}
|
||||
|
||||
local Plot = require 'Plot'
|
||||
local Text = require 'Text'
|
||||
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_SET_FONT_FACE = cairo_set_font_face
|
||||
local _CAIRO_SET_FONT_SIZE = cairo_set_font_size
|
||||
local _CAIRO_MOVE_TO = cairo_move_to
|
||||
local _CAIRO_SHOW_TEXT = cairo_show_text
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local X_LABEL_PAD = 8
|
||||
local Y_LABEL_PAD = 5
|
||||
|
||||
local draw = function(obj, cr)
|
||||
local labels_x = obj.labels.x
|
||||
local labels_y = obj.labels.y
|
||||
local labels_x_1 = labels_x[1]
|
||||
|
||||
_CAIRO_SET_FONT_FACE(cr, labels_x_1.font_face)
|
||||
_CAIRO_SET_FONT_SIZE(cr, labels_x_1.font_size)
|
||||
_CAIRO_SET_SOURCE(cr, labels_x_1.source)
|
||||
|
||||
for i = 1, #labels_x do
|
||||
local current_label = labels_x[i]
|
||||
_CAIRO_MOVE_TO(cr, current_label.x, current_label.y)
|
||||
_CAIRO_SHOW_TEXT(cr, current_label.text)
|
||||
end
|
||||
|
||||
for i = 1, #labels_y do
|
||||
local current_label = labels_y[i]
|
||||
_CAIRO_MOVE_TO(cr, current_label.x, current_label.y)
|
||||
_CAIRO_SHOW_TEXT(cr, current_label.text)
|
||||
end
|
||||
|
||||
Plot.draw(obj.plot, cr)
|
||||
end
|
||||
|
||||
local populate_x_labels = function(obj, cr, input_factor)
|
||||
local labels_x = obj.labels.x
|
||||
local n = #labels_x - 1
|
||||
input_factor = input_factor or 1
|
||||
for i = 0, n do
|
||||
Text.set(labels_x[i + 1], cr, labels_x._func(input_factor * i / n))
|
||||
end
|
||||
labels_x.height = labels_x[1].height + X_LABEL_PAD
|
||||
local plot = obj.plot
|
||||
plot.height = obj.height - labels_x.height
|
||||
plot.bottom_y = plot.height - plot.y
|
||||
end
|
||||
|
||||
local __get_y_axis_width = function(obj)
|
||||
local labels_y = obj.labels.y
|
||||
local width = labels_y[1].width
|
||||
for i = 2, #labels_y do
|
||||
local current_width = labels_y[i].width
|
||||
if current_width > width then
|
||||
width = current_width
|
||||
end
|
||||
end
|
||||
return width + Y_LABEL_PAD
|
||||
end
|
||||
|
||||
local populate_y_labels = function(obj, cr, input_factor)
|
||||
local labels_y = obj.labels.y
|
||||
local n = #labels_y - 1
|
||||
input_factor = input_factor or 1
|
||||
for i = 0, n do
|
||||
Text.set(labels_y[i + 1], cr, labels_y._func(input_factor * (n - i) / n))
|
||||
end
|
||||
labels_y.width = __get_y_axis_width(obj)
|
||||
|
||||
local plot = obj.plot
|
||||
plot.x = obj.x + labels_y.width
|
||||
plot.width = obj.width - labels_y.width
|
||||
end
|
||||
|
||||
local position_x_labels = function(obj)
|
||||
local start_x = obj.plot.x
|
||||
local labels_x = obj.labels.x
|
||||
local x_intrvl_width = obj.plot.width / (#labels_x - 1)
|
||||
for i = 1, #labels_x do
|
||||
Text.move_to_x(labels_x[i], start_x + x_intrvl_width * (i - 1))
|
||||
end
|
||||
end
|
||||
|
||||
local position_y_labels = function(obj)
|
||||
local labels_y = obj.labels.y
|
||||
local y_intrvl_height = obj.plot.height / (#labels_y - 1)
|
||||
for i = 1, #labels_y do
|
||||
Text.move_to_y(labels_y[i], obj.y + y_intrvl_height * (i - 1))
|
||||
end
|
||||
end
|
||||
|
||||
local update = function(obj, value)
|
||||
Plot.update(obj.plot, value)
|
||||
end
|
||||
|
||||
c.update = update
|
||||
c.draw = draw
|
||||
c.position_x_intrvls = Plot.position_x_intrvls
|
||||
c.position_y_intrvls = Plot.position_y_intrvls
|
||||
c.position_graph_outline = Plot.position_graph_outline
|
||||
c.populate_x_labels = populate_x_labels
|
||||
c.populate_y_labels = populate_y_labels
|
||||
c.position_x_labels = position_x_labels
|
||||
c.position_y_labels = position_y_labels
|
||||
|
||||
return c
|
|
@ -0,0 +1,147 @@
|
|||
local c = {}
|
||||
|
||||
local Poly = require 'Poly'
|
||||
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_MOVE_TO = cairo_move_to
|
||||
local _CAIRO_LINE_TO = cairo_line_to
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_LINE_JOIN = cairo_set_line_join
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_FILL_PRESERVE = cairo_fill_preserve
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
local _CAIRO_PATH_DESTROY = cairo_path_destroy
|
||||
local _TABLE_INSERT = table.insert
|
||||
|
||||
local DATA_THICKNESS = 1
|
||||
local DATA_CAP = CAIRO_LINE_CAP_BUTT
|
||||
local DATA_JOIN = CAIRO_LINE_JOIN_MITER
|
||||
local INTRVL_THICKNESS = 1
|
||||
local INTRVL_CAP = CAIRO_LINE_CAP_BUTT
|
||||
local OUTLINE_THICKNESS = 2
|
||||
local OUTLINE_CAP = CAIRO_LINE_CAP_BUTT
|
||||
local OUTLINE_JOIN = CAIRO_LINE_JOIN_MITER
|
||||
|
||||
local update = function(obj, value)
|
||||
local data = obj.data
|
||||
_TABLE_INSERT(data, 1, obj.y + obj.height * (1 - value))
|
||||
if #data == data.n + 2 then data[#data] = nil end
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
|
||||
--draw intervals
|
||||
local intrvls = obj.intrvls
|
||||
local x_intrvls = intrvls.x
|
||||
local y_intrvls = intrvls.y
|
||||
|
||||
_CAIRO_SET_LINE_WIDTH(cr, INTRVL_THICKNESS)
|
||||
_CAIRO_SET_LINE_CAP(cr, INTRVL_CAP)
|
||||
_CAIRO_SET_SOURCE(cr, intrvls.source)
|
||||
for i = 1, #x_intrvls do
|
||||
_CAIRO_APPEND_PATH(cr, x_intrvls[i])
|
||||
end
|
||||
for i = 1, #y_intrvls do
|
||||
_CAIRO_APPEND_PATH(cr, y_intrvls[i])
|
||||
end
|
||||
_CAIRO_STROKE(cr)
|
||||
|
||||
--draw data on graph
|
||||
local data = obj.data
|
||||
local n = #data - 1
|
||||
local spacing = obj.width / data.n
|
||||
local right = obj.x + obj.width
|
||||
|
||||
_CAIRO_MOVE_TO(cr, right, data[1])
|
||||
|
||||
for i = 1, n do
|
||||
_CAIRO_LINE_TO(cr, right - i * spacing, data[i+1])
|
||||
end
|
||||
|
||||
if data.fill_source then
|
||||
local bottom = obj.y + obj.height
|
||||
_CAIRO_LINE_TO(cr, right - n * spacing, bottom)
|
||||
_CAIRO_LINE_TO(cr, right, bottom)
|
||||
_CAIRO_SET_SOURCE(cr, data.fill_source)
|
||||
_CAIRO_FILL_PRESERVE(cr)
|
||||
end
|
||||
|
||||
_CAIRO_SET_LINE_WIDTH (cr, DATA_THICKNESS)
|
||||
_CAIRO_SET_LINE_CAP(cr, DATA_CAP)
|
||||
_CAIRO_SET_LINE_JOIN(cr, DATA_JOIN)
|
||||
_CAIRO_SET_SOURCE(cr, data.line_source)
|
||||
_CAIRO_STROKE(cr)
|
||||
|
||||
--draw graph outline (goes on top of everything)
|
||||
local outline = obj.outline
|
||||
|
||||
_CAIRO_APPEND_PATH(cr, outline.path)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, OUTLINE_THICKNESS)
|
||||
_CAIRO_SET_LINE_JOIN(cr, OUTLINE_JOIN)
|
||||
_CAIRO_SET_LINE_CAP(cr, OUTLINE_CAP)
|
||||
_CAIRO_SET_SOURCE(cr, outline.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
local position_x_intrvls = function(obj)
|
||||
local y1 = obj.y - 0.5
|
||||
local y2 = y1 + obj.height-- + 0.5
|
||||
local x_intrvls = obj.intrvls.x
|
||||
local intrvl_width = obj.width / x_intrvls.n
|
||||
local p1 = {x = 0, y = 0}
|
||||
local p2 = {x = 0, y = 0}
|
||||
|
||||
local obj_x = obj.x
|
||||
|
||||
for i = 1, x_intrvls.n do
|
||||
local x1 = obj_x + intrvl_width * i-- + 0.5
|
||||
p1.x = x1
|
||||
p1.y = y1
|
||||
p2.x = x1
|
||||
p2.y = y2
|
||||
_CAIRO_PATH_DESTROY(x_intrvls[i])
|
||||
x_intrvls[i] = Poly.create_path(nil, p1, p2)
|
||||
end
|
||||
end
|
||||
|
||||
local position_y_intrvls = function(obj)
|
||||
local x1 = obj.x-- + 0.5
|
||||
local x2 = obj.x + obj.width-- + 0.5
|
||||
local y_intrvls = obj.intrvls.y
|
||||
local y_intrvl_height = obj.height / y_intrvls.n
|
||||
local p1 = {x = 0, y = 0}
|
||||
local p2 = {x = 0, y = 0}
|
||||
|
||||
for i = 1, y_intrvls.n do
|
||||
local y1 = obj.y + (i - 1) * y_intrvl_height - 0.5
|
||||
p1.x = x1
|
||||
p1.y = y1
|
||||
p2.x = x2
|
||||
p2.y = y1
|
||||
_CAIRO_PATH_DESTROY(y_intrvls[i])
|
||||
y_intrvls[i] = Poly.create_path(nil, p1, p2)
|
||||
end
|
||||
end
|
||||
|
||||
local position_graph_outline = function(obj)
|
||||
local x1 = obj.x
|
||||
local y1 = obj.y - 0.5
|
||||
local x2 = obj.x + obj.width + 0.5
|
||||
local y2 = obj.y + obj.height + 1.0
|
||||
local p1 = {x = x1, y = y1}
|
||||
local p2 = {x = x1, y = y2}
|
||||
local p3 = {x = x2, y = y2}
|
||||
|
||||
_CAIRO_PATH_DESTROY(obj.outline.path)
|
||||
|
||||
obj.outline.path = Poly.create_path(nil, p1, p2, p3)
|
||||
end
|
||||
|
||||
c.draw = draw
|
||||
c.update = update
|
||||
c.position_x_intrvls = position_x_intrvls
|
||||
c.position_y_intrvls = position_y_intrvls
|
||||
c.position_graph_outline = position_graph_outline
|
||||
|
||||
return c
|
|
@ -0,0 +1,89 @@
|
|||
local c = {}
|
||||
|
||||
local LabelPlot = require 'LabelPlot'
|
||||
|
||||
local _TABLE_INSERT = table.insert
|
||||
local _TABLE_REMOVE = table.remove
|
||||
|
||||
local __scale_data = function(obj, cr, new_domain, new_factor)
|
||||
local y = obj.y
|
||||
local current_factor = obj.scale.factor
|
||||
local data = obj.plot.data
|
||||
local h = obj.plot.height
|
||||
for i = 1, #data do
|
||||
data[i] = y + h * (1 - (1 - (data[i] - y) / h) * (new_factor / current_factor))
|
||||
end
|
||||
obj.scale.domain = new_domain
|
||||
obj.scale.factor = new_factor
|
||||
LabelPlot.populate_y_labels(obj, cr, 1 / new_factor)
|
||||
LabelPlot.position_x_labels(obj)
|
||||
LabelPlot.position_x_intrvls(obj.plot)
|
||||
LabelPlot.position_y_intrvls(obj.plot)
|
||||
LabelPlot.position_graph_outline(obj.plot)
|
||||
end
|
||||
|
||||
local update = function(obj, cr, value)
|
||||
local scale = obj.scale
|
||||
local new_domain, new_factor = obj.scale._func(value)
|
||||
|
||||
--###tick/tock timers
|
||||
|
||||
local timers = scale.timers
|
||||
local n = #timers
|
||||
for i = n, 1, -1 do
|
||||
local current_timer = timers[i]
|
||||
current_timer.remaining = current_timer.remaining - 1
|
||||
if current_timer.remaining == 0 then
|
||||
_TABLE_REMOVE(timers, i)
|
||||
n = n - 1
|
||||
end
|
||||
end
|
||||
|
||||
--###create/destroy timers
|
||||
if new_domain > scale.previous_domain then --zap all timers less than/equal to s
|
||||
for i = n, 1, -1 do
|
||||
if timers[i].domain <= new_domain then
|
||||
_TABLE_REMOVE(timers, i)
|
||||
n = n - 1
|
||||
end
|
||||
end
|
||||
elseif new_domain < scale.previous_domain then --create new timer for prev_s
|
||||
timers[n + 1] = {
|
||||
domain = scale.previous_domain,
|
||||
factor = scale.previous_factor,
|
||||
remaining = obj.plot.data.n
|
||||
}
|
||||
n = n + 1
|
||||
end
|
||||
|
||||
--###scale data
|
||||
|
||||
if new_domain > scale.domain then --scale up
|
||||
__scale_data(obj, cr, new_domain, new_factor)
|
||||
elseif new_domain < scale.domain then --check timers
|
||||
if n == 0 then --scale down bc no timers to block
|
||||
__scale_data(obj, cr, new_domain, new_factor)
|
||||
elseif scale.timers[1].domain < scale.domain then --scale down to active timer
|
||||
__scale_data(obj, cr, scale.timers[1].domain, scale.timers[1].factor)
|
||||
end
|
||||
end
|
||||
|
||||
scale.previous_domain = new_domain
|
||||
scale.previous_factor = new_factor
|
||||
|
||||
local data = obj.plot.data
|
||||
|
||||
_TABLE_INSERT(data, 1, obj.y + obj.plot.height * (1 - value * scale.factor))
|
||||
if #data == data.n + 2 then data[#data] = nil end
|
||||
--~ print('----------------------------------------------------------------------')
|
||||
--~ print('value', value, 'f', scale.factor, 's', scale.domain, 'curr_s', scale.previous_domain)
|
||||
--~ for i, v in pairs(timers) do
|
||||
--~ print('timers', 'i', i, 's', v.domain, 't', v.remaining, 'f', v.factor)
|
||||
--~ end
|
||||
--~ print('length', #timers)
|
||||
end
|
||||
|
||||
c.draw = LabelPlot.draw
|
||||
c.update = update
|
||||
|
||||
return c
|
|
@ -0,0 +1,36 @@
|
|||
local c = {}
|
||||
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local set = function(obj, percent)
|
||||
obj.percent = percent
|
||||
obj.bar_path = obj._make_bar_path(percent)
|
||||
|
||||
if obj.critical.enabled(percent) then
|
||||
obj.current_source = obj.critical.source
|
||||
else
|
||||
obj.current_source = obj.indicator_source
|
||||
end
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, obj.thickness)
|
||||
_CAIRO_SET_LINE_CAP(cr, obj.cap)
|
||||
|
||||
_CAIRO_APPEND_PATH(cr, obj.path)
|
||||
_CAIRO_SET_SOURCE(cr, obj.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
|
||||
_CAIRO_APPEND_PATH(cr, obj.bar_path)
|
||||
_CAIRO_SET_SOURCE(cr, obj.current_source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,34 @@
|
|||
local c = {}
|
||||
|
||||
local Bar = require 'Bar'
|
||||
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
|
||||
local set = function(obj, index, percent)
|
||||
Bar.set(obj.bars[index], percent)
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
local first_bar = obj.bars[1]
|
||||
_CAIRO_SET_LINE_WIDTH(cr, first_bar.thickness)
|
||||
_CAIRO_SET_LINE_CAP(cr, first_bar.cap)
|
||||
|
||||
for i = 1, obj.bars.n do
|
||||
local bar = obj.bars[i]
|
||||
_CAIRO_SET_SOURCE(cr, bar.source)
|
||||
_CAIRO_APPEND_PATH(cr, bar.path)
|
||||
_CAIRO_STROKE(cr)
|
||||
_CAIRO_SET_SOURCE(cr, bar.current_source)
|
||||
_CAIRO_APPEND_PATH(cr, bar.bar_path)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,19 @@
|
|||
local c = {}
|
||||
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_APPEND_PATH(cr, obj.path)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, obj.thickness)
|
||||
_CAIRO_SET_LINE_CAP(cr, obj.cap)
|
||||
_CAIRO_SET_SOURCE(cr, obj.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,39 @@
|
|||
local c = {}
|
||||
|
||||
local _CR = require 'CR'
|
||||
|
||||
local _CAIRO_NEW_PATH = cairo_new_path
|
||||
local _CAIRO_MOVE_TO = cairo_move_to
|
||||
local _CAIRO_LINE_TO = cairo_line_to
|
||||
local _CAIRO_CLOSE_PATH = cairo_close_path
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_COPY_PATH = cairo_copy_path
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_SET_LINE_JOIN = cairo_set_line_join
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local create_path = function(closed, ...)
|
||||
_CAIRO_NEW_PATH(_CR)
|
||||
_CAIRO_MOVE_TO(_CR, arg[1].x, arg[1].y)
|
||||
for i = 2, #arg do
|
||||
_CAIRO_LINE_TO(_CR, arg[i].x, arg[i].y)
|
||||
end
|
||||
if closed then _CAIRO_CLOSE_PATH(_CR) end
|
||||
return _CAIRO_COPY_PATH(_CR)
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_APPEND_PATH(cr, obj.path)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, obj.thickness)
|
||||
_CAIRO_SET_LINE_JOIN(cr, obj.join)
|
||||
_CAIRO_SET_LINE_CAP(cr, obj.cap)
|
||||
_CAIRO_SET_SOURCE(cr, obj.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
c.create_path = create_path
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,24 @@
|
|||
local c = {}
|
||||
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_JOIN = cairo_set_line_join
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_FILL_PRESERVE = cairo_fill_preserve
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_APPEND_PATH(cr, obj.path)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, obj.thickness)
|
||||
_CAIRO_SET_LINE_JOIN(cr, obj.join)
|
||||
|
||||
_CAIRO_SET_SOURCE(cr, obj.fill_source)
|
||||
_CAIRO_FILL_PRESERVE(cr)
|
||||
|
||||
_CAIRO_SET_SOURCE(cr, obj.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,19 @@
|
|||
local c = {}
|
||||
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_JOIN = cairo_set_line_join
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_APPEND_PATH(cr, obj.path)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, obj.thickness)
|
||||
_CAIRO_SET_LINE_JOIN(cr, obj.join)
|
||||
_CAIRO_SET_SOURCE(cr, obj.source)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,29 @@
|
|||
local c = {}
|
||||
|
||||
local Text = require 'Text'
|
||||
|
||||
local _TONUMBER = tonumber
|
||||
|
||||
local set = function(obj, cr, text, force)
|
||||
if text and text ~= obj.pretext then
|
||||
obj.value = _TONUMBER(text) or 0
|
||||
|
||||
if force == 0 then
|
||||
obj.current_source = obj.critical.source
|
||||
elseif force == 1 then
|
||||
obj.current_source = obj.source
|
||||
else
|
||||
if obj.critical.enabled(obj.value) then
|
||||
obj.current_source = obj.critical.source
|
||||
else
|
||||
obj.current_source = obj.source
|
||||
end
|
||||
end
|
||||
Text.set(obj, cr, text)
|
||||
end
|
||||
end
|
||||
|
||||
c.draw = Text.draw
|
||||
c.set = set
|
||||
|
||||
return c
|
|
@ -0,0 +1,73 @@
|
|||
local c = {}
|
||||
|
||||
local TextColumn = require 'TextColumn'
|
||||
local Rect = require 'Rect'
|
||||
|
||||
local _CAIRO_SET_LINE_WIDTH = cairo_set_line_width
|
||||
local _CAIRO_SET_LINE_CAP = cairo_set_line_cap
|
||||
local _CAIRO_APPEND_PATH = cairo_append_path
|
||||
local _CAIRO_STROKE = cairo_stroke
|
||||
local _CAIRO_SET_FONT_FACE = cairo_set_font_face
|
||||
local _CAIRO_SET_FONT_SIZE = cairo_set_font_size
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_MOVE_TO = cairo_move_to
|
||||
local _CAIRO_SHOW_TEXT = cairo_show_text
|
||||
|
||||
local set = function(obj, cr, col_num, row_num, text)
|
||||
local column = obj.table.columns[col_num]
|
||||
TextColumn.set(column, cr, row_num, text)
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
--draw rectangle
|
||||
Rect.draw(obj, cr)
|
||||
|
||||
--draw headers
|
||||
local tbl = obj.table
|
||||
local columns = tbl.columns
|
||||
|
||||
local first_header = columns[1].header
|
||||
_CAIRO_SET_SOURCE(cr, first_header.source)
|
||||
_CAIRO_SET_FONT_FACE(cr, first_header.font_face)
|
||||
_CAIRO_SET_FONT_SIZE(cr, first_header.font_size)
|
||||
|
||||
for c = 1, tbl.num_columns do
|
||||
local header = columns[c].header
|
||||
_CAIRO_MOVE_TO(cr, header.x, header.y)
|
||||
_CAIRO_SHOW_TEXT(cr, header.text)
|
||||
end
|
||||
|
||||
--draw rows
|
||||
local first_cell = columns[1].rows[1]
|
||||
_CAIRO_SET_SOURCE(cr, first_cell.source)
|
||||
_CAIRO_SET_FONT_FACE(cr, first_cell.font_face)
|
||||
_CAIRO_SET_FONT_SIZE(cr, first_cell.font_size)
|
||||
|
||||
for c = 1, tbl.num_columns do
|
||||
local rows = columns[c].rows
|
||||
for r = 1, rows.n do
|
||||
local row = rows[r]
|
||||
_CAIRO_MOVE_TO(cr, row.x, row.y)
|
||||
_CAIRO_SHOW_TEXT(cr, row.text)
|
||||
end
|
||||
end
|
||||
|
||||
--draw separators
|
||||
local separators = tbl.separators
|
||||
|
||||
local first_separator = separators[1]
|
||||
_CAIRO_SET_SOURCE(cr, first_separator.source)
|
||||
_CAIRO_SET_LINE_WIDTH(cr, first_separator.thickness)
|
||||
_CAIRO_SET_LINE_CAP(cr, first_separator.cap)
|
||||
|
||||
for i = 1, separators.n do
|
||||
local line = separators[i]
|
||||
_CAIRO_APPEND_PATH(cr, line.path)
|
||||
_CAIRO_STROKE(cr)
|
||||
end
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
|
@ -0,0 +1,84 @@
|
|||
local c = {}
|
||||
|
||||
local _STRING_SUB = string.sub
|
||||
local _CAIRO_SET_FONT_FACE = cairo_set_font_face
|
||||
local _CAIRO_SET_FONT_SIZE = cairo_set_font_size
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_MOVE_TO = cairo_move_to
|
||||
local _CAIRO_SHOW_TEXT = cairo_show_text
|
||||
local _CAIRO_TEXT_EXTENTS = cairo_text_extents
|
||||
|
||||
local te = cairo_text_extents_t:create()
|
||||
tolua.takeownership(te)
|
||||
|
||||
local trim_to_length = function(text, len)
|
||||
if #text > len then
|
||||
return _STRING_SUB(text, 1, len)..'...'
|
||||
else
|
||||
return text
|
||||
end
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
_CAIRO_SET_FONT_FACE(cr, obj.font_face)
|
||||
_CAIRO_SET_FONT_SIZE(cr, obj.font_size)
|
||||
_CAIRO_SET_SOURCE(cr, obj.current_source)
|
||||
_CAIRO_MOVE_TO(cr, obj.x, obj.y)
|
||||
_CAIRO_SHOW_TEXT(cr, obj.text)
|
||||
end
|
||||
|
||||
local set = function(obj, cr, text)
|
||||
if text and text ~= obj.pretext then
|
||||
obj.pretext = text
|
||||
|
||||
if obj.append_front then text = obj.append_front..text end
|
||||
if obj.append_end then text = text..obj.append_end end
|
||||
|
||||
if text ~= obj.text then
|
||||
local x_align = obj.x_align
|
||||
local te = te
|
||||
|
||||
_CAIRO_SET_FONT_SIZE(cr, obj.font_size)
|
||||
_CAIRO_SET_FONT_FACE(cr, obj.font_face)
|
||||
_CAIRO_TEXT_EXTENTS(cr, text, te)
|
||||
|
||||
obj.width = te.width
|
||||
|
||||
if x_align == 'left' then obj.delta_x = -te.x_bearing
|
||||
elseif x_align == 'center' then obj.delta_x = -(te.x_bearing + obj.width * 0.5)
|
||||
elseif x_align == 'right' then obj.delta_x = -(te.x_bearing + obj.width)
|
||||
end
|
||||
|
||||
obj.x = obj.x_ref + obj.delta_x
|
||||
end
|
||||
obj.text = text
|
||||
end
|
||||
end
|
||||
|
||||
local move_to_x = function(obj, x)
|
||||
if x ~= obj.x then
|
||||
obj.x_ref = x
|
||||
obj.x = x + obj.delta_x
|
||||
end
|
||||
end
|
||||
|
||||
local move_to_y = function(obj, y)
|
||||
if y ~= obj.y then
|
||||
obj.y_ref = y
|
||||
obj.y = y + obj.delta_y
|
||||
end
|
||||
end
|
||||
|
||||
local move_to = function(obj, x, y)
|
||||
move_to_X(obj, x)
|
||||
move_to_Y(obj, y)
|
||||
end
|
||||
|
||||
c.trim_to_length = trim_to_length
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
c.move_to = move_to
|
||||
c.move_to_x = move_to_x
|
||||
c.move_to_y = move_to_y
|
||||
|
||||
return c
|
|
@ -0,0 +1,38 @@
|
|||
local c = {}
|
||||
|
||||
local Text = require 'Text'
|
||||
|
||||
local _CAIRO_SET_FONT_FACE = cairo_set_font_face
|
||||
local _CAIRO_SET_FONT_SIZE = cairo_set_font_size
|
||||
local _CAIRO_SET_SOURCE = cairo_set_source
|
||||
local _CAIRO_MOVE_TO = cairo_move_to
|
||||
local _CAIRO_SHOW_TEXT = cairo_show_text
|
||||
local _STRING_SUB = string.sub
|
||||
|
||||
local set = function(obj, cr, row_num, text)
|
||||
if obj.max_length then
|
||||
Text.set(obj.rows[row_num], cr, Text.trim_to_length(text, obj.max_length))
|
||||
else
|
||||
Text.set(obj.rows[row_num], cr, text)
|
||||
end
|
||||
end
|
||||
|
||||
local draw = function(obj, cr)
|
||||
local rep_row = obj.rows[1]
|
||||
_CAIRO_SET_FONT_FACE(cr, rep_row.font_face)
|
||||
_CAIRO_SET_FONT_SIZE(cr, rep_row.font_size)
|
||||
_CAIRO_SET_SOURCE(cr, rep_row.source)
|
||||
|
||||
local rows = obj.rows
|
||||
|
||||
for i = 1, rows.n do
|
||||
local row = rows[i]
|
||||
_CAIRO_MOVE_TO(cr, row.x, row.y)
|
||||
_CAIRO_SHOW_TEXT(cr, row.text)
|
||||
end
|
||||
end
|
||||
|
||||
c.set = set
|
||||
c.draw = draw
|
||||
|
||||
return c
|
Loading…
Reference in New Issue