771 lines
22 KiB
NASM
771 lines
22 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2025 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
; ***************************************************************************
|
|
; defs
|
|
|
|
.equ WID_WIDGET_INTER_BORDER = 2
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine WID_Widget_new @global
|
|
;
|
|
; @param Y pointer to window SRAM
|
|
; @param X pointer to parent
|
|
; @param r18 WID_OFFS_OPTIONS1
|
|
; @param r19 WID_OFFS_OPTIONS2
|
|
|
|
WID_Widget_Init:
|
|
push r18
|
|
push r19
|
|
push xl
|
|
push xh
|
|
ldi zl, LOW(WID_Widget_Handler)
|
|
ldi zh, HIGH(WID_Widget_Handler)
|
|
clr r17
|
|
rcall OBJ_Init
|
|
pop xh
|
|
pop xl
|
|
pop r19
|
|
pop r18
|
|
std Y+WID_OFFS_OPTIONS1, r18
|
|
std Y+WID_OFFS_OPTIONS2, r19
|
|
mov r16, xl
|
|
or r16, xh
|
|
breq WID_Widget_noParent
|
|
; copy defaults from parent
|
|
adiw xh:xl, WID_OFFS_BG_COL_LO
|
|
ld r16, X+ ; WID_OFFS_BG_COL_LO
|
|
std Y+WID_OFFS_BG_COL_LO, r16
|
|
ld r16, X+ ; WID_OFFS_BG_COL_HI
|
|
std Y+WID_OFFS_BG_COL_HI, r16
|
|
ld r16, X+ ; WID_OFFS_FG_COL_LO
|
|
std Y+WID_OFFS_FG_COL_LO, r16
|
|
ld r16, X+ ; WID_OFFS_FG_COL_HI
|
|
std Y+WID_OFFS_FG_COL_HI, r16
|
|
ld r16, X+ ; WID_OFFS_FONT_LO
|
|
std Y+WID_OFFS_FONT_LO, r16
|
|
ld r16, X+ ; WID_OFFS_FONT_HI
|
|
std Y+WID_OFFS_FONT_HI, r16
|
|
rjmp WID_Widget_end
|
|
WID_Widget_noParent: ; preset without parent
|
|
clr r16
|
|
std Y+WID_OFFS_FONT_LO, r16
|
|
std Y+WID_OFFS_FONT_HI, r16
|
|
|
|
std Y+WID_OFFS_FG_COL_LO, r16 ; foreground black
|
|
std Y+WID_OFFS_FG_COL_HI, r16
|
|
dec r16
|
|
std Y+WID_OFFS_BG_COL_LO, r16 ; background white
|
|
std Y+WID_OFFS_BG_COL_HI, r16
|
|
|
|
ldi r16, 2 ; default borders
|
|
std Y+WID_OFFS_BORDER_TOP, r16
|
|
std Y+WID_OFFS_BORDER_BOT, r16
|
|
std Y+WID_OFFS_BORDER_LEFT, r16
|
|
std Y+WID_OFFS_BORDER_RIGHT, r16
|
|
WID_Widget_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine WID_Widget_Handler
|
|
;
|
|
; Signal handler for an object. A signal can have up to 3 parameters
|
|
; conveyed in registers R18, R19 and X.
|
|
;
|
|
; @param Y pointer to object SRAM
|
|
; @param r16 signal
|
|
; @param R18 1st param
|
|
; @param R19 2nd param
|
|
; @param X 3rd param
|
|
; @clobbers any, !Y
|
|
|
|
WID_Widget_Handler:
|
|
cpi r16, WID_SIGNAL_GETMINWIDTH
|
|
breq WID_Widget_Handler_getMinWidth
|
|
cpi r16, WID_SIGNAL_GETMINHEIGHT
|
|
breq WID_Widget_Handler_getMinHeight
|
|
cpi r16, WID_SIGNAL_LAYOUT
|
|
breq WID_Widget_Handler_layout
|
|
cpi r16, WID_SIGNAL_DRAW
|
|
breq WID_Widget_Handler_draw
|
|
; for now just forward signal to all children
|
|
WID_Widget_Handler_forward:
|
|
rcall OBJ_ForwardSignalToChildren
|
|
ret
|
|
WID_Widget_Handler_getMinWidth:
|
|
rjmp widgetGetMinWidth
|
|
WID_Widget_Handler_getMinHeight:
|
|
rjmp widgetGetMinHeight
|
|
WID_Widget_Handler_layout:
|
|
rjmp widgetLayout
|
|
WID_Widget_Handler_draw:
|
|
rjmp wDraw
|
|
; @end
|
|
|
|
|
|
|
|
|
|
wDraw:
|
|
ldd r16, Y+OBJ_OFFS_OPTIONS
|
|
sbrs r16, WID_OPTIONS0_BIT_VISIBLE ; only draw visible widgets
|
|
rjmp wDraw_ret
|
|
cbr r16, (1<<WID_OPTIONS0_BIT_DIRTY)
|
|
std Y+OBJ_OFFS_OPTIONS, r16
|
|
|
|
; fill window background
|
|
ldd r2, Y+WID_OFFS_BG_COL_LO
|
|
ldd r3, Y+WID_OFFS_BG_COL_HI
|
|
ldd r4, Y+WID_OFFS_ABS_X_LO
|
|
ldd r5, Y+WID_OFFS_ABS_X_HI
|
|
ldd r6, Y+WID_OFFS_ABS_Y_LO
|
|
ldd r7, Y+WID_OFFS_ABS_Y_HI
|
|
ldd r8, Y+WID_OFFS_WIDTH_LO
|
|
ldd r9, Y+WID_OFFS_WIDTH_HI
|
|
ldd r10, Y+WID_OFFS_HEIGHT_LO
|
|
ldd r11, Y+WID_OFFS_HEIGHT_HI
|
|
bigcall ILI9341_FillRect
|
|
wDraw_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
widgetLayout:
|
|
rjmp wVLayout
|
|
|
|
|
|
|
|
wVLayout:
|
|
rcall wSetChildrenWidthsFromMinWidths
|
|
rcall wSetChildrenHeightsFromMinHeights
|
|
|
|
; count number of expandable children
|
|
ldi r16, (1<<WID_OPTIONS1_BIT_STRETCH_Y) ; value
|
|
ldi r17, (1<<WID_OPTIONS1_BIT_STRETCH_Y) ; mask
|
|
rcall widgetCountVisibleChildrenWithOptions1 ; r18=number of matching visible children (r24, r25, X)
|
|
tst r18
|
|
breq wVLayout_Ydone ; no expandable children, nothing to distribute
|
|
; determine full height needed by all children
|
|
push r18 ; number of visible expandable child widgets
|
|
clr r17 ; mask=0 -> count all visible children
|
|
rcall wGetSumOfMatchingVisibleChildrenHeights ; r19:r18=sum of all children heights
|
|
pop r22
|
|
clr r23 ; r23:r22=number of visible expandable children
|
|
; calculate number of bytes to add to each expandable child widget
|
|
ldd r20, Y+WID_OFFS_HEIGHT_LO ; total height
|
|
ldd r21, Y+WID_OFFS_HEIGHT_HI
|
|
clr r16
|
|
ldd r17, Y+WID_OFFS_BORDER_TOP ; subtract top border
|
|
sub r20, r17
|
|
sbc r21, r16
|
|
brcs wVLayout_heightTooSmall ; jmp if too small
|
|
ldd r17, Y+WID_OFFS_BORDER_BOT ; subtract bottom border
|
|
sub r20, r17
|
|
sbc r21, r16
|
|
brcs wVLayout_heightTooSmall ; jmp if too small
|
|
|
|
sub r20, r18 ; r21:r20 = HEIGHT-SUM_OF_VIS_CHILDREN_HEIGHTS
|
|
sbc r21, r19
|
|
brcc wVLayout_heightTooSmall
|
|
breq wVLayout_yDone ; nothing to distribute
|
|
bigcall Utils_Divu16_16_16 ; r17:r16 = r21:r20 / r23:r22
|
|
; add additional pixel to heights of expandable child widgets
|
|
rcall wAddToHeightsOfExpandableVisibleChildren
|
|
|
|
wVLayout_yDone:
|
|
rcall wSetRelYFromHeightInVisibleChildren
|
|
rcall wAlignChildrenHorizontally
|
|
; rcall wSetAbsoluteCoords call in GUI loop after calling layout on all widgets
|
|
wVLayout_heightTooSmall:
|
|
; TODO: how to handle this case?
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
wSetAbsoluteCoords:
|
|
push yl
|
|
push yh
|
|
wSetAbsoluteCoords_loop:
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq wSetAbsoluteCoords_nextSibling
|
|
push yl
|
|
push yh
|
|
bigcall Tree_GetParentObject
|
|
clr r18
|
|
clr r19
|
|
clr r20
|
|
clr r21
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq wSetAbsoluteCoords_r1820set
|
|
mov yl, xl
|
|
mov yh, xh
|
|
ldd r18, Y+WID_OFFS_ABS_X_LO
|
|
ldd r19, Y+WID_OFFS_ABS_X_HI
|
|
ldd r20, Y+WID_OFFS_ABS_Y_LO
|
|
ldd r21, Y+WID_OFFS_ABS_Y_HI
|
|
wSetAbsoluteCoords_r1820set:
|
|
pop yh
|
|
pop yl
|
|
; handle X
|
|
ldd r16, Y+WID_OFFS_REL_X_LO
|
|
ldd r17, Y+WID_OFFS_REL_X_HI
|
|
add r16, r18
|
|
adc r17, r19
|
|
std Y+WID_OFFS_ABS_X_LO, r16
|
|
std Y+WID_OFFS_ABS_X_HI, r17
|
|
; handle Y
|
|
ldd r16, Y+WID_OFFS_REL_Y_LO
|
|
ldd r17, Y+WID_OFFS_REL_Y_HI
|
|
add r16, r20
|
|
adc r17, r21
|
|
std Y+WID_OFFS_ABS_Y_LO, r16
|
|
std Y+WID_OFFS_ABS_Y_HI, r17
|
|
bigcall Tree_GetObjectBelow
|
|
rjmp wSetAbsoluteCoords_loopEnd
|
|
wSetAbsoluteCoords_nextSibling:
|
|
bigcall Tree_GetNextSibling
|
|
wSetAbsoluteCoords_loopEnd:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq wSetAbsoluteCoords_end
|
|
mov yl, xl
|
|
mov yh, xh
|
|
rjmp wSetAbsoluteCoords_loop
|
|
wSetAbsoluteCoords_end:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wAlignChildrenHorizontally
|
|
;
|
|
; Horizontally align children within the width of the parent widget.
|
|
; Only changes Y+WID_OFFS_REL_X_LO/HI.
|
|
;
|
|
; @param Y pointer to object SRAM
|
|
; @clobbers r16, r17, r18, r19, r24, r25
|
|
|
|
wAlignChildrenHorizontally:
|
|
push yl
|
|
push yh
|
|
ldd r24, Y+WID_OFFS_WIDTH_LO ; parent width
|
|
ldd r25, Y+WID_OFFS_WIDTH_HI
|
|
ldd r19, Y+WID_OFFS_BORDER_LEFT ; subtract left border
|
|
mov r16, r19
|
|
clr r17
|
|
sub r24, r16
|
|
sbc r25, r17
|
|
ldd r16, Y+WID_OFFS_BORDER_RIGHT ; subtract right border
|
|
sub r24, r16
|
|
sbc r25, r17 ; r25:r24=parent width minus lateral borders, r19=left border
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
wAlignChildrenHorizontally_loop:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq wAlignChildrenHorizontally_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq wAlignChildrenHorizontally_loopNext
|
|
push r24
|
|
push r25
|
|
push r19
|
|
rcall wAlignHorizontally
|
|
pop r19
|
|
add r24, r19
|
|
adc r25, r19
|
|
sub r25, r19
|
|
std Y+WID_OFFS_REL_X_LO, r24
|
|
std Y+WID_OFFS_REL_X_HI, r25
|
|
pop r25
|
|
pop r24
|
|
wAlignChildrenHorizontally_loopNext:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wAlignChildrenHorizontally_loop
|
|
wAlignChildrenHorizontally_loopEnd:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wAlignHorizontally
|
|
;
|
|
; @param r25:r24 parent width minus lateral borders
|
|
; @return r25:r24 proposed X position relative to parent
|
|
; @clobbers r16, r17
|
|
|
|
wAlignHorizontally:
|
|
ldd r16, Y+WID_OFFS_OPTIONS1
|
|
sbrc r16, WID_OPTIONS1_BIT_STRETCH_X
|
|
rjmp wAlignHorizontally_stretch
|
|
andi r16, (WID_OPTIONS1_BIT_HALIGN0 | WID_OPTIONS1_BIT_HALIGN1)
|
|
cpi r16, (0<<WID_OPTIONS1_BIT_HALIGN1) | (0<<WID_OPTIONS1_BIT_HALIGN0)
|
|
breq wAlignHorizontally_left
|
|
cpi r16, (0<<WID_OPTIONS1_BIT_HALIGN1) | (1<<WID_OPTIONS1_BIT_HALIGN0)
|
|
breq wAlignHorizontally_right
|
|
wAlignHorizontally_center:
|
|
ldd r16, Y+WID_OFFS_WIDTH_LO
|
|
ldd r17, Y+WID_OFFS_WIDTH_HI
|
|
sub r24, r16
|
|
sbc r25, r17
|
|
lsr r25
|
|
ror r24
|
|
ret
|
|
wAlignHorizontally_left:
|
|
clr r24
|
|
clr r25
|
|
ret
|
|
wAlignHorizontally_right:
|
|
ldd r16, Y+WID_OFFS_WIDTH_LO
|
|
ldd r17, Y+WID_OFFS_WIDTH_HI
|
|
sub r24, r16
|
|
sbc r25, r17
|
|
wAlignHorizontally_stretch:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wSetRelYFromHeightInVisibleChildren
|
|
;
|
|
; @param Y pointer to object SRAM
|
|
; @clobbers r17, r18, r19, r24, r25, X
|
|
|
|
wSetRelYFromHeightInVisibleChildren:
|
|
push yl
|
|
push yh
|
|
ldd r24, Y+WID_OFFS_BORDER_TOP
|
|
clr r25
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
wSetRelYFromHeightInVisibleChildren_loop:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq wSetRelYFromHeightInVisibleChildren_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq wSetRelYFromHeightInVisibleChildren_loopNext
|
|
std Y+WID_OFFS_REL_Y_LO, r24
|
|
std Y+WID_OFFS_REL_Y_HI, r25
|
|
ldd r18, Y+WID_OFFS_WIDTH_LO
|
|
ldd r19, Y+WID_OFFS_WIDTH_HI
|
|
add r24, r18 ; TODO: handle carry later
|
|
adc r25, r19
|
|
adiw r25:r24, WID_WIDGET_INTER_BORDER
|
|
wSetRelYFromHeightInVisibleChildren_loopNext:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wSetRelYFromHeightInVisibleChildren_loop
|
|
wSetRelYFromHeightInVisibleChildren_loopEnd:
|
|
mov r18, r24
|
|
mov r19, r25
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetGetMinWidth
|
|
;
|
|
; @return r19:r18 minimum width of widget
|
|
; @clobbers any, !Y
|
|
|
|
widgetGetMinWidth:
|
|
ldi r16, WID_SIGNAL_GETMINWIDTH
|
|
rjmp widgetGetLargestChildMinSize
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetGetMinHeight
|
|
;
|
|
; @return r19:r18 minimum height of widget
|
|
; @clobbers any, !Y
|
|
|
|
widgetGetMinHeight:
|
|
ldi r16, WID_SIGNAL_GETMINHEIGHT
|
|
rjmp widgetSumOfChildrenMinSize
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetSumOfChildrenMinSize
|
|
;
|
|
; @param r16 signal to send (WID_SIGNAL_GETMINWIDTH, WID_SIGNAL_GETMINHEIGHT)
|
|
; @return r19:r18 minimum width or height of widget
|
|
; @clobbers any, !Y
|
|
|
|
widgetSumOfChildrenMinSize:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
clr r24
|
|
clr r25
|
|
widgetSumOfChildrenMinSize_loop:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq widgetSumOfChildrenMinSize_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq widgetSumOfChildrenMinSize_loopNext
|
|
push r16
|
|
push r24
|
|
push r25
|
|
ldi r18, 1 ; default value for when the signal is not handled
|
|
ldi r19, 0 ; default value for when the signal is not handled
|
|
rcall OBJ_Handler ; ask child for its minimum size
|
|
pop r25
|
|
pop r24
|
|
pop r16
|
|
add r24, r18 ; TODO: handle carry later
|
|
adc r25, r19
|
|
adiw r25:r24, WID_WIDGET_INTER_BORDER
|
|
widgetSumOfChildrenMinSize_loopNext:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp widgetSumOfChildrenMinSize_loop
|
|
widgetSumOfChildrenMinSize_loopEnd:
|
|
mov r18, r24
|
|
mov r19, r25
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetGetLargestChildMinSize
|
|
;
|
|
; @param r16 signal to send (WID_SIGNAL_GETMINWIDTH, WID_SIGNAL_GETMINHEIGHT)
|
|
; @return r19:r18 minimum width or height of widget
|
|
; @clobbers any, !Y
|
|
|
|
widgetGetLargestChildMinSize:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
clr r24
|
|
clr r25
|
|
widgetGetLargestChildMinSize_loop:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq widgetGetLargestChildMinSize_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq widgetGetLargestChildMinSize_loopNext
|
|
push r16
|
|
push r24
|
|
push r25
|
|
ldi r18, 1 ; default value for when the signal is not handled
|
|
ldi r19, 0 ; default value for when the signal is not handled
|
|
rcall OBJ_Handler ; ask child for its minimum size
|
|
pop r25
|
|
pop r24
|
|
pop r16
|
|
sub r24, r18
|
|
sbc r25, r19
|
|
add r24, r18
|
|
adc r25, r19
|
|
brcc widgetGetLargestChildMinSize_loopNext
|
|
mov r24, r18
|
|
mov r25, r19
|
|
widgetGetLargestChildMinSize_loopNext:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp widgetGetLargestChildMinSize_loop
|
|
widgetGetLargestChildMinSize_loopEnd:
|
|
mov r18, r24
|
|
mov r19, r25
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetCountVisibleChildrenWithOptions1
|
|
;
|
|
; Count visible direct children with a matching WID_OFFS_OPTIONS1 field.
|
|
;
|
|
; @param r16 option1 value combination wanted
|
|
; @param r17 option1 mask of bits to match
|
|
; @return r18 number of matching direct children
|
|
; @clobbers r18, r24, r25, X
|
|
|
|
widgetCountVisibleChildrenWithOptions1:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
clr r24
|
|
widgetCountVisibleChildrenWithOptions1_loop:
|
|
mov r25, xl
|
|
or r25, xh
|
|
breq widgetCountVisibleChildrenWithOptions1_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq widgetCountVisibleChildrenWithOptions1_next
|
|
ldd r18, Y+WID_OFFS_OPTIONS1
|
|
eor r18, r17
|
|
and r18, r16
|
|
brne widgetCountVisibleChildrenWithOptions1_next
|
|
inc r24
|
|
widgetCountVisibleChildrenWithOptions1_next:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp widgetSumOfChildrenMinSize_loop
|
|
widgetCountVisibleChildrenWithOptions1_loopEnd:
|
|
mov r18, r24
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wGetSumOfMatchingVisibleChildrenHeights
|
|
;
|
|
; Add heights of all matching visible children.
|
|
;
|
|
; @param r16 option1 value combination wanted
|
|
; @param r17 option1 mask of bits to match
|
|
; @return r19:r18 sum of widths of all visible direct children
|
|
; @clobbers r24, r25, X
|
|
|
|
wGetSumOfMatchingVisibleChildrenHeights:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
clr r24
|
|
clr r25
|
|
wGetSumOfMatchingVisibleChildrenHeights_loop:
|
|
mov r18, xl
|
|
or r18, xh
|
|
breq wGetSumOfMatchingVisibleChildrenHeights_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq wGetSumOfMatchingVisibleChildrenHeights_next
|
|
ldd r18, Y+WID_OFFS_OPTIONS1
|
|
eor r18, r17
|
|
and r18, r16
|
|
brne wGetSumOfMatchingVisibleChildrenHeights_next
|
|
ldd r18, Y+WID_OFFS_HEIGHT_LO
|
|
ldd r19, Y+WID_OFFS_HEIGHT_HI
|
|
add r24, r18
|
|
adc r25, r19
|
|
wGetSumOfMatchingVisibleChildrenHeights_next:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wGetSumOfMatchingVisibleChildrenHeights_loop
|
|
wGetSumOfMatchingVisibleChildrenHeights_loopEnd:
|
|
mov r18, r24
|
|
mov r19, r25
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wAddToWidthsOfExpandableVisibleChildren
|
|
;
|
|
; @param Y = pointer to widget data in SRAM
|
|
; @param r17:r16 number to add to the widths of all visible X-expandable children
|
|
; @clobbers r18, r19, X
|
|
|
|
wAddToWidthsOfExpandableVisibleChildren:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
wAddToWidthsOfExpandableVisibleChildren_loop:
|
|
mov r18, xl
|
|
or r18, xh
|
|
breq wAddToWidthsOfExpandableVisibleChildren_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq wAddToWidthsOfExpandableVisibleChildren_next
|
|
ldd r18, Y+WID_OFFS_OPTIONS1
|
|
andi r18, WID_OPTIONS1_BIT_STRETCH_X
|
|
breq wAddToWidthsOfExpandableVisibleChildren_next
|
|
ldd r18, Y+WID_OFFS_WIDTH_LO
|
|
ldd r19, Y+WID_OFFS_WIDTH_HI
|
|
add r18, r16
|
|
adc r19, r17
|
|
std Y+WID_OFFS_WIDTH_LO, r18
|
|
std Y+WID_OFFS_WIDTH_HI, r19
|
|
wAddToWidthsOfExpandableVisibleChildren_next:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wAddToWidthsOfExpandableVisibleChildren_loop
|
|
wAddToWidthsOfExpandableVisibleChildren_loopEnd:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wAddToHeightsOfExpandableVisibleChildren
|
|
;
|
|
; @param Y = pointer to widget data in SRAM
|
|
; @param r17:r16 number to add to the heights of all visible Y-expandable children
|
|
; @clobbers r18, r19, X
|
|
|
|
wAddToHeightsOfExpandableVisibleChildren:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
wAddToHeightsOfExpandableVisibleChildren_loop:
|
|
mov r18, xl
|
|
or r18, xh
|
|
breq wAddToHeightsOfExpandableVisibleChildren_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
andi r18, WID_OPTIONS0_BIT_VISIBLE
|
|
breq wAddToHeightsOfExpandableVisibleChildren_next
|
|
ldd r18, Y+WID_OFFS_OPTIONS1
|
|
andi r18, WID_OPTIONS1_BIT_STRETCH_Y
|
|
breq wAddToHeightsOfExpandableVisibleChildren_next
|
|
ldd r18, Y+WID_OFFS_HEIGHT_LO
|
|
ldd r19, Y+WID_OFFS_HEIGHT_HI
|
|
add r18, r16
|
|
adc r19, r17
|
|
std Y+WID_OFFS_HEIGHT_LO, r18
|
|
std Y+WID_OFFS_HEIGHT_HI, r19
|
|
wAddToHeightsOfExpandableVisibleChildren_next:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wAddToHeightsOfExpandableVisibleChildren_loop
|
|
wAddToHeightsOfExpandableVisibleChildren_loopEnd:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wSetChildrenWidthsFromMinWidths
|
|
;
|
|
; @clobbers any, !Y
|
|
|
|
wSetChildrenWidthsFromMinWidths:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
wSetChildrenWidthsFromMinWidths_loop:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq wSetChildrenWidthsFromMinWidths_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
sbrs r18, WID_OPTIONS0_BIT_VISIBLE
|
|
rjmp wSetChildrenWidthsFromMinWidths_loopNext ; jump if not visible
|
|
sbrc r18, WID_OPTIONS1_BIT_FIXED_WIDTH
|
|
rjmp wSetChildrenWidthsFromMinWidths_loopNext ; jump if fixed width
|
|
ldi r16, WID_SIGNAL_GETMINWIDTH
|
|
ldi r18, 1 ; default value for when the signal is not handled
|
|
ldi r19, 0 ; default value for when the signal is not handled
|
|
rcall OBJ_Handler ; ask child for its minimum size
|
|
std Y+WID_OFFS_WIDTH_LO, r18
|
|
std Y+WID_OFFS_WIDTH_HI, r19
|
|
wSetChildrenWidthsFromMinWidths_loopNext:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wSetChildrenWidthsFromMinWidths_loop
|
|
wSetChildrenWidthsFromMinWidths_loopEnd:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine wSetChildrenHeightsFromMinHeights
|
|
;
|
|
; @clobbers any, !Y
|
|
|
|
wSetChildrenHeightsFromMinHeights:
|
|
push yl
|
|
push yh
|
|
rcall Tree_GetFirstChildObject ; (none)
|
|
wSetChildrenHeightsFromMinHeights_loop:
|
|
mov r17, xl
|
|
or r17, xh
|
|
breq wSetChildrenHeightsFromMinHeights_loopEnd
|
|
mov yl, xl
|
|
mov yh, yl
|
|
ldd r18, Y+OBJ_OFFS_OPTIONS
|
|
sbrs r18, WID_OPTIONS0_BIT_VISIBLE
|
|
rjmp wSetChildrenHeightsFromMinHeights_loopNext ; jump if not visible
|
|
sbrc r18, WID_OPTIONS1_BIT_FIXED_HEIGHT
|
|
rjmp wSetChildrenHeightsFromMinHeights_loopNext ; jump if fixed height
|
|
ldi r16, WID_SIGNAL_GETMINHEIGHT
|
|
ldi r18, 1 ; default value for when the signal is not handled
|
|
ldi r19, 0 ; default value for when the signal is not handled
|
|
rcall OBJ_Handler ; ask child for its minimum size
|
|
std Y+WID_OFFS_HEIGHT_LO, r18
|
|
std Y+WID_OFFS_HEIGHT_HI, r19
|
|
wSetChildrenHeightsFromMinHeights_loopNext:
|
|
rcall Tree_GetNextSibling ; (none)
|
|
rjmp wSetChildrenHeightsFromMinHeights_loop
|
|
wSetChildrenHeightsFromMinHeights_loopEnd:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|