gui2: more work (vlayout doesn't work, yet).

This commit is contained in:
Martin Preuss
2026-03-09 02:08:33 +01:00
parent 92efebccf1
commit 0758579b43
11 changed files with 657 additions and 523 deletions

View File

@@ -27,9 +27,10 @@
.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_OFFS_TMP_LO = WIDGET_OFFS_BEGIN+10
.equ WIDGET_OFFS_TMP_HI = WIDGET_OFFS_BEGIN+11
.equ WIDGET_SIZE = WIDGET_OFFS_BEGIN+12
.equ WIDGET_OFFS_PACK = WIDGET_OFFS_BEGIN+10
.equ WIDGET_OFFS_TMP_LO = WIDGET_OFFS_BEGIN+11
.equ WIDGET_OFFS_TMP_HI = WIDGET_OFFS_BEGIN+12
.equ WIDGET_SIZE = WIDGET_OFFS_BEGIN+13
; widget style object
.equ WIDGET_STYLE_OFFS_FRONTCOL_NORM = 0
@@ -48,29 +49,25 @@
.equ WIDGET_STYLE_OFFS_CHARHEIGHT = 21
.equ WIDGET_STYLE_SIZE = 22
; 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_FILLX_BIT = 3
.equ WIDGET_OPTSLO_FILLY_BIT = 2
; widget opts_lo (bits 7 and 6 used by OBJECT_OPTS)
.equ WIDGET_OPTS_INPUT_BIT = 5 ; TOUCH, KEY
.equ WIDGET_OPTS_BORDER_BIT = 4
; 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
; widget WIDGET_OFFS_PACK
.equ WIDGET_PACK_HSELF0_BIT = 0
.equ WIDGET_PACK_HSELF1_BIT = 1
.equ WIDGET_PACK_VSELF0_BIT = 2
.equ WIDGET_PACK_VSELF1_BIT = 3
.equ WIDGET_PACK_HCONTENT0_BIT = 4
.equ WIDGET_PACK_HCONTENT1_BIT = 5
.equ WIDGET_PACK_VCONTENT0_BIT = 6
.equ WIDGET_PACK_VCONTENT1_BIT = 7
; 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
; values for WIDGET_OFFS_PACK (2 bits)
.equ WIDGET_PACK_BEGIN = 0
.equ WIDGET_PACK_END = 1
.equ WIDGET_PACK_CENTER = 2
.equ WIDGET_PACK_FILLED = 3
; widget flags
.equ WIDGET_FLAGS_VISIBLE_BIT = 7
@@ -105,11 +102,6 @@
.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
; ***************************************************************************
@@ -125,8 +117,8 @@
; @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 r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @clobbers any
Widget_new:
@@ -145,27 +137,23 @@ Widget_new_ret:
; @routine Widget_Init @global
;
; @param Y address of object in SDRAM
; @param r16 value for OBJECT_OFFS_OPTS_LO
; @param r17 value for OBJECT_OFFS_OPTS_HI
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param X parent widget (if any)
; @clobbers r16, r17, X
Widget_Init:
push xl
push xh
; call base class
bigcall OBJ_Init ; (r16, r17, X)
; clear widget-specific data
mov xl, yl
mov xh, yh
adiw xh:xl, WIDGET_OFFS_BEGIN
clr r16
ldi r17, (WIDGET_SIZE-WIDGET_OFFS_BEGIN)
bigcall Utils_FillSram ; (r17, X)
push r17
; call base class
bigcall OBJ_Init ; (r16, r17, X)
pop r17
pop xh
pop xl
std Y+WIDGET_OFFS_PACK, r17
; set default signal map
ldi r16, LOW(Widget_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
@@ -754,134 +742,98 @@ Widget_CalcStringWidthFLASH_done:
; ---------------------------------------------------------------------------
; @routine Widget_AlignContentX @global
; @routine Widget_PackSelfX @global
;
; Calc pos according to WIDGET_PACK_HSELF in WIDGET_OFFS_PACK.
;
; @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
; @clobbers r17, r18, r19, r20, r21
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
Widget_PackSelfX:
ldd r18, Y+WIDGET_OFFS_WIDTH_LO
ldd r19, Y+WIDGET_OFFS_WIDTH_HI
ldd r17, Y+WIDGET_OFFS_PACK
andi r17, 3 ; WIDGET_PACK_HSELF0_BIT = 0, no shift necessary
rcall widgetPack ; r21:r20=new pos (r17, r18, r19)
mov r4, r20
mov r5, r21
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_AlignContentY @global
; @routine Widget_PackSelfY @global
;
; Calc pos according to WIDGET_PACK_VSELF in WIDGET_OFFS_PACK.
;
; @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
; @clobbers r17, r18, r19, r20, r21
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
Widget_PackSelfY:
ldd r18, Y+WIDGET_OFFS_HEIGHT_LO
ldd r19, 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 widgetPack ; r21:r20=new pos (r17, r18, r19)
mov r6, r20
mov r7, r21
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_AlignPos1D
; @routine Widget_PackContentX @global
;
; one-dimensional routine.
; Calc pos according to WIDGET_PACK_HCONTENT in WIDGET_OFFS_PACK.
;
; @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
; @param Y address of widget
; @param R13:R12 width of object to align
; @return R5:R4 X
; @clobbers r17, r18, r19, r20, r21
Widget_AlignPos1D:
clr r22
clr r23
Widget_PackContentX:
ldd r18, Y+WIDGET_OFFS_WIDTH_LO
ldd r19, Y+WIDGET_OFFS_WIDTH_HI
ldd r17, Y+WIDGET_OFFS_PACK
swap r17 ; WIDGET_PACK_HCONTENT0_BIT = 4 -> shift 4 times right
andi r17, 3
rcall widgetPack ; r21:r20=new pos (r17, r18, r19)
mov r4, r20
mov r5, r21
ret
; @end
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
; ---------------------------------------------------------------------------
; @routine Widget_PackContentY @global
;
; Calc pos according to WIDGET_PACK_VCONTENT in WIDGET_OFFS_PACK.
;
; @param Y address of widget
; @param R13:R12 height of object to align
; @return R7:R6 Y
; @clobbers r17, r18, r19, r20, r21
Widget_PackContentY:
ldd r18, Y+WIDGET_OFFS_HEIGHT_LO
ldd r19, Y+WIDGET_OFFS_HEIGHT_HI
ldd r17, Y+WIDGET_OFFS_PACK
swap r17 ; WIDGET_PACK_VCONTENT0_BIT = 6 -> shift 6 times right
lsr r17
lsr r17
andi r17, 3
rcall widgetPack ; r21:r20=new pos (r17, r18, r19)
mov r6, r20
mov r7, r21
ret
; @end
@@ -1044,6 +996,57 @@ widgetCalcAbsPosAndBorders:
; ---------------------------------------------------------------------------
; @routine widgetPack
;
; @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)
; @return R21:R20 pos
; @clobbers r17, r18, r19
widgetPack:
; subtract borders
push zl
push zh
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
lpm r20, Z
pop zh
pop zl
clr r21
sub r18, r20 ; subtract border at begin
sbc r19, r21
sub r18, r20 ; subtract border at end
sbc r19, r21
andi r17, 3 ; only 2 bits pack mode
cpi r17, WIDGET_PACK_END
breq widgetPack_end
cpi r17, WIDGET_PACK_CENTER
breq widgetPack_center
rjmp widgetPack_ret ; begin/filled, align at begin
widgetPack_end:
sub r18, r12
sbc r19, r13
add r20, r18
adc r21, r19
rjmp widgetPack_ret
widgetPack_center:
sub r18, r12
sbc r19, r13
lsr r19
ror r18
add r20, r18
adc r21, r19
rjmp widgetPack_ret
widgetPack_ret:
ret
; @end
@@ -1052,7 +1055,7 @@ widgetCalcAbsPosAndBorders:
Widget_DefaultSignalmap:
; header
.dw Object_DefaultSignalmap ; next table to use
.dw Object_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDraw), HIGH(Widget_OnDraw)
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(Widget_OnLayout), HIGH(Widget_OnLayout)