; *************************************************************************** ; 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_MLAYOUT2_ASM #define AQH_AVR_GUI2_MLAYOUT2_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?? ; *************************************************************************** ; 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 mLayoutColumnLayoutHorizontally: ; prepare rcall mLayoutSetDefaultWidthToTmp ; (any, !Y) rcall mLayoutCopyTmpToWidth ; (r18, r19, r25, Z) rcall mLayoutGetBorders ; r22=spacing, r23=border ; prepare first row rcall mLayoutSetupFirstContiguous ; set max column widths to first row (r18, r19, r25, Z) ; possibly distribute free space to expandable columns push r22 ; spacing push r23 ; border rcall mLayoutColumnExpandColumns ; (r16-r23, r25) pop r23 pop r22 rcall mLayoutColumnCopyTmpFromFirstRow ; copy TMP of every column from first row to following (r18-r21, r25, Z) rcall mLayoutColumnPositionX ; (r12, r13, r16-r21, r25, X) ret ; @end mLayoutColumnLayoutVertically: ; prepare rcall mLayoutSetDefaultHeightToTmp ; (any, !Y) rcall mLayoutCopyTmpToHeight ; (r18, r19, r25, Z) rcall mLayoutGetBorders ; r22=spacing, r23=border ; prepare first row rcall mLayoutSetupFirstSkipped ; set max column widths to first column (r18, r19, r25, Z) ; possibly distribute free space to expandable columns push r22 ; spacing push r23 ; border rcall mLayoutColumnExpandRows ; (r16-r23, r25) pop r23 pop r22 rcall mLayoutColumnCopyTmpFromFirstColumn ; copy TMP of every column from first row to following (r18-r21, r25, Z) rcall mLayoutColumnPositionY ; (r12, r13, r16-r21, r25, X) ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutColumnCopyTmpFromFirstRow ; ; @param Y widget ; @clobbers r18-r21, r25, Z mLayoutColumnCopyTmpFromFirstRow: push yl push yh ldi zl, LOW(mLayoutCallbackColumnCopyRow) ldi zh, HIGH(mLayoutCallbackColumnCopyRow) ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutForEveryObjectContiguous ; (r18-r21, r25, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackColumnCopyRow ; ; @param Y widget ; @clobbers r18, r19, r20, r21, r25 mLayoutCallbackColumnCopyRow: push zl push zh rcall mLayoutColumnCopyTmpAcrossColumn ; (r18, r19, r20, r21, r25, Z) pop zh pop zl clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutColumnCopyTmpAcrossColumn ; ; @param Y widget ; @clobbers r18, r19, r20, r21, r25, Z mLayoutColumnCopyTmpAcrossColumn: push yl push yh ldd r20, Y+WIDGET_OFFS_TMP_LO ldd r21, Y+WIDGET_OFFS_TMP_HI ldi zl, LOW(mLayoutCallbackSetTmp) ldi zh, HIGH(mLayoutCallbackSetTmp) ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutForEveryObjectSkipped ; (r18, r19, r25, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutColumnCopyTmpFromFirstColumn ; ; @param Y widget ; @clobbers r18-r21, r25, Z mLayoutColumnCopyTmpFromFirstColumn: push yl push yh ldi zl, LOW(mLayoutCallbackColumnCopyColumn) ldi zh, HIGH(mLayoutCallbackColumnCopyColumn) ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutForEveryObjectSkipped ; (r18-r21, r25, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackColumnCopyColumn ; ; @param Y widget ; @clobbers r18, r19, r20, r21, r25 mLayoutCallbackColumnCopyColumn: push zl push zh rcall mLayoutColumnCopyTmpAcrossRow ; (r18, r19, r20, r21, r25, Z) pop zh pop zl clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutColumnCopyTmpAcrossRow ; ; @param Y widget ; @clobbers r18, r19, r20, r21, r25, Z mLayoutColumnCopyTmpAcrossRow: push yl push yh ldd r20, Y+WIDGET_OFFS_TMP_LO ldd r21, Y+WIDGET_OFFS_TMP_HI ldi zl, LOW(mLayoutCallbackSetTmp) ldi zh, HIGH(mLayoutCallbackSetTmp) ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutForEveryObjectContiguous ; (r18, r19, r25, Y) pop yh pop yl 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 mLayoutColumnPositionX ; ; Set X and width to all columns of the row ; ; @param Y first widget of current row ; @param r22 spacing between widgets ; @param r23 border at beginning and and ; @clobbers r12, r13, r16-r21, r25, X mLayoutColumnPositionX: mov xl, r23 ; start at border clr xh push yl push yh ldi zl, LOW(mLayoutCallbackPositionX) ldi zh, HIGH(mLayoutCallbackPositionX) ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutForEveryObjectContiguous ; (r12, r13, r16-r21, r25, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackPositionX ; ; @param Y widget ; @param r22 spacing between widgets ; @param X current X pos ; @clobbers r12, r13, r16-r21 mLayoutCallbackPositionX: ldd r16, Y+OBJECT_OFFS_FLAGS sbrs r16, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutCallbackPositionX_ret ldd r18, Y+WIDGET_OFFS_TMP_LO ; calculated cell width ldd r19, 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 (r17, r18, r19) add r20, xl adc r21, xh std Y+WIDGET_OFFS_X_LO, r20 ; set new X std Y+WIDGET_OFFS_X_HI, r21 std Y+WIDGET_OFFS_WIDTH_LO, r18 ; set new width std Y+WIDGET_OFFS_WIDTH_HI, r19 add xl, r18 ; advance X adc xh, r19 add xl, r22 ; add spacing adc xh, r22 sub xh, r22 mLayoutCallbackPositionX_ret: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutColumnPositionY ; ; Set X and width to all columns of the row ; ; @param Y first widget of current row ; @param r22 spacing between widgets ; @param r23 border at beginning and end ; @clobbers r12, r13, r16-r21, r25, X mLayoutColumnPositionY: mov xl, r23 ; start at border clr xh push yl push yh ldi zl, LOW(mLayoutCallbackPositionY) ldi zh, HIGH(mLayoutCallbackPositionY) ldd r25, Y+MLAYOUT_OFFS_COLSORROWS rcall mLayoutForEveryObjectSkipped ; (r12, r13, r16-r21, r25, Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutCallbackPositionY ; ; @param Y widget ; @param r22 spacing between widgets ; @param X current Y pos ; @clobbers r12, r13, r16-r21 mLayoutCallbackPositionY: ldd r16, Y+OBJECT_OFFS_FLAGS sbrs r16, WIDGET_FLAGS_VISIBLE_BIT rjmp mLayoutCallbackPositionY_ret ldd r18, Y+WIDGET_OFFS_TMP_LO ; calculated cell width ldd r19, 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 (r17, r18, r19) add r20, xl adc r21, xh std Y+WIDGET_OFFS_Y_LO, r20 ; set new Y std Y+WIDGET_OFFS_Y_HI, r21 std Y+WIDGET_OFFS_HEIGHT_LO, r18 ; set new width std Y+WIDGET_OFFS_HEIGHT_HI, r19 add xl, r18 ; advance Y adc xh, r19 add xl, r22 ; add spacing adc xh, r22 sub xh, r22 mLayoutCallbackPositionY_ret: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine mLayoutColumnExpandColumns ; ; Calculate additional space per expandable widget in a row. ; ; @param Y first widget of current row ; @return CFLAG set if there is additional space to distribute ; @return r21:r20 space to add to every expandable widget ; @clobbers r16-r23, r25 mLayoutColumnExpandColumns: rcall mLayoutColumnCalcAddSpacePerColumn ; r21:r20=additional space (r16-r23, r25) brcc mLayoutColumnExpandColumns_ret ldi r22, (1<