#84 auto-incrementing x with line break function, removed need for get_offset by having parent prepare child template

This commit is contained in:
Mikayla Fischler 2022-07-28 11:17:34 -04:00
parent f4f36b020b
commit 14b24678f9
17 changed files with 144 additions and 124 deletions

View File

@ -11,7 +11,7 @@ local element = {}
---@field parent? graphics_element
---@field id? string element id
---@field x? integer 1 if omitted
---@field y? integer 1 if omitted
---@field y? integer next line if omitted
---@field offset_x? integer 0 if omitted
---@field offset_y? integer 0 if omitted
---@field width? integer parent width if omitted
@ -30,6 +30,7 @@ function element.new(args)
position = { x = 1, y = 1 },
child_offset = { x = 0, y = 0 },
bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1},
next_y = 1,
children = {},
mt = {}
}
@ -46,84 +47,85 @@ function element.new(args)
return "graphics.element{" .. self.elem_type .. "} @ " .. tostring(self)
end
-- SETUP --
---@class graphics_element
local public = {}
-- get the parent window
self.p_window = args.window
if self.p_window == nil and args.parent ~= nil then
self.p_window = args.parent.window()
end
-- check window
assert(self.p_window, "graphics.element{" .. self.elem_type .. "}: no parent window provided")
-- get frame coordinates/size
if args.gframe ~= nil then
protected.frame.x = args.gframe.x
protected.frame.y = args.gframe.y
protected.frame.w = args.gframe.w
protected.frame.h = args.gframe.h
else
local w, h = self.p_window.getSize()
protected.frame.x = args.x or 1
protected.frame.y = args.y or 1
protected.frame.w = args.width or w
protected.frame.h = args.height or h
end
-- inner offsets
if args.offset_x ~= nil then self.child_offset.x = args.offset_x end
if args.offset_y ~= nil then self.child_offset.y = args.offset_y end
-- adjust window frame if applicable
local f = protected.frame
local x = f.x
local y = f.y
-- apply offsets
if args.parent ~= nil then
-- offset x/y
local offset_x, offset_y = args.parent.get_offset()
x = x + offset_x
y = y + offset_y
-- constrain to parent inner width/height
local w, h = self.p_window.getSize()
f.w = math.min(f.w, w - ((2 * offset_x) + (f.x - 1)))
f.h = math.min(f.h, h - ((2 * offset_y) + (f.y - 1)))
end
-- check frame
assert(f.x >= 1, "graphics.element{" .. self.elem_type .. "}: frame x not >= 1")
assert(f.y >= 1, "graphics.element{" .. self.elem_type .. "}: frame y not >= 1")
assert(f.w >= 1, "graphics.element{" .. self.elem_type .. "}: frame width not >= 1")
assert(f.h >= 1, "graphics.element{" .. self.elem_type .. "}: frame height not >= 1")
-- create window
protected.window = window.create(self.p_window, x, y, f.w, f.h, true)
-- init colors
if args.fg_bg ~= nil then
protected.fg_bg = args.fg_bg
elseif args.parent ~= nil then
protected.fg_bg = args.parent.get_fg_bg()
end
-- set colors
protected.window.setBackgroundColor(protected.fg_bg.bkg)
protected.window.setTextColor(protected.fg_bg.fgd)
protected.window.clear()
-- record position
self.position.x, self.position.y = protected.window.getPosition()
-- calculate bounds
self.bounds.x1 = self.position.x
self.bounds.x2 = self.position.x + f.w - 1
self.bounds.y1 = self.position.y
self.bounds.y2 = self.position.y + f.h - 1
setmetatable(public, self.mt)
-------------------------
-- PROTECTED FUNCTIONS --
-------------------------
-- prepare the template
---@param offset_x integer x offset
---@param offset_y integer y offset
---@param next_y integer next line if no y was provided
function protected.prepare_template(offset_x, offset_y, next_y)
-- get frame coordinates/size
if args.gframe ~= nil then
protected.frame.x = args.gframe.x
protected.frame.y = args.gframe.y
protected.frame.w = args.gframe.w
protected.frame.h = args.gframe.h
else
local w, h = self.p_window.getSize()
protected.frame.x = args.x or 1
protected.frame.y = args.y or next_y
protected.frame.w = args.width or w
protected.frame.h = args.height or h
end
-- inner offsets
if args.offset_x ~= nil then self.child_offset.x = args.offset_x end
if args.offset_y ~= nil then self.child_offset.y = args.offset_y end
-- adjust window frame if applicable
local f = protected.frame
local x = f.x
local y = f.y
-- apply offsets
if args.parent ~= nil then
-- constrain to parent inner width/height
local w, h = self.p_window.getSize()
f.w = math.min(f.w, w - ((2 * offset_x) + (f.x - 1)))
f.h = math.min(f.h, h - ((2 * offset_y) + (f.y - 1)))
-- offset x/y
f.x = x + offset_x
f.y = y + offset_y
end
-- check frame
assert(f.x >= 1, "graphics.element{" .. self.elem_type .. "}: frame x not >= 1")
assert(f.y >= 1, "graphics.element{" .. self.elem_type .. "}: frame y not >= 1")
assert(f.w >= 1, "graphics.element{" .. self.elem_type .. "}: frame width not >= 1")
assert(f.h >= 1, "graphics.element{" .. self.elem_type .. "}: frame height not >= 1")
-- create window
protected.window = window.create(self.p_window, f.x, f.y, f.w, f.h, true)
-- init colors
if args.fg_bg ~= nil then
protected.fg_bg = args.fg_bg
elseif args.parent ~= nil then
protected.fg_bg = args.parent.get_fg_bg()
end
-- set colors
protected.window.setBackgroundColor(protected.fg_bg.bkg)
protected.window.setTextColor(protected.fg_bg.fgd)
protected.window.clear()
-- record position
self.position.x, self.position.y = protected.window.getPosition()
-- calculate bounds
self.bounds.x1 = self.position.x
self.bounds.x2 = self.position.x + f.w - 1
self.bounds.y1 = self.position.y
self.bounds.y2 = self.position.y + f.h - 1
end
-- handle a touch event
---@param event table monitor_touch event
@ -139,43 +141,56 @@ function element.new(args)
return nil
end
---@class graphics_element
local public = {}
setmetatable(public, self.mt)
-- get public interface and wrap up element creation
-- get public interface
---@return graphics_element element, element_id id
function protected.complete()
if not self.define_completed then
self.define_completed = true
function protected.get() return public, self.id end
if args.parent then
self.id = args.parent.__add_child(args.id, public)
end
-----------
-- SETUP --
-----------
return public, self.id
else
assert("graphics.element{" .. self.elem_type .. "}: illegal duplicate call to complete()")
end
-- get the parent window
self.p_window = args.window
if self.p_window == nil and args.parent ~= nil then
self.p_window = args.parent.window()
end
-- check window
assert(self.p_window, "graphics.element{" .. self.elem_type .. "}: no parent window provided")
-- prepare the template
if args.parent == nil then
protected.prepare_template(0, 0, 1)
else
self.id = args.parent.__add_child(args.id, protected)
end
----------------------
-- PUBLIC FUNCTIONS --
----------------------
-- get the window object
function public.window() return protected.window end
-- CHILD ELEMENTS --
-- add a child element
---@param key string|nil id
---@param child graphics_element
---@return graphics_element element, integer|string key
---@param child graphics_template
---@return integer|string key
function public.__add_child(key, child)
child.prepare_template(self.child_offset.x, self.child_offset.y, self.next_y)
self.next_y = child.frame.y + child.frame.h
local child_element = child.get()
if key == nil then
table.insert(self.children, child)
return child, #self.children
table.insert(self.children, child_element)
return #self.children
else
self.children[key] = child
return child, key
self.children[key] = child_element
return key
end
end
@ -203,15 +218,16 @@ function element.new(args)
return nil
end
-- AUTO-PLACEMENT --
-- skip a line for automatically placed elements
function public.line_break() self.next_y = self.next_y + 1 end
-- PROPERTIES --
-- get the foreground/background colors
function public.get_fg_bg() return protected.fg_bg end
-- get offset from this element's frame
---@return integer x, integer y
function public.get_offset()
return self.child_offset.x, self.child_offset.y
end
-- get element width
function public.width()
return protected.frame.w
@ -222,6 +238,13 @@ function element.new(args)
return protected.frame.h
end
-- get the control value reading
function public.get_value()
return protected.get_value()
end
-- FUNCTION CALLBACKS --
-- handle a monitor touch
---@param event monitor_touch monitor touch event
function public.handle_touch(event)
@ -244,10 +267,7 @@ function element.new(args)
protected.on_update(...)
end
-- get the control value reading
function public.get_value()
return protected.get_value()
end
-- VISIBILITY --
-- show the element
function public.show()

