1772 lines
47 KiB
NASM
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
|