gui2: more work on new layout module, started working on hlayout2.

This commit is contained in:
Martin Preuss
2026-04-08 23:54:31 +02:00
parent 2a5f09e239
commit b81d798008
3 changed files with 710 additions and 2 deletions

View File

@@ -333,6 +333,7 @@ GUI2_MODULE_BEGIN:
.include "modules/lcd2/gui2/base/valuelabel.asm" .include "modules/lcd2/gui2/base/valuelabel.asm"
.include "modules/lcd2/gui2/aqhome/sensorwatch.asm" .include "modules/lcd2/gui2/aqhome/sensorwatch.asm"
.include "modules/lcd2/gui2/base/layout2.asm" .include "modules/lcd2/gui2/base/layout2.asm"
.include "modules/lcd2/gui2/base/hlayout2.asm"
GUI2_MODULE_END: GUI2_MODULE_END:
.equ MODULE_SIZE_GUI2 = GUI2_MODULE_END-GUI2_MODULE_BEGIN .equ MODULE_SIZE_GUI2 = GUI2_MODULE_END-GUI2_MODULE_BEGIN

View File

@@ -0,0 +1,313 @@
; ***************************************************************************
; 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_HLAYOUT2_ASM
#define AQH_AVR_GUI2_HLAYOUT2_ASM
; ***************************************************************************
; defines
.equ HLAYOUT2_OFFS_BEGIN = WIDGET_SIZE
.equ HLAYOUT2_OFFS_MODE = HLAYOUT2_OFFS_BEGIN+0
.equ HLAYOUT2_SIZE = HLAYOUT2_OFFS_BEGIN+1
; values for HLAYOUT_OFFS_MODE
.equ HLAYOUT2_MODE_EXPAND = 0
.equ HLAYOUT2_MODE_SPREAD = 1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine HLayout_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 r20 layout mode (HLAYOUT_MODE_EXPAND, HLAYOUT_MODE_SPREAD)
; @clobbers any
HLayout2_new:
push r20
ldi r24, LOW(HLAYOUT2_SIZE)
ldi r25, HIGH(HLAYOUT2_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc HLayout2_new_ret
rcall HLayout2_Init ; (r16, r17, X)
sec
HLayout2_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout2_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 r20 layout mode (HLAYOUT_MODE_EXPAND, HLAYOUT_MODE_SPREAD)
; @clobbers r16, r17, X
HLayout2_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; set widget-specific data
std Y+HLAYOUT2_OFFS_MODE, r20
; set default signal map
ldi r16, LOW(HLayout2_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(HLayout2_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout2_OnLayout
;
; @param Y pointer to widget
; @clobbers any, !Y
HLayout2_OnLayout:
; create layout context
bigcall OBJ_CountDirectChildren ; r16=num of children (r18, r19)
tst r16
breq HLayout2_OnLayout_ret
push r16
bigcall LayoutCtx_new ; X=new ctx (r16, r17, r18, r19, r24, r25)
pop r16
brcc HLayout2_OnLayout_ret
; set borders and spacing in layout context
bigcall Widget_GetBorderAndSpacing ; (none)
adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
st X+, r23 ; store border
st X, r22 ; store spacing
sbiw xh:xl, (LAYOUT_CTX_OFFS_BORDERS+1)
; do layout
mov r25, r16
rcall hLayout2Horizontally
rcall hLayout2Vertically
; release layout context
bigcall LayoutCtx_free
; force re-drawing of this widget, clear layout bit
ldd r16, Y+OBJECT_OFFS_FLAGS
sbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
cbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
HLayout2_OnLayout_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout2_OnGetDefaultHeight
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
HLayout2_OnGetDefaultHeight:
; rcall Layout_SetDefaultHeights
; rcall Layout_GetMaxTmp
; bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout2_OnGetDefaultWidth
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
HLayout2_OnGetDefaultWidth:
; rcall Layout_SetDefaultWidths
; rcall Layout_SumTmpValues ; r19:r18=default width
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayout2Vertically
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !X, !Y
hLayout2Vertically:
ldd r20, Y+WIDGET_OFFS_HEIGHT_LO
ldd r21, Y+WIDGET_OFFS_HEIGHT_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
; layout
push yl
push yh
push r24
bigcall OBJ_GetFirstChild
mov yl, r18
mov yh, r19
; read positions and flags into new layout context
push r25
push yl
push yh
bigcall LayoutCtx_ReadYDimsContiguous
pop yh
pop yl
pop r25
; get default heights
push r25
push yl
push yh
bigcall LayoutCtx_SetDefaultHeightContiguous
pop yh
pop yl
pop r25
pop r24
; layout
bigcall LayoutCtx_GetMaxDefaultSize ; r19:r18=max default size (r18, r19, r20, r21, r24)
bigcall LayoutCtx_SetFixedSize ; (r24)
push r25
bigcall LayoutCtxSetPos ; (r16-r25)
pop r25
; write back dims
push r25
push yl
push yh
bigcall LayoutCtx_WriteYDimsContiguous
pop yh
pop yl
pop r25
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayout2Horizontally
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !Y
hLayout2Horizontally:
; setup layout context for horizontal operations
ldd r20, Y+WIDGET_OFFS_WIDTH_LO
ldd r21, Y+WIDGET_OFFS_WIDTH_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
; layout
ldd r24, Y+HLAYOUT2_OFFS_MODE
push yl
push yh
push r24
bigcall OBJ_GetFirstChild
mov yl, r18
mov yh, r19
; read X positions and flags into new layout context
push r25
push yl
push yh
bigcall LayoutCtx_ReadXDimsContiguous
pop yh
pop yl
pop r25
; get default widths
push r25
push yl
push yh
bigcall LayoutCtx_SetDefaultWidthContiguous
pop yh
pop yl
pop r25
pop r24
; layout
push r25
cpi r24, HLAYOUT_MODE_SPREAD
breq hLayout2Horizontally_spread
bigcall LayoutCtx_LayoutExpand ; (r16-r25)
rjmp hLayout2Horizontally_writeBack
hLayout2Horizontally_spread:
bigcall LayoutCtx_LayoutSpread ; (r16-r25)
hLayout2Horizontally_writeBack:
pop r25
; write back dims
push r25
push yl
push yh
bigcall LayoutCtx_WriteXDimsContiguous
pop yh
pop yl
pop r25
pop yh
pop yl
ret
; @end
; ***************************************************************************
; data in FLASH
HLayout2_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(HLayout2_OnLayout), HIGH(HLayout2_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(HLayout2_OnGetDefaultWidth), HIGH(HLayout2_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(HLayout2_OnGetDefaultHeight), HIGH(HLayout2_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -132,6 +132,360 @@ LayoutCtx_free:
; ---------------------------------------------------------------------------
; @routine LayoutCtx_LayoutExpand
;
; @param X pointer to layout context
; @clobbers r16-r25
LayoutCtx_LayoutExpand:
rcall layoutCtxCalcExpandPerExpandableItem ; r17:r16=space to add to expandable items (r16-r25)
rcall layoutCtxSetSizeWithExtra ; (r20, r21, r22, r24)
rcall LayoutCtxSetPos ; (r16-r25)
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_LayoutSpread
;
; @param X pointer to layout context
; @clobbers r16-r25
LayoutCtx_LayoutSpread:
rcall layoutCtxCalcExpandPerExpandableItem ; r17:r16=space to add to expandable items (r16-r25)
rcall layoutCtxCalcSpreadValue ; r17:r16=space to add to expandable items and between (r16-r25)
push r16
push r17
rcall layoutCtxSetSizeWithExtra ; expand expandable items (r20, r21, r22, r24)
pop r17
pop r16
rcall layoutCtxSetPosWithExtra ; (r16-r25)
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_GetMaxDefaultSize
;
; @param X pointer to ctx
; @return r19:r18 maximum default size
; @clobbers r18, r19, r20, r21, r24
LayoutCtx_GetMaxDefaultSize:
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; X now points to first item
clr r18
clr r19
LayoutCtx_GetMaxDefaultSize_loop:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO
ld r20, X+
ld r21, X
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO+1)
cp r18, r20
cpc r19, r21
brcc LayoutCtx_GetMaxDefaultSize_next
mov r18, r20
mov r19, r21
LayoutCtx_GetMaxDefaultSize_next:
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
dec r24
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_SetFixedSize
;
; @param X pointer to ctx
; @param r19:r18 new size
; @clobbers r24
LayoutCtx_SetFixedSize:
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; X now points to first item
LayoutCtx_SetFixedSize_loop:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO
st X+, r18
st X, r19
adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_SIZE_HI)
dec r24
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxSetSizeWithExtra
;
; Copy default size to size field and add extra space to expandable items.
;
; @param X pointer to layout context
; @param r17:r16 number of bytes to add to expandable items
; @clobbers r20, r21, r22, r24
layoutCtxSetSizeWithExtra:
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; number of items (X now points to first item)
layoutCtxSetSizeWithExtra_loop:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO
ld r20, X+
ld r21, X
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO+1)
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
ld r22, X
sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
andi r22, 3
cpi r22, WIDGET_PACK_FILLED
brne layoutCtxSetSizeWithExtra_store
add r20, r16 ; only add for expandable items
adc r21, r17
layoutCtxSetSizeWithExtra_store:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO
st X+, r20
st X, r21
adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_SIZE_HI)
dec r24
brne layoutCtxSetSizeWithExtra_loop
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtxSetPos
;
; Layout items in their dimension according to their packing flags.
;
; @param X pointer to layout context
; @clobbers r16-r25
LayoutCtxSetPos:
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)
LayoutCtxSetPos_loop: ; r19:r18=current pos, r22=spacing, r23=border, X=1st item
push r18
push r19
rcall layoutCtxPack ; (r16-r21, r25)
pop r19
pop r18
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ld r20, X+
ld r21, X
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_SIZE_LO+1)
add r18, r20 ; add current item size
adc r19, r21
add r18, r22 ; add spacing
adc r19, r23
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE ; next item
dec r24
brne LayoutCtxSetPos_loop
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxSetPosWithExtra
;
; Layout items in their dimension according to their packing flags and also add
; extra space to spacings and borders
;
; @param X pointer to layout context
; @clobbers r16-r25
layoutCtxSetPosWithExtra:
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)
add r22, r16 ; add extra space to spacing
adc r23, r17
add r18, r16 ; add space to border
adc r19, r17
layoutCtxSetPosWithExtra_loop: ; r19:r18=current pos, r22=spacing, r23=border, X=1st item
push r18
push r19
rcall layoutCtxPack ; (r16-r21, r25)
pop r19
pop r18
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ld r20, X+
ld r21, X
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_SIZE_LO+1)
add r18, r20 ; add current item size
adc r19, r21
add r18, r22 ; add spacing
adc r19, r23
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE ; next item
dec r24
brne layoutCtxSetPosWithExtra_loop
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxPack
;
; @param X pointer to current item
; @param r19:r18 current pos
; @clobbers r16-r21, r25
layoutCtxPack:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ld r16, X+ ; size lo
ld r17, X+ ; size hi
ld r20, X+ ; default size lo
ld r21, X+ ; default size lo
ld r25, X ; flags
sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
sub r16, r20 ; r17:r16=(size-defaultSize)
sbc r17, r21
brcs layoutCtxPack_store
andi r25, 3
cpi r25, WIDGET_PACK_END
breq layoutCtxPack_end
cpi r25, WIDGET_PACK_CENTER
breq layoutCtxPack_center
rjmp layoutCtxPack_store
layoutCtxPack_end:
add r18, r16 ; just add difference to pos
adc r19, r17
rjmp layoutCtxPack_store
layoutCtxPack_center:
lsr r17
ror r16
add r18, r16 ; just add half difference to pos
adc r19, r17
layoutCtxPack_store:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_POS_LO
st X+, r18
st X, r19
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_POS_LO+1)
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCalcExpandPerExpandableItem
;
; @param X pointer to layout context
; @clobbers r16-r25
layoutCtxCalcExpandPerExpandableItem:
rcall LayoutCtx_CountExpandableItems ; r16=num (r17, r24)
tst r16
breq layoutCtxCalcExpandPerExpandableItem_none ; no expandable item, nothing to expand
push r16
rcall layoutCtxCalcAvailableExtraSpace ; r21:r20=available extra space (r16-r24)
pop r16
brcc layoutCtxCalcExpandPerExpandableItem_none ; jmp if no extra space
mov r22, r16
clr r23
bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable item
rjmp layoutCtxCalcExpandPerExpandableItem_ret
layoutCtxCalcExpandPerExpandableItem_none:
clr r16
clr r17
layoutCtxCalcExpandPerExpandableItem_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCalcSpreadValue
;
; @param X pointer to layout context
; @return r17:r16 value to add for borders, spacings and expandable items
; @clobbers r16-r25
layoutCtxCalcSpreadValue:
rcall LayoutCtx_CountExpandableItems ; r16=num (r17, r24)
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X
sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
add r16, r24
inc r16
tst r16
breq layoutCtxCalcSpreadValue_none ; no expandable item, nothing to expand
rcall layoutCtxCalcAvailableExtraSpace ; r21:r20=available extra space (r16-r24)
brcc layoutCtxCalcExpandPerExpandableItem_none ; jmp if no extra space
mov r22, r16
clr r23
bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable item (r25)
rjmp layoutCtxCalcSpreadValue_ret
layoutCtxCalcSpreadValue_none:
clr r16
clr r17
layoutCtxCalcSpreadValue_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCalcAvailableExtraSpace
;
; @param X pointer to layout context
; @return CFLAG set if there is extra space, cleared otherwise
; @return r21:r20 available extra space
; @clobbers r16-r24
layoutCtxCalcAvailableExtraSpace:
rcall LayoutCtx_CalcMinimumSize ; r19:r18=size (r16, r17, r22, r23, r24)
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
ld r20, X+
ld r21, X
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
sub r20, r18
sbc r21, r19
; flip carry flag
rol r16 ; rotate CF into r16
com r16 ; flip bit
ror r16 ; rotate bit 0 into CF
brcs layoutCtxCalcAvailableExtraSpace_ret
clr r20
clr r21
clc
layoutCtxCalcAvailableExtraSpace_ret:
ret
; @end
@@ -176,19 +530,58 @@ LayoutCtx_CalcMinimumSize_loop:
; ---------------------------------------------------------------------------
; @routine LayoutCtx_CountExpandableItems
;
; 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 r16 number of expandable items
; @clobbers r17, r24
LayoutCtx_CountExpandableItems:
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; number of items (X now points to first item)
clr r16
LayoutCtx_CountExpandableItems_loop:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
ld r17, X
adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_FLAGS)
andi r17, 3
cpi r17, WIDGET_PACK_FILLED
brne LayoutCtx_CountExpandableItems_next
inc r16
LayoutCtx_CountExpandableItems_next:
dec r24
brne LayoutCtx_CountExpandableItems_loop
pop xh
pop xl
ret
; @end
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine LayoutCtx_ReadXDimsContiguous ; @routine LayoutCtx_ReadXDimsContiguous
; ;
; @param X pointer to ctx ; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to handle ; @param r25 number of widgets to handle
; @clobbers (r16, r18, r19, r24, Y)
LayoutCtx_ReadXDimsContiguous: LayoutCtx_ReadXDimsContiguous:
push xl push xl
push xh push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; X now points to first item ld r24, X+ ; X now points to first item
M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyWidgetXToItem M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyWidgetXToItem ; (r16, r18, r19, r24, Y)
pop xh pop xh
pop xl pop xl
ret ret
@@ -426,7 +819,8 @@ LayoutCtx_SetDefaultHeightSkipped:
; ;
; @param Y widget ; @param Y widget
; @param X item ; @param X item
; @param r24 number of items left in layout context ; @param r24 number of items left in layout context (gets decreased)
; @clobbers r16
layoutCtxCbCopyWidgetXToItem: layoutCtxCbCopyWidgetXToItem:
tst r24 tst r24