; *************************************************************************** ; copyright : (C) 2026 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** ; * This file is part of the project "AqHome". * ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** #ifndef AQH_AVR_GUI2_MLAYOUT_ASM #define AQH_AVR_GUI2_MLAYOUT_ASM ; TODO: use this class also for HLayout and VLayout, those are just special ; cases with only one row (HLayout) or column (VLayout) ; *************************************************************************** ; defines .equ MLAYOUT_OFFS_BEGIN = WIDGET_SIZE .equ MLAYOUT_OFFS_MODE = MLAYOUT_OFFS_BEGIN+0 .equ MLAYOUT_OFFS_COLSORROWS = MLAYOUT_OFFS_BEGIN+1 .equ MLAYOUT_SIZE = MLAYOUT_OFFS_BEGIN+2 ; values for MLAYOUT_OFFS_MODE .equ HLAYOUT_MODE_COLUMNS = 0 .equ HLAYOUT_MODE_ROWS = 1 ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine MLayout_new @global ; ; @return CFLAG set of okay, cleared otherwise ; @return Y address of newly created object ; @param X parent widget ; @param r16 value for OBJECT_OFFS_OPTS ; @param r17 value for WIDGET_OFFS_PACK ; @param r20 layout mode (MLAYOUT_MODE_COLUMNS, MLAYOUT_MODE_ROWS) ; @param r21 number of columns or rows (depending on mode in r20) ; @clobbers any MLayout_new: push r20 push r21 ldi r24, LOW(MLAYOUT_SIZE) ldi r25, HIGH(MLAYOUT_SIZE) bigcall Object_Alloc ; (!r16, !r17, !X) pop r21 pop r20 brcc MLayout_new_ret rcall MLayout_Init ; (r16, r17, X) sec MLayout_new_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine MLayout_Init @global ; ; @param Y address of widget ; @param X parent widget (if any) ; @param r16 value for OBJECT_OFFS_OPTS ; @param r17 value for WIDGET_OFFS_PACK ; @param r20 layout mode (MLAYOUT_MODE_COLUMN, MLAYOUT_MODE_ROW) ; @param r21 number of columns or rows (depending on mode in r20) ; @clobbers r16, r17, X MLayout_Init: push r20 push r21 ; call base class bigcall Widget_Init ; (r16, r17, X) pop r21 pop r20 ; set widget-specific data std Y+MLAYOUT_OFFS_MODE, r20 std Y+MLAYOUT_OFFS_COLSORROWS, r21 ; set default signal map ldi r16, LOW(MLayout_DefaultSignalmap*2) std Y+OBJECT_OFFS_SIGNALMAP_LO, r16 ldi r16, HIGH(MLayout_DefaultSignalmap*2) std Y+OBJECT_OFFS_SIGNALMAP_HI, r16 ret ; @end MLayout_OnLayout: bigcall OBJ_GetFirstChild ; test for children brcc MLayout_OnLayout_ret ; none, done here ; TODO MLayout_OnLayout_ret: sec ret MLayout_OnGetDefaultWidth: MLayout_OnGetDefaultHeight: ret ; --------------------------------------------------------------------------- ; @routine mLayoutColumnsHorizontally ; ; @param Y pointer to widget mLayoutColumnsHorizontally: ; preparations rcall mLayoutSetDefaultWidths ; calc default widths of children and store in Y+WIDGET_OFFS_TMP rcall mLayoutCopyTmpToWidth ; copy to width fields for later rcall mLayoutGetBorders ; r22=spacing, r23=outer borders ; calc size of each column and store it in the first widget of a column as TMP rcall mLayoutCalcAndSetSizesSkipped ; (r18-r31, !Y) ; calc total width of first row (which has the maximum sizes of each column) rcall mLayoutCalcFirstSizesContiguous ; r21:r20 width of first row (r16, r18, r19, r24, r25) ; expand first row ldd r18, Y+WIDGET_OFFS_WIDTH_LO ldd r19, Y+WIDGET_OFFS_WIDTH_HI ldi r22, (1< shift 2 times right lsr r17 andi r17, 3 rcall mLayoutPackCell ; R21:R20=relative pos (r17, r18, r19) add r20, r4 adc r21, r5 std Y+WIDGET_OFFS_Y_LO, r20 ; set new pos std Y+WIDGET_OFFS_Y_HI, r21 std Y+WIDGET_OFFS_HEIGHT_LO, r18 ; set new size std Y+WIDGET_OFFS_HEIGHT_HI, r19 add r4, r18 ; advance pos adc r5, r19 bigcall OBJ_GetNext brcc mLayoutColumnsPositionY_done mov yl, r18 mov yh, r19 dec r24 brne mLayoutColumnsPositionY_loop2 rjmp mLayoutColumnsPositionY_loop1 mLayoutColumnsPositionY_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutPackCell ; ; @param Y address of widget ; @param r19:r18 size of target widget (i.e. width or height) ; @param r17 pack mode (see @ref WIDGET_PACK_BEGIN) ; @param R13:R12 size of object to pack (i.e. width or height) ; @param r22 spacing (between widgets) ; @return R21:R20 pos ; @clobbers r17, r18, r19 mLayoutPackCell: ; subtract borders clr r23 sub r18, r22 ; subtract spacing sbc r19, r23 andi r17, 3 ; only 2 bits pack mode cpi r17, WIDGET_PACK_END breq mLayoutPackCell_end cpi r17, WIDGET_PACK_CENTER breq mLayoutPackCell_center rjmp mLayoutPackCell_ret ; begin/filled, align at begin mLayoutPackCell_end: sub r18, r12 sbc r19, r13 add r20, r18 adc r21, r19 rjmp mLayoutPackCell_ret mLayoutPackCell_center: sub r18, r12 sbc r19, r13 lsr r19 ror r18 add r20, r18 adc r21, r19 rjmp mLayoutPackCell_ret mLayoutPackCell_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCopyTmpFromFirstContiguous ; ; TMP in widgets of first row/column contains the available space per cell. ; ; @param Y pointer to widget ; @clobbers r17, r18, r19, r20, r21, r24 mLayoutCopyTmpFromFirstContiguous: ldd r24, Y+MLAYOUT_OFFS_COLSORROWS cpi r24, 2 ; less than 2 in contiguous direction, nothing to copy brcs mLayoutCopyTmpFromFirstContiguous_ret push yl push yh bigcall OBJ_GetFirstChild mLayoutCopyTmpFromFirstContiguous_loop: push yl push yh ldd r20, Y+WIDGET_OFFS_TMP_LO ldd r21, Y+WIDGET_OFFS_TMP_HI ; goto same cell in next block (e.g. same column in next row) ldd r17, Y+MLAYOUT_OFFS_COLSORROWS mLayoutCopyTmpFromFirstContiguous_loop2: bigcall OBJ_GetNext brcc mLayoutCopyTmpFromFirstContiguous_nextColumn mov yl, r18 mov yh, r19 dec r17 brne mLayoutCopyTmpFromFirstContiguous_loop2 std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, r21 mLayoutCopyTmpFromFirstContiguous_nextColumn: pop yh pop yl bigcall OBJ_GetNext brcc mLayoutCopyTmpFromFirstContiguous_done mov yl, r18 mov yh, r19 rjmp mLayoutCopyTmpFromFirstContiguous_loop mLayoutCopyTmpFromFirstContiguous_done: pop yh pop yl mLayoutCopyTmpFromFirstContiguous_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCopyTmpFromFirstSkipped ; ; TMP in widgets of first row/column contains the available space per cell. ; ; @param Y pointer to widget ; @clobbers r17, r18, r19, r20, r21, r24 mLayoutCopyTmpFromFirstSkipped: ldd r24, Y+MLAYOUT_OFFS_COLSORROWS cpi r24, 2 ; less than 2 in skipping direction, nothing to copy brcs mLayoutCopyTmpFromFirstSkipped_ret push yl push yh bigcall OBJ_GetFirstChild mLayoutCopyTmpFromFirstSkipped_loop: ldd r20, Y+WIDGET_OFFS_TMP_LO ldd r21, Y+WIDGET_OFFS_TMP_HI ldd r17, Y+MLAYOUT_OFFS_COLSORROWS mLayoutCopyTmpFromFirstSkipped_loop2: ; goto next cell in same block (e.g. next column in same row) bigcall OBJ_GetNext brcc mLayoutCopyTmpFromFirstSkipped_done mov yl, r18 mov yh, r19 dec r17 breq mLayoutCopyTmpFromFirstSkipped_loop2end std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, r21 rjmp mLayoutCopyTmpFromFirstSkipped_loop2 mLayoutCopyTmpFromFirstSkipped_loop2end: rjmp mLayoutCopyTmpFromFirstSkipped_loop mLayoutCopyTmpFromFirstSkipped_done: pop yh pop yl mLayoutCopyTmpFromFirstSkipped_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCopyTmpToWidth ; ; @param Y pointer to widget ; mLayoutCopyTmpToWidth: push yl push yh bigcall OBJ_GetFirstChild brcc mLayoutCopyTmpToWidth_ret mLayoutCopyTmpToWidth_loop: mov yl, r18 mov yh, r19 ldd r18, Y+WIDGET_OFFS_TMP_LO ldd r19, Y+WIDGET_OFFS_TMP_HI std Y+WIDGET_OFFS_WIDTH_LO, r18 std Y+WIDGET_OFFS_WIDTH_HI, r19 mLayoutCopyTmpToWidth_next: bigcall OBJ_GetNext brcs mLayoutCopyTmpToWidth_loop mLayoutCopyTmpToWidth_ret: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCopyTmpToHeight ; ; @param Y pointer to widget ; mLayoutCopyTmpToHeight: push yl push yh bigcall OBJ_GetFirstChild brcc mLayoutCopyTmpToHeight_ret mLayoutCopyTmpToHeight_loop: mov yl, r18 mov yh, r19 ldd r18, Y+WIDGET_OFFS_TMP_LO ldd r19, Y+WIDGET_OFFS_TMP_HI std Y+WIDGET_OFFS_HEIGHT_LO, r18 std Y+WIDGET_OFFS_HEIGHT_HI, r19 mLayoutCopyTmpToHeight_next: bigcall OBJ_GetNext brcs mLayoutCopyTmpToHeight_loop mLayoutCopyTmpToHeight_ret: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutExpandFirstContiguous ; ; @param Y pointer to widget ; @param r19:r18 size of first line (width or height) ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK mLayoutExpandFirstContiguous: ldd r24, Y+MLAYOUT_OFFS_COLSORROWS ldi r25, 1 rjmp mLayoutExpandFirst ; --------------------------------------------------------------------------- ; @routine mLayoutExpandFirstSkipped ; ; @param Y pointer to widget ; @param r19:r18 size of first cross line (width or height) ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK mLayoutExpandFirstSkipped: ldi r24, 1 ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rjmp mLayoutExpandFirst ; --------------------------------------------------------------------------- ; @routine mLayoutExpandFirst ; ; @param Y pointer to widget ; @param r19:r18 size of first line (width or height) ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r24 number of widgets to handle per round ; @param r25 number of widgets to skip per round mLayoutExpandFirst: push r18 push r19 push r24 rcall mLayoutCountChildrenWithMatchingPackMode ; r16=count (r17, r18, r19, r24) pop r24 pop r19 pop r18 sub r18, r20 sbc r19, r21 ; space to distribute among widgets brcs mLayoutExpandFirst_ret ; divide available space among expandable children push r22 push r23 mov r20, r18 mov r21, r19 mov r22, r16 clr r23 bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable widget pop r23 pop r22 ; increment TMP (size) of expandable widgets mov r20, r16 mov r21, r17 rcall mLayoutIncTmpOnMatchingPackMode mLayoutExpandFirst_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCountChildrenWithMatchingPackMode ; ; @param Y pointer to widget ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r24 number of widgets to handle per round ; @param r25 number of widgets to skip per round ; @return r16 number of matching children ; @clobbers r17, r18, r19, r24 mLayoutCountChildrenWithMatchingPackMode: clr r16 push yl push yh bigcall OBJ_GetFirstChild mLayoutCountChildrenWithMatchingPackMode_loop: brcc mLayoutCountChildrenWithMatchingPackMode_done mov yl, r18 mov yh, r19 ldd r17, Y+OBJECT_OFFS_FLAGS sbrs r17, WIDGET_FLAGS_VISIBLE_BIT ; skip invisible widgets rjmp mLayoutCountChildrenWithMatchingPackMode_advance ldd r17, Y+WIDGET_OFFS_PACK eor r17, r23 and r17, r22 brne mLayoutCountChildrenWithMatchingPackMode_next inc r16 mLayoutCountChildrenWithMatchingPackMode_next: dec r24 breq mLayoutCountChildrenWithMatchingPackMode_done mLayoutCountChildrenWithMatchingPackMode_advance: mov r17, r25 mLayoutCountChildrenWithMatchingPackMode_loop2: bigcall OBJ_GetNext ; (none) brcc mLayoutCountChildrenWithMatchingPackMode_done dec r17 brne mLayoutCountChildrenWithMatchingPackMode_loop2 rjmp mLayoutCountChildrenWithMatchingPackMode_loop mLayoutCountChildrenWithMatchingPackMode_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutIncTmpOnMatchingPackMode ; ; Ignores invisible widgets. ; ; @param Y pointer to widget ; @param R21:R20 value to add to tmp value of expandable widgets ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r24 number of widgets to handle per round ; @param r25 number of widgets to skip per round ; @clobbers r16, r18, r19, r24 mLayoutIncTmpOnMatchingPackMode: push yl push yh bigcall OBJ_GetFirstChild brcc mLayoutIncTmpOnMatchingPackMode_done mLayoutIncTmpOnMatchingPackMode_loop: mov yl, r18 mov yh, r19 ldd r16, Y+OBJECT_OFFS_FLAGS sbrs r16, WIDGET_FLAGS_VISIBLE_BIT ; skip invisible widgets rjmp mLayoutIncTmpOnMatchingPackMode_next ldd r16, Y+WIDGET_OFFS_PACK eor r16, r23 and r16, r22 brne mLayoutIncTmpOnMatchingPackMode_advance ldd r18, Y+WIDGET_OFFS_TMP_LO ldd r19, Y+WIDGET_OFFS_TMP_HI add r18, r20 adc r19, r21 std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r19 mLayoutIncTmpOnMatchingPackMode_next: dec r24 breq mLayoutCountChildrenWithMatchingPackMode_done mLayoutIncTmpOnMatchingPackMode_advance: mov r17, r25 mLayoutIncTmpOnMatchingPackMode_loop2: bigcall OBJ_GetNext ; (none) brcc mLayoutIncTmpOnMatchingPackMode_done dec r17 brne mLayoutIncTmpOnMatchingPackMode_loop2 rjmp mLayoutIncTmpOnMatchingPackMode_loop mLayoutIncTmpOnMatchingPackMode_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutGetBorders ; ; @param Y address of widget ; @return r22 spacing ; @return r23 outer borders mLayoutGetBorders: ldd zl, Y+WIDGET_OFFS_STYLE_LO ldd zh, Y+WIDGET_OFFS_STYLE_HI adiw zh:zl, WIDGET_STYLE_OFFS_SPACING lpm r22, Z sbiw zh:zl, WIDGET_STYLE_OFFS_SPACING adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE lpm r23, Z ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCalcAndSetSizesSkipped ; ; @param Y address of widget ; @param r22 spacing (between widgets) ; @param r23 outer border size ; @clobbers r18-r31, !Y mLayoutCalcAndSetSizesSkipped: bigcall OBJ_GetFirstChild ldd r20, Y+MLAYOUT_OFFS_COLSORROWS push yl push yh mLayoutCalcAndSetSizesSkipped_loop: mov yl, r18 mov yh, r19 push yl push yh ldi r24, 1 ; number of widgets to handle per loop ldd r25, Y+MLAYOUT_OFFS_COLSORROWS ; number of widgets to skip push r20 rcall mLayoutGetMaxTmpSize ; (r18-r31, !Y) pop r20 pop yh pop yl std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r18 dec r20 breq mLayoutCalcAndSetSizesSkipped_loopEnd bigcall OBJ_GetNext brcs mLayoutCalcAndSetSizesSkipped_loop mLayoutCalcAndSetSizesSkipped_loopEnd: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCalcAndSetSizesContiguous ; ; @param Y address of widget ; @param r22 spacing (between widgets) ; @param r23 outer border size ; @clobbers r18-r31, !Y mLayoutCalcAndSetSizesContiguous: bigcall OBJ_GetFirstChild ldd r20, Y+MLAYOUT_OFFS_COLSORROWS push yl push yh mLayoutCalcAndSetSizesContiguous_loop: mov yl, r18 mov yh, r19 push yl push yh ldd r24, Y+MLAYOUT_OFFS_COLSORROWS ; number of widgets to handle per loop ldi r25, 1 ; number of widgets to skip push r20 rcall mLayoutGetMaxTmpSize ; (r18-r31, !Y) pop r20 pop yh pop yl std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r18 dec r20 breq mLayoutCalcAndSetSizesContiguous_loopEnd bigcall OBJ_GetNext brcs mLayoutCalcAndSetSizesContiguous_loop mLayoutCalcAndSetSizesContiguous_loopEnd: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCalcFirstSizesContiguous ; ; @param Y address of widget ; @param r22 spacing (between widgets) ; @param r23 outer border size ; @return r21:r20 total width of contigous first widgets ; @clobbers r16, r18, r19, r24, r25 mLayoutCalcFirstSizesContiguous: bigcall OBJ_GetFirstChild ; (none) push yl push yh mov yl, r18 mov yh, r19 ldd r24, Y+MLAYOUT_OFFS_COLSORROWS ldi r25, 1 rcall mLayoutSumNextTmpValues ; r21:r20=total size (r16, r18, r19, r24) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCalcFirstSizesSkipped ; ; @param Y address of widget ; @param r22 spacing (between widgets) ; @param r23 outer border size ; @return r21:r20 total width of contigous first widgets ; @clobbers r16, r18, r19, r24, r25 mLayoutCalcFirstSizesSkipped: bigcall OBJ_GetFirstChild ; (none) push yl push yh mov yl, r18 mov yh, r19 ldi r24, 1 ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutSumNextTmpValues ; r21:r20=total size (r16, r18, r19, r24) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutGetMaxTmpSize ; ; @param Y address of widget ; @param r22 spacing (between widgets) ; @param r23 outer border size ; @param r24 number of widgets to handle per round ; @param r25 number of widgets to skip per round ; @return r19:r18 max size ; @clobbers r18-r31, !Y mLayoutGetMaxTmpSize: push yl push yh clr xl clr xh bigcall OBJ_GetFirstChild mLayoutGetMaxRowWidth_loop: push r24 rcall mLayoutSumNextTmpValues ; r21:r20=total size (r16, r18, r19, r24) pop r24 cp xl, r18 cpc xh, r19 brcc mLayoutGetMaxTmpSize_next mov xl, r18 mov xh, r19 mLayoutGetMaxTmpSize_next: mov r16, r24 ; goto next row or column bigcall OBJ_SkipObjects brcc mLayoutGetMaxTmpSize_ret mov yl, r18 mov yh, r19 rjmp mLayoutGetMaxRowWidth_loop mLayoutGetMaxTmpSize_ret: mov r18, xl mov r19, xh pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSumNextTmpValues ; ; Sum TMP of next [R24] widgets and skip [R25] widgets between them. ; ; Ignores invisible widgets. ; ; @param Y address of widget to start with ; @param r22 spacing (between widgets) ; @param r23 outer border size ; @param r24 number of widgets to handle per round ; @param r25 number of widgets to skip per round ; @return r21:r20 sum of tmp values in widgets ; @return Y address of last widget handled (or last available) ; @clobbers r16, r17, r18, r19, r24 mLayoutSumNextTmpValues: mLayoutSumNextTmpValues_loop: ldd r18, Y+OBJECT_OFFS_FLAGS sbrs r18, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutSumNextTmpValues_advance 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 mLayoutSumNextTmpValues_next: dec r24 breq mLayoutSumNextTmpValues_done mLayoutSumNextTmpValues_advance: mov r16, r25 bigcall OBJ_SkipObjects ; (none) brcc mLayoutSumNextTmpValues_done mov yl, r18 mov yh, r19 rjmp mLayoutSumNextTmpValues_loop mLayoutSumNextTmpValues_loopEnd: mov r16, r20 or r16, r21 breq mLayoutSumNextTmpValues_done sub r20, r22 ; sub last spacing sbc r21, r22 add r21, r22 mLayoutSumNextTmpValues_done: ret ; r21:r20=sum ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetDefaultWidths ; ; Set default width in WIDGET_OFFS_TMP_LO/HI of child widgets ; Ignores invisible widgets. ; ; @param Y pointer to widget ; @clobbers any, !Y mLayoutSetDefaultWidths: push yl push yh bigcall OBJ_GetFirstChild brcc mLayoutSetDefaultWidths_ret mLayoutSetDefaultWidths_loop: mov yl, r18 mov yh, r19 ldd r18, Y+OBJECT_OFFS_FLAGS sbrs r18, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutSetDefaultWidths_next bigcall Widget_GetDefaultWidth std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r19 mLayoutSetDefaultWidths_next: bigcall OBJ_GetNext brcs mLayoutSetDefaultWidths_loop mLayoutSetDefaultWidths_ret: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetDefaultHeights ; ; Set default height in WIDGET_OFFS_TMP_LO/HI of child widgets ; Ignores invisible widgets. ; ; @param Y pointer to widget ; @clobbers any, !Y mLayoutSetDefaultHeights: push yl push yh bigcall OBJ_GetFirstChild brcc mLayoutSetDefaultHeights_ret mLayoutSetDefaultHeights_loop: mov yl, r18 mov yh, r19 ldd r18, Y+OBJECT_OFFS_FLAGS sbrs r18, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutSetDefaultHeights_next bigcall Widget_GetDefaultHeight std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r19 mLayoutSetDefaultHeights_next: bigcall OBJ_GetNext brcs mLayoutSetDefaultHeights_loop mLayoutSetDefaultHeights_ret: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine ; ; For every contiguous widget (e.g. in a row) determine the maximum TMP value ; of all widgets orthogonal to that widget, e.g. when working in column mode: ; Get the highest width for every column and store that in the first widget of ; that column (i.e. in the first row). mLayoutSetupFirstContiguous: ldd r25, Y+MLAYOUT_OFFS_COLSORROWS ldi zl, LOW(mLayoutCallbackSetupFirstContiguous) ldi zh, HIGH(mLayoutCallbackSetupFirstContiguous) rcall mLayoutForEveryObjectContiguous ret ; @end mLayoutCallbackSetupFirstContiguous: push zl push zh push yl push yh ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutGetMaxTmpSkipped pop yh pop yl std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_LO, r21 pop zh pop zl clc ret ; @end ; --------------------------------------------------------------------------- ; @routine ; ; For every skipped widget (e.g. in a column) determine the maximum TMP value ; of all widgets orthogonal to that widget. ; Same as mLayoutSetupFirstContiguous except orthograde. mLayoutSetupFirstSkipped: ldi zl, LOW(mLayoutCallbackSetupFirstSkipped) ldi zh, HIGH(mLayoutCallbackSetupFirstSkipped) rcall mLayoutForEveryObjectSkipped ret ; @end mLayoutCallbackSetupFirstSkipped: push zl push zh push yl push yh ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutGetMaxTmpContiguous pop yh pop yl std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_LO, r21 pop zh pop zl clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutGetMaxTmpContiguous ; ; @param Y object to start with ; @param r25 number of widgets to handle ; @return r21:r20 maximum TMP value encountered mLayoutGetMaxTmpContiguous: push yl push yh clr r20 clr r21 ldi zl, LOW(mLayoutCallbackGetMaxTmp) ldi zh, HIGH(mLayoutCallbackGetMaxTmp) rcall mLayoutForEveryObjectContiguous pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutGetMaxTmpSkipped ; ; @param Y object to start with ; @param r25 number of widgets to skip after each widget handled ; @return r21:r20 maximum TMP value encountered mLayoutGetMaxTmpSkipped: push yl push yh clr r20 clr r21 ldi zl, LOW(mLayoutCallbackGetMaxTmp) ldi zh, HIGH(mLayoutCallbackGetMaxTmp) rcall mLayoutForEveryObjectSkipped pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackGetMaxTmp ; ; @param Y object whose TMP value is to be added ; @param r25 number of widgets to handle ; @param r21:r20 current maximum value ; @param r22 spacing between widgets ; @param r23 border at beginning and and ; @return CFLAG clear (to not abort the loop function) ; @clobbers r18, r19 mLayoutCallbackGetMaxTmp: ldd r18, Y+WIDGET_OFFS_TMP_LO ldd r19, Y+WIDGET_OFFS_TMP_HI cp r20, r18 cpc r21, r19 brcc mLayoutCallbackGetMaxTmp_ret mov r20, r18 mov r21, r19 mLayoutCallbackGetMaxTmp_ret: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetDefaultWidthToTmp ; ; @param Y object to start with ; @param r25 number of widgets to handle mLayoutSetDefaultWidthToTmp: push yl push yh clr r25 ; number of widgets to handle (0=all) ldi zl, LOW(mLayoutCallbackDefaultWidthToTmp) ldi zh, HIGH(mLayoutCallbackDefaultWidthToTmp) rcall mLayoutForEveryObjectContiguous pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackDefaultWidthToTmp ; ; @param Y object whose TMP value is to be added ; @return CFLAG clear (to not abort the loop function) ; @clobbers r18, r19 mLayoutCallbackDefaultWidthToTmp: push zl push zh bigcall Widget_GetDefaultWidth pop zh pop zl std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r19 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetDefaultHeightToTmp ; ; @param Y object to start with ; @param r25 number of widgets to handle mLayoutSetDefaultHeightToTmp: push yl push yh clr r25 ; number of widgets to handle (0=all) ldi zl, LOW(mLayoutCallbackDefaultHeightToTmp) ldi zh, HIGH(mLayoutCallbackDefaultHeightToTmp) rcall mLayoutForEveryObjectContiguous pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackDefaultHeightToTmp ; ; @param Y object whose TMP value is to be added ; @return CFLAG clear (to not abort the loop function) ; @clobbers r18, r19 mLayoutCallbackDefaultHeightToTmp: push zl push zh bigcall Widget_GetDefaultHeight pop zh pop zl std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r19 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSumContiguous ; ; @param Y object to start with ; @param r25 number of widgets to handle ; @param r22 spacing between widgets ; @param r23 border at beginning and and mLayoutSumContiguous: push yl push yh mov r20, r23 ; start with border clr r21 ldi zl, LOW(mLayoutCallbackAddToSum) ldi zh, HIGH(mLayoutCallbackAddToSum) rcall mLayoutForEveryObjectContiguous sub r20, r22 ; undo last adding inter-widget space sbc r21, r22 add r21, r22 add r20, r23 ; end with border adc r21, r23 sub r21, r23 pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSumSkipped ; ; @param Y object to start with ; @param r25 number of widgets to skip after each widget handled ; @param r22 spacing between widgets ; @param r23 border at beginning and and mLayoutSumSkipped: push yl push yh mov r20, r23 ; start with border clr r21 ldi zl, LOW(mLayoutCallbackAddToSum) ldi zh, HIGH(mLayoutCallbackAddToSum) rcall mLayoutForEveryObjectSkipped sub r20, r22 ; undo last adding inter-widget space sbc r21, r22 add r21, r22 add r20, r23 ; end with border adc r21, r23 sub r21, r23 pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackAddToSum ; ; @param Y object whose TMP value is to be added ; @param r25 number of widgets to handle ; @param r21:r20 sum so far (TMP will be added to it) ; @param r22 spacing between widgets ; @param r23 border at beginning and and ; @return CFLAG clear (to not abort the loop function) ; @clobbers r18, r19 mLayoutCallbackAddToSum: ldd r18, Y+WIDGET_OFFS_TMP_LO ldd r19, Y+WIDGET_OFFS_TMP_HI add r20, r18 adc r21, r19 add r20, r22 adc r21, r22 sub r21, r22 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutForEveryObjectContiguous ; ; This routine itself uses R18, R19, R25 and Y. All other registers may be ; passed to the callback routine. ; However, the callback function must make sure that it doesn't modify registers ; which are to be passed to next objects later! ; ; This routine traverses the given number of contiguous objects until there is no ; next object. ; ; Y and R25 are preserved around the callback. Z MUST NOT be modified by the callback! ; ; @param Y object to start with ; @param r25 number of widgets to handle ; @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) mLayoutForEveryObjectContiguous: mLayoutForEveryObjectContiguous_loop: push r25 push yl push yh icall pop yh pop yl pop r25 brcs mLayoutForEveryObjectContiguous_ret dec r25 clc breq mLayoutForEveryObjectContiguous_ret bigcall OBJ_GetNext brcc mLayoutForEveryObjectContiguous_ret mov yl, r18 mov yh, r19 rjmp mLayoutForEveryObjectContiguous_loop mLayoutForEveryObjectContiguous_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutForEveryObjectSkipped ; ; This routine itself uses R18, R19, R25 and Y. All other registers may be ; passed to the callback routine. ; However, the callback function must make sure that it doesn't modify registers ; which are to be passed to next objects later! ; ; This routine traverses the given objects skipping [R25] objects after each round ; until there is no next object. ; ; Y and R25 are preserved around the callback. Z MUST NOT be modified by the callback! ; ; @param Y object to start with ; @param r25 number of widgets to skip per round ; @param Z pointer to routine to call (using ICALL) ; @return CFLAG set if the callback returned with CFLAG set on any widget ; @return Y object on which the call returned with CFLAG set (garbage otherwise) mLayoutForEveryObjectSkipped: mLayoutForEveryObjectSkipped_loop: push r25 push yl push yh icall pop yh pop yl pop r25 brcs mLayoutForEveryObjectSkipped_ret breq mLayoutForEveryObjectSkipped_ret push r16 mov r16, r25 bigcall OBJ_SkipObjects pop r16 brcc mLayoutForEveryObjectSkipped_ret mov yl, r18 mov yh, r19 rjmp mLayoutForEveryObjectSkipped_loop mLayoutForEveryObjectSkipped_ret: ret ; @end ; *************************************************************************** ; data in FLASH MLayout_DefaultSignalmap: ; header .dw Widget_DefaultSignalmap*2 ; next table to use ; entries .db 0, WIDGET_SIGNAL_LAYOUT, LOW(MLayout_OnLayout), HIGH(MLayout_OnLayout) .db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(MLayout_OnGetDefaultWidth), HIGH(MLayout_OnGetDefaultWidth) .db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(MLayout_OnGetDefaultHeight), HIGH(MLayout_OnGetDefaultHeight) .db 0, 0, 0, 0 ; end of table #endif