View File

@ -63,7 +63,7 @@ local function push_button(args)
args.callback()
end
return e.complete()
return e.get()
end
return push_button

View File

@ -65,7 +65,7 @@ local function scram_button(args)
args.callback()
end
return e.complete()
return e.get()
end
return scram_button

View File

@ -112,7 +112,7 @@ local function spinbox(args)
---@return number|integer
function e.get_value() return value end
return e.complete()
return e.get()
end
return spinbox

View File

@ -73,7 +73,7 @@ local function switch_button(args)
args.callback(state)
end
return e.complete()
return e.get()
end
return switch_button

View File

@ -15,7 +15,7 @@ local element = require("graphics.element")
---@param args displaybox_args
local function displaybox(args)
-- create new graphics element base object
return element.new(args).complete()
return element.new(args).get()
end
return displaybox

View File

@ -17,7 +17,7 @@ local element = require("graphics.element")
---@return graphics_element element, element_id id
local function div(args)
-- create new graphics element base object
return element.new(args).complete()
return element.new(args).get()
end
return div

View File

@ -93,7 +93,7 @@ local function data(args)
-- initial value draw
e.on_update(args.value)
return e.complete()
return e.get()
end
return data

View File

@ -99,7 +99,7 @@ local function hbar(args)
-- initialize to 0
e.on_update(0)
return e.complete()
return e.get()
end
return hbar

View File

@ -62,7 +62,7 @@ local function icon(args)
-- initial icon draw
e.on_update(args.value or 1)
return e.complete()
return e.get()
end
return icon

View File

@ -45,7 +45,7 @@ local function indicator_light(args)
e.on_update(false)
e.window.write(args.label)
return e.complete()
return e.get()
end
return indicator_light

View File

@ -72,7 +72,7 @@ local function state_indicator(args)
-- initial draw
e.on_update(args.value or 1)
return e.complete()
return e.get()
end
return state_indicator

View File

@ -78,7 +78,7 @@ local function vbar(args)
end
end
return e.complete()
return e.get()
end
return vbar

View File

@ -141,7 +141,7 @@ local function pipenet(args)
end
return e.complete()
return e.get()
end
return pipenet

View File

@ -110,7 +110,7 @@ local function rectangle(args)
end
end
return e.complete()
return e.get()
end
return rectangle

View File

@ -52,7 +52,7 @@ local function textbox(args)
e.window.write(lines[i])
end
return e.complete()
return e.get()
end
return textbox

View File

@ -79,7 +79,7 @@ local function tiling(args)
end
end
return e.complete()
return e.get()
end
return tiling