gui2: started working on autolayout.

This commit is contained in:
Martin Preuss
2026-03-07 00:04:36 +01:00
parent a8cb442502
commit 0af5aed2f6
8 changed files with 1367 additions and 28 deletions

View File

@@ -0,0 +1,344 @@
; ***************************************************************************
; 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_HLAYOUT_ASM
#define AQH_AVR_GUI2_HLAYOUT_ASM
; ***************************************************************************
; defines
.equ HLAYOUT_OFFS_BEGIN = WIDGET_SIZE
; no data for now
.equ HLAYOUT_SIZE = HLAYOUT_OFFS_BEGIN+0
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine HLayout_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_LO
; @param r17 value for OBJECT_OFFS_OPTS_HI
; @param r21:r20 ressource id for title
; @clobbers any
HLayout_new:
push r20
push r21
ldi r24, LOW(HLAYOUT_SIZE)
ldi r25, HIGH(HLAYOUT_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc HLayout_new_ret
rcall HLayout_Init ; (r16, r17, X)
sec
HLayout_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @clobbers r16, r17, X
HLayout_Init:
push r20
push r21
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r21
pop r20
; set default signal map
ldi r16, LOW(HLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(HLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_OnLayout
;
; @param Y pointer to widget
; @clobbers any, !Y
HLayout_OnLayout:
rcall hLayoutHorizontally
rcall hLayoutVerticalAdjust
; force re-drawing of this widget
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_OnGetDefaultWidth
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
HLayout_OnGetDefaultWidth:
rcall Layout_SetDefaultWidths
rcall Layout_SumTmpValues ; r19:r18=default width
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_OnGetDefaultHeight
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
HLayout_OnGetDefaultHeight:
rcall Layout_SetDefaultHeights
rcall Layout_GetMaxTmp
; get outer border
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
lpm r16, Z
clr r17
sbiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
add r18, r16 ; add outer border (top)
adc r19, r17
add r18, r16 ; add outer border (bottom)
adc r19, r17
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutCountFillXChildren
;
; @param Y pointer to widget
; @return r16 number of children with opt WIDGET_OPTSLO_FILLX_BIT
; @clobbers r17, r18, r19
hLayoutCountFillXChildren:
clr r16
push yl
push yh
bigcall OBJ_GetFirstChild
hLayoutCountFillXChildren_loop:
brcc hLayoutCountFillXChildren_done
mov yl, r18
mov yh, r19
ldd r17, Y+OBJECT_OFFS_OPTS_LO
sbrc r17, WIDGET_OPTSLO_FILLX_BIT
inc r16
rcall OBJ_GetNext
rjmp hLayoutCountFillXChildren_loop
hLayoutCountFillXChildren_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutSetX
;
; @param Y pointer to widget
; @clobbers r16, r17, r18, r19, r20, r21, r22, r23, Z
hLayoutSetX:
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
clr r23
sbiw zh:zl, WIDGET_STYLE_OFFS_SPACING
; get outer border
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
lpm r20, Z
clr r21
sbiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
push yl
push yh
bigcall OBJ_GetFirstChild
hLayoutSetX_loop:
brcc hLayoutSetX_loopEnd
mov yl, r18
mov yh, r19
; set X
std Y+WIDGET_OFFS_X_LO, r20
std Y+WIDGET_OFFS_X_HI, r21
; set width
ldd r16, Y+WIDGET_OFFS_TMP_LO
ldd r17, Y+WIDGET_OFFS_TMP_HI
std Y+WIDGET_OFFS_WIDTH_LO, r16
std Y+WIDGET_OFFS_WIDTH_HI, r17
; advance r21:r20
add r20, r16 ; add widget size
adc r21, r17
add r20, r22 ; add spacing
adc r21, r23
; force direct children to re-layout and re-draw
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT) | (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
rcall OBJ_GetNext
rjmp hLayoutSetX_loop
hLayoutSetX_loopEnd:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutVerticalAdjust
;
; @param Y pointer to widget
; @clobbers r17, r18, r19, r20, r21, r22, r23, Z
hLayoutVerticalAdjust:
bigcall Layout_SetDefaultHeights
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
; get outer border
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
lpm r20, Z
clr r21
sbiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
ldd r22, Y+WIDGET_OFFS_HEIGHT_LO
ldd r23, Y+WIDGET_OFFS_HEIGHT_HI
sub r22, r20 ; subtract border (top)
sbc r23, r21
sub r22, r20 ; subtract border (bottom)
sbc r23, r21
push yl
push yh
bigcall OBJ_GetFirstChild
hLayoutVerticalAdjust_loop:
brcc hLayoutVerticalAdjust_loopEnd
mov yl, r18
mov yh, r19
std Y+WIDGET_OFFS_Y_LO, r20
std Y+WIDGET_OFFS_Y_HI, r21
ldd r18, Y+WIDGET_OFFS_TMP_LO
ldd r19, Y+WIDGET_OFFS_TMP_HI
ldd r17, Y+OBJECT_OFFS_OPTS_LO
sbrs r17, WIDGET_OPTSLO_FILLY_BIT
rjmp hLayoutVerticalAdjust_setHeight
mov r18, r22 ; increase height to full height
mov r19, r23
hLayoutVerticalAdjust_setHeight:
std Y+WIDGET_OFFS_HEIGHT_LO, r18
std Y+WIDGET_OFFS_HEIGHT_HI, r19
rcall OBJ_GetNext
rjmp hLayoutVerticalAdjust_loop
hLayoutVerticalAdjust_loopEnd:
pop yh
pop yl
ret
; @end
hLayoutHorizontally:
rcall Layout_SetDefaultWidths
rcall Layout_SumTmpValues ; r21:r20=width
ldd r22, Y+WIDGET_OFFS_WIDTH_LO
ldd r23, Y+WIDGET_OFFS_WIDTH_HI
sub r22, r20
sbc r23, r21
breq hLayoutHorizontally_setX
brcs hLayoutHorizontally_setX
; r23:r22=remaining space to distribute
rcall hLayoutCountFillXChildren ; r16=number of expandable child widgets
tst r16
breq hLayoutHorizontally_setX
; calc space to add to each expandable child widget and add it
mov r20, r22
mov r21, r23
mov r22, r16
clr r23
bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable child widget
mov r20, r16
mov r21, r17
rcall Layout_AddToTmpOfFillXChildren
hLayoutHorizontally_setX:
rcall hLayoutSetX
ret
; @end
; ***************************************************************************
; data in FLASH
HLayout_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap ; next table to use
; entries
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(HLayout_OnLayout), HIGH(HLayout_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(HLayout_OnGetDefaultWidth), HIGH(HLayout_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(HLayout_OnGetDefaultHeight), HIGH(HLayout_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,287 @@
; ***************************************************************************
; 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_LABEL_ASM
#define AQH_AVR_GUI2_LABEL_ASM
; ***************************************************************************
; defines
.equ LABEL_OFFS_BEGIN = WIDGET_SIZE
.equ LABEL_OFFS_TEXTRES_LO = LABEL_OFFS_BEGIN+0
.equ LABEL_OFFS_TEXTRES_HI = LABEL_OFFS_BEGIN+1
.equ LABEL_SIZE = LABEL_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Label_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_LO
; @param r17 value for OBJECT_OFFS_OPTS_HI
; @param r21:r20 ressource id for label text
; @clobbers any
Label_new:
ldi r24, LOW(LABEL_SIZE)
ldi r25, HIGH(LABEL_SIZE)
push r20
push r21
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc Label_new_ret
rcall Label_Init ; (r16, r17, X)
sec
Label_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS_LO
; @param r17 value for OBJECT_OFFS_OPTS_HI
; @param r21:r20 ressource id for label text
; @clobbers r16, r17, X
Label_Init:
push r20
push r21
; call base class
bigcall Widget_Init ; (r16, r17, X)
; clear widget-specific data
mov xl, yl
mov xh, yh
adiw xh:xl, LABEL_OFFS_BEGIN
clr r16
ldi r17, (LABEL_SIZE-LABEL_OFFS_BEGIN)
bigcall Utils_FillSram ; (r17, X)
pop r21
pop r20
; setup label data
std Y+LABEL_OFFS_TEXTRES_LO, r20
std Y+LABEL_OFFS_TEXTRES_HI, r21
; set default signal map
ldi r16, LOW(Label_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(Label_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_SetTextRessourceId @global
;
; @param Y address of widget
; @param X id of text ressource
; @clobbers r16, r17, r18, r19
Label_SetTextRessourceId:
std Y+LABEL_OFFS_TEXTRES_LO, xl
std Y+LABEL_OFFS_TEXTRES_HI, xh
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnDraw @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @clobbers any, !Y
Label_OnDraw:
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq Label_OnDraw_ret
bigcall Widget_Clear
rcall labelWriteText
ldd r16, Y+OBJECT_OFFS_OPTS_LO
andi r16, (1<<WIDGET_OPTSLO_BORDER_BIT)
breq Label_OnDraw_done
bigcall Widget_DrawBorder
Label_OnDraw_done:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
Label_OnDraw_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Label_OnGetDefaultWidth:
rcall labelCalcTextWidth
mov r18, r12
mov r19, r13
ldi r16, 2 ; add small border around text
add r18, r16
adc r19, r16
sub r19, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Label_OnGetDefaultHeight:
rcall Widget_GetCharHeight ; R16=char height
mov r18, r16
clr r19
ldi r16, 2 ; add small border around text
add r18, r16
adc r19, r16
sub r19, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnDraw @global
;
; @param Y address of widget
; @clobbers any, !Y
labelWriteText:
rcall labelAlignTextXY ; (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19)
bigcall Widget_DrawTextFlash ; (any, !Y)
labelWriteText_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine labelAlignTextXY
;
; @param Y address of widget
; @param R13:R12 width of object to align
; @return R5:R4 X
; @return R7:R6 Y
; @return Z byte address pointer to text in FLASH
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25
labelAlignTextXY:
rcall labelCalcTextWidth ; Z=text, R13:R12=text width (r16, r17, r18)
rcall Widget_AlignContentX ; (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25)
rcall Widget_GetCharHeight ; R16=char height
mov r12, r16
clr r13
rcall Widget_AlignContentY ; (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25)
ret
; @end
; ---------------------------------------------------------------------------
; @routine labelCalcTextWidth
;
; @param Y address of widget
; @return Z byte address pointer to text in FLASH
; @return r13:r12 width of string
; @clobbers r16, r17, r18
labelCalcTextWidth:
; get text from ressource id
ldd r16, Y+LABEL_OFFS_TEXTRES_LO
ldd r17, Y+LABEL_OFFS_TEXTRES_HI
ldi zl, LOW(RESSOURCE_ADDR*2)
ldi zh, HIGH(RESSOURCE_ADDR*2)
bigcall RES_GetRessource ; (r16, r17, r18)
brcc labelCalcTextWidth_ret
rcall Widget_GetCharWidth ; R16=char width
mov r18, r16
bigcall Widget_CalcStringWidthFLASH ; r13:r12=size (r16)
sec
labelCalcTextWidth_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
Label_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Label_OnDraw), HIGH(Label_OnDraw)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(Label_OnGetDefaultWidth), HIGH(Label_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(Label_OnGetDefaultHeight), HIGH(Label_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,223 @@
; ***************************************************************************
; 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
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Layout_SetDefaultWidths
;
; Set defaultWidth in WIDGET_OFFS_TMP_LO/HI
;
; @param Y pointer to widget
; @clobbers any, !Y
Layout_SetDefaultWidths:
push yl
push yh
bigcall OBJ_GetFirstChild
Layout_SetDefaultWidths_loop:
brcc Layout_SetDefaultWidths_ret
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultWidth
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
rcall OBJ_GetNext
rjmp Layout_SetDefaultWidths_loop
Layout_SetDefaultWidths_ret:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_SetDefaultHeights
;
; @param Y pointer to widget
; @clobbers any, !Y
Layout_SetDefaultHeights:
push yl
push yh
bigcall OBJ_GetFirstChild
Layout_SetDefaultHeights_loop:
brcc Layout_SetDefaultHeights_ret
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultHeight
std Y+WIDGET_OFFS_TMP_LO, r18
std Y+WIDGET_OFFS_TMP_HI, r19
rcall OBJ_GetNext
rjmp Layout_SetDefaultHeights_loop
Layout_SetDefaultHeights_ret:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_SumTmpValues
;
; @param Y pointer to widget
; @return r19:r18 total width 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
Layout_SumTmpValues_loop:
brcc Layout_SumTmpValues_loopEnd
mov yl, r18
mov yh, r19
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 r20, r22
sub r20, r22
rcall OBJ_GetNext
rjmp Layout_SumTmpValues_loop
Layout_SumTmpValues_loopEnd:
mov r16, r20
or r16, r21
breq Layout_SumTmpValues_done
sub r20, r22 ; sub last spacing
sbc r21, r22
add r21, r22
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
;
; @param Y pointer to widget
; @return r19:r18 maximum value in WIDGET_OFFS_TMP_LO/HI of children
; @clobbers any, !Y
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+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:
rcall OBJ_GetNext
rjmp Layout_GetMaxTmp_loop
Layout_GetMaxTmp_ret:
mov r18, r20
mov r19, r21
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Layout_AddToTmpOfFillXChildren
;
; @param Y pointer to widget
; @param R21:R20 value to add to tmp value of expandable widgets
; @param r22 mask for OBJECT_OFFS_OPTS_LO (e.g. 1<<WIDGET_OPTSLO_FILLX_BIT)
Layout_AddToTmpOfFillXChildren:
clr r16
push yl
push yh
bigcall OBJ_GetFirstChild
Layout_AddToTmpOfFillXChildren_loop:
brcc Layout_AddToTmpOfFillXChildren_done
mov yl, r18
mov yh, r19
ldd r17, Y+OBJECT_OFFS_OPTS_LO
and r17, r22
breq Layout_AddToTmpOfFillXChildren_next
ldd r16, Y+WIDGET_OFFS_TMP_LO
ldd r17, Y+WIDGET_OFFS_TMP_HI
add r16, r20
adc r17, r21
std Y+WIDGET_OFFS_TMP_LO, r16
std Y+WIDGET_OFFS_TMP_HI, r17
Layout_AddToTmpOfFillXChildren_next:
rcall OBJ_GetNext
rjmp Layout_AddToTmpOfFillXChildren_loop
Layout_AddToTmpOfFillXChildren_done:
pop yh
pop yl
ret
; @end
#endif

View File

@@ -10,6 +10,8 @@
#ifndef AQH_AVR_GUI2_MAINWINDOW_ASM
#define AQH_AVR_GUI2_MAINWINDOW_ASM
; TODO: base on VLayout!
; ***************************************************************************
; defines
@@ -32,15 +34,20 @@
;
; @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_LO
; @param r17 value for OBJECT_OFFS_OPTS_HI
; @param X parent widget
; @param r21:r20 ressource id for title
; @clobbers any
MainWindow_new:
ldi r24, LOW(MAINWINDOW_SIZE)
ldi r25, HIGH(MAINWINDOW_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
push r20
push r21
ldi r24, LOW(MAINWINDOW_SIZE)
ldi r25, HIGH(MAINWINDOW_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc MainWindow_new_ret
rcall MainWindow_Init ; (r16, r17, X)
sec
@@ -55,11 +62,22 @@ MainWindow_new_ret:
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r21:r20 ressource id for title
; @clobbers r16, r17, X
MainWindow_Init:
; call base class
bigcall Widget_Init ; (r16, r17, X)
push r20
push r21
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r21
pop r20
; set default signal map
ldi r16, LOW(MainWindow_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(MainWindow_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; move widget
clr r4
@@ -79,6 +97,9 @@ MainWindow_Init:
mov r11, r16
bigcall Widget_Resize ; (R16)
; create sub widgets
rcall mainWindowCreateTitleWidget
ret
; @end
@@ -86,5 +107,158 @@ MainWindow_Init:
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine MainWindow_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
MainWindow_OnGetDefaultWidth:
ldi r18, LOW(DISPLAY_WIDTH)
ldi r19, HIGH(DISPLAY_WIDTH)
ret
; @end
; ---------------------------------------------------------------------------
; @routine MainWindow_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
MainWindow_OnGetDefaultHeight:
ldi r18, LOW(DISPLAY_HEIGHT)
ldi r19, HIGH(DISPLAY_HEIGHT)
ret
; @end
; ---------------------------------------------------------------------------
; @routine MainWindow_OnLayout @global
;
; @param Y address of widget
; @return CFLAG set if signal handled
; @clobbers any, !Y
MainWindow_OnLayout:
ldd r16, Y+OBJECT_OFFS_OPTS_LO
clr r4 ; X
clr r5
clr r6 ; Y
clr r7
; TODO
ret
; @end
; ---------------------------------------------------------------------------
; @routine mainWindowCreateTitleWidget
;
; @param Y address of main window widget
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
mainWindowCreateTitleWidget:
; create title widget
push yl
push yh
mov xl, yl
mov xh, yh
ldi r16, 0
ldi r17, (WIDGET_XALIGN_LEFT<<WIDGET_OPTSHI_CONTENT_XALIGN0_BIT) | (WIDGET_YALIGN_CENTER<<WIDGET_OPTSHI_CONTENT_YALIGN0_BIT)
bigcall Label_new
; set style for title widget
brcc mainWindowCreateTitleWidget_done
ldi r16, LOW(MainWindow_TitleStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(MainWindow_TitleStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
sec
mainWindowCreateTitleWidget_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mainWindowCreateContentWidget
;
; @param Y address of main window widget
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
mainWindowCreateContentWidget:
; create content widget
push yl
push yh
mov xl, yl
mov xh, yh
ldi r16, 0 ; opts lo
ldi r17, 0 ; opts hi
bigcall Widget_new
pop yh
pop yl
ret
; @end
; ***************************************************************************
; data in FLASH
MainWindow_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDrawNop), HIGH(Widget_OnDrawNop)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(MainWindow_OnGetDefaultWidth), HIGH(MainWindow_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(MainWindow_OnGetDefaultHeight), HIGH(MainWindow_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
MainWindow_TitleStyle:
.dw STYLE_WIN_TITLE_FOREGROUND ; frontCol_norm
.dw STYLE_WIN_TITLE_BACKGROUND ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
.dw DISPLAY_COLOR_NAVY ; backCol_activated
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
.db 0, 1 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
#endif

View File

@@ -776,6 +776,35 @@ OBJ_SubFlagsDown_done:
; ---------------------------------------------------------------------------
; @routine OBJ_AddFlagsUp @global @recursive
;
; @param Y address of object
; @param R16 flags to add
; @clobbers r17, r18, r19
OBJ_AddFlagsUp:
push yl
push yh
ldd r17, Y+OBJECT_OFFS_FLAGS
or r17, r16
std Y+OBJECT_OFFS_FLAGS, r17
; handle parents
OBJ_AddFlagsUp_loop:
rcall OBJ_GetParent ; r19:r18=object (none)
brcc OBJ_AddFlagsUp_done
mov yl, r18
mov yh, r19
rcall OBJ_AddFlagsUp ; recursion!
rjmp OBJ_AddFlagsUp_loop
OBJ_AddFlagsUp_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine objHandleSignalWithMap
;

View File

@@ -69,7 +69,7 @@ RootWindow_Init:
adiw xh:xl, ROOTWINDOW_OFFS_BEGIN
clr r16
ldi r17, (ROOTWINDOW_SIZE-ROOTWINDOW_OFFS_BEGIN)
bigcall Utils_FillSram ; (r17, X)
bigcall Utils_FillSram ; (r17, X)
; set default signal map
ldi r16, LOW(RootWindow_DefaultSignalmap*2)
@@ -129,7 +129,7 @@ RootWindow_SetApp:
RootWindow_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap ; next table to use
.dw MainWindow_DefaultSignalmap ; next table to use
; entries
; none for now
.db 0, 0, 0, 0 ; end of table

View File

@@ -27,7 +27,9 @@
.equ WIDGET_OFFS_HEIGHT_HI = WIDGET_OFFS_BEGIN+7
.equ WIDGET_OFFS_STYLE_LO = WIDGET_OFFS_BEGIN+8 ; byte address (for LPM!)
.equ WIDGET_OFFS_STYLE_HI = WIDGET_OFFS_BEGIN+9
.equ WIDGET_SIZE = WIDGET_OFFS_BEGIN+10
.equ WIDGET_OFFS_TMP_LO = WIDGET_OFFS_BEGIN+10
.equ WIDGET_OFFS_TMP_HI = WIDGET_OFFS_BEGIN+11
.equ WIDGET_SIZE = WIDGET_OFFS_BEGIN+12
; widget style object
.equ WIDGET_STYLE_OFFS_FRONTCOL_NORM = 0
@@ -39,7 +41,7 @@
.equ WIDGET_STYLE_OFFS_BORDERCOL_ACTIVATED = 6
.equ WIDGET_STYLE_OFFS_SHADOWCOL_ACTIVATED = 7
.equ WIDGET_STYLE_OFFS_OUTERBORDERSIZE = 8
.equ WIDGET_STYLE_OFFS_INNERBORDERSIZE = 9
.equ WIDGET_STYLE_OFFS_SPACING = 9
.equ WIDGET_STYLE_OFFS_FONT_LO = 10
.equ WIDGET_STYLE_OFFS_FONT_HI = 11
.equ WIDGET_STYLE_OFFS_CHARWIDTH = 12
@@ -49,22 +51,26 @@
; widget opts_lo (bits 7 and 6 used by OBJECT_OPTSLO)
.equ WIDGET_OPTSLO_INPUT_BIT = 5 ; TOUCH, KEY
.equ WIDGET_OPTSLO_BORDER_BIT = 4
.equ WIDGET_OPTSLO_XALIGN1_BIT = 3 ; (2 bit: left, right, center, filled)
.equ WIDGET_OPTSLO_XALIGN0_BIT = 2
.equ WIDGET_OPTSLO_YALIGN1_BIT = 1 ; (2 bit: top, bottom, center, filled)
.equ WIDGET_OPTSLO_YALIGN0_BIT = 0
.equ WIDGET_OPTSLO_FILLX_BIT = 3
.equ WIDGET_OPTSLO_FILLY_BIT = 2
; values for WIDGET_OPTSLO_XALIGN (2 bits)
.equ WIDGET_OPTSLO_XALIGN_LEFT = 0
.equ WIDGET_OPTSLO_XALIGN_RIGHT = 1
.equ WIDGET_OPTSLO_XALIGN_CENTER = 2
.equ WIDGET_OPTSLO_XALIGN_FILLED = 3
; widget opts_hi
.equ WIDGET_OPTSHI_CONTENT_XALIGN1_BIT = 7 ; (2 bit: left, right, center, filled)
.equ WIDGET_OPTSHI_CONTENT_XALIGN0_BIT = 6
.equ WIDGET_OPTSHI_CONTENT_YALIGN1_BIT = 5 ; (2 bit: top, bottom, center, filled)
.equ WIDGET_OPTSHI_CONTENT_YALIGN0_BIT = 4
; values for WIDGET_OPTSLO_YALIGN (2 bits)
.equ WIDGET_OPTSLO_YALIGN_TOP = 0
.equ WIDGET_OPTSLO_YALIGN_BOTTOM = 1
.equ WIDGET_OPTSLO_YALIGN_CENTER = 2
.equ WIDGET_OPTSLO_YALIGN_FILLED = 3
; values for WIDGET_OPTSHI_CONTENT_XALIGN (2 bits)
.equ WIDGET_XALIGN_LEFT = 0
.equ WIDGET_XALIGN_RIGHT = 1
.equ WIDGET_XALIGN_CENTER = 2
.equ WIDGET_XALIGN_FILLED = 3
; values for WIDGET_OPTSHI_CONTENT_YALIGN (2 bits)
.equ WIDGET_YALIGN_TOP = 0
.equ WIDGET_YALIGN_BOTTOM = 1
.equ WIDGET_YALIGN_CENTER = 2
.equ WIDGET_YALIGN_FILLED = 3
; widget flags
.equ WIDGET_FLAGS_VISIBLE_BIT = 7
@@ -94,12 +100,16 @@
.equ WIDGET_SIGNAL_KEEPALIVE = OBJECT_SIGNAL_NEXTFREE+8
.equ WIDGET_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+9
; values for signals WIDGET_SIGNAL_SETVALUE and WIDGET_SIGNAL_GETVALUE
.equ WIDGET_VALUE_DEFAULT_WIDTH = 1
.equ WIDGET_VALUE_DEFAULT_HEIGHT = 2
.equ WIDGET_VALUE_NEXTFREE = 3
; args to Widget_AlignPos
.equ WIDGET_1DALIGN_END_BIT = 0
.equ WIDGET_1DALIGN_CENTER_BIT = 1
.equ WIDGET_1DALIGN_BORDER_BIT = 2
; ***************************************************************************
@@ -108,6 +118,29 @@
.cseg
; ---------------------------------------------------------------------------
; @routine Widget_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_LO
; @param r17 value for OBJECT_OFFS_OPTS_HI
; @clobbers any
Widget_new:
ldi r24, LOW(WIDGET_SIZE)
ldi r25, HIGH(WIDGET_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
brcc Widget_new_ret
rcall Widget_Init ; (r16, r17, X)
sec
Widget_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_Init @global
;
@@ -171,7 +204,7 @@ Widget_Init_setDefaultSize:
mov r16, xl
or r16, xh
breq Widget_Init_ret
bigcall OBJ_AddChild
bigcall OBJ_AddChild ; (r18, r19)
Widget_Init_ret:
ret
@@ -233,6 +266,46 @@ Widget_Move:
; ---------------------------------------------------------------------------
; @routine Widget_GetDefaultWidth @global
;
; @param Y address of widget
; @return r19:r18 default width of the widget
; @clobbers any, !Y
Widget_GetDefaultWidth:
ldi r16, WIDGET_SIGNAL_GETVALUE
ldi r17, WIDGET_VALUE_DEFAULT_WIDTH
bigcall OBJ_HandleSignal
brcs Widget_GetDefaultWidth_ret
ldi r18, 1
clr r19
Widget_GetDefaultWidth_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_GetDefaultHeight @global
;
; @param Y address of widget
; @return r19:r18 default height of the widget
; @clobbers any, !Y
Widget_GetDefaultHeight:
ldi r16, WIDGET_SIGNAL_GETVALUE
ldi r17, WIDGET_VALUE_DEFAULT_HEIGHT
bigcall OBJ_HandleSignal
brcs Widget_GetDefaultHeight_ret
ldi r18, 1
clr r19
Widget_GetDefaultHeight_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_OnDraw @global
;
@@ -339,8 +412,7 @@ Widget_Clear:
; @routine Widget_DrawBorder @global
;
; @param Y address of widget
; @param r3:r2 color
; @clobbers any, !Z
; @clobbers any, !Y
Widget_DrawBorder:
rcall widgetLoadDimsForFullWidget ; (none)
@@ -599,6 +671,211 @@ Widget_SelectBorderColors_readColors:
; ---------------------------------------------------------------------------
; @routine Widget_CalcStringWidthFLASH
;
; @param Z pointer to text in FLASH
; @param R18 char width in px
; @return r13:r12 width of string
; @clobbers r16
Widget_CalcStringWidthFLASH:
clr r12
clr r13
push zl
push zh
Widget_CalcStringWidthFLASH_loop:
lpm r16, Z+
tst r16
breq Widget_CalcStringWidthFLASH_done
add r12, r18
adc r13, r18
sub r13, r18
rjmp Widget_CalcStringWidthFLASH_loop
Widget_CalcStringWidthFLASH_done:
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_AlignContentX @global
;
; @param Y address of widget
; @param R13:R12 width of object to align
; @return R5:R4 X
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25
Widget_AlignContentX:
ldd r8, Y+WIDGET_OFFS_WIDTH_LO
ldd r9, Y+WIDGET_OFFS_WIDTH_HI
ldd r24, Y+OBJECT_OFFS_OPTS_LO
ldd r25, Y+OBJECT_OFFS_OPTS_HI
; align horizontally
clr r17
sbrc r24, WIDGET_OPTSLO_BORDER_BIT
ori r17, (1<<WIDGET_1DALIGN_BORDER_BIT)
mov r16, r25
andi r16, (1<<WIDGET_OPTSHI_CONTENT_XALIGN1_BIT) | (1<<WIDGET_OPTSHI_CONTENT_XALIGN0_BIT)
cpi r16, (WIDGET_XALIGN_RIGHT<<WIDGET_OPTSHI_CONTENT_XALIGN0_BIT)
brne Widget_AlignContentX_h1
ori r17, (1<<WIDGET_1DALIGN_END_BIT)
Widget_AlignContentX_h1:
cpi r16, (WIDGET_XALIGN_CENTER<<WIDGET_OPTSHI_CONTENT_XALIGN0_BIT)
brne Widget_AlignContentX_h2
ori r17, (1<<WIDGET_1DALIGN_CENTER_BIT)
Widget_AlignContentX_h2:
mov r18, r8 ; widget width
mov r19, r9
rcall Widget_AlignPos1D ; (r16, r18, r19)
mov r4, r22
mov r5, r23
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_AlignContentY @global
;
; @param Y address of widget
; @param R13:R12 height of object to align
; @return R7:R6 Y
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25
Widget_AlignContentY:
ldd r10, Y+WIDGET_OFFS_HEIGHT_LO
ldd r11, Y+WIDGET_OFFS_HEIGHT_HI
ldd r24, Y+OBJECT_OFFS_OPTS_LO
ldd r25, Y+OBJECT_OFFS_OPTS_HI
; align vertically
clr r17
sbrc r24, WIDGET_OPTSLO_BORDER_BIT
ori r17, (1<<WIDGET_1DALIGN_BORDER_BIT)
mov r16, r24
andi r16, (1<<WIDGET_OPTSHI_CONTENT_YALIGN1_BIT) | (1<<WIDGET_OPTSHI_CONTENT_YALIGN0_BIT)
cpi r16, (WIDGET_YALIGN_BOTTOM<<WIDGET_OPTSHI_CONTENT_YALIGN0_BIT)
brne Widget_AlignContentY_v1
ori r17, (1<<WIDGET_1DALIGN_END_BIT)
Widget_AlignContentY_v1:
cpi r16, (WIDGET_YALIGN_CENTER<<WIDGET_OPTSHI_CONTENT_YALIGN0_BIT)
brne Widget_AlignContentY_v2
ori r17, (1<<WIDGET_1DALIGN_CENTER_BIT)
Widget_AlignContentY_v2:
mov r18, r10 ; widget height
mov r19, r11
rcall Widget_AlignPos1D ; (r16, r18, r19)
mov r6, r22
mov r7, r23
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_AlignPos1D
;
; one-dimensional routine.
;
; @param R19:R18 size of target
; @param R13:R12 size of object to align
; @param
; @param R17 opts (bit 0: align end, bit 1: align center, bit 2: account for border)
; @return R23:R22 pos
; @clobbers r16, r18, r19
Widget_AlignPos1D:
clr r22
clr r23
sbrc r17, WIDGET_1DALIGN_BORDER_BIT
rcall Widget_AlignPos1D_subBordersFromSize
sbrc r17, WIDGET_1DALIGN_END_BIT
rcall Widget_AlignPos1D_alignEnd
sbrc r17, WIDGET_1DALIGN_CENTER_BIT
rcall Widget_AlignPos1D_alignCenter
sbrc r17, WIDGET_1DALIGN_BORDER_BIT
rcall Widget_AlignPos1D_addBordersToPos
Widget_AlignPos1D_ret:
ret
Widget_AlignPos1D_alignEnd:
mov r22, r18
mov r23, r19
sub r22, r12
sbc r23, r13
brcc Widget_AlignPos1D_ret
clr r22
clr r23
ret
Widget_AlignPos1D_alignCenter:
rcall Widget_AlignPos1D_alignEnd
lsr r23
ror r22
ret
Widget_AlignPos1D_subBordersFromSize:
subi r18, 4
sbci r19, 0
ret
Widget_AlignPos1D_addBordersToPos:
ldi r16, 2
add r22, r16
adc r23, r16
sub r23, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_GetCharWidth @global
;
; @param Y address of widget
; @return R16 character width with current font (in pixels)
; @clobbers none
Widget_GetCharWidth:
push zl
push zh
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_CHARWIDTH
lpm r16, Z
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_GetCharHeight @global
;
; @param Y address of widget
; @return R16 character height with current font (in pixels)
; @clobbers none
Widget_GetCharHeight:
push zl
push zh
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_CHARHEIGHT
lpm r16, Z
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine widgetDrawChar
;