gui2: added Button, RootWindow. Touch now works again.

This commit is contained in:
Martin Preuss
2026-01-19 18:33:36 +01:00
parent 715c4f22c4
commit edc291261f
6 changed files with 959 additions and 527 deletions

View File

@@ -309,7 +309,9 @@ test:
.include "modules/lcd2/gui2/object.asm"
.include "modules/lcd2/gui2/widget.asm"
.include "modules/lcd2/gui2/rootwidget.asm"
.include "modules/lcd2/gui2/label.asm"
.include "modules/lcd2/gui2/button.asm"
.include "modules/lcd2/gui2/imageview.asm"
.include "modules/lcd2/gui2/sensorwatch.asm"
.include "modules/lcd2/gui2/valuelabel.asm"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
; ***************************************************************************
; 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
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Button_OnTouch @global
;
; @param Z byte address of widget object (for LPM!)
; @param X pointer to TOUCH event (see @ref WIDGET_DATA_TOUCH_OFFS_X_LO)
; @return CFLAG set if signal handled
; @clobbers any, !Z
Button_OnTouch:
#if 0
push zl
push zh
bigcall Widget_GetApp
mov zl, r18
mov zh, r19
ldi r16, GUIAPP_SIGNAL_DEBUG
clr r17
bigcall OBJ_HandleSignal
pop zh
pop zl
#endif
rcall Widget_GetSdramPtr ; Y:=SDRAM data for widget
; 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 Button_OnTouch_up
; down (active touch)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
sbrc r16, WIDGET_FLAGS_PRESSED_BIT
rjmp Button_OnTouch_ret ; already pressed, jmp
; newly pressed
rcall widgetLoadCoordsForFullWidget ; get X, Y, W, H (none)
rcall Widget_MakeAbsPos ; (R16, R17)
rcall Widget_IsPointInRect ; (R16, R17)
brcc Button_OnTouch_ret ; touch not inside this widget, jmp
; touch down inside this widget, handle
bigcall Widget_GrabTouchEvents ; (r16, r17, r18, r19, X)
brcc Button_OnTouch_ret
ldi r16, (1<<WIDGET_FLAGS_PRESSED_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
push yl
push yh
bigcall Widget_AddFlagsDown ; (R17, R18, R19, R22, R23, Y)
pop yh
pop yl
rjmp Button_OnTouch_ret
Button_OnTouch_up:
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
sbrs r16, WIDGET_FLAGS_PRESSED_BIT
rjmp Button_OnTouch_ret
; was pressed, not any more
bigcall Widget_UngrabTouchEvents ; (r16, r17, r18, r19, X)
push yl
push yh
ldi r16, (1<<WIDGET_FLAGS_PRESSED_BIT)
bigcall Widget_SubFlagsDown ; (R17, R18, R19, R22, R23, Y)
ldi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall Widget_AddFlagsDown ; (R17, R18, R19, R22, R23, Y)
ldi r16, WIDGET_SIGNAL_CLICKED ; emit "CLICKED" signal
bigcall OBJ_EmitSignal
pop yh
pop yl
Button_OnTouch_ret:
sec
ret
; @end
#endif

View File

@@ -26,7 +26,8 @@
.equ GUIAPP_SIGNAL_RAISE = OBJECT_SIGNAL_NEXTFREE+0 ; app->cntrl: X=WIDGET to raise
.equ GUIAPP_SIGNAL_SHOW = OBJECT_SIGNAL_NEXTFREE+1 ; cntrl->app
.equ GUIAPP_SIGNAL_HIDE = OBJECT_SIGNAL_NEXTFREE+2 ; cntrl->app
.equ GUIAPP_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+3
.equ GUIAPP_SIGNAL_DEBUG = OBJECT_SIGNAL_NEXTFREE+3
.equ GUIAPP_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+4
; SDRAM data for guiapp
.equ GUIAPP_SD_OFFS_FLAGS = 0
@@ -75,7 +76,7 @@ GuiApp_Init:
; ---------------------------------------------------------------------------
; @routine GuiApp_Every100ms
; @routine GuiApp_Every100ms @global
;
; @param Z byte address of guiapp object (for LPM!)
@@ -89,7 +90,7 @@ GuiApp_Every100ms:
; ---------------------------------------------------------------------------
; @routine GuiApp_Every100ms
; @routine GuiApp_MsgReceived @global
;
; @param Z byte address of guiapp object (for LPM!)
@@ -109,7 +110,7 @@ GuiApp_MsgReceived:
GuiApp_OnTimer:
; check for touch event
; rcall guiAppCheckTouch
rcall guiAppCheckTouch
; send timer signal to all accepting widgets
push zl
@@ -154,14 +155,25 @@ GuiApp_OnTimer_ret:
; @param X pointer to touch event in SDRAM
GuiApp_OnTouch:
bigcall onAppDebug
push zl
push zh
adiw zh:zl, GUIAPP_OFFS_ROOTWIDGET_LO
lpm r18, Z+
lpm zh, Z
rcall GuiApp_GetSdramPtr
ldd r18, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO
ldd r19, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI
mov r16, r18
or r16, r19
breq GuiApp_OnTouch_sendToAll
mov zl, r18
or r18, zh
breq GuiApp_OnTouch_done
mov zh, r19
ldi r16, WIDGET_SIGNAL_TOUCH
clr r17
bigcall OBJ_HandleSignal
rjmp GuiApp_OnTouch_done
GuiApp_OnTouch_sendToAll:
rcall GuiApp_GetRootWidgetToZ
brcc GuiApp_OnTouch_done
; send touch signal (TODO: check for grabbed touch)
bigcall Widget_Tree_SendTouchSignal
GuiApp_OnTouch_done:
@@ -326,6 +338,62 @@ GuiApp_ShowView_ret:
; ---------------------------------------------------------------------------
; @routine GuiApp_GrabTouchEvents
;
; @param Z byte address of gui app object (for LPM!)
; @param X byte address of widget grabbing touch events
; @return CFLAG set if grabbed, cleared otherwise
; @clobbers R16, R17, Y
GuiApp_GrabTouchEvents:
rcall OBJ_IsObject ; (none)
brcc GuiApp_GrabTouchEvents_ret
rcall GuiApp_GetSdramPtr ; (none)
ldd r16, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO
ldd r17, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI
or r16, r17
clc
brne GuiApp_GrabTouchEvents_ret ; only grab if not already grabbed!
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO, xl
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI, xh
sec
GuiApp_GrabTouchEvents_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_UngrabTouchEvents
;
; @param Z byte address of gui app object (for LPM!)
; @param X byte address of widget ungrabbing touch events
; @return CFLAG set if ungrabbed, cleared otherwise
; @clobbers R16, R17
GuiApp_UngrabTouchEvents:
rcall OBJ_IsObject ; (none)
brcc GuiApp_UngrabTouchEvents_ret
rcall GuiApp_GetSdramPtr ; (none)
ldd r16, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO
ldd r17, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI
eor r16, xl
eor r17, xh
or r16, r17
clc
brne GuiApp_UngrabTouchEvents_ret ; only ungrab same widget!
clr r16
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO, r16
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI, r16
sec
GuiApp_UngrabTouchEvents_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppHideCurrent
;

View File

@@ -0,0 +1,56 @@
; ***************************************************************************
; 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_ROOTWIDGET_ASM
#define AQH_AVR_GUI2_ROOTWIDGET_ASM
; ***************************************************************************
; defines
; RootWidget in flash
.equ ROOTWIDGET_OFFS_BEGIN = WIDGET_SIZE
.equ ROOTWIDGET_OFFS_APP_LO = ROOTWIDGET_OFFS_BEGIN+0
.equ ROOTWIDGET_OFFS_APP_HI = ROOTWIDGET_OFFS_BEGIN+1
.equ ROOTWIDGET_SIZE = ROOTWIDGET_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine RootWidget_GetApp @global
;
; @param Z byte address of object (for LPM!)
; @return R19:R18 byte address pointer to GuiApp
; @clobbers none
RootWidget_GetApp:
bigcall OBJ_IsObject ; (none)
brcc RootWidget_GetApp_ret
adiw zh:zl, ROOTWIDGET_OFFS_APP_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, ROOTWIDGET_OFFS_APP_LO+1
sec
RootWidget_GetApp_ret:
ret
; @end
#endif

View File

@@ -118,85 +118,6 @@ Widget_OnCreate:
; ---------------------------------------------------------------------------
; @routine Widget_OnTouch @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_OnTouch:
; check whether inputs are handled by this widget
adiw zh:zl, WIDGET_OFFS_OPTS_LO
lpm r16, Z
sbiw zh:zl, WIDGET_OFFS_OPTS_LO
andi r16, (1<<WIDGET_OPTSLO_INPUT_BIT)
clc
breq Widget_OnTouch_ret
rcall Widget_GetSdramPtr
; check whether widget is active
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
andi r17, (1<<WIDGET_FLAGS_ACTIVE_BIT)
breq Widget_OnTouch_secRet ; nope, jmp
; 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
; check for change of touch press
mov r16, r22
andi r16, (1<<DISPLAY_IFLAGS_CHGPRESS_BIT)
breq Widget_OnTouch_secRet ; no press change, jmp
; check for position inside this widget
rcall widgetLoadCoordsForFullWidget
rcall Widget_MakeAbsPos ; (R16, R17)
rcall Widget_IsPointInRect ; (R16, R17)
sbci r16, 0 ; r16=ff if touched inside, 0 otherwise
; touch changed, check whether touch came down or up
mov r18, r22
andi r18, (1<<DISPLAY_IFLAGS_PRESSED_BIT)
breq Widget_OnTouch_up
; touch came down
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
andi r17, (1<<WIDGET_FLAGS_PRESSED_BIT)
brne Widget_OnTouch_secRet ; already down
tst r16 ; down inside this widget?
brne Widget_OnTouch_secRet ; nope, jmp
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_PRESSED_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT) ; up, dirty
std Y+WIDGET_SD_OFFS_FLAGS, r17
rjmp Widget_OnTouch_secRet
Widget_OnTouch_up:
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
andi r17, (1<<WIDGET_FLAGS_PRESSED_BIT)
breq Widget_OnTouch_secRet ; already up
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
cbr r17, (1<<WIDGET_FLAGS_PRESSED_BIT) ; up
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r17
tst r16 ; was touch lost inside this widget?
brne Widget_OnTouch_secRet ; nope, jmp
; emit "CLICKED" signal
ldi r16, WIDGET_SIGNAL_CLICKED
rcall OBJ_EmitSignal
Widget_OnTouch_secRet:
sec
Widget_OnTouch_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_OnDraw @global
;
@@ -278,8 +199,8 @@ Widget_IsPointInRect:
mov r16, r20 ; checkY-widgetY
mov r17, r21
sub r16, r8
sbc r17, r9
sub r16, r6
sbc r17, r7
brcs Widget_IsPointInRect_no ; jmp if above widget
sub r16, r10 ; sub height
sbc r17, r11
@@ -348,6 +269,110 @@ Widget_GetSdramPtr:
; ---------------------------------------------------------------------------
; @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
;
@@ -1264,13 +1289,14 @@ Widget_CalcStringWidthFLASH_done:
; ---------------------------------------------------------------------------
; @routine Widget_AlignPosXY
; @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