1560 lines
40 KiB
NASM
1560 lines
40 KiB
NASM
; ***************************************************************************
|
|
; 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_WIDGET_ASM
|
|
#define AQH_AVR_GUI2_WIDGET_ASM
|
|
|
|
|
|
; ***************************************************************************
|
|
; defines
|
|
|
|
; Widget in flash
|
|
|
|
.equ WIDGET_OFFS_BEGIN = OBJECT_SIZE
|
|
.equ WIDGET_OFFS_X_LO = WIDGET_OFFS_BEGIN+0
|
|
.equ WIDGET_OFFS_X_HI = WIDGET_OFFS_BEGIN+1
|
|
.equ WIDGET_OFFS_Y_LO = WIDGET_OFFS_BEGIN+2
|
|
.equ WIDGET_OFFS_Y_HI = WIDGET_OFFS_BEGIN+3
|
|
.equ WIDGET_OFFS_WIDTH_LO = WIDGET_OFFS_BEGIN+4
|
|
.equ WIDGET_OFFS_WIDTH_HI = WIDGET_OFFS_BEGIN+5
|
|
.equ WIDGET_OFFS_HEIGHT_LO = WIDGET_OFFS_BEGIN+6
|
|
.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_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
|
|
.equ WIDGET_STYLE_OFFS_BACKCOL_NORM = 2
|
|
.equ WIDGET_STYLE_OFFS_BORDERCOL_NORM = 4
|
|
.equ WIDGET_STYLE_OFFS_SHADOWCOL_NORM = 6
|
|
.equ WIDGET_STYLE_OFFS_FRONTCOL_ACTIVATED = 8
|
|
.equ WIDGET_STYLE_OFFS_BACKCOL_ACTIVATED = 10
|
|
.equ WIDGET_STYLE_OFFS_BORDERCOL_ACTIVATED = 12
|
|
.equ WIDGET_STYLE_OFFS_SHADOWCOL_ACTIVATED = 14
|
|
.equ WIDGET_STYLE_OFFS_OUTERBORDERSIZE = 16
|
|
.equ WIDGET_STYLE_OFFS_SPACING = 17
|
|
.equ WIDGET_STYLE_OFFS_FONT_LO = 18
|
|
.equ WIDGET_STYLE_OFFS_FONT_HI = 19
|
|
.equ WIDGET_STYLE_OFFS_CHARWIDTH = 20
|
|
.equ WIDGET_STYLE_OFFS_CHARHEIGHT = 21
|
|
.equ WIDGET_STYLE_SIZE = 22
|
|
|
|
; 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 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_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
|
|
.equ WIDGET_FLAGS_TOUCH_BIT = 6
|
|
.equ WIDGET_FLAGS_DIRTY_BIT = 5
|
|
.equ WIDGET_FLAGS_LAYOUT_BIT = 4
|
|
.equ WIDGET_FLAGS_ACTIVATED_BIT = 3
|
|
.equ WIDGET_FLAGS_SELECTED_BIT = 2
|
|
|
|
; SDRAM data for signal WIDGET_SIGNAL_TOUCH
|
|
.equ WIDGET_TOUCH_OFFS_X_LO = 0
|
|
.equ WIDGET_TOUCH_OFFS_X_HI = 1
|
|
.equ WIDGET_TOUCH_OFFS_Y_LO = 2
|
|
.equ WIDGET_TOUCH_OFFS_Y_HI = 3
|
|
.equ WIDGET_TOUCH_OFFS_STATE = 4
|
|
.equ WIDGET_TOUCH_SIZE = 5
|
|
|
|
; signals
|
|
.equ WIDGET_SIGNAL_SHOW = OBJECT_SIGNAL_NEXTFREE+0
|
|
.equ WIDGET_SIGNAL_HIDE = OBJECT_SIGNAL_NEXTFREE+1
|
|
.equ WIDGET_SIGNAL_LAYOUT = OBJECT_SIGNAL_NEXTFREE+2
|
|
.equ WIDGET_SIGNAL_DRAW = OBJECT_SIGNAL_NEXTFREE+3
|
|
.equ WIDGET_SIGNAL_TOUCH = OBJECT_SIGNAL_NEXTFREE+4
|
|
.equ WIDGET_SIGNAL_COMMAND = OBJECT_SIGNAL_NEXTFREE+5
|
|
.equ WIDGET_SIGNAL_CHANGE = OBJECT_SIGNAL_NEXTFREE+6
|
|
.equ WIDGET_SIGNAL_SETVALUE = OBJECT_SIGNAL_NEXTFREE+7
|
|
.equ WIDGET_SIGNAL_GETVALUE = OBJECT_SIGNAL_NEXTFREE+8
|
|
.equ WIDGET_SIGNAL_KEEPALIVE = OBJECT_SIGNAL_NEXTFREE+9
|
|
.equ WIDGET_SIGNAL_TOUCH_BEGIN = OBJECT_SIGNAL_NEXTFREE+10
|
|
.equ WIDGET_SIGNAL_TOUCH_MOVE = OBJECT_SIGNAL_NEXTFREE+11
|
|
.equ WIDGET_SIGNAL_TOUCH_END = OBJECT_SIGNAL_NEXTFREE+12
|
|
.equ WIDGET_SIGNAL_DIALOG_END = OBJECT_SIGNAL_NEXTFREE+13
|
|
.equ WIDGET_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+14
|
|
|
|
; 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
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.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
|
|
; @param r17 value for WIDGET_OFFS_PACK
|
|
; @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
|
|
;
|
|
; @param Y address of object in SDRAM
|
|
; @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
|
|
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
|
|
ldi r16, HIGH(Widget_DefaultSignalmap*2)
|
|
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
|
|
|
|
; set style
|
|
mov r16, xl
|
|
or r16, xh
|
|
breq Widget_Init_setDefaultStyle
|
|
; use style from parent
|
|
adiw xh:xl, WIDGET_OFFS_STYLE_LO
|
|
ld r16, X+
|
|
std Y+WIDGET_OFFS_STYLE_LO, r16
|
|
ld r16, X
|
|
std Y+WIDGET_OFFS_STYLE_HI, r16
|
|
sbiw xh:xl, (WIDGET_OFFS_STYLE_LO+1)
|
|
rjmp Widget_Init_setDefaultSize
|
|
|
|
Widget_Init_setDefaultStyle:
|
|
ldi r16, LOW(Widget_DefaultStyle*2)
|
|
std Y+WIDGET_OFFS_STYLE_LO, r16
|
|
ldi r16, HIGH(Widget_DefaultStyle*2)
|
|
std Y+WIDGET_OFFS_STYLE_HI, r16
|
|
|
|
Widget_Init_setDefaultSize:
|
|
; initial size: 1x1 px
|
|
ldi r16, 1
|
|
clr r17
|
|
std Y+WIDGET_OFFS_WIDTH_LO, r16
|
|
std Y+WIDGET_OFFS_WIDTH_HI, r17
|
|
std Y+WIDGET_OFFS_HEIGHT_LO, r16
|
|
std Y+WIDGET_OFFS_HEIGHT_HI, r17
|
|
|
|
; add to parent (if any)
|
|
mov r16, xl
|
|
or r16, xh
|
|
breq Widget_Init_ret
|
|
bigcall OBJ_AddChild ; (r18, r19)
|
|
; parent needs to layout with the new child
|
|
adiw xh:xl, OBJECT_OFFS_FLAGS
|
|
ld r16, X
|
|
sbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
|
|
sbiw xh:xl, OBJECT_OFFS_FLAGS
|
|
|
|
; preset flags
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT) | (1<<WIDGET_FLAGS_LAYOUT_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
|
|
Widget_Init_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Fini @global
|
|
;
|
|
; @param Y address of object in SDRAM
|
|
; @clobbers none
|
|
|
|
Widget_Fini:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Resize @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param r9:r8 W
|
|
; @param r11:r10 H
|
|
; @clobbers r16
|
|
|
|
Widget_Resize:
|
|
std Y+WIDGET_OFFS_WIDTH_LO, r8
|
|
std Y+WIDGET_OFFS_WIDTH_HI, r9
|
|
std Y+WIDGET_OFFS_HEIGHT_LO, r10
|
|
std Y+WIDGET_OFFS_HEIGHT_HI, r11
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
ori r16, (1<<WIDGET_FLAGS_LAYOUT_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Move @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param r5:r4 X0
|
|
; @param r7:r6 Y0
|
|
; @clobbers r16
|
|
|
|
Widget_Move:
|
|
std Y+WIDGET_OFFS_X_LO, r4
|
|
std Y+WIDGET_OFFS_X_HI, r5
|
|
std Y+WIDGET_OFFS_Y_LO, r6
|
|
std Y+WIDGET_OFFS_Y_HI, r7
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
ori r16, (1<<WIDGET_FLAGS_LAYOUT_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_SetFullScreen @global
|
|
;
|
|
; @param Y address of widget
|
|
; @clobbers r16
|
|
|
|
Widget_SetFullScreen:
|
|
; set pos and size of widget to display size
|
|
clr r16
|
|
std Y+WIDGET_OFFS_X_LO, r16
|
|
std Y+WIDGET_OFFS_X_HI, r16
|
|
std Y+WIDGET_OFFS_Y_LO, r16
|
|
std Y+WIDGET_OFFS_Y_HI, r16
|
|
ldi r16, LOW(DISPLAY_WIDTH)
|
|
std Y+WIDGET_OFFS_WIDTH_LO, r16
|
|
ldi r16, HIGH(DISPLAY_WIDTH)
|
|
std Y+WIDGET_OFFS_WIDTH_HI, r16
|
|
ldi r16, LOW(DISPLAY_HEIGHT)
|
|
std Y+WIDGET_OFFS_HEIGHT_LO, r16
|
|
ldi r16, HIGH(DISPLAY_HEIGHT)
|
|
std Y+WIDGET_OFFS_HEIGHT_HI, r16
|
|
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
ori r16, (1<<WIDGET_FLAGS_LAYOUT_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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_SetValue @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param r17 value id
|
|
; @param X value to set
|
|
; @return CFLAG set if value set, cleared on error
|
|
; @clobbers any, !Y
|
|
|
|
Widget_SetValue:
|
|
ldi r16, WIDGET_SIGNAL_SETVALUE
|
|
bigcall OBJ_HandleSignal
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_IsPointInRect @global
|
|
;
|
|
; @param R19:R18 check X
|
|
; @param R21:R20 check Y
|
|
; @param R5:R4 widget X
|
|
; @param R7:R6 widget Y
|
|
; @param R9:R8 widget width
|
|
; @param R11:R10 widget height
|
|
; @return CFLAG set if inside rect, cleared otherwise
|
|
; @clobbers R16, R17
|
|
|
|
Widget_IsPointInRect:
|
|
; check X
|
|
mov r16, r18 ; checkX-widgetX
|
|
mov r17, r19
|
|
sub r16, r4
|
|
sbc r17, r5
|
|
brcs Widget_IsPointInRect_no ; jmp if left of widget
|
|
sub r16, r8 ; sub width
|
|
sbc r17, r9
|
|
brcc Widget_IsPointInRect_no ; jmp if right of widget
|
|
|
|
mov r16, r20 ; checkY-widgetY
|
|
mov r17, r21
|
|
sub r16, r6
|
|
sbc r17, r7
|
|
brcs Widget_IsPointInRect_no ; jmp if above widget
|
|
sub r16, r10 ; sub height
|
|
sbc r17, r11
|
|
brcc Widget_IsPointInRect_no ; jmp if below widget
|
|
|
|
sec ; is inside rect
|
|
rjmp Widget_IsPointInRect_ret
|
|
|
|
Widget_IsPointInRect_no:
|
|
clc
|
|
Widget_IsPointInRect_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GetApp @global
|
|
;
|
|
; @param Y address of object
|
|
; @return R19:R18 byte address pointer to GuiApp
|
|
; @clobbers none
|
|
|
|
Widget_GetApp:
|
|
push yl
|
|
push yh
|
|
bigcall OBJ_GetRootToY ; (r18, r19)
|
|
bigcall RootWindow_GetApp ; (none)
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GrabTouchEvents @global
|
|
;
|
|
; Let this widget grab touch events until ungrabbed.
|
|
;
|
|
; @param Y address of object
|
|
; @param X byte address of widget grabbing touch events
|
|
; @return CFLAG set if grabbed, cleared on error
|
|
; @clobbers r16, r17, r18, r19
|
|
|
|
Widget_GrabTouchEvents:
|
|
rcall Widget_GetApp ; r19:r18=guiapp
|
|
push yl
|
|
push yh
|
|
push xl
|
|
push xh
|
|
mov xl, yl
|
|
mov xh, yh
|
|
mov yl, r18
|
|
mov yh, r19
|
|
bigcall GuiApp_GrabTouchEvents ; (r16, r17)
|
|
pop xh
|
|
pop xl
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_UngrabTouchEvents @global
|
|
;
|
|
; Let this widget grab touch events until ungrabbed.
|
|
;
|
|
; @param Y address of object
|
|
; @param X byte address of widget grabbing touch events
|
|
; @return CFLAG set if grabbed, cleared on error
|
|
; @clobbers r16, r17, r18, r19
|
|
|
|
Widget_UngrabTouchEvents:
|
|
rcall Widget_GetApp ; (r18, r19)
|
|
push yl
|
|
push yh
|
|
push xl
|
|
push xh
|
|
mov xl, yl
|
|
mov xh, yh
|
|
mov yl, r18
|
|
mov yh, r19
|
|
bigcall GuiApp_UngrabTouchEvents ; (r16, r17)
|
|
pop xh
|
|
pop xl
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_AddOuterStyleBorders @global
|
|
;
|
|
; @param Y address of object
|
|
; @param r19:r18 value to add the border sizes to
|
|
; @return r19:r18 value with added border sizes
|
|
; @clobbers r20, r21
|
|
|
|
Widget_AddOuterStyleBorders:
|
|
push zl
|
|
push zh
|
|
; add borders
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
|
|
lpm r20, Z
|
|
clr r21
|
|
add r18, r20 ; add border at begin
|
|
adc r19, r21
|
|
add r18, r20 ; add border at end
|
|
adc r19, r21
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GetBorderAndSpacing @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return r23 border size
|
|
; @return r22 spacing
|
|
; @clobbers none
|
|
|
|
Widget_GetBorderAndSpacing:
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
mov r22, zl
|
|
or r22, zh
|
|
brne Widget_GetBorderAndSpacing_read
|
|
clr r22
|
|
clr r23
|
|
rjmp Widget_GetBorderAndSpacing_done
|
|
Widget_GetBorderAndSpacing_read:
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
|
|
lpm r23, Z+ ; borders
|
|
lpm r22, Z ; spacing
|
|
Widget_GetBorderAndSpacing_done:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnDraw @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Y
|
|
|
|
Widget_OnDraw:
|
|
ldd r17, Y+OBJECT_OFFS_FLAGS
|
|
|
|
; check whether widget is visible
|
|
sbrs r17, WIDGET_FLAGS_VISIBLE_BIT
|
|
rjmp Widget_OnDraw_ret
|
|
|
|
; check whether widget is dirty
|
|
sbrs r17, WIDGET_FLAGS_DIRTY_BIT
|
|
rjmp Widget_OnDraw_ret
|
|
|
|
; clear dirty bit
|
|
cbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r17
|
|
|
|
; clear widget background
|
|
rcall Widget_Clear ; (any, !Y)
|
|
|
|
ldd r17, Y+OBJECT_OFFS_OPTS
|
|
sbrs r17, WIDGET_OPTS_BORDER_BIT
|
|
rjmp Widget_OnDraw_ret
|
|
bigcall Widget_DrawBorder
|
|
|
|
Widget_OnDraw_ret:
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnDrawNop @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Y
|
|
|
|
Widget_OnDrawNop:
|
|
ldd r17, Y+OBJECT_OFFS_FLAGS
|
|
; only clear dirty bit
|
|
cbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r17
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnLayout @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Y
|
|
|
|
Widget_OnLayout:
|
|
ldd r17, Y+OBJECT_OFFS_FLAGS
|
|
; only clear layout bit
|
|
cbr r17, (1<<WIDGET_FLAGS_LAYOUT_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r17
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnShow @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Y
|
|
|
|
Widget_OnShow:
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbr r16, (1<<WIDGET_FLAGS_VISIBLE_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT) | (1<<WIDGET_FLAGS_LAYOUT_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnHide @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Y
|
|
|
|
Widget_OnHide:
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
cbr r16, (1<<WIDGET_FLAGS_VISIBLE_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnGetValue @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
|
|
|
|
Widget_OnGetValue:
|
|
cpi r17, WIDGET_VALUE_DEFAULT_WIDTH
|
|
breq Widget_OnGetValue_getDefaultWidth
|
|
cpi r17, WIDGET_VALUE_DEFAULT_HEIGHT
|
|
breq Widget_OnGetValue_getDefaultHeight
|
|
clc
|
|
rjmp Widget_OnGetValue_ret
|
|
|
|
Widget_OnGetValue_getDefaultWidth:
|
|
Widget_OnGetValue_getDefaultHeight:
|
|
ldi r18, 1
|
|
clr r19
|
|
sec
|
|
Widget_OnGetValue_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnTouch @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
|
|
|
|
Widget_OnTouch:
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbrs r16, WIDGET_FLAGS_VISIBLE_BIT
|
|
rjmp Widget_OnTouch_done
|
|
|
|
; read touch signal data from X
|
|
ld r18, X+ ; WIDGET_DATA_TOUCH_OFFS_X_LO
|
|
ld r19, X+ ; WIDGET_DATA_TOUCH_OFFS_X_HI
|
|
ld r20, X+ ; WIDGET_DATA_TOUCH_OFFS_Y_LO
|
|
ld r21, X+ ; WIDGET_DATA_TOUCH_OFFS_Z_HI
|
|
ld r22, X ; WIDGET_DATA_TOUCH_OFFS_STATE
|
|
sbiw xh:xl, 4
|
|
|
|
sbrs r22, DISPLAY_IFLAGS_PRESSED_BIT
|
|
rjmp Widget_OnTouch_up
|
|
|
|
; down (active touch)
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbrc r16, WIDGET_FLAGS_TOUCH_BIT
|
|
rjmp Widget_OnTouch_move ; already pressed, jmp
|
|
; newly pressed
|
|
rcall Widget_LoadDimsForFullWidget ; (none)
|
|
push r18
|
|
push r19
|
|
rcall Widget_MakeAbsPos ; (r16, r17, r18, r19)
|
|
pop r19
|
|
pop r18
|
|
rcall Widget_IsPointInRect ; (R16, R17)
|
|
brcc Widget_OnTouch_done ; touch not inside this widget, jmp
|
|
|
|
; touch down inside this widget, handle
|
|
bigcall Widget_GrabTouchEvents ; (r16, r17, r18, r19)
|
|
brcc Widget_OnTouch_done ; can't grab, abort
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbr r16, (1<<WIDGET_FLAGS_TOUCH_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
; send TOUCH_BEGIN to this object
|
|
ldi r16, WIDGET_SIGNAL_TOUCH_BEGIN
|
|
clr r17
|
|
bigcall OBJ_HandleSignal ; (any, !Y)
|
|
rjmp Widget_OnTouch_done
|
|
Widget_OnTouch_up:
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbrs r16, WIDGET_FLAGS_TOUCH_BIT
|
|
rjmp Widget_OnTouch_done
|
|
; was pressed, not any more
|
|
bigcall Widget_UngrabTouchEvents ; (r16, r17, r18, r19)
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
cbr r16, (1<<WIDGET_FLAGS_TOUCH_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r16
|
|
; send TOUCH_END to this object
|
|
ldi r16, WIDGET_SIGNAL_TOUCH_END
|
|
clr r17
|
|
bigcall OBJ_HandleSignal ; (any, !Y)
|
|
rjmp Widget_OnTouch_done
|
|
Widget_OnTouch_move:
|
|
; send TOUCH_MOVE to this object
|
|
ldi r16, WIDGET_SIGNAL_TOUCH_MOVE
|
|
clr r17
|
|
bigcall OBJ_HandleSignal ; (any, !Y)
|
|
Widget_OnTouch_done:
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Clear @global
|
|
;
|
|
; @param Y address of widget
|
|
; @clobbers any, !Y
|
|
|
|
Widget_Clear:
|
|
rcall Widget_LoadDimsForFullWidget ; (none)
|
|
rcall Widget_MakeAbsPos ; (r16, r17, r18, r19)
|
|
rcall Widget_ValidateDims ; (r16, r17)
|
|
tst r16
|
|
breq Widget_Clear_l1
|
|
; DEBUG
|
|
ldi r16, LOW(DISPLAY_COLOR_MAGENTA)
|
|
mov r2, r16
|
|
ldi r16, HIGH(DISPLAY_COLOR_MAGENTA)
|
|
mov r3, r16
|
|
bigcall Display_FillRect
|
|
ret
|
|
Widget_Clear_l1:
|
|
|
|
rcall Widget_SelectColors ; (R16)
|
|
mov r2, r0 ; use background
|
|
mov r3, r1
|
|
bigcall Display_FillRect
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawBorder @global
|
|
;
|
|
; @param Y address of widget
|
|
; @clobbers any, !Y
|
|
|
|
Widget_DrawBorder:
|
|
rcall Widget_LoadDimsForFullWidget ; (none)
|
|
rcall Widget_MakeAbsPos ; (R16, R17)
|
|
rcall Widget_SelectBorderColors ; (R16)
|
|
bigcall Display_DrawRect
|
|
Widget_DrawBorder_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_FillRect @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param r3:r2 color
|
|
; @param r5:r4 X0
|
|
; @param r7:r6 Y0
|
|
; @param r9:r8 X1/W
|
|
; @param r11:r10 Y1/H
|
|
; @clobbers any, !Z
|
|
|
|
Widget_FillRect:
|
|
rcall Widget_MakeAbsPos ; (r16, r17, r18, r19)
|
|
mov r2, r0 ; use background
|
|
mov r3, r1
|
|
bigcall Display_FillRect
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawImage @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param R1:R0 background color
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param Z byte address pointer to image in FLASH (for LPM!)
|
|
; @clobbers all, !Y
|
|
|
|
Widget_DrawImage:
|
|
push yl
|
|
push yh
|
|
rcall widgetCalcAbsPosAndBorders ; (R16, R17)
|
|
bigcall ili9341ImageDraw
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawTextFlash @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @return Z pointer to next char to write if CFLAG clear
|
|
; @clobbers any, !Y
|
|
|
|
Widget_DrawTextFlash:
|
|
rcall Widget_SelectColors ; (R16)
|
|
rjmp Widget_DrawColoredTextFlash
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawTextRam @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param X pointer to text in SDRAM
|
|
; @return CFLAG set if completely written
|
|
; @return X pointer to next char to write if CFLAG clear
|
|
; @clobbers any, !Y
|
|
|
|
Widget_DrawTextRam:
|
|
rcall Widget_SelectColors ; (R16)
|
|
rjmp Widget_DrawColoredTextRam
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawColoredTextFlash @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param R1:R0 background color
|
|
; @param R3:R2 foreground color
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param Z byte address pointer to text in flash (for LPM!)
|
|
; @return CFLAG set if completely written
|
|
; @return Z pointer to next char to write if CFLAG clear
|
|
; @clobbers any, !Y
|
|
|
|
Widget_DrawColoredTextFlash:
|
|
rcall widgetCalcAbsPosAndBorders ; (R16, R17)
|
|
|
|
Widget_DrawColoredTextFlash_loop:
|
|
lpm r16, Z
|
|
tst r16
|
|
sec
|
|
breq Widget_DrawColoredTextFlash_loopEnd
|
|
push zl
|
|
push zh
|
|
rcall widgetDrawChar ; (any, !Y, !R6, !R7, !R8, !R9, !R10, !R11)
|
|
pop zh
|
|
pop zl
|
|
brcc Widget_DrawColoredTextFlash_loopEnd
|
|
adiw zh:zl, 1
|
|
rjmp Widget_DrawColoredTextFlash_loop
|
|
Widget_DrawColoredTextFlash_loopEnd:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawColoredTextRam @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param R1:R0 background color
|
|
; @param R3:R2 foreground color
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param X pointer to text in SDRAM
|
|
; @return CFLAG set if completely written
|
|
; @clobbers any, !Y
|
|
|
|
Widget_DrawColoredTextRam:
|
|
rcall widgetCalcAbsPosAndBorders ; (R16, R17)
|
|
|
|
Widget_DrawColoredTextRam_loop:
|
|
ld r16, X
|
|
tst r16
|
|
sec
|
|
breq Widget_DrawColoredTextRam_loopEnd
|
|
push xl
|
|
push xh
|
|
rcall widgetDrawChar ; (any, !Y, !R6, !R7, !R8, !R9, !R10, !R11)
|
|
pop xh
|
|
pop xl
|
|
brcc Widget_DrawColoredTextRam_loopEnd
|
|
adiw xh:xl, 1
|
|
rjmp Widget_DrawColoredTextRam_loop
|
|
Widget_DrawColoredTextRam_loopEnd:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_MakeAbsPos @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param r5:r4 X
|
|
; @param r7:r6 Y
|
|
; @clobbers r16, r17, r18, r19
|
|
|
|
Widget_MakeAbsPos:
|
|
push yl
|
|
push yh
|
|
Widget_MakeAbsPos_loop:
|
|
; adjust X
|
|
ldd r16, Y+WIDGET_OFFS_X_LO
|
|
ldd r17, Y+WIDGET_OFFS_X_HI
|
|
add r4, r16
|
|
adc r5, r17
|
|
; adjust Y
|
|
ldd r16, Y+WIDGET_OFFS_Y_LO
|
|
ldd r17, Y+WIDGET_OFFS_Y_HI
|
|
add r6, r16
|
|
adc r7, r17
|
|
; continue with parent
|
|
rcall OBJ_GetParent ; r19:r18=parent widget (none)
|
|
brcc Widget_MakeAbsPos_loopEnd
|
|
mov yl, r18
|
|
mov yh, r19
|
|
rjmp Widget_MakeAbsPos_loop
|
|
Widget_MakeAbsPos_loopEnd:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_ValidateDims @global
|
|
;
|
|
; @param Y address of widget
|
|
; @param r5:r4 X0
|
|
; @param r7:r6 Y0
|
|
; @param r9:r8 X1/W
|
|
; @param r11:r10 Y1/H
|
|
; @return r16 1 if dims modified, 0 if dims where within display range
|
|
; @clobbers r16, r17
|
|
|
|
Widget_ValidateDims:
|
|
push r18
|
|
clr r18
|
|
ldi r16, LOW(DISPLAY_WIDTH) ; check X
|
|
ldi r17, HIGH(DISPLAY_WIDTH)
|
|
cp r4, r16
|
|
cpc r5, r17
|
|
brcs Widget_ValidateDims_width
|
|
ldi r18, 1
|
|
clr r4
|
|
clr r5
|
|
Widget_ValidateDims_width:
|
|
sub r16, r4 ; calculate remaining width from pos on
|
|
sbc r17, r5
|
|
cp r16, r8
|
|
cpc r17, r9
|
|
brcc Widget_ValidateDims_y
|
|
ldi r18, 1
|
|
mov r8, r16
|
|
mov r9, r17
|
|
Widget_ValidateDims_y:
|
|
ldi r16, LOW(DISPLAY_HEIGHT) ; check Y
|
|
ldi r17, HIGH(DISPLAY_HEIGHT)
|
|
cp r6, r16
|
|
cpc r7, r17
|
|
brcs Widget_ValidateDims_height
|
|
ldi r18, 1
|
|
clr r6
|
|
clr r7
|
|
Widget_ValidateDims_height:
|
|
sub r16, r6 ; calculate remaining width from pos on
|
|
sbc r17, r7
|
|
cp r16, r10
|
|
cpc r17, r11
|
|
brcc Widget_ValidateDims_ret
|
|
ldi r18, 1
|
|
mov r10, r16
|
|
mov r11, r17
|
|
Widget_ValidateDims_ret:
|
|
mov r16, r18
|
|
pop r18
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_CheckDims @global
|
|
;
|
|
; @param Y address of widget
|
|
; @clobbers r16, r17, r18, r19
|
|
|
|
Widget_CheckDims:
|
|
ldi r18, LOW(DISPLAY_WIDTH) ; check X
|
|
ldi r19, HIGH(DISPLAY_WIDTH)
|
|
ldd r16, Y+WIDGET_OFFS_X_LO
|
|
ldd r17, Y+WIDGET_OFFS_X_HI
|
|
cp r16, r18
|
|
cpc r17, r19
|
|
brcc Widget_CheckDims_invalid
|
|
sub r18, r16
|
|
sbc r19, r17
|
|
ldd r16, Y+WIDGET_OFFS_WIDTH_LO
|
|
ldd r17, Y+WIDGET_OFFS_WIDTH_HI
|
|
cp r18, r16
|
|
cpc r19, r17
|
|
brcs Widget_CheckDims_invalid
|
|
|
|
ldi r18, LOW(DISPLAY_HEIGHT) ; check Y
|
|
ldi r19, HIGH(DISPLAY_HEIGHT)
|
|
ldd r16, Y+WIDGET_OFFS_Y_LO
|
|
ldd r17, Y+WIDGET_OFFS_Y_HI
|
|
cp r16, r18
|
|
cpc r17, r19
|
|
brcc Widget_CheckDims_invalid
|
|
sub r18, r16
|
|
sbc r19, r17
|
|
ldd r16, Y+WIDGET_OFFS_HEIGHT_LO
|
|
ldd r17, Y+WIDGET_OFFS_HEIGHT_HI
|
|
cp r18, r16
|
|
cpc r19, r17
|
|
brcs Widget_CheckDims_invalid
|
|
; done, all okay so far
|
|
sec
|
|
rjmp Widget_CheckDims_ret
|
|
Widget_CheckDims_invalid:
|
|
clc
|
|
Widget_CheckDims_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_SelectColors @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return r1:r0 background color
|
|
; @return r3:r2 foreground color
|
|
; @clobbers R16
|
|
|
|
Widget_SelectColors:
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbrc r16, WIDGET_FLAGS_ACTIVATED_BIT
|
|
rjmp Widget_SelectColors_activated
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_FRONTCOL_NORM
|
|
rjmp Widget_SelectColors_readColors
|
|
Widget_SelectColors_activated:
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_FRONTCOL_ACTIVATED
|
|
Widget_SelectColors_readColors:
|
|
lpm r2, Z+ ; read foreground color
|
|
lpm r3, Z+
|
|
lpm r0, Z+ ; read background color
|
|
lpm r1, Z
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_SelectBorderColors @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return r1:r0 border color
|
|
; @return r3:r2 shadow color
|
|
; @clobbers R16
|
|
|
|
Widget_SelectBorderColors:
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
ldd r16, Y+OBJECT_OFFS_FLAGS
|
|
sbrc r16, WIDGET_FLAGS_ACTIVATED_BIT
|
|
rjmp Widget_SelectBorderColors_activated
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_BORDERCOL_NORM
|
|
rjmp Widget_SelectBorderColors_readColors
|
|
Widget_SelectBorderColors_activated:
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_BORDERCOL_ACTIVATED
|
|
Widget_SelectBorderColors_readColors:
|
|
lpm r2, Z+ ; read border color
|
|
lpm r3, Z+
|
|
lpm r0, Z+ ; read shadow color
|
|
lpm r1, Z
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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_CalcStringWidthSDRAM
|
|
;
|
|
; @param X pointer to text in SDRAM
|
|
; @param R18 char width in px
|
|
; @return r13:r12 width of string
|
|
; @clobbers r16
|
|
|
|
Widget_CalcStringWidthSDRAM:
|
|
clr r12
|
|
clr r13
|
|
push xl
|
|
push xh
|
|
Widget_CalcStringWidthSDRAM_loop:
|
|
ld r16, X+
|
|
tst r16
|
|
breq Widget_CalcStringWidthSDRAM_done
|
|
add r12, r18
|
|
adc r13, r18
|
|
sub r13, r18
|
|
rjmp Widget_CalcStringWidthSDRAM_loop
|
|
Widget_CalcStringWidthSDRAM_done:
|
|
pop xh
|
|
pop xl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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
|
|
; @param r17 pack mode (see @ref WIDGET_PACK_BEGIN)
|
|
; @return R5:R4 X
|
|
; @clobbers r17, r18, r19, r20, r21
|
|
|
|
Widget_PackSelfX:
|
|
ldd r18, Y+WIDGET_OFFS_WIDTH_LO
|
|
ldd r19, Y+WIDGET_OFFS_WIDTH_HI
|
|
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_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
|
|
; @param r17 pack mode (see @ref WIDGET_PACK_BEGIN)
|
|
; @return R7:R6 Y
|
|
; @clobbers r17, r18, r19, r20, r21
|
|
|
|
Widget_PackSelfY:
|
|
ldd r18, Y+WIDGET_OFFS_HEIGHT_LO
|
|
ldd r19, Y+WIDGET_OFFS_HEIGHT_HI
|
|
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_PackContentX @global
|
|
;
|
|
; Calc pos according to WIDGET_PACK_HCONTENT in WIDGET_OFFS_PACK.
|
|
;
|
|
; @param Y address of widget
|
|
; @param R13:R12 width of object to align
|
|
; @return R5:R4 X
|
|
; @clobbers r17, r18, r19, r20, r21
|
|
|
|
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
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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
|
|
;
|
|
; @param Y address of widget
|
|
; @param R16 char to write
|
|
; @param R5:R4 absolute X on screen (in display coords)
|
|
; @param R7:R6 absolute Y on screen (in display coords)
|
|
; @param R9:R8 first X pos right of windows (in display coords)
|
|
; @return CFLAG set if char printed, cleared otherwise
|
|
; @return R5:R4 X pos behind char
|
|
; @clobbers any, !Y, !R6, !R7, !R8, !R9, !R10, !R11
|
|
|
|
widgetDrawChar:
|
|
push yl
|
|
push yh
|
|
push r16
|
|
; get font and charWidth
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_CHARWIDTH
|
|
lpm r18, Z ; char width
|
|
sbiw zh:zl, WIDGET_STYLE_OFFS_CHARWIDTH
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_FONT_LO
|
|
lpm r19, Z+
|
|
lpm zh, Z
|
|
mov zl, r19
|
|
|
|
; check whether char fits into widget
|
|
mov r16, r18
|
|
clr r17
|
|
add r16, r4 ; char width+X
|
|
adc r17, r5
|
|
cp r8, r16 ; check against window width
|
|
cpc r9, r17
|
|
; sub r16, r8 ; check against window width
|
|
; sbc r17, r9
|
|
pop r16
|
|
brcs widgetDrawChar_done ; not fit, jmp
|
|
|
|
; draw char
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
push r18 ; save char width
|
|
bigcall Display_DrawChar
|
|
pop r18
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
; increment X
|
|
clr r16
|
|
add r4, r18
|
|
adc r5, r16
|
|
sec
|
|
widgetDrawChar_done:
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_LoadDimsForFullWidget
|
|
;
|
|
; @param Y address of widget
|
|
; @return r5:r4 X (0)
|
|
; @return r7:r6 Y (0)
|
|
; @return r9:r8 widget width
|
|
; @return r11:R10 widget height
|
|
; @clobbers none
|
|
|
|
Widget_LoadDimsForFullWidget:
|
|
clr r4
|
|
clr r5
|
|
clr r6
|
|
clr r7
|
|
ldd r8, Y+WIDGET_OFFS_WIDTH_LO
|
|
ldd r9, Y+WIDGET_OFFS_WIDTH_HI
|
|
ldd r10, Y+WIDGET_OFFS_HEIGHT_LO
|
|
ldd r11, Y+WIDGET_OFFS_HEIGHT_HI
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetCalcAbsPosAndBorders
|
|
;
|
|
; @param Y address of widget
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @return R9:R8 first X pos right of widget
|
|
; @return R5:R4 X relative to screen
|
|
; @return R7:R6 Y relative to screen
|
|
; @return R9:R8 first X pos right of widget (abs)
|
|
; @return R11:R10 first Y pos below widget (abs)
|
|
; @clobbers r16, r17
|
|
|
|
widgetCalcAbsPosAndBorders:
|
|
rcall Widget_MakeAbsPos ; (R16, R17)
|
|
ldd r8, Y+WIDGET_OFFS_WIDTH_LO
|
|
ldd r9, Y+WIDGET_OFFS_WIDTH_HI
|
|
add r8, r4 ; convert width to first pos right of widget
|
|
adc r9, r5
|
|
ldd r10, Y+WIDGET_OFFS_HEIGHT_LO
|
|
ldd r11, Y+WIDGET_OFFS_HEIGHT_HI
|
|
add r10, r6
|
|
adc r11, r7 ; convert height to first pos below widget
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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
|
|
; @todo move layoutPack here and use that (shares more code)
|
|
|
|
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 ; r19:r18=host size - (border*2)
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data in FLASH
|
|
|
|
Widget_DefaultSignalmap:
|
|
; header
|
|
.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)
|
|
.db 0, WIDGET_SIGNAL_GETVALUE, LOW(Widget_OnGetValue), HIGH(Widget_OnGetValue) ; handle any value here
|
|
.db 0, WIDGET_SIGNAL_SHOW, LOW(Widget_OnShow), HIGH(Widget_OnShow)
|
|
.db 0, WIDGET_SIGNAL_HIDE, LOW(Widget_OnHide), HIGH(Widget_OnHide)
|
|
.db 0, 0, 0, 0 ; end of table
|
|
|
|
|
|
|
|
Widget_DefaultStyle:
|
|
.dw DISPLAY_COLOR_BLACK ; frontCol_norm
|
|
.dw DISPLAY_COLOR_LIGHTGREY ; 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
|
|
|