gui: started working on keypads.

This commit is contained in:
Martin Preuss
2026-05-06 00:26:08 +02:00
parent 0771986b28
commit 4d57f15dad
3 changed files with 747 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
; ***************************************************************************
; 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_GUI_BASE_D_NUMINPUT_ASM
#define AQH_AVR_GUI_BASE_D_NUMINPUT_ASM
; ***************************************************************************
; defines
.equ DLGNUMINPUT_OFFS_BEGIN = MAINWINDOW_SIZE
.equ DLGNUMINPUT_SIZE = DLGNUMINPUT_OFFS_BEGIN+0
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine DlgNumInput_new @global
;
; @param Y pointer to GUIAPP
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
DlgNumInput_new:
bigcall GuiApp_GetRootWindow
brcc DlgNumInput_new_ret
push r20
push r21
mov xl, r18 ; use root window as parent for main window
mov xh, r19
ldi r24, LOW(DLGNUMINPUT_SIZE)
ldi r25, HIGH(DLGNUMINPUT_SIZE)
bigcall Object_Alloc ; Y=space (!r16, !r17, !X)
pop r21
pop r20
brcc DlgNumInput_new_ret
rcall DlgNumInput_Init
DlgNumInput_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine DlgNumInput_Init @global
;
; @param Y pointer to newly allocated widget data
; @param X pointer to root window
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
; @clobbers any, !Y
DlgNumInput_Init:
ldi r16, 0 ; OPTS
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT) ; PACK
bigcall MainWindow_new ; Y=main window
brcc DlgNumInput_Init_ret
bigcall MainWindow_GetContentWidget ; r19:r18=content window
brcc DlgNumInput_Init_ret
mov xl, r18 ; use content window as parent
mov xh, r19
; Y=MainWindow
push yl ; main window
push yh
push xl ; content window
push xh
rcall dlgNumInputCreateContent
pop xh ; content window
pop xl
; TODO: create button line (OK, ABORT)
bigcall C03App_CreateBackButton
pop yh ; main window
pop yl
DlgNumInput_Init_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine dlgNumInputCreateContent
;
; @param Y pointer to this main window
; @param X pointer to content window of this MainWindow (is a VLayout, becomes parent)
; @return CFLAG set of okay, cleared otherwise
dlgNumInputCreateContent:
; create input field
ldi r16, (1<<WIDGET_OPTS_BORDER_BIT)
ldi r17, (WIDGET_PACK_CENTER<<WIDGET_PACK_HSELF0_BIT) | \
(WIDGET_PACK_BEGIN <<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_END <<WIDGET_PACK_HCONTENT0_BIT) | \
(WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT) ; PACK
clr r20 ; number of postkomma digits
ldi r21, 10 ; max number of digits
push xl
push xh
bigcall ValueLabel_new
pop xh
pop xl
brcc dlgNumInputCreateContent_ret
; create numeric keypad
ldi r16, (1<<WIDGET_OPTS_BORDER_BIT)
ldi r17, (WIDGET_PACK_CENTER<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_CENTER <<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
push xl
push xh
bigcall NumKeyPad_new
pop xh
pop xl
brcc dlgNumInputCreateContent_ret
sec
dlgNumInputCreateContent_ret:
ret
; @end
#endif

View File

@@ -0,0 +1,551 @@
; ***************************************************************************
; 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_KEYPAD_ASM
#define AQH_AVR_GUI2_KEYPAD_ASM
; ***************************************************************************
; defines
.equ KEYPAD_OFFS_BEGIN = WIDGET_SIZE
.equ KEYPAD_OFFS_KEYWIDTH = KEYPAD_OFFS_BEGIN+0
.equ KEYPAD_OFFS_KEYHEIGHT = KEYPAD_OFFS_BEGIN+1
.equ KEYPAD_OFFS_KEYHDIST = KEYPAD_OFFS_BEGIN+2
.equ KEYPAD_OFFS_KEYVDIST = KEYPAD_OFFS_BEGIN+3
.equ KEYPAD_OFFS_TXTOFFS_X = KEYPAD_OFFS_BEGIN+4
.equ KEYPAD_OFFS_TXTOFFS_Y = KEYPAD_OFFS_BEGIN+5
.equ KEYPAD_OFFS_KEYSPERROW = KEYPAD_OFFS_BEGIN+6
.equ KEYPAD_OFFS_ROWS = KEYPAD_OFFS_BEGIN+7
.equ KEYPAD_OFFS_KEYS_LO = KEYPAD_OFFS_BEGIN+8
.equ KEYPAD_OFFS_KEYS_HI = KEYPAD_OFFS_BEGIN+9
.equ KEYPAD_OFFS_SELECTEDKEY = KEYPAD_OFFS_BEGIN+10
.equ KEYPAD_SIZE = KEYPAD_OFFS_BEGIN+11
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine KeyPad_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 number of keys per row
; @param r21 number of rows
; @param r23:r22 pointer to null-terminated string containing keys
; @clobbers any
KeyPad_new:
push r20
push r21
push r22
push r23
ldi r24, LOW(KEYPAD_SIZE)
ldi r25, HIGH(KEYPAD_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r23
pop r22
pop r21
pop r20
brcc KeyPad_new_ret
rcall KeyPad_Init
sec
KeyPad_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine KeyPad_Init @global
;
; @param 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 number of keys per row
; @param r21 number of rows
; @param r23:r22 pointer to null-terminated string containing keys
; @clobbers any
KeyPad_Init:
push r20
push r21
push r22
push r23
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r23
pop r22
pop r21
pop r20
std Y+KEYPAD_OFFS_KEYSPERROW, r20
std Y+KEYPAD_OFFS_ROWS, r21
std Y+KEYPAD_OFFS_KEYS_LO, r22
std Y+KEYPAD_OFFS_KEYS_HI, r23
; set input and timer opts
ldd r16, Y+OBJECT_OFFS_OPTS
sbr r16, (1<<WIDGET_OPTS_INPUT_BIT) | (1<<OBJECT_OPTS_TIMER_BIT)
std Y+OBJECT_OFFS_OPTS, r16
; set default signal map
ldi r16, LOW(KeyPad_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(KeyPad_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; set default style
ldi r16, LOW(KeyPad_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(KeyPad_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
ret
; @end
; ***************************************************************************
; signal handlers
KeyPad_OnLayout:
rcall keyPadLayoutX ; (r16, r18, r19)
rcall keyPadLayoutY ; (r16, r18, r19)
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
KeyPad_OnGetDefaultWidth:
rcall keyPadLayoutX ; (r16, r18, r19)
ldd r18, Y+KEYPAD_OFFS_KEYHDIST
ldd r19, Y+KEYPAD_OFFS_KEYSPERROW
bigcall Utils_Mulu8x8_16 ; R17:R16 = R18 * R19 (r19-r21)
mov r18, r16
mov r19, r17
rcall keyPadAdjustForBordersAndSpacings
sec
ret
; @end
KeyPad_OnGetDefaultHeight:
rcall keyPadLayoutY ; (r16, r18, r19)
ldd r18, Y+KEYPAD_OFFS_KEYVDIST
ldd r19, Y+KEYPAD_OFFS_ROWS
bigcall Utils_Mulu8x8_16 ; R17:R16 = R18 * R19 (r19-r21)
mov r18, r16
mov r19, r17
rcall keyPadAdjustForBordersAndSpacings
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine KeyPad_OnDraw @global
;
; @param Y address of widget
; @return CFLAG set if signal handled
; @clobbers any, !Y
KeyPad_OnDraw:
ldd r17, Y+OBJECT_OFFS_FLAGS
; check whether widget is visible
sbrs r17, WIDGET_FLAGS_VISIBLE_BIT
rjmp KeyPad_OnDraw_ret
; check whether widget is dirty
sbrs r17, WIDGET_FLAGS_DIRTY_BIT
rjmp KeyPad_OnDraw_ret
; clear widget background
bigcall Widget_Clear ; (any, !Y)
; draw keys
rcall keyPadDrawKeys ; (any, !Y)
ldd r17, Y+OBJECT_OFFS_OPTS
sbrs r17, WIDGET_OPTS_BORDER_BIT
rjmp KeyPad_OnDraw_done
bigcall Widget_DrawBorder
KeyPad_OnDraw_done:
; clear dirty bit
cbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
KeyPad_OnDraw_ret:
sec
ret
; @end
KeyPad_OnTimer:
KeyPad_OnTouchBegin:
KeyPad_OnTouchEnd:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine keyPadAdjustForBordersAndSpacings
;
; @param Y widget
; @param r19:r18 size so far (width or height)
; @return r19:r18 adjusted size
; @clobbers r16, r17, r20, r21
keyPadAdjustForBordersAndSpacings:
push zl
push zh
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
lpm r16, Z
pop zh
pop zl
clr r17
sub r18, r16 ; subtract one spacing
sbc r19, r17
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
ret
; @end
; ---------------------------------------------------------------------------
; @routine keyPadLayoutX
;
; @param Y widget
; @clobbers r16-r23, r25
keyPadLayoutX:
bigcall Widget_GetCharWidth ; r16=width (none)
clr r19
mov r18, r16
lsl r18 ; x2
rol r19
add r18, r16 ; x3
adc r19, r16
sub r19, r16
std Y+KEYPAD_OFFS_KEYWIDTH, r18
std Y+KEYPAD_OFFS_TXTOFFS_X, r16
push zl
push zh
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
lpm r16, Z
pop zh
pop zl
add r18, r16
std Y+KEYPAD_OFFS_KEYHDIST, r18
ret
; @end
; ---------------------------------------------------------------------------
; @routine keyPadLayoutY
;
; @param Y widget
; @clobbers r16, r18, r19
keyPadLayoutY:
bigcall Widget_GetCharHeight ; r16=height (none)
clr r19
mov r18, r16
lsl r18 ; x2
rol r19
add r18, r16 ; x3
adc r19, r16
sub r19, r16
std Y+KEYPAD_OFFS_KEYHEIGHT, r18
std Y+KEYPAD_OFFS_TXTOFFS_Y, r16
push zl
push zh
ldd zl, Y+WIDGET_OFFS_STYLE_LO
ldd zh, Y+WIDGET_OFFS_STYLE_HI
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
lpm r16, Z
pop zh
pop zl
add r18, r16
std Y+KEYPAD_OFFS_KEYVDIST, r18
ret
; @end
keyPadDrawKeys:
; get start pos
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
mov r4, r20 ; X
clr r5
mov r6, r20 ; Y
clr r7
; get key contents
ldd zl, Y+KEYPAD_OFFS_KEYS_LO
ldd zh, Y+KEYPAD_OFFS_KEYS_HI
mov r16, zl
or r16, zh
breq keyPadDrawKeys_ret
ldd r16, Y+KEYPAD_OFFS_ROWS
tst r16
breq keyPadDrawKeys_ret
ldd r16, Y+KEYPAD_OFFS_KEYSPERROW
tst r16
breq keyPadDrawKeys_ret
; draw keys
ldd r20, Y+KEYPAD_OFFS_ROWS ; row counter
clr r21 ; key idx
keyPadDrawKeys_loop1: ; loop for every row
push r20
ldd r20, Y+KEYPAD_OFFS_KEYSPERROW ; key counter per row
push r4 ; X
push r5
keyPadDrawKeys_loop2: ; loop for every key in a row
lpm r16, Z
tst r16
breq keyPadDrawKeys_loop2End ; end reached
cpi r16, 0xff
breq keyPadDrawKeys_loop2Next ; no key, ignore
push r4 ; X
push r5
push r6 ; Y
push r7
push r20 ; key counter per row
push r21 ; key idx
rcall keyPadDrawKey
pop r21
pop r20
pop r7
pop r6
pop r5
pop r4
keyPadDrawKeys_loop2Next:
ldd r16, Y+KEYPAD_OFFS_KEYHDIST ; increment X
add r4, r16
adc r5, r16
sub r5, r16
adiw zh:zl, 1
inc r21
dec r20
breq keyPadDrawKeys_loop2End
rjmp keyPadDrawKeys_loop2
keyPadDrawKeys_loop2End:
pop r5
pop r4
pop r20
dec r20
breq keyPadDrawKeys_loop1End
ldd r16, Y+KEYPAD_OFFS_KEYVDIST ; increment Y
add r6, r16
adc r7, r16
sub r7, r16
rjmp keyPadDrawKeys_loop1
keyPadDrawKeys_loop1End:
keyPadDrawKeys_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine keyPadDrawKey
;
; @param Y widget
; @param r5:r4 X
; @param r7:r6 Y
; @param r21 key idx
; @param Z pointer to current key byte
keyPadDrawKey:
; get colors
mov r16, r21
rcall keyPadGetColsForKey ; (r17)
push r4
push r5
push r6
push r7
push r21
push zl
push zh
ldd r8, Y+KEYPAD_OFFS_KEYWIDTH
clr r9
ldd r10, Y+KEYPAD_OFFS_KEYHEIGHT
clr r11
mov r2, r0
mov r3, r1
bigcall Widget_FillRect
pop zh
pop zl
pop r21
pop r7
pop r6
pop r5
pop r4
; get colors again
mov r16, r21
rcall keyPadGetColsForKey ; (r17)
push r4
push r5
push r6
push r7
push r21
push zl
push zh
ldd r8, Y+KEYPAD_OFFS_KEYWIDTH
clr r9
ldd r10, Y+KEYPAD_OFFS_KEYHEIGHT
clr r11
bigcall Widget_DrawRect
pop zh
pop zl
pop r21
pop r7
pop r6
pop r5
pop r4
; get colors again
mov r16, r21
rcall keyPadGetColsForKey ; (r17)
; adjust XPos
clr r17
ldd r16, Y+KEYPAD_OFFS_TXTOFFS_X
add r4, r16
adc r5, r17
; adjust YPos
ldd r16, Y+KEYPAD_OFFS_TXTOFFS_Y
add r6, r16
adc r7, r17
lpm r16, Z
push zl
push zh
bigcall Widget_DrawCharAt
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine keyPadGetColsForKey
;
; @param Y widget
; @param r16 key idx (starting at 0)
; @return r1:r0 background color
; @return r3:r2 foreground color
; @clobbers r17
keyPadGetColsForKey:
ldd r17, Y+KEYPAD_OFFS_SELECTEDKEY
cp r16, r17
breq keyPadGetColsForKey_activated
bigcall Widget_GetNormalColors ; (none)
rjmp keyPadGetColsForKey_ret
keyPadGetColsForKey_activated:
bigcall Widget_GetActivatedColors ; (none)
keyPadGetColsForKey_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
KeyPad_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 4, 8 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
; @end
KeyPad_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, OBJECT_SIGNAL_TIMER, LOW(KeyPad_OnTimer), HIGH(KeyPad_OnTimer)
.db 0, WIDGET_SIGNAL_DRAW, LOW(KeyPad_OnDraw), HIGH(KeyPad_OnDraw)
.db 0, WIDGET_SIGNAL_TOUCH_BEGIN, LOW(KeyPad_OnTouchBegin), HIGH(KeyPad_OnTouchBegin)
.db 0, WIDGET_SIGNAL_TOUCH_END, LOW(KeyPad_OnTouchEnd), HIGH(KeyPad_OnTouchEnd)
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(KeyPad_OnLayout), HIGH(KeyPad_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(KeyPad_OnGetDefaultWidth), HIGH(KeyPad_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(KeyPad_OnGetDefaultHeight), HIGH(KeyPad_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
; @end
#endif

View File

@@ -0,0 +1,57 @@
; ***************************************************************************
; 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_KEYPAD_NUM_ASM
#define AQH_AVR_GUI2_KEYPAD_NUM_ASM
; ***************************************************************************
; defines
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine NumKeyPad_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
NumKeyPad_new:
ldi r20, 5 ; keys per row
ldi r21, 2 ; rows
ldi r22, LOW(numKeyPadKeys*2) ; key defs
ldi r23, HIGH(numKeyPadKeys*2)
bigjmp KeyPad_new
; @end
; ***************************************************************************
; data in FLASH
numKeyPadKeys:
.db '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0
#endif