Files
aqhomecontrol/avr/modules/lcd2/gui/base/layout.asm
2026-04-14 23:53:54 +02:00

1772 lines
47 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_LAYOUT_ASM
#define AQH_AVR_GUI2_LAYOUT_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 = 5
.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_FLAGS = 4
.equ LAYOUT_CTX_ITEM_SIZE = 5 ; 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
lsl r24 ; x4
rol r25
add r24, r16
adc r25, r17 ; x5
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_CreateContextFor1D @global
;
; @param Y pointer to widget
; @return CFLAG set if context created, cleared on error
; @return X pointer to newly created context
; @return R16 number of children
; @clobbers any, !Y
LayoutCtx_CreateContextFor1D:
; create layout context
bigcall OBJ_CountDirectChildren ; r16=num of children (r18, r19)
tst r16
clc
breq LayoutCtx_CreateContextFor1D_ret
rcall LayoutCtx_CreateContextForN
LayoutCtx_CreateContextFor1D_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_CreateContextForN @global
;
; @param Y pointer to widget
; @param R16 number of items
; @return CFLAG set if context created, cleared on error
; @return X pointer to newly created context
; @clobbers any, !R16, !Y
LayoutCtx_CreateContextForN:
tst r16
clc
breq LayoutCtx_CreateContextForN_ret
push r16
bigcall LayoutCtx_new ; X=new ctx (r16, r17, r18, r19, r24, r25)
pop r16
brcc LayoutCtx_CreateContextForN_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
st X, r16 ; store number of items
sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ; back to beginning
sec
LayoutCtx_CreateContextForN_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @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 LayoutCtx_SetPos ; (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_GetMaxSize
;
; @param X pointer to ctx
; @return r19:r18 maximum default size
; @clobbers r18, r19, r20, r21, r24
LayoutCtx_GetMaxSize:
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_GetMaxSize_loop:
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)
cp r18, r20
cpc r19, r21
brcc LayoutCtx_GetMaxSize_next
mov r18, r20
mov r19, r21
LayoutCtx_GetMaxSize_next:
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
dec r24
brne LayoutCtx_GetMaxSize_loop
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
brne LayoutCtx_SetFixedSize_loop
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_SetFixedPos
;
; @param X pointer to ctx
; @param r19:r18 new pos
; @clobbers r24
LayoutCtx_SetFixedPos:
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; X now points to first item
LayoutCtx_SetFixedPos_loop:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_POS_LO
st X+, r18
st X, r19
adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_POS_HI)
dec r24
brne LayoutCtx_SetFixedPos_loop
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_SIZE_LO
ld r20, X+
ld r21, X
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_SIZE_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 LayoutCtx_SetPos
;
; Set pos of all items.
;
; @param X pointer to layout context
; @clobbers r16-r25
LayoutCtx_SetPos:
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)
LayoutCtx_SetPos_loop: ; r19:r18=current pos, r22=spacing, r23=border, X=1st item
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_POS_LO ; store pos
st X+, r18
st X, r19
sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_POS_LO+1)
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 LayoutCtx_SetPos_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
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)
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 r21:r20 default size of the widget
; @return r19:r18 calculated pos
; @return r21:r20 calculated size
; @clobbers r16-r19, r25
layoutCtxPack:
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_POS_LO
ld r18, X+ ; pos lo
ld r19, X+ ; pos hi
ld r16, X+ ; size lo
ld r17, X+ ; size hi
ld r25, X ; flags
sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
rjmp layoutPack
; @end
; ---------------------------------------------------------------------------
; @routine layoutPack
;
; @param r17:r16 space available to the child widget
; @param r21:r20 default size of the child widget
; @param r19:r18 pos
; @param r25 pack flags
; @return r19:r18 calculated pos
; @return r21:r20 calculated size
; @clobbers r16-r19, r25
layoutPack:
sub r16, r20 ; r17:r16=(size-defaultSize)
sbc r17, r21
brcs layoutPack_done
andi r25, 3
cpi r25, WIDGET_PACK_END
breq layoutPack_end
cpi r25, WIDGET_PACK_CENTER
breq layoutPack_center
cpi r25, WIDGET_PACK_FILLED
breq layoutPack_filled
rjmp layoutPack_done
layoutPack_end:
add r18, r16 ; just add difference to pos
adc r19, r17
rjmp layoutPack_done
layoutPack_center:
lsr r17
ror r16
add r18, r16 ; just add half difference to pos
adc r19, r17
rjmp layoutPack_done
layoutPack_filled:
add r16, r20 ; get total size back
adc r17, r21
mov r20, r16
mov r21, r17
layoutPack_done:
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCalcExpandPerExpandableItem
;
; @param X pointer to layout context
; @return r17:r16 space per expandable item
; @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
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 (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
; ---------------------------------------------------------------------------
; @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_SIZE_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_SIZE_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_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
;
; @param X pointer to ctx
; @param Y pointer to widget
; @clobbers R16, r18, r19, r24, Z
LayoutCtx_ReadXDimsContiguous:
ldi zl, LOW(layoutCtxCbCopyWidgetXToItem)
ldi zh, HIGH(layoutCtxCbCopyWidgetXToItem)
rjmp layoutCtxForEveryChildContiguous ; (R16, r18, r19, r24)
; @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:
ldi zl, LOW(layoutCtxCbCopyWidgetXToItem)
ldi zh, HIGH(layoutCtxCbCopyWidgetXToItem)
rjmp layoutCtxForEveryChildSkipped
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_ReadXMaxDimsHorizontal
;
; Read pos and size from first row and then check next rows. Determine the
; highest width of every column and also set item flags to FILLED if any
; widget of a column has this pack mode.
;
; @param X pointer to ctx
; @param Y pointer to widget
; @param r25 number of widgets to handle per row
; @clobbers r16-r20, r24, Y
LayoutCtx_ReadXMaxDimsHorizontal:
rcall layoutCtxResetAllItems ; (R16, R17)
ldi zl, LOW(layoutCtxCbMaxWidgetTmpToItemHPackIncX)
ldi zh, HIGH(layoutCtxCbMaxWidgetTmpToItemHPackIncX)
rjmp LayoutCtx_MultiActionHorizontal ; (r16-r20, r24)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_WriteXDimsContiguous
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to handle
; @clobbers R16, r18, r19, r24, Z
LayoutCtx_WriteXDimsContiguous:
ldi zl, LOW(layoutCtxCbCopyItemToWidgetX)
ldi zh, HIGH(layoutCtxCbCopyItemToWidgetX)
rjmp layoutCtxForEveryChildContiguous ; (R16, r18, r19, r24)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_WriteXDimsSkipped
;
; @param X pointer to ctx
; @param Y pointer to widget
; @param r25 number of widgets to skip in each round
LayoutCtx_WriteXDimsSkipped:
ldi zl, LOW(layoutCtxCbCopyItemToWidgetX)
ldi zh, HIGH(layoutCtxCbCopyItemToWidgetX)
rjmp layoutCtxForEveryChildSkipped
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_ReadYDimsContiguous
;
; @param X pointer to ctx
; @param Y pointer to widget
; @param r25 number of widgets to handle
; @clobbers R16, r18, r19, r24, Z
LayoutCtx_ReadYDimsContiguous:
ldi zl, LOW(layoutCtxCbCopyWidgetYToItem)
ldi zh, HIGH(layoutCtxCbCopyWidgetYToItem)
rjmp layoutCtxForEveryChildContiguous ; (R16, r18, r19, r24)
; @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:
ldi zl, LOW(layoutCtxCbCopyWidgetYToItem)
ldi zh, HIGH(layoutCtxCbCopyWidgetYToItem)
rjmp layoutCtxForEveryChildSkipped
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_ReadYMaxDimsVertical
;
; Same as LayoutCtx_ReadXMaxDimsContinuous but for height and skipped.
;
; @param X pointer to ctx
; @param Y pointer to widget containing childs to handle
; @param r25 number of widgets in a row
; @clobbers r16-r20, Z
LayoutCtx_ReadYMaxDimsVertical:
rcall layoutCtxResetAllItems ; (R16, R17)
ldi zl, LOW(layoutCtxCbMaxWidgetTmpToItemVPackNoIncX)
ldi zh, HIGH(layoutCtxCbMaxWidgetTmpToItemVPackNoIncX) ; (r16-r20)
rjmp LayoutCtx_MultiActionVertical ; (r16-r20)
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxResetAllItems
;
; @param X pointer to ctx
; @clobbers r16, r17
layoutCtxResetAllItems:
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r17, X+ ; X now points to first item
tst r17
breq layoutCtxResetAllItems_done
layoutCtxResetAllItems_loop:
rcall layoutCtxResetItem ; (R16)
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
dec r17
brne layoutCtxResetAllItems_loop
layoutCtxResetAllItems_done:
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxResetItem
;
; @param X pointer to item
; @clobbers r16
layoutCtxResetItem:
clr r16
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_LO
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_HI
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
dec r16
st X, r16 ; LAYOUT_CTX_ITEM_OFFS_FLAGS (write 0xff)
sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_PackYVertical
;
; @param X pointer to ctx
; @param Y pointer to widget containing childs to handle
; @param r25 number of widgets in a row
; @clobbers r16, r18, r19, r24, Z
LayoutCtx_PackYVertical:
ldi zl, LOW(layoutCtxCbPackYNoIncX)
ldi zh, HIGH(layoutCtxCbPackYNoIncX)
rjmp LayoutCtx_MultiActionVertical ; (r16, r18, r19, r24)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_PackXHorizontal
;
; @param X pointer to ctx
; @param Y pointer to widget containing childs to handle
; @param r25 number of widgets in a row
; @clobbers r16, r18, r19, r24, Z
LayoutCtx_PackXHorizontal:
ldi zl, LOW(layoutCtxCbPackXIncX)
ldi zh, HIGH(layoutCtxCbPackXIncX)
rjmp LayoutCtx_MultiActionHorizontal ; (r16, r18, r19)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_WriteYDimsContiguous
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to handle
; @clobbers R16, r18, r19, r24, Z
LayoutCtx_WriteYDimsContiguous:
ldi zl, LOW(layoutCtxCbCopyItemToWidgetYIncX)
ldi zh, HIGH(layoutCtxCbCopyItemToWidgetYIncX)
rjmp layoutCtxForEveryChildContiguous ; (R16, r18, r19, r24)
; @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:
ldi zl, LOW(layoutCtxCbCopyItemToWidgetYIncX)
ldi zh, HIGH(layoutCtxCbCopyItemToWidgetYIncX)
rjmp layoutCtxForEveryChildSkipped ; (R16, r18, r19)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_PackXContiguous
;
; @param X pointer to ctx
; @param Y pointer to widget
; @return CFLAG set if more widgets to handle, cleared otherwise
; @return Y pointer to next widget to handle (if CFLAG set)
; @clobbers r16-r21, r24, r25
LayoutCtx_PackXContiguous:
ldi zl, LOW(layoutCtxCbPackXIncX)
ldi zh, HIGH(layoutCtxCbPackXIncX)
rjmp layoutCtxForEveryChildContiguous ; (r16-r21, r24, r25)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_PackXSkipped
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to skip in each round
; @return CFLAG set if more widgets to handle, cleared otherwise
; @return Y pointer to next widget to handle (if CFLAG set)
LayoutCtx_PackXSkipped:
ldi zl, LOW(layoutCtxCbPackXIncX)
ldi zh, HIGH(layoutCtxCbPackXIncX)
rjmp layoutCtxForEveryChildSkipped ; (R16, r18, r19)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_PackYContiguous
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to handle
; @return CFLAG set if more widgets to handle, cleared otherwise
; @return Y pointer to next widget to handle (if CFLAG set)
; @clobbers R16, r18, r19, r24, Z
LayoutCtx_PackYContiguous:
ldi zl, LOW(layoutCtxCbPackYIncX)
ldi zh, HIGH(layoutCtxCbPackYIncX)
rjmp layoutCtxForEveryChildContiguous ; (R16, r18, r19, r24)
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_PackYSkipped
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to skip in each round
; @return CFLAG set if more widgets to handle, cleared otherwise
; @return Y pointer to next widget to handle (if CFLAG set)
LayoutCtx_PackYSkipped:
ldi zl, LOW(layoutCtxCbPackYIncX)
ldi zh, HIGH(layoutCtxCbPackYIncX)
rjmp layoutCtxForEveryChildSkipped ; (R16, r18, r19)
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbCopyWidgetXToItem
;
; @param Y widget
; @param X item
; @return X next item
; @clobbers r16
layoutCtxCbCopyWidgetXToItem:
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_TMP_LO
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ldd r16, Y+WIDGET_OFFS_TMP_HI
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
ldd r16, Y+WIDGET_OFFS_PACK
andi r16, (1<<WIDGET_PACK_HSELF0_BIT) | (1<<WIDGET_PACK_HSELF1_BIT)
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_FLAGS
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbCopyItemToWidgetX
;
; @param Y widget
; @param X item
; @param r24 number of items left in layout context (gets decremented)
; @return X next item
; @clobbers r16
layoutCtxCbCopyItemToWidgetX:
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_POS_LO
std Y+WIDGET_OFFS_X_LO, r16
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_POS_HI
std Y+WIDGET_OFFS_X_HI, r16
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
std Y+WIDGET_OFFS_WIDTH_LO, r16
ld r16, X ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
std Y+WIDGET_OFFS_WIDTH_HI, r16
adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_SIZE_HI)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbCopyWidgetYToItem
;
; @param Y widget
; @param X item
; @return X next item
; @clobbers r16
layoutCtxCbCopyWidgetYToItem:
ldd r16, Y+WIDGET_OFFS_Y_LO
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_LO
ldd r16, Y+WIDGET_OFFS_Y_HI
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_HI
ldd r16, Y+WIDGET_OFFS_TMP_LO
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ldd r16, Y+WIDGET_OFFS_TMP_HI
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
ldd r16, Y+WIDGET_OFFS_PACK
andi r16, (1<<WIDGET_PACK_VSELF0_BIT) | (1<<WIDGET_PACK_VSELF1_BIT)
lsr r16
lsr r16
st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_FLAGS
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbMaxWidgetTmpToItemHPackNoIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r20
layoutCtxCbMaxWidgetTmpToItemHPackNoIncX:
ldd r20, Y+WIDGET_OFFS_PACK
andi r20, (1<<WIDGET_PACK_HSELF0_BIT) | (1<<WIDGET_PACK_HSELF1_BIT)
rcall layoutCtxCopyWidgetTmpToItemSizeNoIncX
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbMaxWidgetTmpToItemHPackIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r20
layoutCtxCbMaxWidgetTmpToItemHPackIncX:
ldd r20, Y+WIDGET_OFFS_PACK
andi r20, (1<<WIDGET_PACK_HSELF0_BIT) | (1<<WIDGET_PACK_HSELF1_BIT)
rcall layoutCtxCopyWidgetTmpToItemSizeNoIncX
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbMaxWidgetTmpToItemVPackNoIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r20
layoutCtxCbMaxWidgetTmpToItemVPackNoIncX:
ldd r20, Y+WIDGET_OFFS_PACK
andi r20, (1<<WIDGET_PACK_VSELF0_BIT) | (1<<WIDGET_PACK_VSELF1_BIT)
lsr r20
lsr r20
andi r20, 3
rcall layoutCtxCopyWidgetTmpToItemSizeNoIncX ; (r16-r19)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbMaxWidgetTmpToItemVPackIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r20
layoutCtxCbMaxWidgetTmpToItemVPackIncX:
ldd r20, Y+WIDGET_OFFS_PACK
andi r20, (1<<WIDGET_PACK_VSELF0_BIT) | (1<<WIDGET_PACK_VSELF1_BIT)
lsr r20
lsr r20
rcall layoutCtxCopyWidgetTmpToItemSizeNoIncX ; (r16-r19)
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCopyWidgetTmpToItemSizeNoIncX
;
; @param Y widget
; @param X item
; @param r20 widget pack transformed to item flags
; @clobbers r16-r19
layoutCtxCopyWidgetTmpToItemSizeNoIncX:
ldd r16, Y+WIDGET_OFFS_TMP_LO
ldd r17, Y+WIDGET_OFFS_TMP_HI
adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ld r18, X+ ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
ld r19, X ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
cp r18, r16
cpc r19, r17
brcc layoutCtxCopyWidgetTmpToItemSizeNoIncX_checkFlags
st X, r17 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
st -X, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
adiw xh:xl, 1 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
layoutCtxCopyWidgetTmpToItemSizeNoIncX_checkFlags:
adiw xh:xl, 1 ; LAYOUT_CTX_ITEM_OFFS_FLAGS
ld r17, X ; LAYOUT_CTX_ITEM_OFFS_FLAGS
cpi r17, 0xff
breq layoutCtxCopyWidgetTmpToItemSizeNoIncX_storeFlags
cpi r20, WIDGET_PACK_FILLED
brne layoutCtxCopyWidgetTmpToItemSizeNoIncX_done
layoutCtxCopyWidgetTmpToItemSizeNoIncX_storeFlags:
st X, r20
layoutCtxCopyWidgetTmpToItemSizeNoIncX_done:
sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbCopyItemToWidgetYIncX
;
; @param Y widget
; @param X item
; @return X pointer to next item
; @clobbers r16
layoutCtxCbCopyItemToWidgetYIncX:
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_POS_LO
std Y+WIDGET_OFFS_Y_LO, r16
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_POS_HI
std Y+WIDGET_OFFS_Y_HI, r16
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
std Y+WIDGET_OFFS_HEIGHT_LO, r16
ld r16, X ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
std Y+WIDGET_OFFS_HEIGHT_HI, r16
adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_SIZE_HI)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbCopyItemToWidgetYNoXInc
;
; @param Y widget
; @param X item
; @clobbers r16
layoutCtxCbCopyItemToWidgetYNoXInc:
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_POS_LO
std Y+WIDGET_OFFS_Y_LO, r16
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_POS_HI
std Y+WIDGET_OFFS_Y_HI, r16
ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO
std Y+WIDGET_OFFS_HEIGHT_LO, r16
ld r16, X ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI
std Y+WIDGET_OFFS_HEIGHT_HI, r16
sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_HI
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbPackXIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r21, r25
layoutCtxCbPackXIncX:
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
rcall layoutCtxPack ; (r16-r19, r25)
std Y+WIDGET_OFFS_X_LO, r18
std Y+WIDGET_OFFS_X_HI, r19
std Y+WIDGET_OFFS_WIDTH_LO, r20
std Y+WIDGET_OFFS_WIDTH_HI, r21
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbPackXNoIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r21, r25
layoutCtxCbPackXNoIncX:
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
rcall layoutCtxPack ; (r16-r19, r25)
std Y+WIDGET_OFFS_X_LO, r18
std Y+WIDGET_OFFS_X_HI, r19
std Y+WIDGET_OFFS_WIDTH_LO, r20
std Y+WIDGET_OFFS_WIDTH_HI, r21
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbPackYIncX
;
; @param Y widget
; @param X item
; @return X next item
; @clobbers r16-r21, r25
layoutCtxCbPackYIncX:
rcall layoutCtxCbPackYNoIncX
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxCbPackYNoIncX
;
; @param Y widget
; @param X item
; @clobbers r16-r21, r25
layoutCtxCbPackYNoIncX:
ldd r20, Y+WIDGET_OFFS_TMP_LO
ldd r21, Y+WIDGET_OFFS_TMP_HI
rcall layoutCtxPack ; (r16-r19, r25)
std Y+WIDGET_OFFS_Y_LO, r18
std Y+WIDGET_OFFS_Y_HI, r19
std Y+WIDGET_OFFS_HEIGHT_LO, r20
std Y+WIDGET_OFFS_HEIGHT_HI, r21
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_CountChildrenSkipped
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param r25 number of widgets to skip in each round
; @return r16 number of items in skipped mode (e.g. number of rows)
; @clobbers r18, r19
Layout_CountChildrenSkipped:
push yl
push yh
clr r16
bigcall OBJ_GetFirstChild
brcc Layout_CountChildrenSkipped_done
mov yl, r18
mov yh, r19
M_LAYOUT_FOREVERY_SKIPPED layoutCbCount ; (r18, r19)
Layout_CountChildrenSkipped_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCbCount
;
; @param Y widget
; @clobbers none
layoutCbCount:
inc r16
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_MultiActionVertical
;
;
; @param X pointer to ctx
; @param Y pointer to widget containing childs to handle
; @param r25 number of widgets in a row
; @param Z routine to call on every child widget
; @clobbers r18, r19, {any}, !r25, !X, !Y
LayoutCtx_MultiActionVertical:
bigcall OBJ_GetFirstChild
brcc LayoutCtx_MultiActionVertical_ret
push yl
push yh
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_ITEMS
LayoutCtx_MultiActionVertical_loop:
mov yl, r18
mov yh, r19
rcall layoutForEveryObjectContiguous ; (r18, r19, {any}, !r25)
bigcall OBJ_GetNext
brcc LayoutCtx_MultiActionVertical_done
adiw xh:xl, LAYOUT_CTX_ITEM_SIZE
rjmp LayoutCtx_MultiActionVertical_loop
LayoutCtx_MultiActionVertical_done:
pop xh
pop xl
pop yh
pop yl
LayoutCtx_MultiActionVertical_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine LayoutCtx_MultiActionHorizontal
;
;
; @param X pointer to ctx
; @param Y pointer to widget containing children to work on
; @param r25 number of widgets to handle per row
; @param Z routine to call on every child widget
; @clobbers r16, r18, r19, r24
LayoutCtx_MultiActionHorizontal:
bigcall OBJ_GetFirstChild
brcc LayoutCtx_MultiActionHorizontal_ret
push yl
push yh
push xl
push xh
adiw xh:xl, LAYOUT_CTX_OFFS_ITEMS
LayoutCtx_MultiActionHorizontal_loop:
mov yl, r18
mov yh, r19
push xl ; first item
push xh
rcall layoutForEveryObjectContiguous ; (r18, r19, Y {any})
pop xh
pop xl ; first item
bigcall OBJ_GetNext
brcc LayoutCtx_MultiActionHorizontal_done
rjmp LayoutCtx_MultiActionHorizontal_loop
LayoutCtx_MultiActionHorizontal_done:
pop xh
pop xl
pop yh
pop yl
LayoutCtx_MultiActionHorizontal_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxForEveryChildContiguous
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param Z routine to call
; @clobbers r18, r19, r24, {any}, !r25, !X, !Y
layoutCtxForEveryChildContiguous:
bigcall OBJ_GetFirstChild
brcc layoutCtxForEveryChildContiguous_ret
push yl
push yh
mov yl, r18
mov yh, r19
push xl
push xh
push r25
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; X now points to first item
clr r25
rcall layoutForEveryObjectContiguous ; (r18, r19, Y {any})
pop r25
pop xh
pop xl
pop yh
pop yl
layoutCtxForEveryChildContiguous_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutCtxForEveryChildSkipped
;
; @param X pointer to ctx
; @param Y pointer to first widget to handle
; @param Z routine to call
; @param r25 number of widgets per row
; @clobbers any, !r25, !X, !Y
layoutCtxForEveryChildSkipped:
bigcall OBJ_GetFirstChild
brcc layoutCtxForEveryChildSkipped_ret
push yl
push yh
mov yl, r18
mov yh, r19
push xl
push xh
push r25
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
ld r24, X+ ; X now points to first item
rcall layoutForEveryObjectSkipped
pop r25
pop xh
pop xl
pop yh
pop yl
layoutCtxForEveryChildSkipped_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutForEveryObjectContiguous
;
; 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}
layoutForEveryObjectContiguous:
push r25
mov r18, r25
layoutForEveryObjectContiguous_loop:
push r18
push r25
push yl
push yh
icall
pop yh
pop yl
pop r25
pop r18
brcs layoutForEveryObjectContiguous_ret
tst r18
breq layoutForEveryObjectContiguous_next
dec r18
clc
breq layoutForEveryObjectContiguous_ret
layoutForEveryObjectContiguous_next:
push r18
bigcall OBJ_GetNext
brcs layoutForEveryObjectContiguous_loopEnd
pop r18
rjmp layoutForEveryObjectContiguous_ret
layoutForEveryObjectContiguous_loopEnd:
mov yl, r18
mov yh, r19
pop r18
rjmp layoutForEveryObjectContiguous_loop
layoutForEveryObjectContiguous_ret:
pop r25
ret
; @end
; ---------------------------------------------------------------------------
; @routine layoutForEveryObjectSkipped
;
; 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}
layoutForEveryObjectSkipped:
layoutForEveryObjectSkipped_loop:
push r25
push yl
push yh
icall
pop yh
pop yl
pop r25
brcs layoutForEveryObjectSkipped_ret
push r16
mov r16, r25
bigcall OBJ_SkipObjects ; (R16)
pop r16
brcc layoutForEveryObjectSkipped_ret
mov yl, r18
mov yh, r19
rjmp layoutForEveryObjectSkipped_loop
layoutForEveryObjectSkipped_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_SetDefaultWidths
;
; Set default width in WIDGET_OFFS_TMP_LO/HI of child widgets
;
; @param Y pointer to widget
; @clobbers any, !Y
Layout_SetDefaultWidths:
push yl
push yh
bigcall OBJ_GetFirstChild
brcc Layout_SetDefaultWidths_ret
Layout_SetDefaultWidths_loop:
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultWidth
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
bigcall OBJ_GetNext
brcs Layout_SetDefaultWidths_loop
Layout_SetDefaultWidths_ret:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_SetDefaultHeights
;
; Set default height in WIDGET_OFFS_TMP_LO/HI of child widgets
;
; @param Y pointer to widget
; @clobbers any, !Y
Layout_SetDefaultHeights:
bigcall OBJ_GetFirstChild
brcc Layout_SetDefaultHeights_ret
push yl
push yh
Layout_SetDefaultHeights_loop:
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultHeight
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
bigcall OBJ_GetNext
brcs Layout_SetDefaultHeights_loop
pop yh
pop yl
Layout_SetDefaultHeights_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_SumTmpValues
;
; Ignores invisible widgets.
;
; @param Y pointer to widget
; @return r19:r18 total size of all child widgets plus space between
; @clobbers r16, r17, r18, r19, r20, r21, r22, r23, Z
Layout_SumTmpValues:
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
; get spacing
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
lpm r22, Z
sbiw zh:zl, WIDGET_STYLE_OFFS_SPACING
; get outer border
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
lpm r23, Z
sbiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
; start adding
clr r20
clr r21
push yl
push yh
bigcall OBJ_GetFirstChild
brcc Layout_SumTmpValues_finish
Layout_SumTmpValues_loop:
mov yl, r18
mov yh, r19
ldd r18, Y+OBJECT_OFFS_FLAGS
sbrs r18, WIDGET_FLAGS_VISIBLE_BIT
rjmp Layout_SumTmpValues_next
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
add r20, r18 ; add widget size
adc r21, r19
add r20, r22 ; add spacing
adc r21, r22
sub r21, r22
Layout_SumTmpValues_next:
bigcall OBJ_GetNext
brcs Layout_SumTmpValues_loop
Layout_SumTmpValues_loopEnd:
mov r16, r20
or r16, r21
breq Layout_SumTmpValues_finish
sub r20, r22 ; sub last spacing
sbc r21, r22
add r21, r22
Layout_SumTmpValues_finish:
add r20, r23 ; add outer border (begin)
adc r21, r23
sub r21, r23
add r20, r23 ; add outer border (end)
adc r21, r23
sub r21, r23
Layout_SumTmpValues_done:
mov r18, r20
mov r19, r21
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_GetMaxTmp
;
; Ignores invisible widgets.
;
; @param Y pointer to widget
; @return r19:r18 maximum value in WIDGET_OFFS_TMP_LO/HI of children
; @clobbers r20, r21
Layout_GetMaxTmp:
clr r20
clr r21
push yl
push yh
bigcall OBJ_GetFirstChild
Layout_GetMaxTmp_loop:
brcc Layout_GetMaxTmp_ret
mov yl, r18
mov yh, r19
ldd r18, Y+OBJECT_OFFS_FLAGS
sbrs r18, WIDGET_FLAGS_VISIBLE_BIT
rjmp Layout_GetMaxTmp_next
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
; max
cp r20, r18
cpc r21, r19
brcc Layout_GetMaxTmp_next
mov r20, r18
mov r21, r19
Layout_GetMaxTmp_next:
bigcall OBJ_GetNext
rjmp Layout_GetMaxTmp_loop
Layout_GetMaxTmp_ret:
mov r18, r20
mov r19, r21
pop yh
pop yl
ret
; @end
#endif