diff --git a/avr/devices/c03/main/main.asm b/avr/devices/c03/main/main.asm index f794433..302dd70 100644 --- a/avr/devices/c03/main/main.asm +++ b/avr/devices/c03/main/main.asm @@ -531,18 +531,19 @@ GUI_MODULE_BEGIN: .include "modules/lcd2/gui/base/hlayout.asm" .include "modules/lcd2/gui/base/vlayout.asm" .include "modules/lcd2/gui/base/mclayout.asm" -.include "modules/lcd2/gui/base/hspinner.asm" -.include "modules/lcd2/gui/base/mainwindow.asm" +.include "modules/lcd2/gui/composite/hspinner.asm" +.include "modules/lcd2/gui/composite/mainwindow.asm" .include "modules/lcd2/gui/base/keypad.asm" .include "modules/lcd2/gui/base/keypad_num.asm" -.include "modules/lcd2/gui/base/d_numinput.asm" +.include "modules/lcd2/gui/composite/d_numinput.asm" .include "modules/lcd2/gui/base/cwidget.asm" -.include "modules/lcd2/gui/base/dialog.asm" -.include "modules/lcd2/gui/base/cdialog.asm" +.include "modules/lcd2/gui/composite/dialog.asm" +.include "modules/lcd2/gui/composite/cdialog.asm" .include "modules/lcd2/gui/aqhome/sensorwatch.asm" .include "modules/lcd2/gui/aqhome/lightsettings.asm" .include "modules/lcd2/gui/aqhome/d_light_conns.asm" .include "modules/lcd2/gui/aqhome/d_nodevalueid.asm" +.include "modules/lcd2/gui/composite/textsel.asm" .include "modules/lcd2/gui/screensavers/simple.asm" GUI_MODULE_END: .equ MODULE_SIZE_GUI = GUI_MODULE_END-GUI_MODULE_BEGIN diff --git a/avr/modules/lcd2/gui/0BUILD b/avr/modules/lcd2/gui/0BUILD index ea98aaf..433e565 100644 --- a/avr/modules/lcd2/gui/0BUILD +++ b/avr/modules/lcd2/gui/0BUILD @@ -5,6 +5,7 @@ aqhome base + composite screensavers diff --git a/avr/modules/lcd2/gui/base/0BUILD b/avr/modules/lcd2/gui/base/0BUILD index 98dbb20..6139d71 100644 --- a/avr/modules/lcd2/gui/base/0BUILD +++ b/avr/modules/lcd2/gui/base/0BUILD @@ -4,19 +4,29 @@ button.asm + buttongroup.asm + checkbox.asm + cwidget.asm guiapp.asm + hbuttongroup.asm hlayout.asm + imagebutton.asm + imagelabel.asm imageview.asm + keypad.asm + keypad_num.asm label.asm layout.asm - mainwindow.asm mclayout.asm object.asm rootwindow.asm textbutton.asm + tile.asm valuelabel.asm vlayout.asm widget.asm + wlist.asm + wlist_elem.asm diff --git a/avr/modules/lcd2/gui/base/object.asm b/avr/modules/lcd2/gui/base/object.asm index 412b435..ae0fdcd 100644 --- a/avr/modules/lcd2/gui/base/object.asm +++ b/avr/modules/lcd2/gui/base/object.asm @@ -156,7 +156,7 @@ OBJ_Fini: ; CAVEAT: Y is invalid after return! ; ; @param Y address of object in SDRAM -; @clobbers none +; @clobbers any, !Y OBJ_Free: tst yl @@ -1111,6 +1111,42 @@ OBJ_CountDirectChildren_done: +; --------------------------------------------------------------------------- +; @routine OBJ_FreeChildren @global +; +; @param Y address of object whose children are to be free'd +; @clobbers any, !Y + +OBJ_FreeChildren: + push yl + push yh + clr r16 + rcall OBJ_GetFirstChild + brcc OBJ_FreeChildren_done +OBJ_FreeChildren_loop: + mov yl, r18 + mov yh, r19 + rcall OBJ_GetNext + brcs OBJ_FreeChildren_loopFree + clr r18 + clr r19 +OBJ_FreeChildren_loopFree: + push r18 + push r19 + rcall OBJ_Free + pop r19 + pop r18 + mov r16, r18 + or r16, r19 + brne OBJ_FreeChildren_loop +OBJ_FreeChildren_done: + pop yh + pop yl + ret +; @end + + + ; *************************************************************************** ; data in FLASH diff --git a/avr/modules/lcd2/gui/base/widget.asm b/avr/modules/lcd2/gui/base/widget.asm index a047962..5a4799c 100644 --- a/avr/modules/lcd2/gui/base/widget.asm +++ b/avr/modules/lcd2/gui/base/widget.asm @@ -1089,6 +1089,7 @@ Widget_DrawCharAt: ; @param R5:R4 X relative to widget ; @param R7:R6 Y relative to widget ; @return Z pointer to next char to write if CFLAG clear +; @return R5:R4 X pos behind last written char ; @clobbers any, !Y Widget_DrawTextFlash: @@ -1127,6 +1128,7 @@ Widget_DrawTextRam: ; @param Z byte address pointer to text in flash (for LPM!) ; @return CFLAG set if completely written ; @return Z pointer to next char to write if CFLAG clear +; @return R5:R4 X pos behind last written char ; @clobbers any, !Y Widget_DrawColoredTextFlash: diff --git a/avr/modules/lcd2/gui/base/wlist.asm b/avr/modules/lcd2/gui/base/wlist.asm new file mode 100644 index 0000000..ac61d56 --- /dev/null +++ b/avr/modules/lcd2/gui/base/wlist.asm @@ -0,0 +1,200 @@ +; *************************************************************************** +; copyright : (C) 2026 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_GUI2_WLIST_ASM +#define AQH_AVR_GUI2_WLIST_ASM + + +; *************************************************************************** +; defines + +.equ WLIST_OFFS_BEGIN = VLAYOUT_SIZE +.equ WLIST_OFFS_ELEMLIST_LO = VLAYOUT_OFFS_BEGIN+0 +.equ WLIST_OFFS_ELEMLIST_HI = VLAYOUT_OFFS_BEGIN+1 +.equ WLIST_OFFS_ELEMOFFSET = VLAYOUT_OFFS_BEGIN+2 +.equ WLIST_OFFS_ELEMNUM = VLAYOUT_OFFS_BEGIN+3 +.equ WLIST_SIZE = VLAYOUT_OFFS_BEGIN+4 + + +; signals +.equ WLIST_SIGNAL_MKOBJECT = WIDGET_SIGNAL_NEXTFREE+0 +.equ WLIST_SIGNAL_NEXTFREE = WIDGET_SIGNAL_NEXTFREE+1 + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine WList_new @global +; +; @return CFLAG set of okay, cleared otherwise +; @return Y address of newly created object +; @param X parent widget +; @param r16 value for OBJECT_OFFS_OPTS +; @param r17 value for WIDGET_OFFS_PACK +; @clobbers any + +WList_new: + ldi r24, LOW(VLAYOUT_SIZE) + ldi r25, HIGH(VLAYOUT_SIZE) + bigcall Object_Alloc ; (!r16, !r17, !X) + brcc WList_new_ret + rcall WList_Init ; (r16, r17, X) + sec +WList_new_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine WList_Init @global +; +; @param Y address of widget +; @param X parent widget (if any) +; @param r16 value for OBJECT_OFFS_OPTS +; @param r17 value for WIDGET_OFFS_PACK +; @clobbers r16, r17, X + +WList_Init: + ; call base class + ldi r20, VLAYOUT_MODE_EXPAND + bigcall VLayout_Init ; (r16, r17, X) + + ; set widget-specific data + + ; set default signal map + ldi r16, LOW(WList_DefaultSignalmap*2) + std Y+OBJECT_OFFS_SIGNALMAP_LO, r16 + ldi r16, HIGH(WList_DefaultSignalmap*2) + std Y+OBJECT_OFFS_SIGNALMAP_HI, r16 + + ret +; @end + + + + +wListRebuild: + ; release current widgets + bigcall OBJ_FreeChildren ; (any, !Y) + + rcall wListGetStartElement + brcc wListRebuild_ret + + ; get startY and height + bigcall Widget_GetBorderAndSpacing + mov r6, r23 ; YPOS (start after border) + clr r7 + ldd r10, Y+WIDGET_OFFS_HEIGHT_LO + ldd r11, Y+WIDGET_OFFS_HEIGHT_HI + sub r10, r23 + sbc r11, r23 + add r11, r23 + +wListRebuild_loop: + ; check height (does element fit?) + adiw xh:xl, WLIST_ELEM_OFFS_HEIGHT_LO + ld r18, X+ + ld r19, X + sbiw xh:xl, (WLIST_ELEM_OFFS_HEIGHT_LO+1) + add r18, r6 ; height+currentY + adc r19, r7 + cp r18, r10 + cpc r19, r11 + brcc wListRebuild_ret ; outside window, done + + ; create child widget for item + push r6 + push r7 + push r10 + push r11 + push r22 + push xl + push xh + ldi r16, WLIST_SIGNAL_MKOBJECT ; in: list element + clr r17 + bigcall OBJ_HandleSignal ; out: r19:r18=result (if CFLAG set) + pop xh + pop xl + pop r22 + pop r11 + pop r10 + pop r7 + pop r6 + brcc wListRebuild_ret + + ; increment Y + adiw xh:xl, WLIST_ELEM_OFFS_HEIGHT_LO + ld r18, X+ + ld r19, X + sbiw xh:xl, (WLIST_ELEM_OFFS_HEIGHT_LO+1) + add r6, r18 ; add item height + adc r7, r19 + add r6, r22 ; add spacing + adc r7, r22 + sub r7, r22 + + ; next element + ld r16, X+ + ld r17, X + mov xl, r16 + mov xh, r17 + or r16, r17 + brne wListRebuild_loop + +wListRebuild_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine wListGetStartElement @global +; +; @param Y address of widget +; @return CFLAG set if start element found, cleared otherwise +; @return X pointer to start element + +wListGetStartElement: + push yl + push yh + ldd r16, Y+WLIST_OFFS_ELEMOFFSET + ldd r17, Y+WLIST_OFFS_ELEMLIST_LO + ldd yh, Y+WLIST_OFFS_ELEMLIST_HI + mov yl, r17 + bigcall List_GetItemAt ; X=element at (r16, r17) + pop yh + pop yl + ret +; @end + + + + +; *************************************************************************** +; data in FLASH + +WList_DefaultSignalmap: + ; header + .dw VLayout_DefaultSignalmap*2 ; next table to use + ; entries + + .db 0, 0, 0, 0 ; end of table + + + + +#endif + diff --git a/avr/modules/lcd2/gui/base/wlist_elem.asm b/avr/modules/lcd2/gui/base/wlist_elem.asm new file mode 100644 index 0000000..1d51957 --- /dev/null +++ b/avr/modules/lcd2/gui/base/wlist_elem.asm @@ -0,0 +1,86 @@ +; *************************************************************************** +; copyright : (C) 2026 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_GUI_WLIST_ELEM_ASM +#define AQH_AVR_GUI_WLIST_ELEM_ASM + + + +; *************************************************************************** +; defines + +.equ WLIST_ELEM_OFFS_BEGIN = LIST_SIZE +.equ WLIST_ELEM_OFFS_IMGRES_LO = WLIST_ELEM_OFFS_BEGIN+0 +.equ WLIST_ELEM_OFFS_IMGRES_HI = WLIST_ELEM_OFFS_BEGIN+1 +.equ WLIST_ELEM_OFFS_TXTRES_LO = WLIST_ELEM_OFFS_BEGIN+2 +.equ WLIST_ELEM_OFFS_TXTRES_HI = WLIST_ELEM_OFFS_BEGIN+3 +.equ WLIST_ELEM_OFFS_USER_LO = WLIST_ELEM_OFFS_BEGIN+4 +.equ WLIST_ELEM_OFFS_USER_HI = WLIST_ELEM_OFFS_BEGIN+5 +.equ WLIST_ELEM_OFFS_HEIGHT_LO = WLIST_ELEM_OFFS_BEGIN+6 +.equ WLIST_ELEM_OFFS_HEIGHT_HI = WLIST_ELEM_OFFS_BEGIN+7 +.equ WLIST_ELEM_SIZE = WLIST_ELEM_OFFS_BEGIN+8 + + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine WidgetListElem_new @global +; +; @return Y address of created object + +WidgetListElem_new: + ldi r24, LOW(WLIST_ELEM_SIZE) + ldi r25, HIGH(WLIST_ELEM_SIZE) + bigcall Heap_AllocAndZero + brcc WidgetListElem_new_ret + mov yl, xl + mov yh, xh + bigcall List_InitObject ; (r16) + sec + ret +WidgetListElem_new_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine WidgetListElem_free @global +; +; @param Y address of object +; @clobbers r16, r17, r24, r25, X + +WidgetListElem_free: + tst yl + brne WidgetListElem_free_notNull + tst yh + brne WidgetListElem_free_notNull + rjmp WidgetListElem_free_ret +WidgetListElem_free_notNull: + bigcall List_FiniObject ; (r16) + mov xl, yl + mov xh, yh + bigcall Heap_Free ; (r16, r17, r24, r25, X) +WidgetListElem_free_ret: + ret +; @end + + + + + + +#endif diff --git a/avr/modules/lcd2/gui/composite/0BUILD b/avr/modules/lcd2/gui/composite/0BUILD new file mode 100644 index 0000000..18c9bc1 --- /dev/null +++ b/avr/modules/lcd2/gui/composite/0BUILD @@ -0,0 +1,15 @@ + + + + + + cdialog.asm + d_numinput.asm + dialog.asm + hspinner.asm + mainwindow.asm + + + + + diff --git a/avr/modules/lcd2/gui/base/cdialog.asm b/avr/modules/lcd2/gui/composite/cdialog.asm similarity index 100% rename from avr/modules/lcd2/gui/base/cdialog.asm rename to avr/modules/lcd2/gui/composite/cdialog.asm diff --git a/avr/modules/lcd2/gui/base/d_numinput.asm b/avr/modules/lcd2/gui/composite/d_numinput.asm similarity index 100% rename from avr/modules/lcd2/gui/base/d_numinput.asm rename to avr/modules/lcd2/gui/composite/d_numinput.asm diff --git a/avr/modules/lcd2/gui/base/dialog.asm b/avr/modules/lcd2/gui/composite/dialog.asm similarity index 100% rename from avr/modules/lcd2/gui/base/dialog.asm rename to avr/modules/lcd2/gui/composite/dialog.asm diff --git a/avr/modules/lcd2/gui/base/hspinner.asm b/avr/modules/lcd2/gui/composite/hspinner.asm similarity index 100% rename from avr/modules/lcd2/gui/base/hspinner.asm rename to avr/modules/lcd2/gui/composite/hspinner.asm diff --git a/avr/modules/lcd2/gui/base/mainwindow.asm b/avr/modules/lcd2/gui/composite/mainwindow.asm similarity index 100% rename from avr/modules/lcd2/gui/base/mainwindow.asm rename to avr/modules/lcd2/gui/composite/mainwindow.asm diff --git a/avr/modules/lcd2/gui/composite/textsel.asm b/avr/modules/lcd2/gui/composite/textsel.asm new file mode 100644 index 0000000..f048ac8 --- /dev/null +++ b/avr/modules/lcd2/gui/composite/textsel.asm @@ -0,0 +1,506 @@ +; *************************************************************************** +; copyright : (C) 2026 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_GUI_TEXTSEL_ASM +#define AQH_AVR_GUI_TEXTSEL_ASM + + +; *************************************************************************** +; *************************************************************************** + + + + +; *************************************************************************** +; defines + +.equ TEXTSEL_OFFS_BEGIN = HLAYOUT_SIZE +.equ TEXTSEL_OFFS_CURVALUE_LO = TEXTSEL_OFFS_BEGIN+0 +.equ TEXTSEL_OFFS_CURVALUE_HI = TEXTSEL_OFFS_BEGIN+1 +.equ TEXTSEL_OFFS_TEXTLIST_LO = TEXTSEL_OFFS_BEGIN+2 +.equ TEXTSEL_OFFS_TEXTLIST_HI = TEXTSEL_OFFS_BEGIN+3 +.equ TEXTSEL_OFFS_CURRIDX = TEXTSEL_OFFS_BEGIN+4 +.equ TEXTSEL_OFFS_COUNT = TEXTSEL_OFFS_BEGIN+5 +.equ TEXTSEL_SIZE = TEXTSEL_OFFS_BEGIN+6 + + +; selectors +.equ TEXTSEL_SEL_LEFT = 1 +.equ TEXTSEL_SEL_RIGHT = 2 + + +; child widgets +.equ TEXTSEL_CHILDIDX_LEFT = 0 +.equ TEXTSEL_CHILDIDX_VALUE = 1 +.equ TEXTSEL_CHILDIDX_EIGHT = 2 + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine TextSel_new @global +; +; @return CFLAG set of okay, cleared otherwise +; @return Y address of newly created object +; @param X parent widget +; @param r16 value for OBJECT_OFFS_OPTS +; @param r17 value for WIDGET_OFFS_PACK +; @param r21:r20 pointer to null-terminated list of text ressources in FLASH (byte address for LPM!) +; @clobbers any + +TextSel_new: + ldi r24, LOW(TEXTSEL_SIZE) + ldi r25, HIGH(TEXTSEL_SIZE) + push r20 + push r21 + bigcall Object_Alloc ; (!r16, !r17, !X) + pop r21 + pop r20 + brcc TextSel_new_ret + rcall TextSel_Init ; (any, !Y) + sec +TextSel_new_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine TextSel_Init @global +; +; @param Y address of widget +; @param X parent widget (if any) +; @param r16 value for OBJECT_OFFS_OPTS +; @param r17 value for WIDGET_OFFS_PACK +; @param r21:r20 pointer to null-terminated list of text ressources in FLASH (byte address for LPM!) +; @clobbers any, !Y + +TextSel_Init: + ; call base class + push r20 + push r21 + ldi r20, HLAYOUT_MODE_EXPAND + bigcall HLayout_Init + pop r21 + pop r20 + brcc TextSel_Init_ret + + ; set values + std Y+TEXTSEL_OFFS_TEXTLIST_LO, r20 + std Y+TEXTSEL_OFFS_TEXTLIST_HI, r21 + + ; set default signal map + ldi r16, LOW(TextSel_DefaultSignalmap*2) + std Y+OBJECT_OFFS_SIGNALMAP_LO, r16 + ldi r16, HIGH(TextSel_DefaultSignalmap*2) + std Y+OBJECT_OFFS_SIGNALMAP_HI, r16 + + rcall textSelCreateChildren ; (any, !Y) +TextSel_Init_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine textSelCreateChildren +; +; @param Y spinner object +; @clobbers any, !Y + +textSelCreateChildren: + push yl + push yh + mov xl, yl ; parent + mov xh, yh + + ; create left button + call textSelCreateLeftButton + brcc textSelCreateChildren_popRet + ; create label + ldi r16, 0 ; OPTS + ldi r17, (WIDGET_PACK_END<