Files
aqhomecontrol/avr/modules/lcd2/gui2/base/mlayout.asm
2026-04-06 01:45:56 +02:00

1151 lines
29 KiB
NASM

; ***************************************************************************
; 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_MLAYOUT_ASM
#define AQH_AVR_GUI2_MLAYOUT_ASM
; TODO:
; - use this class also for HLayout and VLayout, those are just special
; cases with only one row (HLayout) or column (VLayout)
; - add TMP2, use TMP1 for X, TMP2 for Y, position cells ??
; - set X=left pos of space allocated to object, Y=top pos??
; - use that to position cells in the end??
.macro M_MLAYOUT_FOREVERY_CONT
push yl
push yh
ldi zl, LOW(@0)
ldi zh, HIGH(@0)
rcall mLayoutForEveryObjectContiguous
pop yh
pop yl
.endmacro
.macro M_MLAYOUT_FOREVERY_SKIPPED
push yl
push yh
ldi zl, LOW(@0)
ldi zh, HIGH(@0)
rcall mLayoutForEveryObjectSkipped
pop yh
pop yl
.endmacro
; ***************************************************************************
; defines
.equ MLAYOUT_OFFS_BEGIN = WIDGET_SIZE
.equ MLAYOUT_OFFS_MODE = MLAYOUT_OFFS_BEGIN+0
.equ MLAYOUT_OFFS_COLSORROWS = MLAYOUT_OFFS_BEGIN+1
.equ MLAYOUT_SIZE = MLAYOUT_OFFS_BEGIN+2
; values for MLAYOUT_OFFS_MODE
.equ MLAYOUT_MODE_COLUMNS = 0
.equ MLAYOUT_MODE_ROWS = 1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine MLayout_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 (MLAYOUT_MODE_COLUMNS, MLAYOUT_MODE_ROWS)
; @param r21 number of columns or rows (depending on mode in r20)
; @clobbers any
MLayout_new:
push r20
push r21
ldi r24, LOW(MLAYOUT_SIZE)
ldi r25, HIGH(MLAYOUT_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc MLayout_new_ret
rcall MLayout_Init ; (r16, r17, X)
sec
MLayout_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine MLayout_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 (MLAYOUT_MODE_COLUMN, MLAYOUT_MODE_ROW)
; @param r21 number of columns or rows (depending on mode in r20)
; @clobbers r16, r17, X
MLayout_Init:
push r20
push r21
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r21
pop r20
; set widget-specific data
std Y+MLAYOUT_OFFS_MODE, r20
std Y+MLAYOUT_OFFS_COLSORROWS, r21
; set default signal map
ldi r16, LOW(MLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(MLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine MLayout_OnLayout @global
;
; @param Y widget
; @clobbers any, !Y
MLayout_OnLayout:
bigcall OBJ_GetFirstChild ; test for children
brcc MLayout_OnLayout_ret ; none, done here
ldd r16, Y+MLAYOUT_OFFS_MODE
cpi r16, MLAYOUT_MODE_COLUMNS
breq MLayout_OnLayout_columns
rjmp MLayout_OnLayout_ret
MLayout_OnLayout_columns:
rcall MLayout_Layout_ColumnMode
MLayout_OnLayout_ret:
sec
ret
; ---------------------------------------------------------------------------
; @routine MLayout_OnGetDefaultWidth @global
;
; @param Y widget
; @clobbers any, !Y
MLayout_OnGetDefaultWidth:
bigcall OBJ_GetFirstChild ; test for children
brcc MLayout_OnGetDefaultWidth_ret ; none, done here
ldd r16, Y+MLAYOUT_OFFS_MODE
cpi r16, MLAYOUT_MODE_COLUMNS
breq MLayout_OnGetDefaultWidth_columns
rjmp MLayout_OnLayout_ret
MLayout_OnGetDefaultWidth_columns:
rcall MLayout_OnGetDefaultWidth_ColumnMode
MLayout_OnGetDefaultWidth_ret:
sec
ret
; ---------------------------------------------------------------------------
; @routine MLayout_OnGetDefaultHeight @global
;
; @param Y widget
; @clobbers any, !Y
MLayout_OnGetDefaultHeight:
bigcall OBJ_GetFirstChild ; test for children
brcc MLayout_OnGetDefaultHeight_ret ; none, done here
ldd r16, Y+MLAYOUT_OFFS_MODE
cpi r16, MLAYOUT_MODE_COLUMNS
breq MLayout_OnGetDefaultHeight_columns
rjmp MLayout_OnLayout_ret
MLayout_OnGetDefaultHeight_columns:
rcall MLayout_OnGetDefaultHeight_ColumnMode
MLayout_OnGetDefaultHeight_ret:
sec
ret
; ---------------------------------------------------------------------------
; @routine MLayout_GetFirstChildToY
;
; @param Y widget
; @return CFLAG set if child found, cleared on error
; @return Y first child widget
; @clobbers none
MLayout_GetFirstChildToY:
push r18
push r19
bigcall OBJ_GetFirstChild
brcc MLayout_GetFirstChildToY_ret
mov yl, r18
mov yh, r19
MLayout_GetFirstChildToY_ret:
pop r19
pop r18
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackSetTmp
;
; @param Y widget
; @param r21:r20 TMP to set
; @clobbers none
mLayoutCallbackSetTmp:
std Y+WIDGET_OFFS_TMP_LO, r20
std Y+WIDGET_OFFS_TMP_HI, r21
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackSetXTmp
;
; @param Y widget
; @param r21:r20 TMP to set
; @param X X to set
; @clobbers none
mLayoutCallbackSetXTmp:
std Y+WIDGET_OFFS_X_LO, xl
std Y+WIDGET_OFFS_X_HI, xh
std Y+WIDGET_OFFS_TMP_LO, r20
std Y+WIDGET_OFFS_TMP_HI, r21
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackSetYTmp
;
; @param Y widget
; @param r21:r20 TMP to set
; @param X Y to set
; @clobbers none
mLayoutCallbackSetYTmp:
std Y+WIDGET_OFFS_Y_LO, xl
std Y+WIDGET_OFFS_Y_HI, xh
std Y+WIDGET_OFFS_TMP_LO, r20
std Y+WIDGET_OFFS_TMP_HI, r21
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackGridX
;
; @param Y widget
; @param r22 spacing between widgets
; @param X current X pos
; @clobbers r10-r13, r16-r21
mLayoutCallbackGridX:
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
std Y+WIDGET_OFFS_X_LO, xl ; set new X
std Y+WIDGET_OFFS_X_HI, xh
add xl, r20 ; add cell width
adc xh, r21
add xl, r22 ; add spacing
adc xh, r22
sub xh, r22
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackPackX
;
; @param Y widget
; @param r22 spacing between widgets
; @clobbers r10-r13, r16-r21, X
mLayoutCallbackPackX:
ldd r10, Y+WIDGET_OFFS_TMP_LO ; calculated cell width
ldd r11, Y+WIDGET_OFFS_TMP_HI
ldd r12, Y+WIDGET_OFFS_WIDTH_LO ; default width
ldd r13, Y+WIDGET_OFFS_WIDTH_HI
ldd r17, Y+WIDGET_OFFS_PACK
andi r17, 3 ; WIDGET_PACK_HSELF0_BIT = 0, no shift necessary
rcall mLayoutPackCell ; R21:R20=relative pos, R19:R18=new size (r16, r17, r18, r19)
ldd xl, Y+WIDGET_OFFS_X_LO
ldd xh, Y+WIDGET_OFFS_X_HI
add xl, r20
adc xh, r21
std Y+WIDGET_OFFS_X_LO, xl
std Y+WIDGET_OFFS_X_HI, xh
std Y+WIDGET_OFFS_WIDTH_LO, r18
std Y+WIDGET_OFFS_WIDTH_HI, r19
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackGridY
;
; @param Y widget
; @param r22 spacing between widgets
; @param X current Y pos
; @clobbers r10-r13, r16-r21
mLayoutCallbackGridY:
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
std Y+WIDGET_OFFS_Y_LO, xl ; set new Y
std Y+WIDGET_OFFS_Y_HI, xh
add xl, r20 ; add cell width
adc xh, r21
add xl, r22 ; add spacing
adc xh, r22
sub xh, r22
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackPackY
;
; @param Y widget
; @param r22 spacing between widgets
; @clobbers r10-r13, r16-r21, X
mLayoutCallbackPackY:
ldd r10, Y+WIDGET_OFFS_TMP_LO ; calculated cell width
ldd r11, Y+WIDGET_OFFS_TMP_HI
ldd r12, Y+WIDGET_OFFS_HEIGHT_LO ; default width
ldd r13, Y+WIDGET_OFFS_HEIGHT_HI
ldd r17, Y+WIDGET_OFFS_PACK
lsr r17 ; WIDGET_PACK_VSELF0_BIT = 2 -> shift 2 times right
lsr r17
andi r17, 3
rcall mLayoutPackCell ; R21:R20=relative pos, R19:R18=new size (r16, r17, r18, r19)
ldd xl, Y+WIDGET_OFFS_Y_LO
ldd xh, Y+WIDGET_OFFS_Y_HI
add xl, r20
adc xh, r21
std Y+WIDGET_OFFS_Y_LO, xl
std Y+WIDGET_OFFS_Y_HI, xh
std Y+WIDGET_OFFS_HEIGHT_LO, r18
std Y+WIDGET_OFFS_HEIGHT_HI, r19
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutSetupFirstContiguous
;
; For every contiguous widget (e.g. in a row) determine the maximum TMP value
; of all widgets orthogonal to that widget, e.g. when working in column mode:
; Get the highest width for every column and store that in the first widget of
; that column (i.e. in the first row).
;
; @param R25 widgets per row/column
; @param r25 widgets per row/column
; @clobbers r18, r19, Z
mLayoutSetupFirstContiguous:
push yl
push yh
ldi zl, LOW(mLayoutCallbackSetupFirstContiguous)
ldi zh, HIGH(mLayoutCallbackSetupFirstContiguous)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackSetupFirstContiguous
;
; @param Y object to start with
; @param r25 widgets per row/column
; @clobbers r18, r19, r20, r21
mLayoutCallbackSetupFirstContiguous:
push zl
push zh
push yl
push yh
rcall mLayoutGetMaxTmpSkipped ; (r18, r19, Z)
pop yh
pop yl
std Y+WIDGET_OFFS_TMP_LO, r20
std Y+WIDGET_OFFS_TMP_HI, r21
pop zh
pop zl
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutSetupFirstSkipped
;
; For every skipped widget (e.g. in a column) determine the maximum TMP value
; of all widgets orthogonal to that widget.
; Same as mLayoutSetupFirstContiguous except orthograde.
;
; @param Y object to start with
; @param r25 number of widgets to skip
; @clobbers r18, r19, Z
mLayoutSetupFirstSkipped:
push yl
push yh
ldi zl, LOW(mLayoutCallbackSetupFirstSkipped)
ldi zh, HIGH(mLayoutCallbackSetupFirstSkipped)
rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackSetupFirstSkipped
;
; For every skipped widget (e.g. in a column) determine the maximum TMP value
; of all widgets orthogonal to that widget.
; Same as mLayoutSetupFirstContiguous except orthograde.
;
; @param Y object to start with
; @param r25 number of widgets to skip
; @clobbers r18, r19
mLayoutCallbackSetupFirstSkipped:
push zl
push zh
push yl
push yh
rcall mLayoutGetMaxTmpContiguous ; (r18, r19, Z)
pop yh
pop yl
std Y+WIDGET_OFFS_TMP_LO, r20
std Y+WIDGET_OFFS_TMP_HI, r21
pop zh
pop zl
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutGetMaxTmpContiguous
;
; @param Y object to start with
; @param r25 number of widgets to handle
; @return r21:r20 maximum TMP value encountered
; @clobbers r18, r19, Z
mLayoutGetMaxTmpContiguous:
push yl
push yh
clr r20
clr r21
ldi zl, LOW(mLayoutCallbackGetMaxTmp)
ldi zh, HIGH(mLayoutCallbackGetMaxTmp)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutGetMaxTmpSkipped
;
; @param Y object to start with
; @param r25 number of widgets to skip after each widget handled
; @return r21:r20 maximum TMP value encountered
; @clobbers r18, r19, Z
mLayoutGetMaxTmpSkipped:
push yl
push yh
clr r20
clr r21
ldi zl, LOW(mLayoutCallbackGetMaxTmp)
ldi zh, HIGH(mLayoutCallbackGetMaxTmp)
rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackGetMaxTmp
;
; @param Y object whose TMP value is to be added
; @param r21:r20 current maximum value
; @return CFLAG clear (to not abort the loop function)
; @clobbers r18, r19
mLayoutCallbackGetMaxTmp:
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
cp r20, r18
cpc r21, r19
brcc mLayoutCallbackGetMaxTmp_ret
mov r20, r18
mov r21, r19
mLayoutCallbackGetMaxTmp_ret:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCountMatchingPackContiguous
;
; @param Y object whose TMP value is to be added
; @param r22 mask for WIDGET_OFFS_PACK
; @param r23 value for WIDGET_OFFS_PACK
; @param r25 number of widgets to handle
; @return r20 number of matching children
; @clobbers r18, r19
mLayoutCountMatchingPackContiguous:
push yl
push yh
clr r20
ldi zl, LOW(mLayoutCallbackCountMatchingPack)
ldi zh, HIGH(mLayoutCallbackCountMatchingPack)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCountChildrenMatchingPackSkipped
;
; @param Y object whose TMP value is to be added
; @param r22 mask for WIDGET_OFFS_PACK
; @param r23 value for WIDGET_OFFS_PACK
; @param r25 number of widgets to handle (0=all)
; @return r20 number of matching children
; @clobbers r18, r19, r25
mLayoutCountChildrenMatchingPackSkipped:
push yl
push yh
clr r20
ldi zl, LOW(mLayoutCallbackCountMatchingPack)
ldi zh, HIGH(mLayoutCallbackCountMatchingPack)
rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackCountMatchingPack
;
; @param Y object whose TMP value is to be added
; @param r20 number of matching children so far
; @param r22 mask for WIDGET_OFFS_PACK
; @param r23 value for WIDGET_OFFS_PACK
; @return CFLAG clear (to not abort the loop function)
; @clobbers r18
mLayoutCallbackCountMatchingPack:
ldd r18, Y+OBJECT_OFFS_FLAGS
sbrs r18, WIDGET_FLAGS_VISIBLE_BIT
rjmp mLayoutCallbackCountMatchingPack_ret
ldd r18, Y+WIDGET_OFFS_PACK
eor r18, r23
and r18, r22
brne mLayoutCallbackCountMatchingPack_ret
inc r20
mLayoutCallbackCountMatchingPack_ret:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutExpandMatchingPackContiguous
;
; @param Y object whose TMP value is to be added
; @param r21:r20 value to add to TMP
; @param r22 mask for WIDGET_OFFS_PACK
; @param r23 value for WIDGET_OFFS_PACK
; @param r25 number of widgets to handle
; @clobbers r18, r19
mLayoutExpandMatchingPackContiguous:
push yl
push yh
ldi zl, LOW(mLayoutCallbackExpandMatchingPack)
ldi zh, HIGH(mLayoutCallbackExpandMatchingPack)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutExpandMatchingPackSkipped
;
; @param Y object whose TMP value is to be added
; @param r21:r20 value to add to TMP
; @param r22 mask for WIDGET_OFFS_PACK
; @param r23 value for WIDGET_OFFS_PACK
; @param r25 number of widgets to skip
; @clobbers r18, r19
mLayoutExpandMatchingPackSkipped:
push yl
push yh
ldi zl, LOW(mLayoutCallbackExpandMatchingPack)
ldi zh, HIGH(mLayoutCallbackExpandMatchingPack)
rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackExpandMatchingPack
;
; @param Y object whose TMP value is to be added
; @param r21:r20 space to add to expandable widgets
; @param r22 mask for WIDGET_OFFS_PACK
; @param r23 value for WIDGET_OFFS_PACK
; @return CFLAG clear (to not abort the loop function)
; @clobbers r18, r19
mLayoutCallbackExpandMatchingPack:
ldd r18, Y+OBJECT_OFFS_FLAGS
sbrs r18, WIDGET_FLAGS_VISIBLE_BIT
rjmp mLayoutCallbackExpandMatchingPack_ret
ldd r18, Y+WIDGET_OFFS_PACK
eor r18, r23
and r18, r22
brne mLayoutCallbackExpandMatchingPack_ret
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
add r18, r20
adc r19, r21
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
mLayoutCallbackExpandMatchingPack_ret:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutSetDefaultWidthToTmp
;
; @param Y object to start with
; @param r25 number of widgets to handle (0=any)
; @clobbers any, !Y
mLayoutSetDefaultWidthToTmp:
push yl
push yh
ldi zl, LOW(mLayoutCallbackDefaultWidthToTmp)
ldi zh, HIGH(mLayoutCallbackDefaultWidthToTmp)
rcall mLayoutForEveryObjectContiguous ; (any)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackDefaultWidthToTmp
;
; @param Y object whose TMP value is to be added
; @return CFLAG clear (to not abort the loop function)
; @clobbers r18, r19 (any, !Y)
mLayoutCallbackDefaultWidthToTmp:
push zl
push zh
bigcall Widget_GetDefaultWidth ; (any, !Y)
pop zh
pop zl
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutSetDefaultHeightToTmp
;
; @param Y object to start with
; @param r25 number of widgets to handle (0=any)
; @clobbers any, !Y
mLayoutSetDefaultHeightToTmp:
push yl
push yh
ldi zl, LOW(mLayoutCallbackDefaultHeightToTmp)
ldi zh, HIGH(mLayoutCallbackDefaultHeightToTmp)
rcall mLayoutForEveryObjectContiguous ; (any)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackDefaultHeightToTmp
;
; @param Y object whose TMP value is to be added
; @return CFLAG clear (to not abort the loop function)
; @clobbers r18, r19 (any, !Y)
mLayoutCallbackDefaultHeightToTmp:
push zl
push zh
bigcall Widget_GetDefaultHeight ; (any, !Y)
pop zh
pop zl
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCopyTmpToWidth
;
; @param Y object to start with
; @param r25 number of widgets to handle (0=all)
; @clobbers r18, r19, Z
mLayoutCopyTmpToWidth:
push yl
push yh
ldi zl, LOW(mLayoutCallbackCopyTmpToWidth)
ldi zh, HIGH(mLayoutCallbackCopyTmpToWidth)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackCopyTmpToWidth
;
; @param Y object to start with
; @clobbers r18, r19
mLayoutCallbackCopyTmpToWidth:
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
std Y+WIDGET_OFFS_WIDTH_LO, r18
std Y+WIDGET_OFFS_WIDTH_HI, r19
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCopyTmpToHeight
;
; @param Y object to start with
; @param r25 number of widgets to handle (0=all)
; @clobbers r18, r19, Z
mLayoutCopyTmpToHeight:
push yl
push yh
ldi zl, LOW(mLayoutCallbackCopyTmpToHeight)
ldi zh, HIGH(mLayoutCallbackCopyTmpToHeight)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackCopyTmpToHeight
;
; @param Y object to start with
; @clobbers r18, r19
mLayoutCallbackCopyTmpToHeight:
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
std Y+WIDGET_OFFS_HEIGHT_LO, r18
std Y+WIDGET_OFFS_HEIGHT_HI, r19
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutSumContiguous
;
; @param Y object to start with
; @param r25 widgets per column/row
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @return r21:r20 total size in the given dimension including borders and inter-widget spacing
; @clobbers r18, r19
mLayoutSumContiguous:
push yl
push yh
mov r20, r23 ; start with border
clr r21
ldi zl, LOW(mLayoutCallbackAddToSum)
ldi zh, HIGH(mLayoutCallbackAddToSum)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
sub r20, r22 ; undo last adding inter-widget space
sbc r21, r22
add r21, r22
add r20, r23 ; end with border
adc r21, r23
sub r21, r23
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutSumSkipped
;
; @param Y object to start with
; @param r25 number of widgets to skip after each widget handled
; @param r22 spacing between widgets
; @param r23 border at beginning and end
; @return r21:r20 sum of TMP values
; @clobbers r18, r19, r25
mLayoutSumSkipped:
push yl
push yh
mov r20, r23 ; start with border
clr r21
ldi zl, LOW(mLayoutCallbackAddToSum)
ldi zh, HIGH(mLayoutCallbackAddToSum)
rcall mLayoutForEveryObjectSkipped ; (r18, r19, r25, Y)
sub r20, r22 ; undo last adding inter-widget space
sbc r21, r22
add r21, r22
add r20, r23 ; end with border
adc r21, r23
sub r21, r23
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackAddToSum
;
; @param Y object whose TMP value is to be added
; @param r25 number of widgets to handle
; @param r21:r20 sum so far (TMP will be added to it)
; @param r22 spacing between widgets
; @return CFLAG clear (to not abort the loop function)
; @clobbers r18, r19
mLayoutCallbackAddToSum:
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
add r20, r18 ; add TMP
adc r21, r19
add r20, r22 ; add spacing
adc r21, r22
sub r21, r22
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutForEveryObjectContiguous
;
; This routine itself uses R18, R19, R25 and Y. All other registers may be
; passed to the callback routine.
; However, the callback function must make sure that it doesn't modify registers
; which are to be passed to next objects later!
;
; This routine traverses the given number of contiguous objects until there is no
; next object.
;
; Y and R25 are preserved around the callback. Z MUST NOT be modified by the callback!
;
; @param Y object to start with
; @param r25 number of widgets to handle (0=all)
; @param Z pointer to routine to call (using ICALL)
; @return CFLAG set if the callback returned with CFLAG set on any widget
; @return Y object on which the call returned with CFLAG set (otherwise last object handled)
; @clobbers r18, r19, Y {any}
mLayoutForEveryObjectContiguous:
push r25
mov r18, r25
mLayoutForEveryObjectContiguous_loop:
push r18
push r25
push yl
push yh
icall
pop yh
pop yl
pop r25
pop r18
brcs mLayoutForEveryObjectContiguous_ret
tst r18
breq mLayoutForEveryObjectContiguous_next
dec r18
clc
breq mLayoutForEveryObjectContiguous_ret
mLayoutForEveryObjectContiguous_next:
push r18
bigcall OBJ_GetNext
brcs mLayoutForEveryObjectContiguous_loopEnd
pop r18
rjmp mLayoutForEveryObjectContiguous_ret
mLayoutForEveryObjectContiguous_loopEnd:
mov yl, r18
mov yh, r19
pop r18
rjmp mLayoutForEveryObjectContiguous_loop
mLayoutForEveryObjectContiguous_ret:
pop r25
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutForEveryObjectSkipped
;
; This routine itself uses R18, R19, R25 and Y. All other registers may be
; passed to the callback routine.
; However, the callback function must make sure that it doesn't modify registers
; which are to be passed to next objects later!
;
; This routine traverses the given objects skipping [R25] objects after each round
; until there is no next object.
;
; Y and R25 are preserved around the callback. Z MUST NOT be modified by the callback!
;
; @param Y object to start with
; @param r25 number of widgets to skip per round
; @param Z pointer to routine to call (using ICALL)
; @return CFLAG set if the callback returned with CFLAG set on any widget
; @return Y object on which the call returned with CFLAG set (garbage otherwise)
; @clobbers r18, r19, Y {any}
mLayoutForEveryObjectSkipped:
mLayoutForEveryObjectSkipped_loop:
push r25
push yl
push yh
icall
pop yh
pop yl
pop r25
brcs mLayoutForEveryObjectSkipped_ret
push r16
mov r16, r25
bigcall OBJ_SkipObjects ; (R16)
pop r16
brcc mLayoutForEveryObjectSkipped_ret
mov yl, r18
mov yh, r19
rjmp mLayoutForEveryObjectSkipped_loop
mLayoutForEveryObjectSkipped_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutGetBorders
;
; @param Y address of widget
; @return r22 spacing
; @return r23 outer borders
; @clobbers Z
mLayoutGetBorders:
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
lpm r22, Z
sbiw zh:zl, WIDGET_STYLE_OFFS_SPACING
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
lpm r23, Z
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutPackCell
;
; @param Y address of widget
; @param r17 pack mode (see @ref WIDGET_PACK_BEGIN)
; @param R11:R10 size of cell area (i.e. width or height)
; @param R13:R12 size of object to pack (i.e. width or height)
; @param r22 spacing (between widgets)
; @return R21:R20 pos
; @return R19:R18 new size of widget
; @clobbers r16, r17, r18, r19
mLayoutPackCell:
clr r20 ; preset pos
clr r21
mov r18, r12 ; preset widget size
mov r19, r13
; subtract borders from cell size
clr r16
sub r10, r22 ; subtract spacing
sbc r11, r16
brcs mLayoutPackCell_ret
andi r17, 3 ; only 2 bits pack mode
cpi r17, WIDGET_PACK_FILLED
breq mLayoutPackCell_filled
cpi r17, WIDGET_PACK_END
breq mLayoutPackCell_end
cpi r17, WIDGET_PACK_CENTER
breq mLayoutPackCell_center
rjmp mLayoutPackCell_ret ; begin/filled, align at begin
mLayoutPackCell_filled:
mov r18, r10 ; use full cell size (minus spacing)
mov r19, r11
rjmp mLayoutPackCell_ret
mLayoutPackCell_end:
sub r10, r12
sbc r11, r13
mov r20, r10
mov r21, r11
rjmp mLayoutPackCell_ret
mLayoutPackCell_center:
sub r10, r12
sbc r11, r13
lsr r11
ror r10
mov r20, r10
mov r21, r11
rjmp mLayoutPackCell_ret
mLayoutPackCell_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
MLayout_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(MLayout_OnLayout), HIGH(MLayout_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(MLayout_OnGetDefaultWidth), HIGH(MLayout_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(MLayout_OnGetDefaultHeight), HIGH(MLayout_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif