From 544f8cedbf464e47179418e3209af41a643751ea Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Thu, 5 Feb 2026 21:04:28 +0900 Subject: [PATCH 1/7] ignore .DS_Store (mac files) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b77c008..e400688 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.luac *.zip +.DS_Store From 42ce2584fd2e9716a2c888f90cab7a2b810a152c Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Thu, 5 Feb 2026 21:13:42 +0900 Subject: [PATCH 2/7] adds some transparency around the widget to allow to see when the widget has the focus --- lib/w_paint.lua | 19 +++++++++++-------- main.lua | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/w_paint.lua b/lib/w_paint.lua index 2c97611..3d75e85 100644 --- a/lib/w_paint.lua +++ b/lib/w_paint.lua @@ -37,6 +37,9 @@ local wPaint = { LINE_CENTERED = 2, -- align middle (vertical centered) LINE_BOTTOM = 3, -- align bottom + -- Transparency Box offset (to show that widget has the Focus) + TRANSPARENCY_X_OFFSET = 1, -- left and right offset + TRANSPARENCY_Y_OFFSET = 1, -- top and bottom offset } -- library structure -- required libraries @@ -77,16 +80,16 @@ function wPaint.text(text, fontSize, horizontalAlign, verticalAlign, shiftLine) _, textHeight = lcd.getTextSize("") if verticalAlign == wPaint.LINE_TOP then -- align top - textPosY = wPaint.FREE_ABOVE + wPaint.titleHeight + textPosY = wPaint.TRANSPARENCY_Y_OFFSET + wPaint.FREE_ABOVE + wPaint.titleHeight elseif verticalAlign == wPaint.LINE_BOTTOM then -- align bottom - textPosY = (widget.height - textHeight - wPaint.footerHeight - wPaint.FREE_BELOW) + textPosY = (widget.height - textHeight - wPaint.footerHeight - wPaint.FREE_BELOW - wPaint.TRANSPARENCY_Y_OFFSET) else -- align centered (default) -- textPosY = wPaint.FREE_ABOVE + -- ((widget.height - wPaint.titleHeight - wPaint.FREE_ABOVE - wPaint.footerHeight - wPaint.FREE_BELOW) / 2 - textHeight / 2) + -- wPaint.titleHeight - local boxTop = wPaint.titleHeight + wPaint.FREE_ABOVE - local boxHeight = widget.height - wPaint.FREE_BELOW - wPaint.footerHeight - boxTop + local boxTop = wPaint.titleHeight + wPaint.FREE_ABOVE + wPaint.TRANSPARENCY_Y_OFFSET + local boxHeight = widget.height - wPaint.FREE_BELOW - wPaint.footerHeight - wPaint.TRANSPARENCY_Y_OFFSET - boxTop local boxMiddle = boxTop + boxHeight / 2 textPosY = boxMiddle - textHeight / 2 end @@ -94,9 +97,9 @@ function wPaint.text(text, fontSize, horizontalAlign, verticalAlign, shiftLine) textPosY = textPosY + (shiftLine * textHeight) -- shift line if horizontalAlign == TEXT_LEFT then - lcd.drawText(wPaint.FREE_LEFT, textPosY, text, TEXT_LEFT) + lcd.drawText(wPaint.FREE_LEFT + wPaint.TRANSPARENCY_X_OFFSET, textPosY, text, TEXT_LEFT) elseif horizontalAlign == TEXT_RIGHT then - lcd.drawText(widget.width - wPaint.FREE_RIGHT, textPosY, text, TEXT_RIGHT) + lcd.drawText(widget.width - wPaint.FREE_RIGHT - wPaint.TRANSPARENCY_X_OFFSET, textPosY, text, TEXT_RIGHT) else lcd.drawText((widget.width / 2), textPosY, text, TEXT_CENTERED) end @@ -116,7 +119,7 @@ function wPaint.title(titleText, titleBGColor, titleTxColor) titleHeight = wPaint.FREE_ABOVE + titleHeight + wPaint.FREE_BELOW lcd.color(titleBGColor) - lcd.drawFilledRectangle(0, 0, widget.width, titleHeight) + lcd.drawFilledRectangle(wPaint.TRANSPARENCY_X_OFFSET, wPaint.TRANSPARENCY_Y_OFFSET, widget.width - (2 * wPaint.TRANSPARENCY_X_OFFSET), titleHeight - wPaint.TRANSPARENCY_Y_OFFSET) --- draw title text lcd.color(titleTxColor) @@ -141,7 +144,7 @@ function wPaint.footer(footerText, footerBGColor, footerTxColor) if footerBGColor ~= nil then footerHeight = wPaint.FREE_ABOVE + footerHeight lcd.color(footerBGColor) - lcd.drawFilledRectangle(0, widget.height - footerHeight, widget.width, widget.height) + lcd.drawFilledRectangle(wPaint.TRANSPARENCY_X_OFFSET, widget.height - footerHeight - (2 * wPaint.TRANSPARENCY_Y_OFFSET), widget.width - (2 * wPaint.TRANSPARENCY_X_OFFSET), widget.height - (2 * wPaint.TRANSPARENCY_Y_OFFSET)) end --- draw footer text lcd.color(footerTxColor) diff --git a/main.lua b/main.lua index 9c5bb31..248f033 100644 --- a/main.lua +++ b/main.lua @@ -274,7 +274,7 @@ local function paint(widget) -- paint background lcd.color(widget:getStateBgColor()) - lcd.drawFilledRectangle(0, 0, widget.width, widget.height) + lcd.drawFilledRectangle(wPaint.TRANSPARENCY_X_OFFSET, wPaint.TRANSPARENCY_Y_OFFSET, widget.width - (2 * wPaint.TRANSPARENCY_X_OFFSET), widget.height - (2 * wPaint.TRANSPARENCY_Y_OFFSET)) -- paint title (must be before paint state text or debug information) paintTitle() @@ -295,7 +295,7 @@ local function paint(widget) local function paintSourceMissed() local debug = wHelper.Debug:new(widget.no, "paintSourceMissed"):info() lcd.color(COLOR_BLACK) - lcd.drawFilledRectangle(0, 0, widget.width, widget.height) + lcd.drawFilledRectangle(wPaint.TRANSPARENCY_X_OFFSET, wPaint.TRANSPARENCY_Y_OFFSET, widget.width - (2 * wPaint.TRANSPARENCY_X_OFFSET), widget.height - (2 * wPaint.TRANSPARENCY_Y_OFFSET)) --- paint title paintTitle() From 04fef3041394a1fa09ce80bffeb7853fef905575 Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Thu, 5 Feb 2026 21:15:07 +0900 Subject: [PATCH 3/7] adds dynamic threshold once the source is defined --- main.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main.lua b/main.lua index 248f033..000df16 100644 --- a/main.lua +++ b/main.lua @@ -360,8 +360,16 @@ local function configure(widget) wConfig.addSourceField("source") -- thresholds - wConfig.addNumberField("thresholdDown", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) - wConfig.addNumberField("thresholdUp", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) + if wHelper.existSource(widget.source) and widget.source.maximum and widget.source.minimum then + -- Not perfect since to have this code working you will need + -- to configure the widget to set the source first + -- and then to configure again to set the remaining parameters + wConfig.addNumberField("thresholdDown", widget.source:minimum(), widget.source:maximum(), THRESHOLD_PRECISION) + wConfig.addNumberField("thresholdUp", widget.source:minimum(), widget.source:maximum(), THRESHOLD_PRECISION) + else + wConfig.addNumberField("thresholdUp", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) + wConfig.addNumberField("thresholdDown", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) + end -- Font size wConfig.addChoiceField("fontSizeIndex", FONT_SIZE_SELECTION) From 8f83a4c4aa7cf091fdf63a0ccf298bba4685e960 Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Thu, 5 Feb 2026 21:15:45 +0900 Subject: [PATCH 4/7] adds a contextual menu to reset the source (when available) --- i18n/cs.lua | 1 + i18n/de.lua | 1 + i18n/en.lua | 1 + i18n/es.lua | 1 + i18n/fr.lua | 1 + i18n/it.lua | 1 + main.lua | 19 +++++++++++++++++++ 7 files changed, 25 insertions(+) diff --git a/i18n/cs.lua b/i18n/cs.lua index 921a706..c13bc90 100644 --- a/i18n/cs.lua +++ b/i18n/cs.lua @@ -5,6 +5,7 @@ return { FontSizeIndex = "Velikost písma", Source = "Zdroj", SourceMissed = "žádný zdroj", + SourceReset = "%s Reset", BackgroundColor = "Barva pozadí", StateDown = "Dole", StateMiddle = "Střed", diff --git a/i18n/de.lua b/i18n/de.lua index 733ccb9..2dea309 100644 --- a/i18n/de.lua +++ b/i18n/de.lua @@ -5,6 +5,7 @@ return { FontSizeIndex = "Schriftgröße", Source = "Quelle", SourceMissed = "keine Quelle", + SourceReset = "%s zurücksetzen", BackgroundColor = "Hintergrundfarbe", StateDown = "Unten", StateMiddle = "Mitte", diff --git a/i18n/en.lua b/i18n/en.lua index e734dbb..c2c2339 100644 --- a/i18n/en.lua +++ b/i18n/en.lua @@ -5,6 +5,7 @@ return { FontSizeIndex = "Font size", Source = "Source", SourceMissed = "no source", + SourceReset = "Reset %s", BackgroundColor = "Background color", StateDown = "Down", StateMiddle = "Middle", diff --git a/i18n/es.lua b/i18n/es.lua index 5343e3e..e1c85d9 100644 --- a/i18n/es.lua +++ b/i18n/es.lua @@ -5,6 +5,7 @@ return { FontSizeIndex = "Tamaño de fuente", Source = "Fuente", SourceMissed = "sin fuente", + SourceReset = "Reiniciar %s", BackgroundColor = "Color de fondo", StateDown = "Abajo", StateMiddle = "Medio", diff --git a/i18n/fr.lua b/i18n/fr.lua index 4862e20..1e6ed08 100644 --- a/i18n/fr.lua +++ b/i18n/fr.lua @@ -5,6 +5,7 @@ return { FontSizeIndex = "Taille de police", Source = "Source", SourceMissed = "aucune source", + SourceReset = "Réinitialiser %s", BackgroundColor = "Couleur de fond", StateDown = "Bas", StateMiddle = "Milieu", diff --git a/i18n/it.lua b/i18n/it.lua index 312c68c..c6a6238 100644 --- a/i18n/it.lua +++ b/i18n/it.lua @@ -5,6 +5,7 @@ return { FontSizeIndex = "Dimensione carattere", Source = "Sorgente", SourceMissed = "nessuna sorgente", + SourceReset = "%s ReImposta", BackgroundColor = "Colore sfondo", StateDown = "Giù", StateMiddle = "Centro", diff --git a/main.lua b/main.lua index 000df16..00afa82 100644 --- a/main.lua +++ b/main.lua @@ -507,6 +507,24 @@ local function read(widget) wStorage.read("debugMode") end +local function menu(widget) + local CATEGORY_LUA = 29 + if wHelper.existSource(widget.source) and widget.source.reset then + local category = widget.source:category() + if + category == CATEGORY_TIMER or + category == CATEGORY_TELEMETRY_SENSOR or + category == CATEGORY_LUA + then + return { + {string.format(STR("SourceReset"), widget.source:name()), + function() + widget.source:reset() + end}, + } + end + end +end ------------------------------------------------------------------------------------------------------------------------ --- Initialize the widget (register it in the system). local function init() @@ -520,6 +538,7 @@ local function init() configure = configure, read = read, write = write, + menu=menu, title = false }) end From 44f2593b01eac546fb2531f6c9479a73ff4b36c0 Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Thu, 5 Feb 2026 22:15:33 +0900 Subject: [PATCH 5/7] fix thresholdDown/thresholdUp order --- main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.lua b/main.lua index 00afa82..74eb3ed 100644 --- a/main.lua +++ b/main.lua @@ -367,8 +367,8 @@ local function configure(widget) wConfig.addNumberField("thresholdDown", widget.source:minimum(), widget.source:maximum(), THRESHOLD_PRECISION) wConfig.addNumberField("thresholdUp", widget.source:minimum(), widget.source:maximum(), THRESHOLD_PRECISION) else - wConfig.addNumberField("thresholdUp", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) wConfig.addNumberField("thresholdDown", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) + wConfig.addNumberField("thresholdUp", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) end -- Font size From 7eee434d6177d7af619f457aeb2f248eb4388c55 Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Fri, 6 Feb 2026 03:17:40 +0900 Subject: [PATCH 6/7] menu must always return a table --- main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/main.lua b/main.lua index 74eb3ed..adc8941 100644 --- a/main.lua +++ b/main.lua @@ -524,6 +524,7 @@ local function menu(widget) } end end + return {} end ------------------------------------------------------------------------------------------------------------------------ --- Initialize the widget (register it in the system). From a41f17a0c83b7ba02072d3efc4b44a965aa15d14 Mon Sep 17 00:00:00 2001 From: Eric Delord <04-ete.elit@icloud.com> Date: Mon, 9 Feb 2026 10:26:56 +0100 Subject: [PATCH 7/7] thresholds precision, minimum and maximum updated on source change --- main.lua | 72 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/main.lua b/main.lua index adc8941..33c3121 100644 --- a/main.lua +++ b/main.lua @@ -356,20 +356,68 @@ local function configure(widget) updateLanguage(widget) -- check if system language has changed wConfig.init({ form = form, widget = widget, STR = STR }) - -- Source - wConfig.addSourceField("source") + -- Source and thresholds + local function sourcePrecision(source) + local precision = THRESHOLD_PRECISION + if wHelper.existSource(source) and source.decimals and source:decimals()~=nil then + precision = source:decimals() + end + return precision + end + local function sourceFactorInt(x, source) -- adjust on source change + local precision = sourcePrecision(source) + local factor = 10 ^ precision + return math.floor(x * factor + 0.5) -- convert & round to nearest factor integer + end + local function sourceFactorFloat(x, source) -- adjust on source change + local precision = sourcePrecision(source) + local factor = 10 ^ precision + return math.floor(x + 0.5) / factor -- reconvert & round to nearest factor float + end + local function updateFieldRange(field, source) + local precision = sourcePrecision(source) + local min = -THRESHOLD_RANGE + local max = THRESHOLD_RANGE + if wHelper.existSource(source) then + if source.minimum and source:minimum()~=nil then + min = source:minimum() + end + if source.maximum and source:maximum()~=nil then + max = source:maximum() + end + end + if field then + field:decimals(precision) + field:minimum(sourceFactorInt(min, source)) + field:maximum(sourceFactorInt(max, source)) + end + end + + line = wConfig.addLine(wHelper.capitalizeFirstLetter("source")) + local thresholdDownField + local thresholdUpField + local sourceField = form.addSourceField(line, nil, function() return widget["source"] end, + function(value) + widget["source"] = value + updateFieldRange(thresholdDownField, value) + updateFieldRange(thresholdUpField, value) + end) -- thresholds - if wHelper.existSource(widget.source) and widget.source.maximum and widget.source.minimum then - -- Not perfect since to have this code working you will need - -- to configure the widget to set the source first - -- and then to configure again to set the remaining parameters - wConfig.addNumberField("thresholdDown", widget.source:minimum(), widget.source:maximum(), THRESHOLD_PRECISION) - wConfig.addNumberField("thresholdUp", widget.source:minimum(), widget.source:maximum(), THRESHOLD_PRECISION) - else - wConfig.addNumberField("thresholdDown", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) - wConfig.addNumberField("thresholdUp", -THRESHOLD_RANGE, THRESHOLD_RANGE, THRESHOLD_PRECISION) - end + + line = wConfig.addLine(wHelper.capitalizeFirstLetter("thresholdDown")) + thresholdDownField = form.addNumberField(line, nil, 0, 0, -- min max adjusted in updateFieldRangeForSource + function() return sourceFactorInt(widget["thresholdDown"], widget.source) end, + function(value) widget["thresholdDown"] = sourceFactorFloat(value, widget.source) end + ) + updateFieldRange(thresholdDownField, widget.source) + + line = wConfig.addLine(wHelper.capitalizeFirstLetter("thresholdUp")) + thresholdUpField = form.addNumberField(line, nil, 0, 0, -- min max adjusted in updateFieldRangeForSource + function() return sourceFactorInt(widget["thresholdUp"], widget.source) end, + function(value) widget["thresholdUp"] = sourceFactorFloat(value, widget.source) end + ) + updateFieldRange(thresholdUpField, widget.source) -- Font size wConfig.addChoiceField("fontSizeIndex", FONT_SIZE_SELECTION)