From acda37edd13b9c6aca16cd1d1ee9183368d5b40c Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Fri, 9 Apr 2021 23:11:31 -0400 Subject: lua print table put_line a do_menu alternative add stylized lines to lua the exported do_menu has a severe limitation of 64 items it also requires double the memory put_line is the way rockbox builds menus update printtable user config from core -- done code cleanup fixed for 1-bit screens changed button behavior fixed for 2-bit screens Change-Id: I4de55e42685aa1d2f53a33bc8e980827864e810b --- apps/plugins/lua/include_lua/print.lua | 165 +++++++++++++----- apps/plugins/lua/include_lua/printmenus.lua | 249 ++++++++++++++++++++++++++++ apps/plugins/lua/include_lua/printtable.lua | 63 ++++--- apps/plugins/lua/lua.make | 2 +- apps/plugins/lua/rbdefines_helper.pl | 1 + apps/plugins/lua/rocklib_img.c | 148 +++++++++++++++-- apps/plugins/lua_scripts.lua | 22 ++- apps/plugins/lua_scripts/file_browser.lua | 2 +- apps/plugins/lua_scripts/fileview.lua | 2 +- apps/plugins/lua_scripts/fileviewers.lua | 3 + apps/plugins/lua_scripts/printmenu.lua | 83 ---------- apps/plugins/lua_scripts/rlimg.lua | 2 +- apps/plugins/lua_scripts/tagnav.lua | 2 +- 13 files changed, 581 insertions(+), 163 deletions(-) create mode 100644 apps/plugins/lua/include_lua/printmenus.lua delete mode 100755 apps/plugins/lua_scripts/printmenu.lua diff --git a/apps/plugins/lua/include_lua/print.lua b/apps/plugins/lua/include_lua/print.lua index 3fb19bef1f..3b4c389848 100644 --- a/apps/plugins/lua/include_lua/print.lua +++ b/apps/plugins/lua/include_lua/print.lua @@ -123,6 +123,49 @@ local _print = {} do return w, h, msg end -------------------------------------------------------------------------------- + local function set_linedesc(t_linedesc, opts) + local o = opts or _print.opt.get(true) + --local out = function() local t = {} for k, v in pairs(o) do t[#t + 1] = tostring(k) t[#t + 1] = tostring(v) end return table.concat(t, "\n") end + --rb.splash_scroller(1000, out()) + local linedesc ={ + --These are the defaults - changes will be made below if you supplied t_linedesc + indent = 0, -- internal indent text + line = 0, -- line index within group + nlines = 1, -- selection grouping + offset = 0, -- internal item offset + scroll = true, + selected = false, --internal + separator_height = 0, + line_separator = false, + show_cursor = false, + show_icons = false, + icon = -1, + icon_fn = function() return -1 end, + style = rb.STYLE_COLORBAR, + text_color = o.fg_pattern or WHITE, + line_color = o.bg_pattern or BLACK, + line_end_color= o.bg_pattern or BLACK, + } + if type(t_linedesc) == "table" then + + if not o.linedesc then + o.linedesc = {} + for k, v in pairs(linedesc) do + o.linedesc[k] = v + end + end + + for k, v in pairs(t_linedesc) do + o.linedesc[k] = v + end + if o.linedesc.separator_height > 0 then + o.linedesc.line_separator = true + end + return + end + o.linedesc = linedesc + return o.linedesc + end -- set defaults for print view local function set_defaults() @@ -138,11 +181,13 @@ local _print = {} do line = 1, max_line = _NIL, col = 0, - ovfl = "auto", - justify = "left", - autoupdate = true, - drawsep = false, + header = false, --Internal use - treats first entry as header + ovfl = "auto", -- auto, manual, none + justify = "left", --left, center, right + autoupdate = true, --updates screen as items are added + drawsep = false, -- separator between items } + set_linedesc(nil, _p_opts) -- default line display _p_opts.max_line = max_lines(_p_opts) s_lines, col_buf = {}, {} @@ -187,29 +232,16 @@ local _print = {} do -- helper function sets up colors/marker for selected items local function show_selected(iLine, msg) - local o = get_settings() -- using a copy of opts so changes revert - - if s_lines[iLine] == true then - if not rb.lcd_set_background then - o.drawmode = bit.bxor(o.drawmode, 4) - else - o.fg_pattern = o.bg_pattern - o.bg_pattern = o.sel_pattern - end - -- alternative selection method - --msg = "> " .. msg - end - - if not o then rb.set_viewport() return end - if rb.LCD_DEPTH == 2 then -- invert 2-bit screens + local o = get_settings() -- using a copy of opts so changes revert + if not o then rb.set_viewport() return end o.fg_pattern = 3 - o.fg_pattern o.bg_pattern = 3 - o.bg_pattern + rb.set_viewport(o) + o = _NIL + else + show_selected = function() end -- no need to check again end - - rb.set_viewport(o) - - o = _NIL end -- sets line explicitly or increments line if line is _NIL @@ -274,31 +306,82 @@ local _print = {} do s_lines[iLine] = true end - -- Internal print function + -- Internal print function local function print_internal(t_opts, x, w, h, msg) + local linedesc + local line_separator = false local o = t_opts - if o.justify == "center" then - x = x + (o.width - w) / 2 - elseif o.justify == "right" then - x = x + (o.width - w) + local ld = o.linedesc or set_linedesc() + local show_cursor = ld.show_cursor or 0 + local line_indent = 0 + + local linestyle = ld.style or rb.STYLE_COLORBAR + + if o.justify ~= "left" then + line_indent = (o.width - w) --"right" + if o.justify == "center" then + line_indent = line_indent / 2 + end end local line = o.line - 1 -- rb is 0-based lua is 1-based - if(o.ovfl == "auto" and w >= o.width) then -- -o.x - rb.lcd_puts_scroll(0, line, msg) + + if o.ovfl == "manual" then --save msg for later side scroll + col_buf_insert(msg, o.line, o) + end + + -- bit of a pain to set the fields this way but its much more efficient than iterating a table to set them + local function set_desc(tld, scroll, separator_height, selected, style, indent, text_color, line_color, line_end_color) + tld.scroll = scroll + tld.separator_height = separator_height + tld.selected = selected + tld.style = style + tld.indent = indent + tld.text_color = text_color + tld.line_color = line_color + tld.line_end_color = line_end_color + end + + line_separator = ld.line_separator + + if o.line == 1 and o.header then + --rb scroller doesn't like negative offset! + local indent = line_indent < 0 and 0 or line_indent + set_desc(ld, true, 1, false, rb.STYLE_DEFAULT, + indent, o.fg_pattern, o.bg_pattern, o.bg_pattern) + ld.show_cursor = false + elseif s_lines[o.line] then + --/* Display line selector */ + local style = show_cursor == true and rb.STYLE_DEFAULT or linestyle + + local indent = line_indent < 0 and 0 or line_indent + --rb scroller doesn't like negative offset! + local ovfl = (o.ovfl == "auto" and w >= o.width and x == 0) + set_desc(ld, ovfl, 0, true, style, indent, + o.bg_pattern, o.sel_pattern, o.sel_pattern) else - rb.lcd_putsxy(x, line * h, msg) - if o.ovfl == "manual" then --save msg for later side scroll - col_buf_insert(msg, o.line, o) - end + set_desc(ld, false, 0, false, rb.STYLE_DEFAULT,line_indent, + o.fg_pattern, o.bg_pattern, o.bg_pattern) end - if o.drawsep == true then - if s_lines[o.line] == true then - rb.set_viewport(o) --nned to revert drawmode if selected + + if ld.show_icons then + ld.icon = ld.icon_fn(line, ld.icon or -1) + end + + rb.lcd_put_line(x, line *h, msg, ld) + + ld.show_cursor = show_cursor + ld.style = linestyle + if line_separator then + if ld.selected == true then + rb.set_viewport(o) -- revert drawmode if selected end rb.lcd_drawline(0, line * h, o.width, line * h) + rb.lcd_drawline(0, line * h + h, o.width, line * h + h) --only to add the last line + -- but we don't have an idea which line is the last line here so every line is the last line! end + --only update the line we changed update_line(o.autoupdate, o, line, h) @@ -308,7 +391,7 @@ local _print = {} do -- Helper function that acts mostly like a normal printf() would local function printf(fmt, v1, ...) local o = get_settings(true) - local w, h, msg + local w, h, msg, rep local line = o.line - 1 -- rb is 0-based lua is 1-based if not (fmt) or (fmt) == "\n" then -- handles blank line / single '\n' @@ -322,6 +405,9 @@ local _print = {} do return o.line, o.max_line, o.width, h end + fmt, rep = fmt.gsub(fmt or "", "%%h", "%%s") + o.header = (rep == 1) + msg = string.format(fmt, v1, ...) show_selected(o.line, msg) @@ -337,6 +423,8 @@ local _print = {} do local function set_column(x) local o = get_settings() if o.ovfl ~= "manual" then return end -- no buffer stored to scroll + rb.lcd_scroll_stop() + local res, w, h, str, line for key, value in pairs(col_buf) do @@ -367,6 +455,7 @@ local _print = {} do _print.opt.justify = set_justify _print.opt.sel_line = select_line _print.opt.line = set_line + _print.opt.linedesc = set_linedesc _print.opt.autoupdate = set_update _print.clear = clear _print.f = printf diff --git a/apps/plugins/lua/include_lua/printmenus.lua b/apps/plugins/lua/include_lua/printmenus.lua new file mode 100644 index 0000000000..3e8f870104 --- /dev/null +++ b/apps/plugins/lua/include_lua/printmenus.lua @@ -0,0 +1,249 @@ +--[[ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2017 William Wilgus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +]] +if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end + +require("printtable") + +local _clr = require("color") + +local _LCD = rb.lcd_framebuffer() + +--[[ -- dpad requires: +require("actions") -- Contains rb.actions & rb.contexts +local _timer = require("timer") +-- Button definitions -- +local CANCEL_BUTTON = rb.actions.PLA_CANCEL +local DOWN_BUTTON = rb.actions.PLA_DOWN +local DOWNR_BUTTON = rb.actions.PLA_DOWN_REPEAT +local EXIT_BUTTON = rb.actions.PLA_EXIT +local LEFT_BUTTON = rb.actions.PLA_LEFT +local LEFTR_BUTTON = rb.actions.PLA_LEFT_REPEAT +local RIGHT_BUTTON = rb.actions.PLA_RIGHT +local RIGHTR_BUTTON = rb.actions.PLA_RIGHT_REPEAT +local SEL_BUTTON = rb.actions.PLA_SELECT +local SELREL_BUTTON = rb.actions.PLA_SELECT_REL +local SELR_BUTTON = rb.actions.PLA_SELECT_REPEAT +local UP_BUTTON = rb.actions.PLA_UP +local UPR_BUTTON = rb.actions.PLA_UP_REPEAT +]] +-------------------------------------------------------------------------------- +local function get_core_settings() + if rb.core_color_table ~= nil and rb.core_talk_table ~= nil and + rb.core_list_settings_table ~= nil then return end + + local rbs_is_loaded = (package.loaded.rbsettings ~= nil) + local s_is_loaded = (package.loaded.settings ~= nil) + + require("rbsettings") + require("settings") + rb.metadata = nil -- remove track metadata settings + + local rb_settings = rb.settings.dump('global_settings', "system") + local color_table = {} + local talk_table = {} + local list_settings_table = {} + local list_settings = "cursor_style|show_icons|statusbar|scrollbar|scrollbar_width|list_separator_height|backdrop_file|" + for key, value in pairs(rb_settings) do + key = key or "" + if (key:find("color")) then + color_table[key]=value + elseif (key:find("talk")) then + talk_table[key]=value + elseif (list_settings:find(key)) then + list_settings_table[key]=value + end + end + + if not s_is_loaded then + rb.settings = nil + package.loaded.settings = nil + end + + if not rbs_is_loaded then + rb.system = nil + rb.metadata = nil + package.loaded.rbsettings = nil + end + + rb.core_color_table = color_table + rb.core_talk_table = talk_table + rb.core_list_settings_table = list_settings_table + collectgarbage("collect") +end + +--[[ cursor style button routine +-- left / right are x, xi is increment xir is increment when repeat +-- up / down are y, yi is increment yir is increment when repeat +-- cancel is returned as 0,1 +-- select as 0, 1, 2, 3 (none, pressed, repeat, relesed) +-- x_chg and y_chg are the amount x or y changed +-- timeout == nil or -1 loop waits indefinitely till button is pressed +-- time since last button press is returned in ticks.. +-- make xi, xir, yi, yir negative to flip direction... +]] +--[[ +local function dpad(x, xi, xir, y, yi, yir, timeout, overflow) + local scroll_is_fixed = overflow ~= "manual" + _timer("dpad") -- start a persistant timer; keeps time between button events + if timeout == nil then timeout = -1 end + local cancel, select = 0, 0 + local x_chg, y_chg = 0, 0 + local button + while true do + button = rb.get_plugin_action(timeout) + + if button == CANCEL_BUTTON then + cancel = 1 + break; + elseif button == EXIT_BUTTON then + cancel = 1 + break; + elseif button == SEL_BUTTON then + select = 1 + timeout = timeout + 1 + elseif button == SELR_BUTTON then + select = 2 + timeout = timeout + 1 + elseif button == SELREL_BUTTON then + select = -1 + timeout = timeout + 1 + elseif button == LEFT_BUTTON then + x_chg = x_chg - xi + if scroll_is_fixed then + cancel = 1 + break; + end + elseif button == LEFTR_BUTTON then + x_chg = x_chg - xir + elseif button == RIGHT_BUTTON then + x_chg = x_chg + xi + if scroll_is_fixed then + select = 1 + timeout = timeout + 1 + end + elseif button == RIGHTR_BUTTON then + x_chg = x_chg + xir + elseif button == UP_BUTTON then + y_chg = y_chg + yi + elseif button == UPR_BUTTON then + y_chg = y_chg + yir + elseif button == DOWN_BUTTON then + y_chg = y_chg - yi + elseif button == DOWNR_BUTTON then + y_chg = y_chg - yir + elseif timeout >= 0 then--and rb.button_queue_count() < 1 then + break; + end + + if x_chg ~= 0 or y_chg ~= 0 then + timeout = timeout + 1 + end + end + + x = x + x_chg + y = y + y_chg + + return cancel, select, x_chg, x, y_chg, y, _timer.check("dpad", true) +end -- dpad +]] +-------------------------------------------------------------------------------- +-- displays text in menu_t calls function in same indice of func_t when selected +function print_menu(menu_t, func_t, selected, settings, copy_screen) + + local i, start, vcur, screen_img + + if selected then vcur = selected + 1 end + if vcur and vcur <= 1 then vcur = 2 end + + get_core_settings() + local c_table = rb.core_color_table or {} + + if not settings then + settings = {} + settings.default = true + end + + settings.justify = settings.justify or "center" + settings.wrap = settings.wrap or true + settings.hfgc = settings.hfgc or c_table.lst_color or _clr.set( 0, 000, 000, 000) + settings.hbgc = settings.hbgc or c_table.bg_color or _clr.set(-1, 255, 255, 255) + settings.ifgc = settings.ifgc or c_table.fg_color or _clr.set(-1, 000, 255, 060) + settings.ibgc = settings.ibgc or c_table.bg_color or _clr.set( 0, 000, 000, 000) + settings.iselc = settings.iselc or c_table.lss_color or _clr.set( 1, 000, 200, 100) + + if not settings.linedesc or rb.core_list_settings_table then + settings.linedesc = settings.linedesc or {} + local t_l = rb.core_list_settings_table + local linedesc = { + separator_height = t_l.list_separator_height or 0, + show_cursor = (t_l.cursor_style or 0) == 0, + style = t_l.cursor_style or 0xFFFF, --just a random non used index + show_icons = t_l.show_icons or false, + text_color = c_table.fg_color or _clr.set(-1, 000, 255, 060), + line_color = c_table.bg_color or _clr.set( 0, 000, 000, 000), + line_end_color= c_table.bg_color or _clr.set( 0, 000, 000, 000), + } + local styles = {rb.STYLE_NONE, rb.STYLE_INVERT, rb.STYLE_GRADIENT, rb.STYLE_COLORBAR, rb.STYLE_DEFAULT} + linedesc.style = styles[linedesc.style + 1] or rb.STYLE_COLORBAR + + for k, v in pairs(linedesc) do + --dont overwrite supplied settings + settings.linedesc[k] = settings.linedesc[k] or v + end + end + + settings.hasheader = true + settings.co_routine = nil + settings.msel = false + settings.start = start + settings.curpos = vcur + --settings.dpad_fn = dpad + + while not i or i > 0 do + if copy_screen == true then + --make a copy of screen for restoration + screen_img = screen_img or rb.new_image() + screen_img:copy(_LCD) + else + screen_img = nil + end + + _LCD:clear(settings.ibgc) + + settings.start = start + settings.curpos = vcur + + i, start, vcur = print_table(menu_t, #menu_t, settings) + --vcur = vcur + 1 + collectgarbage("collect") + if copy_screen == true then _LCD:copy(screen_img) end + + if func_t and func_t[i] then + if func_t[i](i, menu_t) == true then break end + else + break + end + end + if settings.default == true then settings = nil end + return screen_img, i +end diff --git a/apps/plugins/lua/include_lua/printtable.lua b/apps/plugins/lua/include_lua/printtable.lua index b289beeb0e..c23d801f83 100644 --- a/apps/plugins/lua/include_lua/printtable.lua +++ b/apps/plugins/lua/include_lua/printtable.lua @@ -27,9 +27,9 @@ require("actions") -- Contains rb.actions & rb.contexts local _clr = require("color") local _print = require("print") local _timer = require("timer") +local sb_width = 5 -- Button definitions -- -local EXIT_BUTTON = rb.PLA_EXIT local CANCEL_BUTTON = rb.actions.PLA_CANCEL local DOWN_BUTTON = rb.actions.PLA_DOWN local DOWNR_BUTTON = rb.actions.PLA_DOWN_REPEAT @@ -71,8 +71,8 @@ end -- time since last button press is returned in ticks.. -- make xi, xir, yi, yir negative to flip direction... ]] - -local function dpad(x, xi, xir, y, yi, yir, timeout) +local function dpad(x, xi, xir, y, yi, yir, timeout, overflow) + local scroll_is_fixed = overflow ~= "manual" _timer("dpad") -- start a persistant timer; keeps time between button events if timeout == nil then timeout = -1 end local cancel, select = 0, 0 @@ -98,10 +98,18 @@ local function dpad(x, xi, xir, y, yi, yir, timeout) timeout = timeout + 1 elseif button == LEFT_BUTTON then x_chg = x_chg - xi + if scroll_is_fixed then + cancel = 1 + break; + end elseif button == LEFTR_BUTTON then x_chg = x_chg - xir elseif button == RIGHT_BUTTON then x_chg = x_chg + xi + if scroll_is_fixed then + select = 1 + timeout = timeout + 1 + end elseif button == RIGHTR_BUTTON then x_chg = x_chg + xir elseif button == UP_BUTTON then @@ -152,19 +160,26 @@ function print_table(t, t_count, settings) end local wrap, justify, start, curpos, co_routine, hasheader, m_sel - local header_fgc, header_bgc, item_fgc, item_bgc, item_selc, drawsep + local header_fgc, header_bgc, item_fgc, item_bgc, item_selc + local table_linedesc, drawsep, overflow, dpad_fn do local s = settings or _print.get_settings() - wrap, justify = s.wrap, s.justify - start, curpos = s.start, s.curpos - co_routine = s.co_routine - hasheader = s.hasheader - drawsep = s.drawsep - m_sel = false + wrap, justify = s.wrap, s.justify + start, curpos = s.start, s.curpos + co_routine = s.co_routine + hasheader = s.hasheader + drawsep = s.drawsep + sb_width = s.sb_width or sb_width + m_sel = false + table_linedesc = s.linedesc + dpad_fn = s.dpad_fn + if type(dpad_fn) ~= "function" then dpad_fn = dpad end + if co_routine == nil then --no multi select in incremental mode m_sel = s.msel end + overflow = s.ovfl or "auto" header_fgc = s.hfgc or _clr.set( 0, 000, 000, 000) header_bgc = s.hbgc or _clr.set(-1, 255, 255, 255) item_fgc = s.ifgc or _clr.set(-1, 000, 255, 060) @@ -210,16 +225,19 @@ function print_table(t, t_count, settings) -- displays header text at top local function disp_header(hstr) local header = header or hstr - local opts = _print.opt.get() - _print.opt.overflow("none") -- don't scroll header; colors change + local opts = _print.opt.get() -- save to restore settings + _print.opt.overflow("auto") -- don't scroll header; colors change _print.opt.color(header_fgc, header_bgc) _print.opt.line(1) + rb.set_viewport(_print.opt.get(true)) _print.f() - local line = _print.f(header) + _print.f("%h", tostring(header)) --hack to signal header - _print.opt.set(opts) + _print.opt.set(opts) -- restore settings _print.opt.line(2) + rb.set_viewport(opts) + opts = nil return 2 end @@ -229,7 +247,7 @@ function print_table(t, t_count, settings) rb.lcd_update() local quit, select, x_chg, xi, y_chg, yi, timeb = - dpad(t_p.col, -1, -t_p.col_scrl, t_p.row, -1, -t_p.row_scrl) + dpad_fn(t_p.col, -1, -t_p.col_scrl, t_p.row, -1, -t_p.row_scrl, nil, overflow) t_p.vcursor = t_p.vcursor + y_chg @@ -322,6 +340,7 @@ function print_table(t, t_count, settings) rb.button_clear_queue() -- keep the button queue from overflowing end + rb.lcd_scroll_stop() return sel end -- display_table --============================================================================-- @@ -331,7 +350,7 @@ function print_table(t, t_count, settings) _print.opt.color(item_fgc, item_bgc, item_selc) table_p = init_position(15, 5) - line, maxline = _print.opt.area(5, 1, rb.LCD_WIDTH - 10, rb.LCD_HEIGHT - 2) + line, maxline = _print.opt.area(5, 1, rb.LCD_WIDTH - 10 - sb_width, rb.LCD_HEIGHT - 2) maxline = math.min(maxline, t_count) -- allow user to start at a position other than the beginning @@ -349,9 +368,11 @@ function print_table(t, t_count, settings) end _print.opt.sel_line(table_p.vcursor) - _print.opt.overflow("manual") + _print.opt.overflow(overflow) _print.opt.justify(justify) + _print.opt.linedesc(table_linedesc) + local opts = _print.opt.get() opts.drawsep = drawsep _print.opt.set(opts) @@ -360,17 +381,19 @@ function print_table(t, t_count, settings) -- initialize vertical scrollbar set_vsb(); do local vsb =_print.opt.get() + vsb.width = vsb.width + sb_width + if rb.LCD_DEPTH == 2 then -- invert 2-bit screens vsb.fg_pattern = 3 - vsb.fg_pattern vsb.bg_pattern = 3 - vsb.bg_pattern end set_vsb = function (item) - if t_count > (maxline or t_count) then + if sb_width > 0 and t_count > (maxline or t_count) then rb.set_viewport(vsb) item = item or 0 local m = maxline / 2 + 1 - rb.gui_scrollbar_draw(vsb.width - 5, vsb.y, 5, vsb.height, + rb.gui_scrollbar_draw(vsb.width - sb_width, vsb.y, sb_width, vsb.height, t_count, math.max(0, item - m), math.min(item + m, t_count), 0) end @@ -378,7 +401,7 @@ function print_table(t, t_count, settings) end -- set_vsb local selected = display_table(table_p, 0, 1, 0) - _print.opt.defaults() + _print.opt.defaults() --restore settings if m_sel == true then -- walk the table to get selected items selected = {} diff --git a/apps/plugins/lua/lua.make b/apps/plugins/lua/lua.make index daa8a05384..1e74277549 100644 --- a/apps/plugins/lua/lua.make +++ b/apps/plugins/lua/lua.make @@ -18,7 +18,7 @@ OTHER_SRC += $(LUA_SRC) LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua draw.lua draw_floodfill.lua draw_poly.lua \ draw_num.lua draw_text.lua files.lua image.lua image_save.lua lcd.lua math_ex.lua \ - print.lua timer.lua playlist.lua pcm.lua sound.lua \ + print.lua timer.lua playlist.lua pcm.lua sound.lua printmenus.lua\ rbcompat.lua rbsettings.lua poly_points.lua printtable.lua) diff --git a/apps/plugins/lua/rbdefines_helper.pl b/apps/plugins/lua/rbdefines_helper.pl index b55609077d..eca09187fa 100755 --- a/apps/plugins/lua/rbdefines_helper.pl +++ b/apps/plugins/lua/rbdefines_helper.pl @@ -53,6 +53,7 @@ if ($def_type eq "rb_defines") { '^PLUGIN_DIR$', '^PLUGIN(_APPS_|_GAMES_|_)DATA_DIR$', '^ROCKBOX_DIR$', + '^STYLE_(NONE|DEFAULT|INVERT|COLORBAR|GRADIENT|COLORED)', '^VIEWERS_DATA_DIR$'); } elsif ($def_type eq "sound_defines") { diff --git a/apps/plugins/lua/rocklib_img.c b/apps/plugins/lua/rocklib_img.c index 13e5503f75..b0ca769ca4 100644 --- a/apps/plugins/lua/rocklib_img.c +++ b/apps/plugins/lua/rocklib_img.c @@ -23,6 +23,9 @@ #define lrockimg_c #define LUA_LIB +#define ICON_PADDING_S "1" + + #include "lua.h" #include "lauxlib.h" @@ -1292,6 +1295,137 @@ RB_WRAP(lcd_puts) return 0; } +/* Helper function for opt_viewport lcd_put_line */ +static int check_tablevalue_def(lua_State *L, const char* key, int tablepos, int def) +{ + lua_getfield(L, tablepos, key); /* Find table[key] */ + + int val; + + if (lua_isboolean(L, -1)) + val = lua_toboolean (L, -1); /*True = 1 and False = 0*/ + else + val = luaL_optinteger(L, -1, def); + + lua_pop(L, 1); /* Pop the value off the stack */ + return val; +} + +/* Helper function for opt_viewport lcd_put_line */ +static int check_tablevalue(lua_State *L, const char* key, int tablepos) +{ + /* returns 0 if key doesn't exist */ + return check_tablevalue_def(L, key, tablepos, 0); +} + +RB_WRAP(lcd_put_line) +{ + /*x, y, text, t_linedesc, [screen = MAIN]*/ + +#if 0 + /* height of the line (in pixels). -1 to inherit the height + * from the font. The text will be centered if the height is larger, + * but the decorations will span the entire height */ + int height; + /* multiline support: For some decorations (e.g. gradient) to work + * across multiple lines (e.g. to draw a line selector across 2 lines) + * the line index and line count must be known. For normal, single + * lines specify nlines=1 and line=0 */ + /* line count of a group */ + int16_t nlines; + /* index of the line in the group */ + int16_t line; + /* line text color if STYLE_COLORED is specified, in native + * lcd format (convert with LCD_RGBPACK() if necessary) */ + unsigned text_color; + /* line color if STYLE_COLORBAR or STYLE_GRADIENT is specified, in native + * lcd format (convert with LCD_RGBPACK() if necessary) */ + unsigned line_color, line_end_color; + /* line decorations, see STYLE_DEFAULT etc. */ + enum line_styles style; + /* whether the line can scroll */ + bool scroll; + /* height of the line separator (in pixels). 0 to disable drawing + * of the separator */ + int8_t separator_height; +#endif + +/*LINE_DESC_DEFINIT { .style = STYLE_DEFAULT, .height = -1, .separator_height = 0, .line = 0, .nlines = 1, .scroll = false }*/ + + struct line_desc linedes = LINE_DESC_DEFINIT; + + bool is_selected = false; + bool show_icons = false; + bool show_cursor = false; + + int line_indent = 0; + int item_offset = 0; + + int x = (int) luaL_checkint(L, 1); + int y = (int) luaL_checkint(L, 2); + + const unsigned char * string = luaL_checkstring(L, 3); + int icon = Icon_NOICON; + const int narg = 4; + + if(lua_type(L, narg) == LUA_TTABLE) + { + /* check_tablevalue only returns INTS */ + linedes.line = check_tablevalue(L, "line", narg); + linedes.height = check_tablevalue_def(L, "height", narg, -1); + linedes.nlines = check_tablevalue_def(L, "nlines", narg, 1); + linedes.style = check_tablevalue_def(L, "style", narg, STYLE_DEFAULT); + linedes.separator_height = check_tablevalue(L, "separator_height", narg); + linedes.scroll = check_tablevalue(L, "scroll", narg) > 0; + + linedes.text_color = check_tablevalue(L, "text_color", narg); + linedes.line_color = check_tablevalue(L, "line_color", narg); + linedes.line_end_color = check_tablevalue(L, "line_end_color", narg); + + icon = check_tablevalue_def(L, "icon", narg, Icon_NOICON); + show_icons = check_tablevalue(L, "show_icons", narg) > 0 && icon > Icon_NOICON; + show_cursor = check_tablevalue(L, "show_cursor", narg) > 0; + is_selected = check_tablevalue(L, "selected", narg) > 0; + + line_indent = check_tablevalue(L, "indent", narg); + item_offset = check_tablevalue(L, "offset", narg); + + } + + while (*string == '\t') + { + line_indent++; + string++; + } + + /* mask out gradient and colorbar styles for non-color displays */ + if (RB_SCREEN_STRUCT(L, 5)->depth < 16) + { + if (linedes.style & (STYLE_COLORBAR|STYLE_GRADIENT)) + { + linedes.style &= ~(STYLE_COLORBAR|STYLE_GRADIENT); + linedes.style |= STYLE_INVERT; + } + linedes.style &= ~STYLE_COLORED; + } + + if (show_cursor && (show_icons && icon > Icon_NOICON)) + RB_SCREENS(L, 5, put_line, x, y, &linedes, + "$*s$"ICON_PADDING_S"I$i$"ICON_PADDING_S"s$*t", + line_indent, is_selected ? Icon_Cursor : Icon_NOICON, + icon, item_offset, string); + else if (show_cursor || (show_icons && icon > Icon_NOICON)) + RB_SCREENS(L, 5, put_line, x, y, &linedes, + "$*s$"ICON_PADDING_S"I$*t", line_indent, + show_cursor ? (is_selected ? Icon_Cursor:Icon_NOICON):icon, + item_offset, string); + else + RB_SCREENS(L, 5, put_line, x, y, &linedes, "$*s$*t", line_indent, item_offset, string); + + + return 0; +} + RB_WRAP(lcd_puts_scroll) { int x, y; @@ -1307,17 +1441,6 @@ RB_WRAP(lcd_scroll_stop) return 0; } -/* Helper function for opt_viewport */ -static int check_tablevalue(lua_State *L, const char* key, int tablepos) -{ - lua_getfield(L, tablepos, key); /* Find table[key] */ - - int val = lua_tointeger(L, -1); - - lua_pop(L, 1); /* Pop the value off the stack */ - return val; -} - static inline struct viewport* opt_viewport(lua_State *L, int narg, struct viewport* vp, @@ -1333,7 +1456,7 @@ static inline struct viewport* opt_viewport(lua_State *L, vp->width = check_tablevalue(L, "width", narg); vp->height = check_tablevalue(L, "height", narg); vp->font = check_tablevalue(L, "font", narg); - vp->drawmode = check_tablevalue(L, "drawmode", narg); + vp->drawmode = check_tablevalue_def(L, "drawmode", narg, DRMODE_SOLID); #if LCD_DEPTH > 1 vp->fg_pattern = (unsigned int) check_tablevalue(L, "fg_pattern", narg); vp->bg_pattern = (unsigned int) check_tablevalue(L, "bg_pattern", narg); @@ -1686,6 +1809,7 @@ static const luaL_Reg rocklib_img[] = R(lcd_set_drawmode), R(lcd_putsxy), R(lcd_puts), + R(lcd_put_line), R(lcd_puts_scroll), R(lcd_scroll_stop), R(set_viewport), diff --git a/apps/plugins/lua_scripts.lua b/apps/plugins/lua_scripts.lua index 02fe50b327..43593d96b0 100644 --- a/apps/plugins/lua_scripts.lua +++ b/apps/plugins/lua_scripts.lua @@ -24,13 +24,15 @@ local scrpath = rb.current_path() .. "/lua_scripts/" package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path -require("printtable") +require("printmenus") rb.actions = nil package.loaded["actions"] = nil local excludedsrc = ";filebrowse.lua;fileviewers.lua;printmenu.lua;dbgettags.lua;" -------------------------------------------------------------------------------- +local Icon_Plugin = 0x9 + local function get_files(path, norecurse, finddir, findfile, f_t, d_t) @@ -120,6 +122,15 @@ local function get_files(path, norecurse, finddir, findfile, f_t, d_t) end -- get_files -------------------------------------------------------------------------------- +function icon_fn(item, icon) + if item ~= 0 then + icon = Icon_Plugin + else + icon = -1 + end + return icon +end + -- uses print_table and get_files to display simple file browser function script_choose(dir, title) local dstr @@ -128,8 +139,8 @@ function script_choose(dir, title) local norecurse = true local f_finddir = false -- function to match directories; nil all, false none local f_findfile = nil -- function to match files; nil all, false none - - local p_settings = {wrap = true, hasheader = true} + local t_linedesc = {show_icons = true, icon_fn = icon_fn} + local p_settings = {wrap = true, hasheader = true, justify = "left", linedesc = t_linedesc} local files = {} local dirs = {} local item = 1 @@ -142,10 +153,11 @@ function script_choose(dir, title) for i = 1, #files do table.insert(dirs, "\t" .. string.gsub(files[i], ".*/","")) end - - item = print_table(dirs, #dirs, p_settings) + --print_menu(menu_t, func_t, selected, settings, copy_screen) + _, item = print_menu(dirs, nil, 0, p_settings) -- If item was selected follow directory or return filename + item = item or -1 if item > 0 then dir = files[item - 1] if not rb.dir_exists("/" .. dir) then diff --git a/apps/plugins/lua_scripts/file_browser.lua b/apps/plugins/lua_scripts/file_browser.lua index 19f475acf3..ab246a2a7e 100644 --- a/apps/plugins/lua_scripts/file_browser.lua +++ b/apps/plugins/lua_scripts/file_browser.lua @@ -33,7 +33,7 @@ local scrpath = rb.current_path()--rb.PLUGIN_DIR .. "/demos/lua_scripts/" package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path -require("printmenu") --menu +require("printmenus") --menu require("filebrowse") -- file browser rb.actions = nil diff --git a/apps/plugins/lua_scripts/fileview.lua b/apps/plugins/lua_scripts/fileview.lua index 920281bbef..08eea0337c 100755 --- a/apps/plugins/lua_scripts/fileview.lua +++ b/apps/plugins/lua_scripts/fileview.lua @@ -33,7 +33,7 @@ local scrpath = rb.current_path()--rb.PLUGIN_DIR .. "/demos/lua_scripts/" package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path -require("printmenu") --menu +require("printmenus") --menu require("filebrowse") -- file browser require("fileviewers") -- fileviewer, hexviewer diff --git a/apps/plugins/lua_scripts/fileviewers.lua b/apps/plugins/lua_scripts/fileviewers.lua index 5a9c417d36..c686f3eeda 100755 --- a/apps/plugins/lua_scripts/fileviewers.lua +++ b/apps/plugins/lua_scripts/fileviewers.lua @@ -205,6 +205,7 @@ function print_file(filename, maxlinelen, settings) end settings.hasheader = true settings.co_routine = nil + settings.ovfl = "manual" local sel = print_table(ftable, #ftable, settings) @@ -309,6 +310,7 @@ function print_file_increment(filename, settings) settings.hasheader = true settings.co_routine = co settings.msel = false + settings.ovfl = "manual" table.insert(file_t, 1, hstr) --position 1 is header/title local sel = @@ -437,6 +439,7 @@ function print_file_hex(filename, bytesperline, settings) settings.co_routine = co settings.start = start settings.curpos = vcur + settings.ovfl = "manual" while sel > 0 do settings.start = start diff --git a/apps/plugins/lua_scripts/printmenu.lua b/apps/plugins/lua_scripts/printmenu.lua deleted file mode 100755 index 3cb17d8026..0000000000 --- a/apps/plugins/lua_scripts/printmenu.lua +++ /dev/null @@ -1,83 +0,0 @@ ---[[ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2017 William Wilgus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -]] -if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end - -require("printtable") -local _clr = require("color") - -local _LCD = rb.lcd_framebuffer() --------------------------------------------------------------------------------- --- displays text in menu_t calls function in same indice of func_t when selected -function print_menu(menu_t, func_t, selected, settings, copy_screen) - - local i, start, vcur, screen_img - - if selected then vcur = selected + 1 end - if vcur and vcur <= 1 then vcur = 2 end - - if not settings then - settings = {} - settings.justify = "center" - settings.wrap = true - settings.hfgc = _clr.set( 0, 000, 000, 000) - settings.hbgc = _clr.set(-1, 255, 255, 255) - settings.ifgc = _clr.set(-1, 000, 255, 060) - settings.ibgc = _clr.set( 0, 000, 000, 000) - settings.iselc = _clr.set( 1, 000, 200, 100) - settings.default = true - end - - settings.hasheader = true - settings.co_routine = nil - settings.msel = false - settings.start = start - settings.curpos = vcur - - while not i or i > 0 do - if copy_screen == true then - --make a copy of screen for restoration - screen_img = screen_img or rb.new_image() - screen_img:copy(_LCD) - else - screen_img = nil - end - - _LCD:clear(settings.ibgc) - - settings.start = start - settings.curpos = vcur - - i, start, vcur = print_table(menu_t, #menu_t, settings) - --vcur = vcur + 1 - collectgarbage("collect") - if copy_screen == true then _LCD:copy(screen_img) end - - if func_t and func_t[i] then - if func_t[i](i, menu_t) == true then break end - else - break - end - end - if settings.default == true then settings = nil end - return screen_img -end diff --git a/apps/plugins/lua_scripts/rlimg.lua b/apps/plugins/lua_scripts/rlimg.lua index 801d0c5fac..c9dde65ed4 100755 --- a/apps/plugins/lua_scripts/rlimg.lua +++ b/apps/plugins/lua_scripts/rlimg.lua @@ -36,7 +36,7 @@ local _draw_text = require("draw_text") --package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path -require("printmenu") --menu +require("printmenus") --menu --[[ RBIMAGE library functions NOTE!! on x, y coordinates + width & height diff --git a/apps/plugins/lua_scripts/tagnav.lua b/apps/plugins/lua_scripts/tagnav.lua index f62f27973b..9646f359e3 100644 --- a/apps/plugins/lua_scripts/tagnav.lua +++ b/apps/plugins/lua_scripts/tagnav.lua @@ -25,7 +25,7 @@ --local scrpath = rb.current_path()" --package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path -require("printmenu") +require("printmenus") require("printtable") require("dbgettags") -- cgit v1.2.3