1408 lines
36 KiB
NASM
1408 lines
36 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_WIDGET = OBJECT_SIZE
|
|
.equ WIDGET_OFFS_OPTS_LO = WIDGET_OFFS_WIDGET+0
|
|
.equ WIDGET_OFFS_OPTS_HI = WIDGET_OFFS_WIDGET+1
|
|
.equ WIDGET_OFFS_X_LO = WIDGET_OFFS_WIDGET+2
|
|
.equ WIDGET_OFFS_X_HI = WIDGET_OFFS_WIDGET+3
|
|
.equ WIDGET_OFFS_Y_LO = WIDGET_OFFS_WIDGET+4
|
|
.equ WIDGET_OFFS_Y_HI = WIDGET_OFFS_WIDGET+5
|
|
.equ WIDGET_OFFS_WIDTH_LO = WIDGET_OFFS_WIDGET+6
|
|
.equ WIDGET_OFFS_WIDTH_HI = WIDGET_OFFS_WIDGET+7
|
|
.equ WIDGET_OFFS_HEIGHT_LO = WIDGET_OFFS_WIDGET+8
|
|
.equ WIDGET_OFFS_HEIGHT_HI = WIDGET_OFFS_WIDGET+9
|
|
.equ WIDGET_OFFS_FRONTCOL_LO = WIDGET_OFFS_WIDGET+10
|
|
.equ WIDGET_OFFS_FRONTCOL_HI = WIDGET_OFFS_WIDGET+11
|
|
.equ WIDGET_OFFS_BACKCOL_LO = WIDGET_OFFS_WIDGET+12
|
|
.equ WIDGET_OFFS_BACKCOL_HI = WIDGET_OFFS_WIDGET+13
|
|
.equ WIDGET_OFFS_FONT_LO = WIDGET_OFFS_WIDGET+14
|
|
.equ WIDGET_OFFS_FONT_HI = WIDGET_OFFS_WIDGET+15
|
|
.equ WIDGET_OFFS_SDRAM_LO = WIDGET_OFFS_WIDGET+16
|
|
.equ WIDGET_OFFS_SDRAM_HI = WIDGET_OFFS_WIDGET+17
|
|
.equ WIDGET_SIZE = WIDGET_OFFS_WIDGET+18
|
|
|
|
; SDRAM data for widget
|
|
.equ WIDGET_SD_OFFS_FLAGS = 0
|
|
.equ WIDGET_SD_SIZE = 1
|
|
|
|
; widget opts_lo
|
|
.equ WIDGET_OPTSLO_BORDER_BIT = 7
|
|
.equ WIDGET_OPTSLO_INPUT_BIT = 6 ; TOUCH, KEY
|
|
.equ WIDGET_OPTSLO_TIMER_BIT = 5
|
|
.equ WIDGET_OPTSLO_MSGRECV_BIT = 4
|
|
|
|
.equ WIDGET_OPTSHI_HALIGNRIGHT_BIT = 7
|
|
.equ WIDGET_OPTSHI_HALIGNCENTER_BIT = 6
|
|
.equ WIDGET_OPTSHI_VALIGNBOTTOM_BIT = 5
|
|
.equ WIDGET_OPTSHI_VALIGNCENTER_BIT = 4
|
|
|
|
; widget flags
|
|
.equ WIDGET_FLAGS_ACTIVE_BIT = 7
|
|
.equ WIDGET_FLAGS_TOUCH_BIT = 6
|
|
.equ WIDGET_FLAGS_DIRTY_BIT = 5
|
|
.equ WIDGET_FLAGS_PRESSED_BIT = 4
|
|
|
|
; SDRAM data for signal WIDGET_SIGNAL_TOUCH
|
|
.equ WIDGET_DATA_TOUCH_OFFS_X_LO = 0
|
|
.equ WIDGET_DATA_TOUCH_OFFS_X_HI = 1
|
|
.equ WIDGET_DATA_TOUCH_OFFS_Y_LO = 2
|
|
.equ WIDGET_DATA_TOUCH_OFFS_Y_HI = 3
|
|
.equ WIDGET_DATA_TOUCH_OFFS_STATE = 4
|
|
.equ WIDGET_DATA_TOUCH_SIZE = 5
|
|
|
|
; signals
|
|
.equ WIDGET_SIGNAL_SHOW = OBJECT_SIGNAL_NEXTFREE+0
|
|
.equ WIDGET_SIGNAL_HIDE = OBJECT_SIGNAL_NEXTFREE+1
|
|
.equ WIDGET_SIGNAL_DRAW = OBJECT_SIGNAL_NEXTFREE+2
|
|
.equ WIDGET_SIGNAL_TOUCH = OBJECT_SIGNAL_NEXTFREE+3
|
|
.equ WIDGET_SIGNAL_CLICKED = OBJECT_SIGNAL_NEXTFREE+4
|
|
.equ WIDGET_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+5
|
|
|
|
|
|
; args to Widget_AlignPos
|
|
.equ WIDGET_1DALIGN_END_BIT = 0
|
|
.equ WIDGET_1DALIGN_CENTER_BIT = 1
|
|
.equ WIDGET_1DALIGN_BORDER_BIT = 2
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Init @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
|
|
Widget_Init:
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
clr r16
|
|
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+WIDGET_SD_OFFS_FLAGS, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnCreate @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Z
|
|
|
|
Widget_OnCreate:
|
|
rcall Widget_Init
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnDraw @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Z
|
|
|
|
Widget_OnDraw:
|
|
rcall Widget_GetSdramPtr
|
|
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
|
|
|
|
; check whether widget is active
|
|
sbrs r17, WIDGET_FLAGS_ACTIVE_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+WIDGET_SD_OFFS_FLAGS, r17
|
|
; clear widget background
|
|
rcall Widget_Clear
|
|
|
|
Widget_OnDraw_ret:
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_OnDrawNop @global
|
|
;
|
|
; this routine only clears the DIRTY bit
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Z
|
|
|
|
Widget_OnDrawNop:
|
|
rcall Widget_GetSdramPtr
|
|
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
|
|
cbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+WIDGET_SD_OFFS_FLAGS, r17
|
|
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_LoadDisplayRegs @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @return R1:R0 background color
|
|
; @return R3:R2 foreground color
|
|
; @return R5:R4 X
|
|
; @return R7:R6 Y
|
|
; @return R9:R8 widget width
|
|
; @return R11:R10 widget height
|
|
; @clobbers none
|
|
|
|
Widget_LoadDisplayRegs:
|
|
push zl
|
|
push zh
|
|
adiw zh:zl, WIDGET_OFFS_X_LO
|
|
lpm r4, Z+ ; X_LO
|
|
lpm r5, Z+
|
|
lpm r6, Z+ ; Y_LO
|
|
lpm r7, Z+
|
|
lpm r8, Z+ ; WIDTH_LO
|
|
lpm r9, Z+
|
|
lpm r10, Z+ ; HEIGHT_LO
|
|
lpm r11, Z+
|
|
lpm r2, Z+ ; FRONTCOL_LO
|
|
lpm r3, Z+
|
|
lpm r0, Z+ ; BACKCOL_LO
|
|
lpm r1, Z+
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GetSdramPtr @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @return Y pointer to SDRAM data for widget
|
|
; @clobbers none
|
|
|
|
Widget_GetSdramPtr:
|
|
adiw zh:zl, WIDGET_OFFS_SDRAM_LO
|
|
lpm yl, Z+
|
|
lpm yh, Z
|
|
sbiw zh:zl, WIDGET_OFFS_SDRAM_LO+1
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GetRootWidget @global
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @return Z byte address pointer to RootWidget
|
|
; @clobbers r18, r19
|
|
|
|
Widget_GetRootWidget:
|
|
rcall OBJ_IsObject ; (none)
|
|
brcc Widget_GetRootWidget_end
|
|
Widget_GetRootWidget_loop:
|
|
bigcall OBJ_GetParent ; (none)
|
|
brcc Widget_GetRootWidget_found ; no parent, return current Z
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rjmp Widget_GetRootWidget_loop
|
|
Widget_GetRootWidget_found:
|
|
sec
|
|
Widget_GetRootWidget_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GetApp @global
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @return R19:R18 byte address pointer to GuiApp
|
|
; @clobbers (r18, r19)
|
|
|
|
Widget_GetApp:
|
|
rcall OBJ_IsObject ; (none)
|
|
brcc Widget_GetApp_ret
|
|
push zl
|
|
push zh
|
|
rcall Widget_GetRootWidget ; Z:=rootWidget (r18, r19)
|
|
brcc Widget_GetApp_popRet
|
|
rcall RootWidget_GetApp ; R19:R18=app (none)
|
|
Widget_GetApp_popRet:
|
|
pop zh
|
|
pop zl
|
|
Widget_GetApp_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_GrabTouchEvents @global
|
|
;
|
|
; Let this widget grab touch events until ungrabbed.
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @return CFLAG set if grabbed, cleared on error
|
|
; @clobbers X, Y (r16, r17, r18, r19)
|
|
|
|
Widget_GrabTouchEvents:
|
|
push zl
|
|
push zh
|
|
mov xl, zl
|
|
mov xh, zh
|
|
rcall Widget_GetApp ; R19:R18:=app
|
|
brcc Widget_GrabTouchEvents_popRet
|
|
mov zl, r18
|
|
mov zh, r19
|
|
bigcall GuiApp_GrabTouchEvents ; (R16, R17)
|
|
Widget_GrabTouchEvents_popRet:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_UngrabTouchEvents @global
|
|
;
|
|
; Let this widget un-grab touch events.
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @return CFLAG set if ungrabbed, cleared on error
|
|
; @clobbers X (r16, r17, r18, r19)
|
|
|
|
Widget_UngrabTouchEvents:
|
|
push zl
|
|
push zh
|
|
mov xl, zl
|
|
mov xh, zh
|
|
rcall Widget_GetApp ; R19:R18:=app
|
|
brcc Widget_UngrabTouchEvents_popRet
|
|
mov zl, r18
|
|
mov zh, r19
|
|
bigcall GuiApp_UngrabTouchEvents ; (R16, R17)
|
|
Widget_UngrabTouchEvents_popRet:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_AddFlagsDown @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R16 flags to add
|
|
; @clobbers R17, R18, R19, Y
|
|
|
|
Widget_AddFlagsDown:
|
|
rcall OBJ_IsObject ; (none)
|
|
brcc Widget_AddFlagsDown_ret
|
|
|
|
rcall Widget_AddFlags ; (R17)
|
|
push zl
|
|
push zh
|
|
bigcall OBJ_GetFirstChild ; R19:R18=next object (none)
|
|
Widget_AddFlagsDown_loop:
|
|
brcc Widget_AddFlagsDown_loopEnd
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rcall Widget_AddFlagsDown ; (R17, R18, R19, Y)
|
|
rcall OBJ_GetNext ; R19:R18=next object (none)
|
|
rjmp Widget_AddFlagsDown_loop
|
|
|
|
Widget_AddFlagsDown_loopEnd:
|
|
pop zh
|
|
pop zl
|
|
Widget_AddFlagsDown_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_SubFlagsDown @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R16 flags to add
|
|
; @clobbers R17, R18, R19, R22, R23
|
|
|
|
Widget_SubFlagsDown:
|
|
rcall OBJ_IsObject ; (none)
|
|
brcc Widget_SubFlagsDown_ret
|
|
rcall Widget_SubFlags ; (R17)
|
|
push zl
|
|
push zh
|
|
bigcall OBJ_GetFirstChild ; R19:R18=next object
|
|
Widget_SubFlagsDown_loop:
|
|
brcc Widget_SubFlagsDown_loopEnd
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rcall Widget_SubFlagsDown
|
|
rcall OBJ_GetNext
|
|
rjmp Widget_SubFlagsDown_loop
|
|
|
|
Widget_SubFlagsDown_loopEnd:
|
|
pop zh
|
|
pop zl
|
|
Widget_SubFlagsDown_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_AddFlags @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R16 flags to add
|
|
; @clobbers R17
|
|
|
|
Widget_AddFlags:
|
|
rcall OBJ_IsObject ; (none)
|
|
brcc Widget_AddFlags_ret
|
|
|
|
push yl
|
|
push yh
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
|
|
or r17, r16
|
|
std Y+WIDGET_SD_OFFS_FLAGS, r17
|
|
pop yh
|
|
pop yl
|
|
Widget_AddFlags_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_SubFlags @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R16 flags to clear
|
|
; @clobbers R17
|
|
|
|
Widget_SubFlags:
|
|
mov r17, zl
|
|
or r17, zh
|
|
breq Widget_SubFlags_ret
|
|
|
|
push yl
|
|
push yh
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
|
|
com r16 ; one's-complement
|
|
and r17, r16
|
|
com r16
|
|
std Y+WIDGET_SD_OFFS_FLAGS, r17
|
|
pop yh
|
|
pop yl
|
|
Widget_SubFlags_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Clear @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
|
|
Widget_Clear:
|
|
rcall OBJ_IsObject
|
|
brcc Widget_Clear_ret
|
|
|
|
rcall widgetLoadCoordsForFullWidget
|
|
rcall Widget_MakeAbsPos ; (R16, R17)
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
rcall Widget_SelectColors ; (R16)
|
|
mov r2, r0 ; use background
|
|
mov r3, r1
|
|
bigcall Display_FillRect
|
|
Widget_Clear_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawBorder @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param r3:r2 color
|
|
; @clobbers any, !Z
|
|
|
|
Widget_DrawBorder:
|
|
rcall OBJ_IsObject
|
|
brcc Widget_DrawBorder_ret
|
|
rcall widgetLoadCoordsForFullWidget
|
|
rcall Widget_MakeAbsPos ; (R16, R17)
|
|
bigcall Display_DrawRect
|
|
Widget_DrawBorder_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_SelectColors @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param Y pointer to Widget data in SDRAM
|
|
; @return r1:r0 background color
|
|
; @return r3:r2 foreground color
|
|
; @clobbers R16
|
|
|
|
Widget_SelectColors:
|
|
ldd r16, Y+WIDGET_SD_OFFS_FLAGS ; flags
|
|
andi r16, (1<<WIDGET_FLAGS_PRESSED_BIT)
|
|
brne Widget_SelectColors_pressed
|
|
push zl
|
|
push zh
|
|
adiw zh:zl, WIDGET_OFFS_FRONTCOL_LO
|
|
lpm r2, Z+
|
|
lpm r3, Z+
|
|
lpm r0, Z+
|
|
lpm r1, Z
|
|
pop zh
|
|
pop zl
|
|
rjmp Widget_SelectColors_ret
|
|
|
|
Widget_SelectColors_pressed:
|
|
; background color
|
|
ldi r16, LOW(STYLE_BUTTON_COL_BG_PRESSED)
|
|
mov r0, r16
|
|
ldi r16, HIGH(STYLE_BUTTON_COL_BG_PRESSED)
|
|
mov r1, r16
|
|
|
|
; foreground color
|
|
ldi r16, LOW(STYLE_BUTTON_COL_FG_PRESSED)
|
|
mov r2, r16
|
|
ldi r16, HIGH(STYLE_BUTTON_COL_FG_PRESSED)
|
|
mov r3, r16
|
|
|
|
Widget_SelectColors_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_MakeAbsPos @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param r5:r4 X
|
|
; @param r7:r6 Y
|
|
; @clobbers r16, r17
|
|
|
|
Widget_MakeAbsPos:
|
|
push zl
|
|
push zh
|
|
push r18
|
|
push r19
|
|
Widget_MakeAbsPos_loop:
|
|
adiw zh:zl, WIDGET_OFFS_X_LO
|
|
lpm r16, Z+
|
|
lpm r17, Z+
|
|
add r4, r16 ; adjust X
|
|
adc r5, r17
|
|
lpm r16, Z+
|
|
lpm r17, Z
|
|
add r6, r16 ; adjust Y
|
|
adc r7, r17
|
|
sbiw zh:zl, WIDGET_OFFS_X_LO+3
|
|
rcall OBJ_GetParent
|
|
brcc Widget_MakeAbsPos_loopEnd
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rjmp Widget_MakeAbsPos_loop
|
|
Widget_MakeAbsPos_loopEnd:
|
|
pop r19
|
|
pop r18
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_FillRect @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @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)
|
|
bigcall Display_FillRect ; directly call graphics function
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawImage @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R1:R0 background color
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param R13:R12 byte address pointer to image in FLASH (for LPM!)
|
|
|
|
Widget_DrawImage:
|
|
rcall widgetCalcAbsPosAndBorders
|
|
push zl
|
|
push zh
|
|
mov zl, r12
|
|
mov zh, r13
|
|
bigcall ili9341ImageDraw
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawTextFlash @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param R13:R12 byte address pointer to text in flash (for LPM!)
|
|
; @clobbers any, !Z
|
|
|
|
Widget_DrawTextFlash:
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
rcall Widget_SelectColors
|
|
rjmp Widget_DrawColoredTextFlash
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawColoredTextFlash @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @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 R13:R12 byte address pointer to text in flash (for LPM!)
|
|
; @clobbers any, !Z
|
|
|
|
Widget_DrawColoredTextFlash:
|
|
rcall widgetCalcAbsPosAndBorders
|
|
Widget_DrawColoredTextFlash_loop:
|
|
push zl
|
|
push zh
|
|
mov zl, r12
|
|
mov zh, r13
|
|
lpm r16, Z
|
|
pop zh
|
|
pop zl
|
|
tst r16
|
|
breq Widget_DrawColoredTextFlash_loopEnd
|
|
rcall widgetDrawChar
|
|
brcc Widget_DrawColoredTextFlash_loopEnd
|
|
ldi r16, 1
|
|
add r12, r16
|
|
adc r13, r12
|
|
sub r13, r12
|
|
rjmp Widget_DrawColoredTextFlash_loop
|
|
Widget_DrawColoredTextFlash_loopEnd:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawTextSDRAM @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param X pointer to text in SDRAM
|
|
; @clobbers any, !Z
|
|
|
|
Widget_DrawTextSDRAM:
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
rcall Widget_SelectColors ; (R16)
|
|
rjmp Widget_DrawColoredTextSDRAM
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawColoredTextSDRAM @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @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 R5:R4 X pos behind last written char
|
|
; @clobbers any, !Z
|
|
|
|
Widget_DrawColoredTextSDRAM:
|
|
rcall widgetCalcAbsPosAndBorders ; (R16, R17)
|
|
Widget_DrawColoredTextSDRAM_loop:
|
|
ld r16, X
|
|
tst r16
|
|
breq Widget_DrawColoredTextSDRAM_loopEnd
|
|
push xl
|
|
push xh
|
|
rcall widgetDrawChar ; (any, !Y, !R6, !R7, !R8, !R9, !R10, !R11)
|
|
pop xh
|
|
pop xl
|
|
brcc Widget_DrawColoredTextSDRAM_loopEnd
|
|
adiw xh:xl, 1
|
|
rjmp Widget_DrawColoredTextSDRAM_loop
|
|
Widget_DrawColoredTextSDRAM_loopEnd:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_DrawCharAt @global
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param
|
|
; @param R5:R4 X relative to widget
|
|
; @param R7:R6 Y relative to widget
|
|
; @param X pointer to text in SDRAM
|
|
; @clobbers any, !Z
|
|
|
|
Widget_DrawCharAt:
|
|
push r16
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
rcall Widget_SelectColors ; (R16)
|
|
rcall widgetCalcAbsPosAndBorders ; (R16, R17)
|
|
pop r16
|
|
push xl
|
|
push xh
|
|
rcall widgetDrawChar ; (any, !Y, !R6, !R7, !R8, !R9, !R10, !R11)
|
|
pop xh
|
|
pop xl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetCalcAbsPosAndBorders
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @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:
|
|
push zl
|
|
push zh
|
|
rcall Widget_MakeAbsPos ; (R16, R17)
|
|
adiw zh:zl, WIDGET_OFFS_WIDTH_LO
|
|
lpm r8, Z+ ; WIDTH_LO
|
|
lpm r9, Z+
|
|
add r8, r4 ; convert width to first pos right of widget
|
|
adc r9, r5
|
|
lpm r10, Z+ ; HEIGHT_LO
|
|
lpm r11, Z+
|
|
add r10, r6 ; convert height to first pos below widget
|
|
adc r11, r7
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetDrawChar
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R16 char to write
|
|
; @param R5:R4 absolute X on screen
|
|
; @param R7:R6 absolute Y on screen
|
|
; @param R9:R8 first X pos right of windows
|
|
; @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 zl
|
|
push zh
|
|
; save R16 (char to write)
|
|
mov r14, r16
|
|
|
|
; get font to Z
|
|
adiw zh:zl, WIDGET_OFFS_FONT_LO
|
|
lpm r18, Z+
|
|
lpm zh, Z
|
|
mov zl, r18
|
|
or r18, zh
|
|
clc
|
|
breq widgetDrawChar_done
|
|
|
|
; check whether the char fits inside window
|
|
bigcall FONT_GetCharWidth ; r16=char width
|
|
|
|
clr r17
|
|
add r16, r4 ; char width+X
|
|
adc r17, r5
|
|
sub r16, r8 ; check against window width
|
|
sbc r17, r9
|
|
brcc widgetDrawChar_done ; not fit, jmp
|
|
|
|
; actually draw char
|
|
mov r16, r14
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
bigcall Display_DrawChar
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
clr r16
|
|
add r4, r18 ; increment X
|
|
adc r5, r16
|
|
sec ; write succeeded
|
|
widgetDrawChar_done:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Tree_Init @global
|
|
;
|
|
; @param Z byte address of root widget object (for LPM!)
|
|
|
|
Widget_Tree_Init:
|
|
push zl
|
|
push zh
|
|
Widget_Tree_Init_loop:
|
|
mov r16, zl
|
|
or r16, zh
|
|
breq Widget_Tree_Init_loopEnd
|
|
rcall Widget_Init
|
|
bigcall OBJ_GetBelow
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rjmp Widget_Tree_Init_loop
|
|
Widget_Tree_Init_loopEnd:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Tree_SendDrawSignal @global
|
|
;
|
|
; @param Z byte address of root widget object (for LPM!)
|
|
|
|
Widget_Tree_SendDrawSignal:
|
|
ldi r16, WIDGET_SIGNAL_DRAW
|
|
clr r17
|
|
; only let active and dirty widgets draw
|
|
ldi r20, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
ldi r21, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
rcall Widget_TreeMatchFlagsAndSendSignalToActive
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Tree_SendTouchSignal @global
|
|
;
|
|
; @param Z byte address of root widget object (for LPM!)
|
|
; @param X pointer to touch event datain SDRAM
|
|
|
|
Widget_Tree_SendTouchSignal:
|
|
ldi r16, WIDGET_SIGNAL_TOUCH
|
|
clr r17
|
|
; only check active widgets
|
|
ldi r20, (1<<WIDGET_OPTSLO_INPUT_BIT)
|
|
ldi r21, (1<<WIDGET_OPTSLO_INPUT_BIT)
|
|
rcall Widget_TreeMatchOptsAndSendSignalToActive
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Tree_SendTimerSignal @global
|
|
;
|
|
; @param Z byte address of root widget object (for LPM!)
|
|
|
|
Widget_Tree_SendTimerSignal:
|
|
ldi r16, OBJECT_SIGNAL_TIMER
|
|
clr r17
|
|
; only check active widgets
|
|
ldi r20, (1<<WIDGET_OPTSLO_TIMER_BIT)
|
|
ldi r21, (1<<WIDGET_OPTSLO_TIMER_BIT)
|
|
rcall Widget_TreeMatchOptsAndSendSignal
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_Tree_SendMsgRecvSignal @global
|
|
;
|
|
; @param Z byte address of root widget object (for LPM!)
|
|
; @param X pointer to received message in SDRAM
|
|
|
|
Widget_Tree_SendMsgRecvSignal:
|
|
ldi r16, OBJECT_SIGNAL_RECVMSG
|
|
clr r17
|
|
; only check active widgets
|
|
ldi r20, (1<<WIDGET_OPTSLO_MSGRECV_BIT)
|
|
ldi r21, (1<<WIDGET_OPTSLO_MSGRECV_BIT)
|
|
rcall Widget_TreeMatchOptsAndSendSignal
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_TreeMatchOptsAndSendSignal @global
|
|
;
|
|
; Send signal to all widgets whose WIDGET_OFFS_OPTS_LO matches the given mask/value.
|
|
; Widgets which don't match will not be called, but there children will still be checked
|
|
; (as opposed to Widget_TreeMatchingHandleSignal which would also skip the children).
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @param R16 signal number
|
|
; @param R17 selector
|
|
; @param R20 mask for WIDGET_OFFS_OPTS_LO to match
|
|
; @param R21 value for WIDGET_OFFS_OPTS_LO to match
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @clobbers any, !R16, !R17, !X, !Z
|
|
|
|
Widget_TreeMatchOptsAndSendSignal:
|
|
push zl
|
|
push zh
|
|
|
|
Widget_TreeMatchOptsAndSendSignal_loop:
|
|
mov r18, zl
|
|
or r18, zh
|
|
breq Widget_TreeMatchOptsAndSendSignal_done
|
|
adiw zh:zl, WIDGET_OFFS_OPTS_LO
|
|
lpm r18, Z
|
|
sbiw zh:zl, WIDGET_OFFS_OPTS_LO
|
|
eor r18, r21 ; XOR with value (1 if different)
|
|
and r18, r20 ; AND with mask
|
|
brne Widget_TreeMatchOptsAndSendSignal_next
|
|
push r20
|
|
push r21
|
|
rcall OBJ_HandleSignalSaveInRegs
|
|
pop r21
|
|
pop r20
|
|
Widget_TreeMatchOptsAndSendSignal_next:
|
|
push r16
|
|
rcall OBJ_GetBelow ; (R16)
|
|
pop r16
|
|
brcc Widget_TreeMatchOptsAndSendSignal_done
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rjmp Widget_TreeMatchOptsAndSendSignal_loop
|
|
Widget_TreeMatchOptsAndSendSignal_done:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_TreeMatchOptsAndSendSignalToActive @global
|
|
;
|
|
; Send signal to all widgets whose WIDGET_OFFS_OPTS_LO matches the given mask/value.
|
|
; Inactive branches are skipped.
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @param R16 signal number
|
|
; @param R17 selector
|
|
; @param R20 mask for WIDGET_OFFS_OPTS_LO to match
|
|
; @param R21 value for WIDGET_OFFS_OPTS_LO to match
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @clobbers any, !R16, !R17, !X, !Z
|
|
|
|
Widget_TreeMatchOptsAndSendSignalToActive:
|
|
push zl
|
|
push zh
|
|
|
|
Widget_TreeMatchOptsAndSendSignalToActive_loop:
|
|
mov r18, zl
|
|
or r18, zh
|
|
breq Widget_TreeMatchOptsAndSendSignalToActive_done
|
|
|
|
; check flags
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
ldd r18, Y+WIDGET_SD_OFFS_FLAGS
|
|
sbrc r18, WIDGET_FLAGS_ACTIVE_BIT
|
|
rjmp Widget_TreeMatchOptsAndSendSignalToActive_checkOpts
|
|
push r16
|
|
rcall OBJ_GetBelowSkipChildren ; (R16)
|
|
pop r16
|
|
rjmp Widget_TreeMatchOptsAndSendSignalToActive_next
|
|
Widget_TreeMatchOptsAndSendSignalToActive_checkOpts:
|
|
adiw zh:zl, WIDGET_OFFS_OPTS_LO
|
|
lpm r18, Z
|
|
sbiw zh:zl, WIDGET_OFFS_OPTS_LO
|
|
eor r18, r21 ; XOR with value (1 if different)
|
|
and r18, r20 ; AND with mask
|
|
brne Widget_TreeMatchOptsAndSendSignalToActive_below
|
|
push r20
|
|
push r21
|
|
rcall OBJ_HandleSignalSaveInRegs
|
|
pop r21
|
|
pop r20
|
|
Widget_TreeMatchOptsAndSendSignalToActive_below:
|
|
push r16
|
|
rcall OBJ_GetBelow ; (R16)
|
|
pop r16
|
|
Widget_TreeMatchOptsAndSendSignalToActive_next:
|
|
brcc Widget_TreeMatchOptsAndSendSignalToActive_done
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rjmp Widget_TreeMatchOptsAndSendSignalToActive_loop
|
|
Widget_TreeMatchOptsAndSendSignalToActive_done:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Widget_TreeMatchFlagsAndSendSignalToActive @global
|
|
;
|
|
; Send signal to all widgets whose WIDGET_SD_OFFS_FLAGS matches the given mask/value.
|
|
; Inactive branches are skipped.
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @param R16 signal number
|
|
; @param R17 selector
|
|
; @param R20 mask for WIDGET_SD_OFFS_FLAGS to match
|
|
; @param R21 value for WIDGET_SD_OFFS_FLAGS to match
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @clobbers any, !R16, !R17, !X, !Z
|
|
|
|
#if 0
|
|
; non-iterative routine
|
|
Widget_TreeMatchFlagsAndSendSignalToActive:
|
|
push zl
|
|
push zh
|
|
Widget_TreeMatchFlagsAndSendSignalToActive_loop:
|
|
mov r18, zl
|
|
or r18, zh
|
|
breq Widget_TreeMatchFlagsAndSendSignalToActive_done
|
|
|
|
; check flags
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
ldd r18, Y+WIDGET_SD_OFFS_FLAGS
|
|
sbrc r18, WIDGET_FLAGS_ACTIVE_BIT
|
|
rjmp Widget_TreeMatchFlagsAndSendSignalToActive_checkFlags
|
|
push r16
|
|
rcall OBJ_GetBelowSkipChildren ; (R16)
|
|
pop r16
|
|
rjmp Widget_TreeMatchFlagsAndSendSignalToActive_next
|
|
Widget_TreeMatchFlagsAndSendSignalToActive_checkFlags:
|
|
ldd r18, Y+WIDGET_SD_OFFS_FLAGS
|
|
eor r18, r21 ; XOR with value (1 if different)
|
|
and r18, r20 ; AND with mask
|
|
brne Widget_TreeMatchFlagsAndSendSignalToActive_below
|
|
push r20
|
|
push r21
|
|
rcall OBJ_HandleSignalSaveInRegs
|
|
pop r21
|
|
pop r20
|
|
Widget_TreeMatchFlagsAndSendSignalToActive_below:
|
|
push r16
|
|
rcall OBJ_GetBelow ; (R16)
|
|
pop r16
|
|
Widget_TreeMatchFlagsAndSendSignalToActive_next:
|
|
brcc Widget_TreeMatchFlagsAndSendSignalToActive_done
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rjmp Widget_TreeMatchFlagsAndSendSignalToActive_loop
|
|
Widget_TreeMatchFlagsAndSendSignalToActive_done:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
#else
|
|
; iterative routine
|
|
|
|
Widget_TreeMatchFlagsAndSendSignalToActive:
|
|
rcall OBJ_IsObject
|
|
brcc Widget_TreeMatchFlagsAndSendSignalToActive_ret
|
|
rcall widgetTreeMatchFlagsAndSendSignalToActive
|
|
Widget_TreeMatchFlagsAndSendSignalToActive_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine widgetTreeMatchFlagsAndSendSignalToActive
|
|
;
|
|
; Send signal to all widgets whose WIDGET_SD_OFFS_FLAGS matches the given mask/value.
|
|
; Inactive branches are skipped.
|
|
;
|
|
; @param Z byte address of object (for LPM!)
|
|
; @param R16 signal number
|
|
; @param R17 selector
|
|
; @param R20 mask for WIDGET_SD_OFFS_FLAGS to match
|
|
; @param R21 value for WIDGET_SD_OFFS_FLAGS to match
|
|
; @param xl param1
|
|
; @param xh param2
|
|
; @clobbers any, !R16, !R17, !R20, !R21, !X, !Z
|
|
|
|
widgetTreeMatchFlagsAndSendSignalToActive:
|
|
push zl
|
|
push zh
|
|
; check flags
|
|
rcall Widget_GetSdramPtr ; (none)
|
|
ldd r18, Y+WIDGET_SD_OFFS_FLAGS
|
|
sbrs r18, WIDGET_FLAGS_ACTIVE_BIT
|
|
rjmp widgetTreeMatchFlagsAndSendSignalToActive_done ; skip inactive branches
|
|
eor r18, r21 ; XOR with value (1 if different)
|
|
and r18, r20 ; AND with mask
|
|
brne widgetTreeMatchFlagsAndSendSignalToActive_l1
|
|
push r20
|
|
push r21
|
|
rcall OBJ_HandleSignalSaveInRegs ; (any, !R16, !R17, !X, !Z)
|
|
pop r21
|
|
pop r20
|
|
widgetTreeMatchFlagsAndSendSignalToActive_l1:
|
|
bigcall OBJ_GetFirstChild ; R19:R18=next (none)
|
|
widgetTreeMatchFlagsAndSendSignalToActive_loop:
|
|
brcc widgetTreeMatchFlagsAndSendSignalToActive_done
|
|
mov zl, r18
|
|
mov zh, r19
|
|
rcall widgetTreeMatchFlagsAndSendSignalToActive ; (any, !R16, !R17, !R20, !R21, !X, !Z)
|
|
bigcall OBJ_GetNext ; R19:R18=next (none)
|
|
rjmp widgetTreeMatchFlagsAndSendSignalToActive_loop
|
|
|
|
widgetTreeMatchFlagsAndSendSignalToActive_done:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
#endif
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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_AlignPosXY
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @param R13:R12 width of object to align
|
|
; @return R5:R4 X
|
|
; @return R7:R6 Y
|
|
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25
|
|
|
|
Widget_AlignPosXY:
|
|
adiw zh:zl, WIDGET_OFFS_WIDTH_LO
|
|
lpm r8, Z+ ; WIDTH_LO
|
|
lpm r9, Z+
|
|
lpm r10, Z+ ; HEIGHT_LO
|
|
lpm r11, Z
|
|
sbiw zh:zl, WIDGET_OFFS_WIDTH_LO+3
|
|
|
|
adiw zh:zl, WIDGET_OFFS_OPTS_LO
|
|
lpm r24, Z+
|
|
lpm r25, Z
|
|
sbiw zh:zl, WIDGET_OFFS_OPTS_LO+1
|
|
|
|
; align horizontally
|
|
clr r17
|
|
sbrc r24, WIDGET_OPTSLO_BORDER_BIT
|
|
ori r17, (1<<WIDGET_1DALIGN_BORDER_BIT)
|
|
sbrc r25, WIDGET_OPTSHI_HALIGNRIGHT_BIT
|
|
ori r17, (1<<WIDGET_1DALIGN_END_BIT)
|
|
sbrc r25, WIDGET_OPTSHI_HALIGNCENTER_BIT
|
|
ori r17, (1<<WIDGET_1DALIGN_CENTER_BIT)
|
|
mov r18, r8 ; widget width
|
|
mov r19, r9
|
|
rcall Widget_AlignPos1D ; (r16, r18, r19)
|
|
mov r4, r22
|
|
mov r5, r23
|
|
|
|
; align vertically
|
|
clr r17
|
|
sbrc r24, WIDGET_OPTSLO_BORDER_BIT
|
|
ori r17, (1<<WIDGET_1DALIGN_BORDER_BIT)
|
|
sbrc r25, WIDGET_OPTSHI_VALIGNBOTTOM_BIT
|
|
ori r17, (1<<WIDGET_1DALIGN_END_BIT)
|
|
sbrc r25, WIDGET_OPTSHI_VALIGNCENTER_BIT
|
|
ori r17, (1<<WIDGET_1DALIGN_CENTER_BIT)
|
|
ldi r16, STYLE_WIN_FONT_HEIGHT ; use font height
|
|
mov r12, r16
|
|
clr r13
|
|
mov r18, r10 ; widget height
|
|
mov r19, r11
|
|
rcall Widget_AlignPos1D ; (r16, r18, r19)
|
|
mov r6, r22
|
|
mov r7, r23
|
|
|
|
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_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 widgetLoadCoordsForFullWidget
|
|
;
|
|
; @param Z byte address of widget object (for LPM!)
|
|
; @return r5:r4 X (0)
|
|
; @return r7:r6 Y (0)
|
|
; @return r9:r8 widget width
|
|
; @return r11:R10 widget height
|
|
; @clobbers none
|
|
|
|
widgetLoadCoordsForFullWidget:
|
|
clr r4
|
|
clr r5
|
|
clr r6
|
|
clr r7
|
|
adiw zh:zl, WIDGET_OFFS_WIDTH_LO
|
|
lpm r8, Z+ ; WIDTH_LO
|
|
lpm r9, Z+
|
|
lpm r10, Z+ ; HEIGHT_LO
|
|
lpm r11, Z
|
|
sbiw zh:zl, WIDGET_OFFS_WIDTH_LO+3
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
#endif
|