gui2: added generic button class

this gives child elements a button behavior.
This commit is contained in:
Martin Preuss
2026-03-09 18:20:51 +01:00
parent f5e19ac0a1
commit 2827f4e063
6 changed files with 598 additions and 18 deletions

View File

@@ -265,11 +265,34 @@ test:
ldi r20, LOW(RESSSOURCE_TXT_LIVINGROOM) ldi r20, LOW(RESSSOURCE_TXT_LIVINGROOM)
ldi r21, HIGH(RESSSOURCE_TXT_LIVINGROOM) ldi r21, HIGH(RESSSOURCE_TXT_LIVINGROOM)
bigcall MainWindow_new bigcall MainWindow_new
bigcall MainWindow_GetContentWidget
brcc DEBUG_STOP
mov xl, yl mov xl, yl
mov xh, yh mov xh, yh
push xl
push xh
mov xl, r18
mov xh, r19
ldi r16, (1<<OBJECT_OPTS_TIMER_BIT) | (1<<WIDGET_OPTS_INPUT_BIT) ; OPTS
ldi r17, (WIDGET_PACK_BEGIN<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) ; PACK
ldi r20, BUTTON_MODE_NORMAL
bigcall Button_new
mov xl, yl
mov xh, yh
ldi r16, (1<<WIDGET_OPTS_BORDER_BIT)
ldi r17, (WIDGET_PACK_BEGIN<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) |\
(WIDGET_PACK_BEGIN<<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VCONTENT0_BIT)
ldi r20, LOW(RESSSOURCE_TXT_BUERO)
ldi r21, HIGH(RESSSOURCE_TXT_BUERO)
bigcall Label_new
pop xh
pop xl
pop yh pop yh
pop yl pop yl
brcc DEBUG_STOP brcc DEBUG_STOP
bigcall GuiApp_EnterWindow bigcall GuiApp_EnterWindow
brcc DEBUG_STOP3 brcc DEBUG_STOP3
@@ -329,6 +352,7 @@ DEBUG_STOP3:
.include "modules/lcd2/gui2/base/mainwindow.asm" .include "modules/lcd2/gui2/base/mainwindow.asm"
.include "modules/lcd2/gui2/base/rootwindow.asm" .include "modules/lcd2/gui2/base/rootwindow.asm"
.include "modules/lcd2/gui2/base/label.asm" .include "modules/lcd2/gui2/base/label.asm"
.include "modules/lcd2/gui2/base/button.asm"

View File

