; *************************************************************************** ; 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<