diff --git a/avr/devices/c03/test/main.asm b/avr/devices/c03/test/main.asm index 5d5e249..4e4baef 100644 --- a/avr/devices/c03/test/main.asm +++ b/avr/devices/c03/test/main.asm @@ -332,6 +332,7 @@ GUI2_MODULE_BEGIN: .include "modules/lcd2/gui2/base/imageview.asm" .include "modules/lcd2/gui2/base/valuelabel.asm" .include "modules/lcd2/gui2/aqhome/sensorwatch.asm" +.include "modules/lcd2/gui2/base/layout2.asm" GUI2_MODULE_END: .equ MODULE_SIZE_GUI2 = GUI2_MODULE_END-GUI2_MODULE_BEGIN diff --git a/avr/modules/lcd2/gui2/base/layout2.asm b/avr/modules/lcd2/gui2/base/layout2.asm new file mode 100644 index 0000000..ad87a98 --- /dev/null +++ b/avr/modules/lcd2/gui2/base/layout2.asm @@ -0,0 +1,717 @@ +; *************************************************************************** +; 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_LAYOUT2_ASM +#define AQH_AVR_GUI2_LAYOUT2_ASM + + +; *************************************************************************** +; defines + + +.equ LAYOUT_CTX_OFFS_TOTALSIZE_LO = 0 +.equ LAYOUT_CTX_OFFS_TOTALSIZE_HI = 1 +.equ LAYOUT_CTX_OFFS_BORDERS = 2 +.equ LAYOUT_CTX_OFFS_SPACING = 3 +.equ LAYOUT_CTX_OFFS_NUMITEMS = 4 +.equ LAYOUT_CTX_OFFS_ITEMS = 6 + +.equ LAYOUT_CTX_ITEM_OFFS_POS_LO = 0 +.equ LAYOUT_CTX_ITEM_OFFS_POS_HI = 1 +.equ LAYOUT_CTX_ITEM_OFFS_SIZE_LO = 2 +.equ LAYOUT_CTX_ITEM_OFFS_SIZE_HI = 3 +.equ LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO = 4 +.equ LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI = 5 +.equ LAYOUT_CTX_ITEM_OFFS_FLAGS = 6 +.equ LAYOUT_CTX_ITEM_SIZE = 7 ; CAVEAT: change code in LayoutCtx_new if size changed! + + + +; *************************************************************************** +; macros + + +.macro M_LAYOUT_FOREVERY_CONT + push yl + push yh + ldi zl, LOW(@0) + ldi zh, HIGH(@0) + rcall layoutForEveryObjectContiguous + pop yh + pop yl +.endmacro + + + +.macro M_LAYOUT_FOREVERY_SKIPPED + push yl + push yh + ldi zl, LOW(@0) + ldi zh, HIGH(@0) + rcall layoutForEveryObjectSkipped + pop yh + pop yl +.endmacro + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_new @global +; +; @param r16 number of entries to reserve +; @return X pointer to new layout context +; @clobbers r16, r17, r18, r19, r24, r25 + +LayoutCtx_new: + push r16 + clr r17 + mov r24, r16 + mov r25, r17 + lsl r24 ; x2 + rol r25 + add r24, r16 + adc r25, r17 ; x3 + lsl r24 ; x6 + rol r25 + add r24, r16 + adc r25, r17 ; x7 + ldi r16, LOW(LAYOUT_CTX_OFFS_ITEMS) + ldi r17, HIGH(LAYOUT_CTX_OFFS_ITEMS) + add r24, r16 + adc r25, r17 + ; alloc on heap + push r24 + push r25 + bigcall Heap_Alloc ; (r16, r17, r18, r19, r24, r25) + pop r25 + pop r24 + pop r16 + brcc LayoutCtx_new_ret + ; preset with 0 + push xl + push xh + clr r17 +LayoutCtx_new_loop: + st X+, r17 + sbiw r25:r24, 1 + brne LayoutCtx_new_loop + pop xh + pop xl + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + st X, r16 ; store number of items + sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + sec +LayoutCtx_new_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_free @global +; +; @param X pointer to layout context +; @clobbers r16, r17, r24, r25, X + +LayoutCtx_free: + bigjmp Heap_Free ; (r16, r17, r24, r25, X) +; @end + + + + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_CalcMinimumSize +; +; Calculate minimum size needed for the given items (containing borders and +; spacings) by using the defaultSize fields of the items. +; +; @param X pointer to layout ctx object +; @return r19:r18 calculated size (including borders and spacings) +; @clobbers r16, r17, r22, r23, r24 + +LayoutCtx_CalcMinimumSize: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS + ld r18, X+ ; borders (start calculated size with one border) + clr r19 + ld r22, X+ ; spacing + clr r23 + ld r24, X+ ; number of items (X now points to first item) + lsl r18 ; add border at beginning and end + rol r19 +LayoutCtx_CalcMinimumSize_loop: + adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO + ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO + ld r17, X ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI + adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI) + add r18, r16 ; add size + adc r19, r17 + add r18, r22 ; add spacing + adc r19, r23 + dec r24 + brne LayoutCtx_CalcMinimumSize_loop + sub r18, r22 ; sub last spacing + sbc r19, r23 + pop xh + pop xl + ret +; @end + + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_ReadXDimsContiguous +; +; @param X pointer to ctx +; @param r25 number of widgets to handle + +LayoutCtx_ReadXDimsContiguous: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyWidgetXToItem + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_ReadXDimsSkipped +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to skip in each round + +LayoutCtx_ReadXDimsSkipped: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyWidgetXToItem + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_WriteXDimsContiguous +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to handle + +LayoutCtx_WriteXDimsContiguous: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyItemToWidgetX + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_WriteXDimsSkipped +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to skip in each round + +LayoutCtx_WriteXDimsSkipped: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyItemToWidgetX + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_ReadYDimsContiguous +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to handle + +LayoutCtx_ReadYDimsContiguous: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyWidgetYToItem + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_ReadYDimsSkipped +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to skip in each round + +LayoutCtx_ReadYDimsSkipped: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyWidgetYToItem + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_WriteYDimsContiguous +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to handle + +LayoutCtx_WriteYDimsContiguous: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyItemToWidgetY + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_WriteYDimsSkipped +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to skip in each round + +LayoutCtx_WriteYDimsSkipped: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyItemToWidgetY + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_SetDefaultWidthContiguous +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to handle + +LayoutCtx_SetDefaultWidthContiguous: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_CONT layoutCtxCbsetDefaultWidth + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_SetDefaultWidthSkipped +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to skip in each round + +LayoutCtx_SetDefaultWidthSkipped: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbsetDefaultWidth + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_SetDefaultHeightContiguous +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to handle + +LayoutCtx_SetDefaultHeightContiguous: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_CONT layoutCtxCbsetDefaultHeight + pop xh + pop xl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LayoutCtx_SetDefaultHeightSkipped +; +; @param X pointer to ctx +; @param Y pointer to first widget to handle +; @param r25 number of widgets to skip in each round + +LayoutCtx_SetDefaultHeightSkipped: + push xl + push xh + adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS + ld r24, X+ ; X now points to first item + M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbsetDefaultHeight + pop xh + pop xl + ret +; @end + + + + + + + + +; --------------------------------------------------------------------------- +; @routine layoutCtxCbCopyWidgetXToItem +; +; @param Y widget +; @param X item +; @param r24 number of items left in layout context + +layoutCtxCbCopyWidgetXToItem: + tst r24 + sec + breq layoutCtxCbCopyWidgetXToItem_ret + + ldd r16, Y+WIDGET_OFFS_X_LO + st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_LO + ldd r16, Y+WIDGET_OFFS_X_HI + st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_HI + ldd r16, Y+WIDGET_OFFS_WIDTH_LO + st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO + ldd r16, Y+WIDGET_OFFS_WIDTH_HI + st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI + clr r16 + st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO + st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI + ldd r16, Y+WIDGET_OFFS_PACK + andi r16, (1<