mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#226 updated the other controls for new mouse events, added tabbar control
This commit is contained in:
parent
4ef1915137
commit
2c2f936232
@ -28,6 +28,7 @@ local element = {}
|
||||
---|sidebar_args
|
||||
---|spinbox_args
|
||||
---|switch_button_args
|
||||
---|tabbar_args
|
||||
---|alarm_indicator_light
|
||||
---|core_map_args
|
||||
---|data_indicator_args
|
||||
|
@ -141,7 +141,7 @@ local function hazard_button(args)
|
||||
end
|
||||
|
||||
-- handle mouse interaction
|
||||
---@param event mouse_interaction
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
if e.enabled then
|
||||
if core.events.was_clicked(event.type) then
|
||||
|
@ -70,7 +70,7 @@ local function push_button(args)
|
||||
end
|
||||
|
||||
-- handle mouse interaction
|
||||
---@param event mouse_interaction
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
if e.enabled then
|
||||
if event.type == CLICK_TYPE.TAP then
|
||||
|
@ -1,5 +1,6 @@
|
||||
-- Radio Button Graphics Element
|
||||
|
||||
local core = require("graphics.core")
|
||||
local element = require("graphics.element")
|
||||
|
||||
---@class radio_button_args
|
||||
@ -82,10 +83,10 @@ local function radio_button(args)
|
||||
-- handle mouse interaction
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
-- determine what was pressed
|
||||
if e.enabled then
|
||||
if args.options[event.y] ~= nil then
|
||||
e.value = event.y
|
||||
if e.enabled and core.events.was_clicked(event.type) and (event.initial.y == event.current.y) then
|
||||
-- determine what was pressed
|
||||
if args.options[event.current.y] ~= nil then
|
||||
e.value = event.current.y
|
||||
draw()
|
||||
args.callback(e.value)
|
||||
end
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
local tcd = require("scada-common.tcallbackdsp")
|
||||
|
||||
local core = require("graphics.core")
|
||||
local element = require("graphics.element")
|
||||
|
||||
local CLICK_TYPE = core.events.CLICK_TYPE
|
||||
|
||||
---@class sidebar_tab
|
||||
---@field char string character identifier
|
||||
---@field color cpair tab colors (fg/bg)
|
||||
@ -39,7 +42,10 @@ local function sidebar(args)
|
||||
|
||||
-- show the button state
|
||||
---@param pressed boolean if the currently selected tab should appear as actively pressed
|
||||
local function draw(pressed)
|
||||
---@param pressed_idx? integer optional index to show as held (that is not yet selected)
|
||||
local function draw(pressed, pressed_idx)
|
||||
pressed_idx = pressed_idx or e.value
|
||||
|
||||
for i = 1, #args.tabs do
|
||||
local tab = args.tabs[i] ---@type sidebar_tab
|
||||
|
||||
@ -47,7 +53,7 @@ local function sidebar(args)
|
||||
|
||||
e.window.setCursorPos(1, y)
|
||||
|
||||
if pressed and e.value == i then
|
||||
if pressed and i == pressed_idx then
|
||||
e.window.setTextColor(e.fg_bg.fgd)
|
||||
e.window.setBackgroundColor(e.fg_bg.bkg)
|
||||
else
|
||||
@ -74,16 +80,27 @@ local function sidebar(args)
|
||||
function e.handle_mouse(event)
|
||||
-- determine what was pressed
|
||||
if e.enabled then
|
||||
local idx = math.ceil(event.y / 3)
|
||||
local cur_idx = math.ceil(event.current.y / 3)
|
||||
local ini_idx = math.ceil(event.initial.y / 3)
|
||||
|
||||
if args.tabs[idx] ~= nil then
|
||||
e.value = idx
|
||||
draw(true)
|
||||
|
||||
-- show as unpressed in 0.25 seconds
|
||||
tcd.dispatch(0.25, function () draw(false) end)
|
||||
|
||||
args.callback(e.value)
|
||||
if args.tabs[cur_idx] ~= nil then
|
||||
if event.type == CLICK_TYPE.TAP then
|
||||
e.value = cur_idx
|
||||
draw(true)
|
||||
-- show as unpressed in 0.25 seconds
|
||||
tcd.dispatch(0.25, function () draw(false) end)
|
||||
args.callback(e.value)
|
||||
elseif event.type == CLICK_TYPE.DOWN then
|
||||
draw(true, cur_idx)
|
||||
elseif event.type == CLICK_TYPE.UP then
|
||||
if cur_idx == ini_idx then
|
||||
e.value = cur_idx
|
||||
draw(false)
|
||||
args.callback(e.value)
|
||||
else draw(false) end
|
||||
elseif event.type == CLICK_TYPE.EXITED then
|
||||
draw(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local core = require("graphics.core")
|
||||
local element = require("graphics.element")
|
||||
|
||||
---@class spinbox_args
|
||||
@ -130,19 +131,22 @@ local function spinbox(args)
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
-- only handle if on an increment or decrement arrow
|
||||
if e.enabled and event.x ~= dec_point_x then
|
||||
local idx = util.trinary(event.x > dec_point_x, event.x - 1, event.x)
|
||||
if digits[idx] ~= nil then
|
||||
if event.y == 1 then
|
||||
-- increment
|
||||
digits[idx] = digits[idx] + 1
|
||||
elseif event.y == 3 then
|
||||
-- decrement
|
||||
digits[idx] = digits[idx] - 1
|
||||
end
|
||||
if e.enabled and core.events.was_clicked(event.type) and
|
||||
(event.current.x ~= dec_point_x) and (event.current.y ~= 2) then
|
||||
if event.current.x == event.initial.x and event.current.y == event.initial.y then
|
||||
local idx = util.trinary(event.current.x > dec_point_x, event.current.x - 1, event.current.x)
|
||||
if digits[idx] ~= nil then
|
||||
if event.current.y == 1 then
|
||||
-- increment
|
||||
digits[idx] = digits[idx] + 1
|
||||
elseif event.current.y == 3 then
|
||||
-- decrement
|
||||
digits[idx] = digits[idx] - 1
|
||||
end
|
||||
|
||||
update_value()
|
||||
show_num()
|
||||
update_value()
|
||||
show_num()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,5 +1,6 @@
|
||||
-- Button Graphics Element
|
||||
|
||||
local core = require("graphics.core")
|
||||
local element = require("graphics.element")
|
||||
|
||||
---@class switch_button_args
|
||||
@ -63,8 +64,9 @@ local function switch_button(args)
|
||||
draw_state()
|
||||
|
||||
-- handle mouse interaction
|
||||
function e.handle_mouse(_)
|
||||
if e.enabled then
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
if e.enabled and core.events.was_clicked(event.type) then
|
||||
-- toggle state
|
||||
e.value = not e.value
|
||||
draw_state()
|
||||
|
130
graphics/elements/controls/tabbar.lua
Normal file
130
graphics/elements/controls/tabbar.lua
Normal file
@ -0,0 +1,130 @@
|
||||
-- Tab Bar Graphics Element
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local core = require("graphics.core")
|
||||
local element = require("graphics.element")
|
||||
|
||||
---@class tabbar_tab
|
||||
---@field name string tab name
|
||||
---@field color cpair tab colors (fg/bg)
|
||||
---@field _start_x integer starting touch x range (inclusive)
|
||||
---@field _end_x integer ending touch x range (inclusive)
|
||||
|
||||
---@class tabbar_args
|
||||
---@field tabs table tab options
|
||||
---@field callback function function to call on tab change
|
||||
---@field min_width? integer text length + 2 if omitted
|
||||
---@field parent graphics_element
|
||||
---@field id? string element id
|
||||
---@field x? integer 1 if omitted
|
||||
---@field y? integer 1 if omitted
|
||||
---@field width? integer parent width if omitted
|
||||
---@field fg_bg? cpair foreground/background colors
|
||||
|
||||
-- new tab selector
|
||||
---@param args tabbar_args
|
||||
---@return graphics_element element, element_id id
|
||||
local function tabbar(args)
|
||||
assert(type(args.tabs) == "table", "graphics.elements.controls.tabbar: tabs is a required field")
|
||||
assert(#args.tabs > 0, "graphics.elements.controls.tabbar: at least one tab is required")
|
||||
assert(type(args.callback) == "function", "graphics.elements.controls.tabbar: callback is a required field")
|
||||
assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0),
|
||||
"graphics.elements.controls.tabbar: min_width must be nil or a number > 0")
|
||||
|
||||
-- always 1 tall
|
||||
args.height = 1
|
||||
|
||||
-- determine widths
|
||||
local max_width = 1
|
||||
for i = 1, #args.tabs do
|
||||
local opt = args.tabs[i] ---@type tabbar_tab
|
||||
if string.len(opt.name) > max_width then
|
||||
max_width = string.len(opt.name)
|
||||
end
|
||||
end
|
||||
|
||||
local button_width = math.max(max_width, args.min_width or 0)
|
||||
|
||||
-- create new graphics element base object
|
||||
local e = element.new(args)
|
||||
|
||||
assert(e.frame.w >= (button_width * #args.tabs), "graphics.elements.controls.tabbar: width insufficent to display all tabs")
|
||||
|
||||
-- default to 1st tab
|
||||
e.value = 1
|
||||
|
||||
-- calculate required tab dimension information
|
||||
local next_x = 1
|
||||
for i = 1, #args.tabs do
|
||||
local tab = args.tabs[i] ---@type tabbar_tab
|
||||
|
||||
tab._start_x = next_x
|
||||
tab._end_x = next_x + button_width - 1
|
||||
|
||||
next_x = next_x + button_width
|
||||
end
|
||||
|
||||
-- show the tab state
|
||||
local function draw()
|
||||
for i = 1, #args.tabs do
|
||||
local tab = args.tabs[i] ---@type tabbar_tab
|
||||
|
||||
e.window.setCursorPos(tab._start_x, 1)
|
||||
|
||||
if e.value == i then
|
||||
e.window.setTextColor(tab.color.fgd)
|
||||
e.window.setBackgroundColor(tab.color.bkg)
|
||||
else
|
||||
e.window.setTextColor(e.fg_bg.fgd)
|
||||
e.window.setBackgroundColor(e.fg_bg.bkg)
|
||||
end
|
||||
|
||||
e.window.write(util.pad(tab.name, button_width))
|
||||
end
|
||||
end
|
||||
|
||||
-- check which tab a given x is within
|
||||
---@return integer|nil button index or nil if not within a tab
|
||||
local function which_tab(x)
|
||||
for i = 1, #args.tabs do
|
||||
local tab = args.tabs[i] ---@type tabbar_tab
|
||||
if x >= tab._start_x and x <= tab._end_x then return i end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- handle mouse interaction
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
-- determine what was pressed
|
||||
if e.enabled and core.events.was_clicked(event.type) then
|
||||
-- a button may have been pressed, which one was it?
|
||||
local tab_ini = which_tab(event.initial.x)
|
||||
local tab_cur = which_tab(event.current.x)
|
||||
|
||||
-- mouse up must always have started with a mouse down on the same tab to count as a click
|
||||
-- tap always has identical coordinates, so this always passes for taps
|
||||
if tab_ini == tab_cur and tab_cur ~= nil then
|
||||
e.value = tab_cur
|
||||
draw()
|
||||
args.callback(e.value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- set the value
|
||||
---@param val integer new value
|
||||
function e.set_value(val)
|
||||
e.value = val
|
||||
draw()
|
||||
end
|
||||
|
||||
-- initial draw
|
||||
draw()
|
||||
|
||||
return e.get()
|
||||
end
|
||||
|
||||
return tabbar
|
Loading…
Reference in New Issue
Block a user