diff options
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua')
-rw-r--r-- | Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua new file mode 100644 index 0000000..292c4a6 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua @@ -0,0 +1,433 @@ +--[[ + A library to facilitate primitive creation and manipulation. +]] + +windower.prim.saved_prims = {} +local prims = {} +local meta = {} + +_libs = _libs or {} +_libs.prims = prims + +_meta = _meta or {} +_meta.Prim = _meta.Prim or {} +_meta.Prim.__class = 'Prim' +_meta.Prim.__index = prims + +--[[ + settings = { + pos = {x,y}, + w = number, + color = {a,r,g,b}, + h = number, + visible = boolean, + image = boolean, + texture = string, + fit = boolean, + tile = {x_rep,y_rep} + } +--]] + +local events = { + left_click = true, + right_click = true, + middle_click = true, + scroll_up = true, + scroll_down = true, + hover = true, + hover_begin = true, + hover_end = true, + drag = true, + right_drag = true, +} + +function prims.new(settings) + local t = {} + settings = settings or {} + settings.pos = settings.pos or {0, 0} + local m = { + color = settings.color and {unpack(settings.color)} or {255, 255, 255, 255}, + width = settings.w or 0, + height = settings.h or 0, + visible = settings.visible or false, + image = settings.set_texture or false, + texture = settings.texture, + fit = settings.fit_texture or false, + tile = settings.tile or {1, 1}, + events = {} + } + m.x1, m.x2 = m.width >= 0 and settings.pos[1], m.width + settings.pos[1] or m.width + settings.pos[1], settings.pos[1] + m.y1, m.y2 = m.height >= 0 and m.height + settings.pos[2], settings.pos[2] or settings.pos[2], m.height + settings.pos[2] + + meta[t] = m + m.name = (_addon and _addon.name or 'prim') .. '_gensym_' .. tostring(t):sub(8) .. '_%.8X':format(16^8 * math.random()):sub(3) + windower.prim.create(m.name) + --defaults for prims seem pointless, but these will prevent errors if people forget information. + + if settings.color then + windower.prim.set_color(m.name, unpack(m.color)) + end + + windower.prim.set_position(m.name, m.x1, m.y2) + windower.prim.set_size(m.name, m.width, m.height) + windower.prim.set_visibility(m.name, m.visible) + + if m.image then + windower.prim.set_fit_to_texture(m.name, m.fit) + windower.prim.set_texture(m.name, m.texture) + if settings.tile then + windower.prim.set_repeat(m.name, unpack(m.tile)) + end + end + + return setmetatable(t, _meta.Prim) +end + +-- Makes the primitive visible +function prims.show(t) + windower.prim.set_visibility(meta[t].name, true) + meta[t].visible = true +end + +-- Makes the primitive invisible +function prims.hide(t) + windower.prim.set_visibility(meta[t].name, false) + meta[t].visible = false +end + +--[[ + The following methods all either set the respective values or return them, if no arguments to set them are provided. +]] + +-- Returns whether or not the prim object is visible +function prims.visible(t, visible) + if visible == nil then + return meta[t].visible + end + windower.prim.set_visibility(meta[t].name, visible) + meta[t].visible = visible +end + +function prims.append_label(t, str) +end + +function prims.pos(t, x, y) + if not y then + return meta[t].width >= 0 and meta[t].x1 or meta[t].x2, + meta[t].height >= 0 and meta[t].y2 or meta[t].y1 + end + + local m = meta[t] + windower.prim.set_position(m.name, x, y) + + m.x1, m.x2 = m.width >= 0 and x, m.width + x or m.width + x, x + m.y1, m.y2 = m.height >= 0 and m.height + y, y or y, m.height + y +end + +function prims.pos_x(t, x) + if not x then + return meta[t].width >= 0 and meta[t].x1 or meta[t].x2 + end + + local m = meta[t] + windower.prim.set_position(m.name, x, meta[t].height >= 0 and m.y2 or m.y1) -- swapped these + + m.x1, m.x2 = m.width >= 0 and x, m.width + x or m.width + x, x +end + +function prims.pos_y(t, y) + if not y then + return meta[t].height >= 0 and meta[t].y2 or meta[t].y1 -- swapped these + end + + local m = meta[t] + windower.prim.set_position(m.name, m.width >= 0 and m.x1 or m.x2, y) + + m.y1, m.y2 = m.height >= 0 and m.height + y, y or y, m.height + y +end + +function prims.right(t, d) + local m = meta[t] + t:pos_x((m.width >= 0 and m.x1 or m.x2) + d) +end + +function prims.left(t, d) + local m = meta[t] + t:pos_x((m.width >= 0 and m.x1 or m.x2) - d) +end + +function prims.up(t, d) + local m = meta[t] + t:pos_y((m.height >= 0 and m.y2 or m.y1) - d) +end + +function prims.down(t, d) + local m = meta[t] + t:pos_y((m.height >= 0 and m.y2 or m.y1) + d) +end + +function prims.width(t, width) + if not width then + return meta[t].width + end + + local m = meta[t] + local w = m.width + + windower.prim.set_size(m.name, width, m.height) + m.width = width + if w * width >= 0 then + if w >= 0 then + m.x2 = m.x1 + width + else + m.x1 = m.x2 + width + end + else + if w >= 0 then + m.x1, m.x2 = m.x2 + width, m.x2 + else + m.x1, m.x2 = m.x1 + width, m.x1 + end + end +end + +local newanimator = function(n) + return function(fn) + while fn() do + coroutine.sleep(n) + end + end +end + +function prims.width_smooth(t, width, time_interval, dwidth) + local m = meta[t] + m.width_actual = width + + if not t.animator then + dwidth = (width - m.width) * dwidth > 0 and dwidth or -dwidth + t.animator = newanimator(time_interval) + t.animator(function() + local n = m.width + dwidth + if dwidth > 0 and n >= m.width_actual or dwidth < 0 and n <= m.width_actual then + t:width(m.width_actual) + t.animator = nil + return false + else + t:width(n) + return true + end + end) + end +end + +function prims.height(t, height) + if not height then + return meta[t].height + end + + local m = meta[t] + local h = m.height + + windower.prim.set_size(m.name, m.width, height) + m.height = height + if h * height >= 0 then + if h >= 0 then + m.y1 = m.y2 + height + else + m.y2 = m.y1 + height + end + else + if h >= 0 then + m.y1, m.y2 = m.y2, m.y2 + height + else + m.y1, m.y2 = m.y1 + height, m.y1 + end + end +end + +function prims.height_smooth(t, height, time_interval, dheight) + local m = meta[t] + m.height_actual = height + + if not t.animator then + dheight = (height - m.height) * dheight > 0 and dheight or -dheight + t.animator = newanimator(time_interval) + t.animator(function() + local n = m.height + dheight + if dheight > 0 and n >= m.height_actual or dheight < 0 and n <= m.height_actual then + t:height(m.height_actual) + t.animator = nil + return false + else + t:height(n) + return true + end + end) + end +end + +function prims.size(t, width, height) + if not height then + return meta[t].width, meta[t].height + end + + local m = meta[t] + local w = m.width + local h = m.height + + if w * width >= 0 then + if w >= 0 then + m.x2 = m.x1 + width + else + m.x1 = m.x2 + width + end + else + if w >= 0 then + m.x1, m.x2 = m.x2 + width, m.x2 + else + m.x1, m.x2 = m.x1 + width, m.x1 + end + end + + if h * height >= 0 then + if h >= 0 then + m.y1 = m.y2 + height + else + m.y2 = m.y1 + height + end + else + if h >= 0 then + m.y1, m.y2 = m.y2, m.y2 + height + else + m.y1, m.y2 = m.y1 + height, m.y1 + end + end + + windower.prim.set_size(m.name, width, height) + m.width, m.height = width, height +end + +function prims.extents(t) + return meta[t].width, meta[t].height +end + +function prims.color(t, red, green, blue) + if not blue then + return unpack(meta[t].color,2,4) + end + + local m = meta[t] + windower.prim.set_color(m.name, m.color[1], red, green, blue) + m.color[2], m.color[3], m.color[4] = red, green, blue +end + +function prims.alpha(t, alpha) + if not alpha then + return meta[t].color[1] + end + local m = meta[t] + windower.prim.set_color(m.name, alpha, m.color[2], m.color[3], m.color[4]) + m.color[1] = alpha +end + +function prims.argb(t, a, r, g, b) + if not b then + return unpack(meta[t].color) + end + + local m = meta[t] + windower.prim.set_color(m.name, a, r, g, b) + m.color[1], m.color[2], m.color[3], m.color[4] = a, r, g, b +end +-- Sets/returns prim transparency. Based on percentage values, with 1 being fully transparent, while 0 is fully opaque. +function prims.transparency(t, alpha) + if not alpha then + return 1 - meta[t].color[1]/255 + end + + alpha = math.floor(255*(1-alpha)) + local m = meta[t] + windower.prim.set_color(m.name, alpha, m.color[2], m.color[3], m.color[4]) + m.color[1] = alpha +end + +function prims.tile(t, x_rep, y_rep) + if not y_rep then + return unpack(meta[t].tile) + end + + local m = meta[t] + windower.prim.set_repeat(m.name, x_rep, y_rep) + m.tile[1], m.tile[2] = x_rep, y_rep +end + +function prims.texture(t, path) + if not path then + return meta[t].texture + end + + windower.prim.set_texture(meta[t].name, path) + meta[t].texture = path +end + +function prims.fit(t, fit) + if fit == nil then + return meta[t].fit + end + + windower.prim.set_fit_to_texture(meta[t].name, fit) + meta[t].fit = fit +end + +function prims.hover(t, x, y) + local m = meta[t] + return (m.x2 >= x + and m.x1 <= x + and m.y1 >= y + and m.y2 <= y) +end + +function prims.destroy(t) + windower.prim.delete(meta[t].name) + meta[t] = nil + t = nil +end + +function prims.get_events(t) + return meta[t].events +end + +function prims.register_event(t, event, fn) + if not events[event] then + error('The event ' .. event .. ' is not available to the ' .. class(t) .. ' class.') + return + end + + local m = meta[t].events + + m[event] = m[event] or {n = 0} + local n = #m[event] + 1 + m[event][n] = fn + m[event].n = m[event].n > n and m[event].n or n + + return n +end + +function prims.unregister_event(t, event, n) + if not (events[event] and meta[t].events[event]) then + return + end + + if type(n) == 'number' then + meta[t].events[event][n] = nil + else + for i = 1, meta[t].events[event].n do + if meta[t].events[event][i] == n then + meta[t].events[event][i] = nil + return + end + end + end +end + +return prims |