; *************************************************************************** ; 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) ; - add TMP2, use TMP1 for X, TMP2 for Y, position cells ?? ; - set X=left pos of space allocated to object, Y=top pos?? ; - use that to position cells in the end?? .macro M_MLAYOUT_FOREVERY_CONT push yl push yh ldi zl, LOW(@0) ldi zh, HIGH(@0) rcall mLayoutForEveryObjectContiguous pop yh pop yl .endmacro .macro M_MLAYOUT_FOREVERY_SKIPPED push yl push yh ldi zl, LOW(@0) ldi zh, HIGH(@0) rcall mLayoutForEveryObjectSkipped pop yh pop yl .endmacro ; *************************************************************************** ; 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 MLAYOUT_MODE_COLUMNS = 0 .equ MLAYOUT_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 ; --------------------------------------------------------------------------- ; @routine MLayout_OnLayout @global ; ; @param Y widget ; @clobbers any, !Y MLayout_OnLayout: bigcall OBJ_GetFirstChild ; test for children brcc MLayout_OnLayout_ret ; none, done here ldd r16, Y+MLAYOUT_OFFS_MODE cpi r16, MLAYOUT_MODE_COLUMNS breq MLayout_OnLayout_columns rjmp MLayout_OnLayout_ret MLayout_OnLayout_columns: rcall MLayout_Layout_ColumnMode MLayout_OnLayout_ret: sec ret ; --------------------------------------------------------------------------- ; @routine MLayout_OnGetDefaultWidth @global ; ; @param Y widget ; @clobbers any, !Y MLayout_OnGetDefaultWidth: bigcall OBJ_GetFirstChild ; test for children brcc MLayout_OnGetDefaultWidth_ret ; none, done here ldd r16, Y+MLAYOUT_OFFS_MODE cpi r16, MLAYOUT_MODE_COLUMNS breq MLayout_OnGetDefaultWidth_columns rjmp MLayout_OnLayout_ret MLayout_OnGetDefaultWidth_columns: rcall MLayout_OnGetDefaultWidth_ColumnMode MLayout_OnGetDefaultWidth_ret: sec ret ; --------------------------------------------------------------------------- ; @routine MLayout_OnGetDefaultHeight @global ; ; @param Y widget ; @clobbers any, !Y MLayout_OnGetDefaultHeight: bigcall OBJ_GetFirstChild ; test for children brcc MLayout_OnGetDefaultHeight_ret ; none, done here ldd r16, Y+MLAYOUT_OFFS_MODE cpi r16, MLAYOUT_MODE_COLUMNS breq MLayout_OnGetDefaultHeight_columns rjmp MLayout_OnLayout_ret MLayout_OnGetDefaultHeight_columns: rcall MLayout_OnGetDefaultHeight_ColumnMode MLayout_OnGetDefaultHeight_ret: sec ret ; --------------------------------------------------------------------------- ; @routine MLayout_GetFirstChildToY ; ; @param Y widget ; @return CFLAG set if child found, cleared on error ; @return Y first child widget ; @clobbers none MLayout_GetFirstChildToY: push r18 push r19 bigcall OBJ_GetFirstChild brcc MLayout_GetFirstChildToY_ret mov yl, r18 mov yh, r19 MLayout_GetFirstChildToY_ret: pop r19 pop r18 ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackSetTmp ; ; @param Y widget ; @param r21:r20 TMP to set ; @clobbers none mLayoutCallbackSetTmp: std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, r21 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackSetXTmp ; ; @param Y widget ; @param r21:r20 TMP to set ; @param X X to set ; @clobbers none mLayoutCallbackSetXTmp: std Y+WIDGET_OFFS_X_LO, xl std Y+WIDGET_OFFS_X_HI, xh std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, r21 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackSetYTmp ; ; @param Y widget ; @param r21:r20 TMP to set ; @param X Y to set ; @clobbers none mLayoutCallbackSetYTmp: std Y+WIDGET_OFFS_Y_LO, xl std Y+WIDGET_OFFS_Y_HI, xh std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, r21 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackGridX ; ; @param Y widget ; @param r22 spacing between widgets ; @param X current X pos ; @clobbers r10-r13, r16-r21 mLayoutCallbackGridX: ldd r20, Y+WIDGET_OFFS_TMP_LO ldd r21, Y+WIDGET_OFFS_TMP_HI std Y+WIDGET_OFFS_X_LO, xl ; set new X std Y+WIDGET_OFFS_X_HI, xh add xl, r20 ; add cell width adc xh, r21 add xl, r22 ; add spacing adc xh, r22 sub xh, r22 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackPackX ; ; @param Y widget ; @param r22 spacing between widgets ; @clobbers r10-r13, r16-r21, X mLayoutCallbackPackX: ldd r10, Y+WIDGET_OFFS_TMP_LO ; calculated cell width ldd r11, Y+WIDGET_OFFS_TMP_HI ldd r12, Y+WIDGET_OFFS_WIDTH_LO ; default width ldd r13, Y+WIDGET_OFFS_WIDTH_HI ldd r17, Y+WIDGET_OFFS_PACK andi r17, 3 ; WIDGET_PACK_HSELF0_BIT = 0, no shift necessary rcall mLayoutPackCell ; R21:R20=relative pos, R19:R18=new size (r16, r17, r18, r19) ldd xl, Y+WIDGET_OFFS_X_LO ldd xh, Y+WIDGET_OFFS_X_HI add xl, r20 adc xh, r21 std Y+WIDGET_OFFS_X_LO, xl std Y+WIDGET_OFFS_X_HI, xh std Y+WIDGET_OFFS_WIDTH_LO, r18 std Y+WIDGET_OFFS_WIDTH_HI, r19 ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackGridY ; ; @param Y widget ; @param r22 spacing between widgets ; @param X current Y pos ; @clobbers r10-r13, r16-r21 mLayoutCallbackGridY: ldd r20, Y+WIDGET_OFFS_TMP_LO ldd r21, Y+WIDGET_OFFS_TMP_HI std Y+WIDGET_OFFS_Y_LO, xl ; set new Y std Y+WIDGET_OFFS_Y_HI, xh add xl, r20 ; add cell width adc xh, r21 add xl, r22 ; add spacing adc xh, r22 sub xh, r22 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackPackY ; ; @param Y widget ; @param r22 spacing between widgets ; @clobbers r10-r13, r16-r21, X mLayoutCallbackPackY: ldd r10, Y+WIDGET_OFFS_TMP_LO ; calculated cell width ldd r11, Y+WIDGET_OFFS_TMP_HI ldd r12, Y+WIDGET_OFFS_HEIGHT_LO ; default width ldd r13, Y+WIDGET_OFFS_HEIGHT_HI ldd r17, Y+WIDGET_OFFS_PACK lsr r17 ; WIDGET_PACK_VSELF0_BIT = 2 -> shift 2 times right lsr r17 andi r17, 3 rcall mLayoutPackCell ; R21:R20=relative pos, R19:R18=new size (r16, r17, r18, r19) ldd xl, Y+WIDGET_OFFS_Y_LO ldd xh, Y+WIDGET_OFFS_Y_HI add xl, r20 adc xh, r21 std Y+WIDGET_OFFS_Y_LO, xl std Y+WIDGET_OFFS_Y_HI, xh std Y+WIDGET_OFFS_HEIGHT_LO, r18 std Y+WIDGET_OFFS_HEIGHT_HI, r19 ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetupFirstContiguous ; ; 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). ; ; @param R25 widgets per row/column ; @param r25 widgets per row/column ; @clobbers r18, r19, Z mLayoutSetupFirstContiguous: push yl push yh ldi zl, LOW(mLayoutCallbackSetupFirstContiguous) ldi zh, HIGH(mLayoutCallbackSetupFirstContiguous) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackSetupFirstContiguous ; ; @param Y object to start with ; @param r25 widgets per row/column ; @clobbers r18, r19, r20, r21 mLayoutCallbackSetupFirstContiguous: push zl push zh push yl push yh rcall mLayoutGetMaxTmpSkipped ; (r18, r19, Z) pop yh pop yl std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, r21 pop zh pop zl clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetupFirstSkipped ; ; 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. ; ; @param Y object to start with ; @param r25 number of widgets to skip ; @clobbers r18, r19, Z mLayoutSetupFirstSkipped: push yl push yh ldi zl, LOW(mLayoutCallbackSetupFirstSkipped) ldi zh, HIGH(mLayoutCallbackSetupFirstSkipped) rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackSetupFirstSkipped ; ; 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. ; ; @param Y object to start with ; @param r25 number of widgets to skip ; @clobbers r18, r19 mLayoutCallbackSetupFirstSkipped: push zl push zh push yl push yh rcall mLayoutGetMaxTmpContiguous ; (r18, r19, Z) pop yh pop yl std Y+WIDGET_OFFS_TMP_LO, r20 std Y+WIDGET_OFFS_TMP_HI, 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 ; @clobbers r18, r19, Z mLayoutGetMaxTmpContiguous: push yl push yh clr r20 clr r21 ldi zl, LOW(mLayoutCallbackGetMaxTmp) ldi zh, HIGH(mLayoutCallbackGetMaxTmp) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) 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 ; @clobbers r18, r19, Z mLayoutGetMaxTmpSkipped: push yl push yh clr r20 clr r21 ldi zl, LOW(mLayoutCallbackGetMaxTmp) ldi zh, HIGH(mLayoutCallbackGetMaxTmp) rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackGetMaxTmp ; ; @param Y object whose TMP value is to be added ; @param r21:r20 current maximum value ; @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 mLayoutCountMatchingPackContiguous ; ; @param Y object whose TMP value is to be added ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r25 number of widgets to handle ; @return r20 number of matching children ; @clobbers r18, r19 mLayoutCountMatchingPackContiguous: push yl push yh clr r20 ldi zl, LOW(mLayoutCallbackCountMatchingPack) ldi zh, HIGH(mLayoutCallbackCountMatchingPack) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCountChildrenMatchingPackSkipped ; ; @param Y object whose TMP value is to be added ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r25 number of widgets to handle (0=all) ; @return r20 number of matching children ; @clobbers r18, r19, r25 mLayoutCountChildrenMatchingPackSkipped: push yl push yh clr r20 ldi zl, LOW(mLayoutCallbackCountMatchingPack) ldi zh, HIGH(mLayoutCallbackCountMatchingPack) rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackCountMatchingPack ; ; @param Y object whose TMP value is to be added ; @param r20 number of matching children so far ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @return CFLAG clear (to not abort the loop function) ; @clobbers r18 mLayoutCallbackCountMatchingPack: ldd r18, Y+OBJECT_OFFS_FLAGS sbrs r18, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutCallbackCountMatchingPack_ret ldd r18, Y+WIDGET_OFFS_PACK eor r18, r23 and r18, r22 brne mLayoutCallbackCountMatchingPack_ret inc r20 mLayoutCallbackCountMatchingPack_ret: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutExpandMatchingPackContiguous ; ; @param Y object whose TMP value is to be added ; @param r21:r20 value to add to TMP ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r25 number of widgets to handle ; @clobbers r18, r19 mLayoutExpandMatchingPackContiguous: push yl push yh ldi zl, LOW(mLayoutCallbackExpandMatchingPack) ldi zh, HIGH(mLayoutCallbackExpandMatchingPack) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutExpandMatchingPackSkipped ; ; @param Y object whose TMP value is to be added ; @param r21:r20 value to add to TMP ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @param r25 number of widgets to skip ; @clobbers r18, r19 mLayoutExpandMatchingPackSkipped: push yl push yh ldi zl, LOW(mLayoutCallbackExpandMatchingPack) ldi zh, HIGH(mLayoutCallbackExpandMatchingPack) rcall mLayoutForEveryObjectSkipped ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackExpandMatchingPack ; ; @param Y object whose TMP value is to be added ; @param r21:r20 space to add to expandable widgets ; @param r22 mask for WIDGET_OFFS_PACK ; @param r23 value for WIDGET_OFFS_PACK ; @return CFLAG clear (to not abort the loop function) ; @clobbers r18, r19 mLayoutCallbackExpandMatchingPack: ldd r18, Y+OBJECT_OFFS_FLAGS sbrs r18, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutCallbackExpandMatchingPack_ret ldd r18, Y+WIDGET_OFFS_PACK eor r18, r23 and r18, r22 brne mLayoutCallbackExpandMatchingPack_ret 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 mLayoutCallbackExpandMatchingPack_ret: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSetDefaultWidthToTmp ; ; @param Y object to start with ; @param r25 number of widgets to handle (0=any) ; @clobbers any, !Y mLayoutSetDefaultWidthToTmp: push yl push yh ldi zl, LOW(mLayoutCallbackDefaultWidthToTmp) ldi zh, HIGH(mLayoutCallbackDefaultWidthToTmp) rcall mLayoutForEveryObjectContiguous ; (any) 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 (any, !Y) mLayoutCallbackDefaultWidthToTmp: push zl push zh bigcall Widget_GetDefaultWidth ; (any, !Y) 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 (0=any) ; @clobbers any, !Y mLayoutSetDefaultHeightToTmp: push yl push yh ldi zl, LOW(mLayoutCallbackDefaultHeightToTmp) ldi zh, HIGH(mLayoutCallbackDefaultHeightToTmp) rcall mLayoutForEveryObjectContiguous ; (any) 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 (any, !Y) mLayoutCallbackDefaultHeightToTmp: push zl push zh bigcall Widget_GetDefaultHeight ; (any, !Y) pop zh pop zl std Y+WIDGET_OFFS_TMP_LO, r18 std Y+WIDGET_OFFS_TMP_HI, r19 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCopyTmpToWidth ; ; @param Y object to start with ; @param r25 number of widgets to handle (0=all) ; @clobbers r18, r19, Z mLayoutCopyTmpToWidth: push yl push yh ldi zl, LOW(mLayoutCallbackCopyTmpToWidth) ldi zh, HIGH(mLayoutCallbackCopyTmpToWidth) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackCopyTmpToWidth ; ; @param Y object to start with ; @clobbers r18, r19 mLayoutCallbackCopyTmpToWidth: 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 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCopyTmpToHeight ; ; @param Y object to start with ; @param r25 number of widgets to handle (0=all) ; @clobbers r18, r19, Z mLayoutCopyTmpToHeight: push yl push yh ldi zl, LOW(mLayoutCallbackCopyTmpToHeight) ldi zh, HIGH(mLayoutCallbackCopyTmpToHeight) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackCopyTmpToHeight ; ; @param Y object to start with ; @clobbers r18, r19 mLayoutCallbackCopyTmpToHeight: 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 clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutSumContiguous ; ; @param Y object to start with ; @param r25 widgets per column/row ; @param r22 spacing between widgets ; @param r23 border at beginning and and ; @return r21:r20 total size in the given dimension including borders and inter-widget spacing ; @clobbers r18, r19 mLayoutSumContiguous: push yl push yh mov r20, r23 ; start with border clr r21 ldi zl, LOW(mLayoutCallbackAddToSum) ldi zh, HIGH(mLayoutCallbackAddToSum) rcall mLayoutForEveryObjectContiguous ; (r18, r19, Y) 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 end ; @return r21:r20 sum of TMP values ; @clobbers r18, r19, r25 mLayoutSumSkipped: push yl push yh mov r20, r23 ; start with border clr r21 ldi zl, LOW(mLayoutCallbackAddToSum) ldi zh, HIGH(mLayoutCallbackAddToSum) rcall mLayoutForEveryObjectSkipped ; (r18, r19, r25, Y) 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 ; @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 ; add TMP adc r21, r19 add r20, r22 ; add spacing 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 (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} mLayoutForEveryObjectContiguous: push r25 mov r18, r25 mLayoutForEveryObjectContiguous_loop: push r18 push r25 push yl push yh icall pop yh pop yl pop r25 pop r18 brcs mLayoutForEveryObjectContiguous_ret tst r18 breq mLayoutForEveryObjectContiguous_next dec r18 clc breq mLayoutForEveryObjectContiguous_ret mLayoutForEveryObjectContiguous_next: push r18 bigcall OBJ_GetNext brcs mLayoutForEveryObjectContiguous_loopEnd pop r18 rjmp mLayoutForEveryObjectContiguous_ret mLayoutForEveryObjectContiguous_loopEnd: mov yl, r18 mov yh, r19 pop r18 rjmp mLayoutForEveryObjectContiguous_loop mLayoutForEveryObjectContiguous_ret: pop r25 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) ; @clobbers r18, r19, Y {any} mLayoutForEveryObjectSkipped: mLayoutForEveryObjectSkipped_loop: push r25 push yl push yh icall pop yh pop yl pop r25 brcs mLayoutForEveryObjectSkipped_ret push r16 mov r16, r25 bigcall OBJ_SkipObjects ; (R16) pop r16 brcc mLayoutForEveryObjectSkipped_ret mov yl, r18 mov yh, r19 rjmp mLayoutForEveryObjectSkipped_loop mLayoutForEveryObjectSkipped_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutGetBorders ; ; @param Y address of widget ; @return r22 spacing ; @return r23 outer borders ; @clobbers Z 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 mLayoutPackCell ; ; @param Y address of widget ; @param r17 pack mode (see @ref WIDGET_PACK_BEGIN) ; @param R11:R10 size of cell area (i.e. width or height) ; @param R13:R12 size of object to pack (i.e. width or height) ; @param r22 spacing (between widgets) ; @return R21:R20 pos ; @return R19:R18 new size of widget ; @clobbers r16, r17, r18, r19 mLayoutPackCell: clr r20 ; preset pos clr r21 mov r18, r12 ; preset widget size mov r19, r13 ; subtract borders from cell size clr r16 sub r10, r22 ; subtract spacing sbc r11, r16 brcs mLayoutPackCell_ret andi r17, 3 ; only 2 bits pack mode cpi r17, WIDGET_PACK_FILLED breq mLayoutPackCell_filled 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_filled: mov r18, r10 ; use full cell size (minus spacing) mov r19, r11 rjmp mLayoutPackCell_ret mLayoutPackCell_end: sub r10, r12 sbc r11, r13 mov r20, r10 mov r21, r11 rjmp mLayoutPackCell_ret mLayoutPackCell_center: sub r10, r12 sbc r11, r13 lsr r11 ror r10 mov r20, r10 mov r21, r11 rjmp mLayoutPackCell_ret mLayoutPackCell_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