summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua433
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