Files
aqhomecontrol/avr/modules/lcd2/gui2/base/mlayout_column.asm
2026-03-23 23:15:38 +01:00

642 lines
16 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_COLUMN_ASM
#define AQH_AVR_GUI2_MLAYOUT_COLUMN_ASM
; ***************************************************************************
; defines
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine MLayout_OnGetDefaultWidth_ColumnMode @global
;
; @param Y widget
; @return r19:r18 value
; @clobbers any, !Y
MLayout_OnGetDefaultWidth_ColumnMode:
; DEBUG
ldi r18, 10
clr r19
sec
ret
rcall mLayoutSetDefaultWidthToTmp ; (any, !Y)
rcall mLayoutGetBorders ; r22=spacing, r23=border
push yl
push yh
rcall MLayout_GetFirstChildToY
rcall mLayoutSumContiguous ; r21:r20 needed minimum row width (r18, r19, r25)
pop yh
pop yl
mov r18, r20
mov r19, r21
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine MLayout_OnGetDefaultHeight_ColumnMode @global
;
; @param Y widget
; @return r19:r18 value
; @clobbers any, !Y
MLayout_OnGetDefaultHeight_ColumnMode:
; DEBUG
ldi r18, 10
clr r19
sec
ret
bigcall OBJ_GetFirstChild
push yl
push yh
mov yl, r18
mov yh, r19
rcall mLayoutSetDefaultHeightToTmp ; (any, !Y)
rcall mLayoutGetBorders ; r22=spacing, r23=border
rcall mLayoutSumSkipped ; r21:r20 needed minimum row width (r18, r19, r25)
mov r18, r20
mov r19, r21
pop yh
pop yl
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine MLayout_LayoutColumnMode @global
;
; @param Y widget
; @clobbers any, !Y
MLayout_Layout_ColumnMode:
rcall mLayoutColumnLayoutHorizontally
rcall mLayoutColumnLayoutVertically
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnLayoutHorizontally
;
; @param Y widget
; @clobbers any, !Y
mLayoutColumnLayoutHorizontally:
rcall mLayoutGetBorders ; r22=spacing, r23=border
ldd r25, Y+MLAYOUT_OFFS_COLSORROWS
push yl
push yh
rcall MLayout_GetFirstChildToY ; (none)
push r22
push r23
push r25
clr r25
rcall mLayoutSetDefaultWidthToTmp ; (any, !Y)
clr r25
rcall mLayoutCopyTmpToWidth ; (r18, r19, Z)
pop r25
pop r23
pop r22
; prepare first row
rcall mLayoutSetupFirstContiguous ; set max column widths to first row (r18, r19, Z)
rcall mLayoutColumnExpandColumns ; (r16-r23)
rcall mLayoutColumnGridX
rcall mLayoutColumnCopyXTmpFromFirstRow
rcall mLayoutColumnPackX ; (r10-r13, r16-r21, X)
pop yh
pop yl
ret
; @end
mLayoutColumnLayoutVertically:
rcall mLayoutGetBorders ; r22=spacing, r23=border
ldd r25, Y+MLAYOUT_OFFS_COLSORROWS
push yl
push yh
rcall MLayout_GetFirstChildToY ; (none)
push r22
push r23
push r25
clr r25
rcall mLayoutSetDefaultHeightToTmp ; (any, !Y)
clr r25
rcall mLayoutCopyTmpToHeight ; (r18, r19, Z)
pop r25
pop r23
pop r22
rcall mLayoutSetupFirstSkipped ; set max column heights to first column (r18, r19, Z)
rcall mLayoutColumnExpandRows ; (r16-r23)
rcall mLayoutColumnGridY
rcall mLayoutColumnCopyTmpFromFirstColumn
rcall mLayoutColumnPackY ; (r10-r13, r16-r21, X)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCopyXTmpFromFirstRow
;
; @param Y widget
; @param R25 widgets per row/column
; @clobbers r18-r21, Z
mLayoutColumnCopyXTmpFromFirstRow:
M_MLAYOUT_FOREVERY_CONT mLayoutCallbackColumnCopyRow
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackColumnCopyRow
;
; @param Y widget
; @clobbers r18, r19, r20, r21
mLayoutCallbackColumnCopyRow:
push zl
push zh
rcall mLayoutColumnCopyXTmpAcrossColumn ; (r18, r19, r20, r21, X, Z)
pop zh
pop zl
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCopyXTmpAcrossColumn
;
; @param Y widget
; @param R25 widgets per row/column
; @clobbers r18, r19, r20, r21, X, Z
mLayoutColumnCopyXTmpAcrossColumn:
push yl
push yh
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
ldd xl, Y+WIDGET_OFFS_X_LO
ldd xh, Y+WIDGET_OFFS_X_HI
ldi zl, LOW(mLayoutCallbackSetXTmp)
ldi zh, HIGH(mLayoutCallbackSetXTmp)
rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCopyTmpFromFirstColumn
;
; @param Y widget
; @param R25 widgets per row/column
; @clobbers r18-r21, Z
mLayoutColumnCopyTmpFromFirstColumn:
push yl
push yh
ldi zl, LOW(mLayoutCallbackColumnCopyColumn)
ldi zh, HIGH(mLayoutCallbackColumnCopyColumn)
rcall mLayoutForEveryObjectSkipped ; (r18-r21, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutCallbackColumnCopyColumn
;
; @param Y widget
; @param R25 widgets per row/column
; @clobbers r18, r19, r20, r21
mLayoutCallbackColumnCopyColumn:
push zl
push zh
rcall mLayoutColumnCopyYTmpAcrossRow ; (r18, r19, r20, r21, Z)
pop zh
pop zl
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCopyTmpAcrossRow
;
; @param Y widget
; @param R25 widgets per row/column
; @clobbers r18, r19, r20, r21, Z
mLayoutColumnCopyYTmpAcrossRow:
push yl
push yh
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
ldd xl, Y+WIDGET_OFFS_Y_LO
ldd xh, Y+WIDGET_OFFS_Y_HI
ldi zl, LOW(mLayoutCallbackSetYTmp)
ldi zh, HIGH(mLayoutCallbackSetYTmp)
rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnGridX
;
; Set X and width to all columns of the row
;
; @param Y first widget of current row
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param R25 widgets per row/column
; @clobbers r12, r13, r16-r21, X, Z
mLayoutColumnGridX:
mov xl, r23 ; start at border
clr xh
push yl
push yh
ldi zl, LOW(mLayoutCallbackGridX)
ldi zh, HIGH(mLayoutCallbackGridX)
rcall mLayoutForEveryObjectContiguous ; (r12, r13, r16-r21, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnPackX
;
; Pack each widget inside its cell.
;
; @param Y first widget of current row
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param R25 widgets per row/column
; @clobbers r10-r13, r16-r21, X
mLayoutColumnPackX:
push r25
clr r25
M_MLAYOUT_FOREVERY_CONT mLayoutCallbackPackX ; (r10-r13, r16-r21, X)
pop r25
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnGridY
;
; Set Y and height to all rows of a column
;
; @param Y first widget of current row
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param R25 widgets per row/column
; @clobbers r12, r13, r16-r21, X, Z
mLayoutColumnGridY:
mov xl, r23 ; start at border
clr xh
push yl
push yh
ldi zl, LOW(mLayoutCallbackGridY)
ldi zh, HIGH(mLayoutCallbackGridY)
rcall mLayoutForEveryObjectSkipped ; (r12, r13, r16-r21, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnPackY
;
; Pack each widget inside its cell.
;
; @param Y first widget of current row
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @clobbers r10-r13, r16-r21, X
mLayoutColumnPackY:
push r25
clr r25
M_MLAYOUT_FOREVERY_CONT mLayoutCallbackPackY ; (r10-r13, r16-r21, X)
pop r25
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnExpandColumns
;
; Calculate additional space per expandable widget in a row.
;
; @param Y first widget of current row
; @param R25 widgets per row/column
; @return CFLAG set if there is additional space to distribute
; @return r21:r20 space to add to every expandable widget
; @clobbers r16-r21
mLayoutColumnExpandColumns:
push yl
push yh
bigcall OBJ_GetParent
mov yl, r18
mov yh, r19
ldd r18, Y+WIDGET_OFFS_WIDTH_LO
ldd r19, Y+WIDGET_OFFS_WIDTH_HI
pop yh
pop yl
rcall mLayoutColumnCalcAddSpacePerColumn ; r21:r20=additional space (r16-r23)
brcc mLayoutColumnExpandColumns_ret
push r22
push r23
ldi r22, (1<<WIDGET_PACK_HSELF1_BIT) | (1<<WIDGET_PACK_HSELF0_BIT) ; mask
ldi r23, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) ; value
rcall mLayoutExpandMatchingPackContiguous ; (r18, r19)
pop r23
pop r22
mLayoutColumnExpandColumns_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCalcAddSpacePerColumn
;
; Calculate additional space per expandable widget in a row.
;
; @param Y first widget of current row
; @param r19:r18 width of parent widget
; @return CFLAG set if there is additional space to distribute
; @return r21:r20 space to add to every expandable widget
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param r25 widgets per row/column
; @clobbers r16-r21
mLayoutColumnCalcAddSpacePerColumn:
push r22
push r23
rcall mLayoutColumnCalcAdditionalSpaceContiguous ; r21:r20=additional space (R18, R19)
brcc mLayoutColumnCalcAddSpacePerColumn_ret
push r20
push r21
ldi r22, (1<<WIDGET_PACK_HSELF1_BIT) | (1<<WIDGET_PACK_HSELF0_BIT) ; mask
ldi r23, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) ; value
rcall mLayoutCountMatchingPackContiguous ; r20=num of matching items (r18, r19)
mov r22, r20
clr r23
pop r21
pop r20
tst r22
breq mLayoutColumnCalcAddSpacePerColumn_none ; don't divide by zero!
push r25
bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable widget (r25)
pop r25
mov r20, r16
mov r21, r17
sec
rjmp mLayoutColumnCalcAddSpacePerColumn_ret
mLayoutColumnCalcAddSpacePerColumn_none:
clr r20
clr r21
clc
mLayoutColumnCalcAddSpacePerColumn_ret:
pop r23
pop r22
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCalcAdditionalSpaceContiguous
;
; Calculate additional space in a row.
;
; @param Y first widget of current row
; @param r19:r18 width of parent widget
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param r25 widgets per row/column
; @return CFLAG set if there is additional space to distribute
; @return r21:r20 available additional space
; @clobbers r18, r19
mLayoutColumnCalcAdditionalSpaceContiguous:
push r18
push r19
rcall mLayoutSumContiguous ; r21:r20 needed minimum row width (r18, r19)
pop r19
pop r18
sub r18, r20
sbc r19, r21
brcs mLayoutColumnCalcAdditionalSpaceContiguous_none
breq mLayoutColumnCalcAdditionalSpaceContiguous_none
mov r20, r18
mov r21, r19
sec
rjmp mLayoutColumnCalcAdditionalSpaceContiguous_ret
mLayoutColumnCalcAdditionalSpaceContiguous_none:
clr r20
clr r21
clc
mLayoutColumnCalcAdditionalSpaceContiguous_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnExpandRows
;
; Calculate additional space per expandable widget in a column.
;
; @param Y first widget of current row
; @param R25 widgets per row/column
; @return CFLAG set if there is additional space to distribute
; @return r21:r20 space to add to every expandable widget
; @clobbers r16-r21
mLayoutColumnExpandRows:
push yl
push yh
bigcall OBJ_GetParent
mov yl, r18
mov yh, r19
ldd r18, Y+WIDGET_OFFS_HEIGHT_LO
ldd r19, Y+WIDGET_OFFS_HEIGHT_HI
pop yh
pop yl
rcall mLayoutColumnCalcAddSpacePerRow ; r21:r20=additional space (r16-r23)
brcc mLayoutColumnExpandRows_ret
push r22
push r23
ldi r22, (1<<WIDGET_PACK_VSELF1_BIT) | (1<<WIDGET_PACK_VSELF0_BIT) ; mask
ldi r23, (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT) ; value
rcall mLayoutExpandMatchingPackSkipped ; (r18, r19)
pop r23
pop r22
mLayoutColumnExpandRows_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCalcAddSpacePerRow
;
; Calculate additional space per expandable widget in a column.
;
; @param Y first widget of current row
; @param r19:r18 width of parent widget
; @return CFLAG set if there is additional space to distribute
; @return r21:r20 space to add to every expandable widget
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param r25 widgets per row/column
; @clobbers r16-r21
mLayoutColumnCalcAddSpacePerRow:
push r22
push r23
rcall mLayoutColumnCalcAdditionalSpaceSkipped ; r21:r20=additional space (R18, R19)
brcc mLayoutColumnCalcAddSpacePerRow_ret
push r20
push r21
ldi r22, (1<<WIDGET_PACK_VSELF1_BIT) | (1<<WIDGET_PACK_VSELF0_BIT) ; mask
ldi r23, (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT) ; value
rcall mLayoutCountMatchingPackContiguous ; r20=num of matching items (r18, r19)
mov r22, r20
clr r23
pop r21
pop r20
tst r22
breq mLayoutColumnCalcAddSpacePerRow_none ; don't divide by zero!
push r25
bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable widget (r25)
pop r25
mov r20, r16
mov r21, r17
sec
rjmp mLayoutColumnCalcAddSpacePerRow_ret
mLayoutColumnCalcAddSpacePerRow_none:
clr r20
clr r21
clc
mLayoutColumnCalcAddSpacePerRow_ret:
pop r23
pop r22
ret
; @end
; ---------------------------------------------------------------------------
; @routine mLayoutColumnCalcAdditionalSpaceSkipped
;
; Calculate additional space in a row.
;
; @param Y first widget of current row
; @param r19:r18 width of parent widget
; @param r22 spacing between widgets
; @param r23 border at beginning and and
; @param r25 widgets per row/column
; @return CFLAG set if there is additional space to distribute
; @return r21:r20 available additional space
; @clobbers r18, r19
mLayoutColumnCalcAdditionalSpaceSkipped:
push r18
push r19
rcall mLayoutSumSkipped ; r21:r20 needed minimum row width (r18, r19)
pop r19
pop r18
sub r18, r20
sbc r19, r21
brcs mLayoutColumnCalcAdditionalSpaceSkipped_none
breq mLayoutColumnCalcAdditionalSpaceSkipped_none
mov r20, r18
mov r21, r19
sec
rjmp mLayoutColumnCalcAdditionalSpaceSkipped_ret
mLayoutColumnCalcAdditionalSpaceSkipped_none:
clr r20
clr r21
clc
mLayoutColumnCalcAdditionalSpaceSkipped_ret:
ret
; @end
#endif