@@ -0,0 +1,343 @@
; ***************************************************************************
; 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_BUTTON_ASM
#define AQH_AVR_GUI2_BUTTON_ASM
; ***************************************************************************
; defines
.equ BUTTON_OFFS_BEGIN = WIDGET_SIZE
.equ BUTTON_OFFS_MODE = BUTTON_OFFS_BEGIN+0
.equ BUTTON_OFFS_STATE = BUTTON_OFFS_BEGIN+1
.equ BUTTON_OFFS_TIMER = BUTTON_OFFS_BEGIN+2
.equ BUTTON_SIZE = BUTTON_OFFS_BEGIN+3
.equ BUTTON_REPEAT_TIMER_WAITREPEAT = 10
.equ BUTTON_REPEAT_TIMER_REPEAT = 7
; button modes
.equ BUTTON_MODE_NORMAL = 0
.equ BUTTON_MODE_REPEATED = 1
; button states
.equ BUTTON_STATE_INACTIVE = 0
.equ BUTTON_STATE_ACTIVE = 1
.equ BUTTON_STATE_WAITREPEAT = 2
.equ BUTTON_STATE_REPEATING = 3
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Button_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
; @param r20 mode
; @clobbers any
Button_new:
push r20
ldi r24, LOW(BUTTON_SIZE)
ldi r25, HIGH(BUTTON_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc Button_new_ret
rcall Button_Init ; (r16, r17, X)
sec
Button_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 mode
; @clobbers r16, r17, X
Button_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; setup button data
std Y+BUTTON_OFFS_MODE, r20
; set default signal map
ldi r16, LOW(Button_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(Button_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTouchBegin @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTouchBegin:
ldi r16, (1<<WIDGET_FLAGS_ACTIVATED_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall OBJ_AddFlagsDown ; (r17, r18, r19)
ldd r16, Y+BUTTON_OFFS_MODE
cpi r16, BUTTON_MODE_REPEATED
breq Button_OnTouchBegin_repeated
ldi r16, BUTTON_STATE_ACTIVE
std Y+BUTTON_OFFS_STATE, r16
clr r16
std Y+BUTTON_OFFS_TIMER, r16
rjmp Button_OnTouchBegin_done
Button_OnTouchBegin_repeated:
ldi r16, BUTTON_STATE_WAITREPEAT
std Y+BUTTON_OFFS_STATE, r16
ldi r16, BUTTON_REPEAT_TIMER_WAITREPEAT
std Y+BUTTON_OFFS_TIMER, r16
Button_OnTouchBegin_done:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTouchEnd @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTouchEnd:
ldi r16, (1<<WIDGET_FLAGS_ACTIVATED_BIT)
bigcall OBJ_SubFlagsDown ; (r17, r18, r19)
ldi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall OBJ_AddFlagsDown ; (r17, r18, r19)
clr r16
std Y+BUTTON_OFFS_TIMER, r16
ldd r16, Y+BUTTON_OFFS_STATE
cpi r16, BUTTON_STATE_REPEATING
breq Button_OnTouchEnd_done
ldi r16, WIDGET_SIGNAL_COMMAND
bigcall OBJ_EmitSignal
Button_OnTouchEnd_done:
ldi r16, BUTTON_STATE_INACTIVE
std Y+BUTTON_OFFS_STATE, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTouchMove @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTouchMove:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTimer @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTimer:
ldd r16, Y+BUTTON_OFFS_TIMER
tst r16
breq Button_OnTimer_ret
dec r16
std Y+BUTTON_OFFS_TIMER, r16
brne Button_OnTimer_ret
; timer elapsed
ldd r17, Y+BUTTON_OFFS_STATE
cpi r17, BUTTON_STATE_WAITREPEAT
breq Button_OnTimer_waitRepeat
cpi r17, BUTTON_STATE_REPEATING
breq Button_OnTimer_repeating
rjmp Button_OnTimer_ret
Button_OnTimer_waitRepeat:
ldi r17, BUTTON_STATE_REPEATING
std Y+BUTTON_OFFS_STATE, r17
Button_OnTimer_repeating:
ldi r16, BUTTON_REPEAT_TIMER_REPEAT
std Y+BUTTON_OFFS_TIMER, r16
ldi r16, WIDGET_SIGNAL_COMMAND
bigcall OBJ_EmitSignal
Button_OnTimer_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Button_OnGetDefaultWidth:
bigcall OBJ_GetFirstChild
brcc Button_OnGetDefaultWidth_ret
push yl
push yh
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultWidth
pop yh
pop yl
Button_OnGetDefaultWidth_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Button_OnGetDefaultHeight:
bigcall OBJ_GetFirstChild
brcc Button_OnGetDefaultHeight_ret
push yl
push yh
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultHeight
pop yh
pop yl
Button_OnGetDefaultHeight_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnLayout @global
;
; @param Y address of widget
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnLayout:
bigcall OBJ_GetFirstChild
brcc Button_OnLayout_ret
ldd r16, Y+WIDGET_OFFS_WIDTH_LO
ldd r17, Y+WIDGET_OFFS_WIDTH_HI
ldd r20, Y+WIDGET_OFFS_HEIGHT_LO
ldd r21, Y+WIDGET_OFFS_HEIGHT_HI
push yl
push yh
mov yl, r18
mov yh, r19
std Y+WIDGET_OFFS_WIDTH_LO, r16
std Y+WIDGET_OFFS_WIDTH_HI, r17
std Y+WIDGET_OFFS_HEIGHT_LO, r20
std Y+WIDGET_OFFS_HEIGHT_HI, r21
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
; force layout and redraw
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_LAYOUT_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
pop yh
pop yl
Button_OnLayout_ret:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
sec
ret
; @end
; ***************************************************************************
; data in FLASH
Button_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, OBJECT_SIGNAL_TIMER, LOW(Button_OnTimer), HIGH(Button_OnTimer)
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDrawNop), HIGH(Widget_OnDrawNop)
.db 0, WIDGET_SIGNAL_TOUCH, LOW(Widget_OnTouch), HIGH(Widget_OnTouch)
.db 0, WIDGET_SIGNAL_TOUCH_BEGIN, LOW(Button_OnTouchBegin), HIGH(Button_OnTouchBegin)
.db 0, WIDGET_SIGNAL_TOUCH_END, LOW(Button_OnTouchEnd), HIGH(Button_OnTouchEnd)
.db 0, WIDGET_SIGNAL_TOUCH_MOVE, LOW(Button_OnTouchMove), HIGH(Button_OnTouchMove)
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(Button_OnLayout), HIGH(Button_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(Button_OnGetDefaultWidth), HIGH(Button_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(Button_OnGetDefaultHeight), HIGH(Button_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -182,7 +182,7 @@ GuiApp_PreventScreenSaver_ret:
; @param Y address of object in SDRAM ; @param Y address of object in SDRAM
; @param X byte address of widget grabbing touch events ; @param X byte address of widget grabbing touch events
; @return CFLAG set if grabbed, cleared otherwise ; @return CFLAG set if grabbed, cleared otherwise
; @clobbers R16, R17, Y ; @clobbers R16, R17
GuiApp_GrabTouchEvents: GuiApp_GrabTouchEvents:
ldd r16, Y+GUIAPP_OFFS_TOUCHWIDGET_LO ldd r16, Y+GUIAPP_OFFS_TOUCHWIDGET_LO
@@ -356,8 +356,8 @@ GuiApp_OnDestroy:
; @clobbers any, !Y ; @clobbers any, !Y
GuiApp_OnTimer: GuiApp_OnTimer:
; rcall guiAppCheckTouch ; (any, !Y) rcall guiAppCheckTouch ; (any, !Y)
; rcall guiAppSendTimerEvents ; (any, !Y) rcall guiAppSendTimerEvents ; (any, !Y)
rcall guiAppCheckSendGuiEvents ; (any, !Y) rcall guiAppCheckSendGuiEvents ; (any, !Y)
sec sec
ret ret
@@ -372,6 +372,8 @@ GuiApp_OnTimer:
; @param X pointer to message received in SDRAM ; @param X pointer to message received in SDRAM
GuiApp_OnMsgReceived: GuiApp_OnMsgReceived:
rcall guiAppSendRootMsgEvents
sec
ret ret
; @end ; @end
@@ -381,6 +383,7 @@ GuiApp_OnMsgReceived:
; @routine GuiApp_OnTouch ; @routine GuiApp_OnTouch
; ;
; @param Y address of object in SDRAM ; @param Y address of object in SDRAM
; @param X pointer to touch object (see @ref WIDGET_TOUCH_OFFS_X_LO)
; @clobbers any, !Y ; @clobbers any, !Y
GuiApp_OnTouch: GuiApp_OnTouch:
@@ -629,6 +632,7 @@ guiAppCheckSendGuiEvents_done:
; Send touch events to current window or grabbing widget. ; Send touch events to current window or grabbing widget.
; ;
; @param Y ptr to GUIAPP ; @param Y ptr to GUIAPP
; @param X pointer to touch object (see @ref WIDGET_TOUCH_OFFS_X_LO)
; @clobbers any, !Y ; @clobbers any, !Y
guiAppSendTouchEvents: guiAppSendTouchEvents:
@@ -677,7 +681,7 @@ guiAppSendTouchEvents_done:
; @clobbers any, !Y ; @clobbers any, !Y
guiAppSendRootMsgEvents: guiAppSendRootMsgEvents:
ldi r16, WIDGET_SIGNAL_TOUCH ldi r16, OBJECT_SIGNAL_RECVMSG
clr r17 clr r17
ldi r20, (1<<OBJECT_OPTS_MSGRECV_BIT) ldi r20, (1<<OBJECT_OPTS_MSGRECV_BIT)
ldi r21, (1<<OBJECT_OPTS_MSGRECV_BIT) ldi r21, (1<<OBJECT_OPTS_MSGRECV_BIT)
@@ -757,7 +761,8 @@ GuiApp_DefaultSignalmap:
; header ; header
.dw Object_DefaultSignalmap*2 ; next table to use .dw Object_DefaultSignalmap*2 ; next table to use
; entries ; entries
.db 0, OBJECT_SIGNAL_TIMER, LOW(GuiApp_OnTimer), HIGH(GuiApp_OnTimer) .db 0, OBJECT_SIGNAL_TIMER, LOW(GuiApp_OnTimer), HIGH(GuiApp_OnTimer)
.db 0, WIDGET_SIGNAL_TOUCH, LOW(GuiApp_OnTouch), HIGH(GuiApp_OnTouch)
.db 0, OBJECT_SIGNAL_DESTROY, LOW(GuiApp_OnDestroy), HIGH(GuiApp_OnDestroy) .db 0, OBJECT_SIGNAL_DESTROY, LOW(GuiApp_OnDestroy), HIGH(GuiApp_OnDestroy)
.db 0, 0, 0, 0 ; end of table .db 0, 0, 0, 0 ; end of table

View File

@@ -337,19 +337,19 @@ OBJ_GetLastChild_ret:
; @param R16 idx of child to get (starting at 0) ; @param R16 idx of child to get (starting at 0)
; @return CFLAG set, if found, cleared otherwise ; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object ; @return r19:r18 resulting object
; @clobbers none ; @clobbers r16
OBJ_GetChildAt: OBJ_GetChildAt:
push yl push yl
push yh push yh
rcall OBJ_GetFirstChild ; R19:R18=obj (none) rcall OBJ_GetFirstChild ; R19:R18=obj (none)
brcc OBJ_GetChildAt_ret brcc OBJ_GetChildAt_ret
OBJ_GetChildAt_loop: OBJ_GetChildAt_loop:
tst r16 tst r16
breq OBJ_GetChildAt_secRet breq OBJ_GetChildAt_secRet
mov yl, r18 mov yl, r18
mov yh, r19 mov yh, r19
dec r16
rcall OBJ_GetNext ; R19:R18=obj (none) rcall OBJ_GetNext ; R19:R18=obj (none)
brcs OBJ_GetChildAt_loop brcs OBJ_GetChildAt_loop
rjmp OBJ_GetChildAt_ret ; idx too high, not found rjmp OBJ_GetChildAt_ret ; idx too high, not found

View File

@@ -162,8 +162,7 @@ RootWindow_DefaultSignalmap:
RootWindow_DefaultStyle: RootWindow_DefaultStyle:
.dw DISPLAY_COLOR_BLACK ; frontCol_norm .dw DISPLAY_COLOR_BLACK ; frontCol_norm
; .dw DISPLAY_COLOR_LIGHTGREY ; backCol_norm .dw DISPLAY_COLOR_LIGHTGREY ; backCol_norm
.dw DISPLAY_COLOR_YELLOW ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm .dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm .dw DISPLAY_COLOR_WHITE ; shadowCol_norm

View File

@@ -91,11 +91,15 @@
.equ WIDGET_SIGNAL_LAYOUT = OBJECT_SIGNAL_NEXTFREE+2 .equ WIDGET_SIGNAL_LAYOUT = OBJECT_SIGNAL_NEXTFREE+2
.equ WIDGET_SIGNAL_DRAW = OBJECT_SIGNAL_NEXTFREE+3 .equ WIDGET_SIGNAL_DRAW = OBJECT_SIGNAL_NEXTFREE+3
.equ WIDGET_SIGNAL_TOUCH = OBJECT_SIGNAL_NEXTFREE+4 .equ WIDGET_SIGNAL_TOUCH = OBJECT_SIGNAL_NEXTFREE+4
.equ WIDGET_SIGNAL_CLICKED = OBJECT_SIGNAL_NEXTFREE+5 .equ WIDGET_SIGNAL_COMMAND = OBJECT_SIGNAL_NEXTFREE+5
.equ WIDGET_SIGNAL_SETVALUE = OBJECT_SIGNAL_NEXTFREE+6 .equ WIDGET_SIGNAL_CHANGE = OBJECT_SIGNAL_NEXTFREE+6
.equ WIDGET_SIGNAL_GETVALUE = OBJECT_SIGNAL_NEXTFREE+7 .equ WIDGET_SIGNAL_SETVALUE = OBJECT_SIGNAL_NEXTFREE+7
.equ WIDGET_SIGNAL_KEEPALIVE = OBJECT_SIGNAL_NEXTFREE+8 .equ WIDGET_SIGNAL_GETVALUE = OBJECT_SIGNAL_NEXTFREE+8
.equ WIDGET_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+9 .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_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+13
; values for signals WIDGET_SIGNAL_SETVALUE and WIDGET_SIGNAL_GETVALUE ; values for signals WIDGET_SIGNAL_SETVALUE and WIDGET_SIGNAL_GETVALUE
.equ WIDGET_VALUE_DEFAULT_WIDTH = 1 .equ WIDGET_VALUE_DEFAULT_WIDTH = 1
@@ -335,6 +339,133 @@ Widget_GetDefaultHeight_ret:
; ---------------------------------------------------------------------------
; @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_OnDraw @global ; @routine Widget_OnDraw @global
; ;
@@ -470,6 +601,84 @@ Widget_OnGetValue_ret:
; ---------------------------------------------------------------------------
; @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 ; @routine Widget_Clear @global
; ;
@@ -477,7 +686,7 @@ Widget_OnGetValue_ret:
; @clobbers any, !Y ; @clobbers any, !Y
Widget_Clear: Widget_Clear:
rcall widgetLoadDimsForFullWidget ; (none) rcall Widget_LoadDimsForFullWidget ; (none)
rcall Widget_MakeAbsPos ; (r16, r17, r18, r19) rcall Widget_MakeAbsPos ; (r16, r17, r18, r19)
rcall Widget_SelectColors ; (R16) rcall Widget_SelectColors ; (R16)
mov r2, r0 ; use background mov r2, r0 ; use background
@@ -495,7 +704,7 @@ Widget_Clear:
; @clobbers any, !Y ; @clobbers any, !Y
Widget_DrawBorder: Widget_DrawBorder:
rcall widgetLoadDimsForFullWidget ; (none) rcall Widget_LoadDimsForFullWidget ; (none)
rcall Widget_MakeAbsPos ; (R16, R17) rcall Widget_MakeAbsPos ; (R16, R17)
rcall Widget_SelectBorderColors ; (R16) rcall Widget_SelectBorderColors ; (R16)
bigcall Display_DrawRect bigcall Display_DrawRect
@@ -987,7 +1196,7 @@ widgetDrawChar_done:
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine widgetLoadDimsForFullWidget ; @routine Widget_LoadDimsForFullWidget
; ;
; @param Y address of widget ; @param Y address of widget
; @return r5:r4 X (0) ; @return r5:r4 X (0)
@@ -996,7 +1205,7 @@ widgetDrawChar_done:
; @return r11:R10 widget height ; @return r11:R10 widget height
; @clobbers none ; @clobbers none
widgetLoadDimsForFullWidget: Widget_LoadDimsForFullWidget:
clr r4 clr r4
clr r5 clr r5
clr r6 clr r6