gui: added configuration-based dialog
creates a dialog with widgets from a configuration stored as sequence of bytes in flash.
This commit is contained in:
403
avr/modules/lcd2/gui/base/cdialog.asm
Normal file
403
avr/modules/lcd2/gui/base/cdialog.asm
Normal file
@@ -0,0 +1,403 @@
|
||||
; ***************************************************************************
|
||||
; 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_CDIALOG_ASM
|
||||
#define AQH_AVR_GUI_BASE_CDIALOG_ASM
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; defines
|
||||
|
||||
; CDIALOG data
|
||||
.equ CDIALOG_OFFS_BEGIN = MAINWINDOW_SIZE
|
||||
.equ CDIALOG_OFFS_CONFIG_LO = CDIALOG_OFFS_BEGIN+0
|
||||
.equ CDIALOG_OFFS_CONFIG_HI = CDIALOG_OFFS_BEGIN+1
|
||||
.equ CDIALOG_SIZE = CDIALOG_OFFS_BEGIN+2
|
||||
|
||||
|
||||
; CDIALOG dialog configuration
|
||||
.equ CDIALOGCFG_MAINWIDGET_TYPE_HLAYOUT = 1
|
||||
.equ CDIALOGCFG_MAINWIDGET_TYPE_VLAYOUT = 2
|
||||
.equ CDIALOGCFG_MAINWIDGET_TYPE_MLAYOUT = 3
|
||||
.equ CDIALOGCFG_MAINWIDGET_TYPE_NEXT = 4
|
||||
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_LABEL = 1
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_VALUELABEL = 2
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_IMAGEVIEW = 3
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_HSPINNER = 4
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_TEXTBUTTON = 5
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_IMAGEBUTTON = 6
|
||||
.equ CDIALOGCFG_WIDGET_TYPE_NEXT = 7
|
||||
|
||||
.equ CDIALOGCFG_WIDGET_FLAGS_MINMAXVALUES_BIT = 0
|
||||
|
||||
.equ CDIALOGCFG_OFFS_HEADER_TYPE = 0 ; HLAYOUT, VLAYOUT, MLAYOUT
|
||||
.equ CDIALOGCFG_OFFS_HEADER_FLAGS = 1
|
||||
.equ CDIALOGCFG_OFFS_HEADER_PARAM1 = 2 ; R20
|
||||
.equ CDIALOGCFG_OFFS_HEADER_PARAM2 = 3 ; R21
|
||||
.equ CDIALOGCFG_HEADER_SIZE = 4
|
||||
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_TYPE = 0 ; 0=end
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_FLAGS = 1
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_SELECTOR = 2
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_RESERVED = 3
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_OPTS = 4
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_PACK = 5
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_STYLE_LO = 6
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_STYLE_HI = 7
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_PARAM1 = 8 ; R20
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_PARAM2 = 9 ; R21
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_PARAM3 = 10 ; R22
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_PARAM4 = 11 ; R23
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_MINVALUE_LO = 12
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_MINVALUE_HI = 13
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_MAXVALUE_LO = 14
|
||||
.equ CDIALOGCFG_OFFS_WIDGET_MAXVALUE_HI = 15
|
||||
.equ CDIALOGCFG_WIDGET_SIZE = 16
|
||||
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine CDialog__Init @global
|
||||
;
|
||||
; @param Y pointer to MainWindow
|
||||
; @param X pointer to root window
|
||||
; @param R21:R20 title ressource
|
||||
; @param r23:r22 pointer to settings (byte addr for LPM!)
|
||||
; @return CFLAG set of okay, cleared otherwise
|
||||
; @clobbers any, !Y
|
||||
|
||||
CDialog_Init:
|
||||
push r22
|
||||
push r23
|
||||
ldi r16, 0 ; OPTS
|
||||
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT) ; PACK
|
||||
bigcall MainWindow_Init
|
||||
pop r23
|
||||
pop r22
|
||||
brcc CDialog_Init_ret
|
||||
|
||||
; store config
|
||||
std Y+CDIALOG_OFFS_CONFIG_LO, r22
|
||||
std Y+CDIALOG_OFFS_CONFIG_HI, r23
|
||||
|
||||
; create content
|
||||
bigcall MainWindow_GetContentWidget ; r19:r18=content window
|
||||
brcc CDialog_Init_ret
|
||||
mov xl, r18 ; use content window as parent
|
||||
mov xh, r19
|
||||
push zl
|
||||
push zh
|
||||
push xl ; content window
|
||||
push xh
|
||||
ldd zl, Y+CDIALOG_OFFS_CONFIG_LO
|
||||
ldd zh, Y+CDIALOG_OFFS_CONFIG_HI
|
||||
push yl ; main window
|
||||
push yh
|
||||
rcall cDialogCreateContent
|
||||
pop yh
|
||||
pop yl
|
||||
pop xh
|
||||
pop xl
|
||||
pop zh
|
||||
pop zl
|
||||
brcc CDialog_Init_ret
|
||||
push yl
|
||||
push yh
|
||||
bigcall C03App_CreateBackButton
|
||||
pop yh
|
||||
pop yl
|
||||
CDialog_Init_ret:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine CDialog_GetChildBySelector
|
||||
;
|
||||
; @param Y pointer to MainWindow
|
||||
; @param Z pointer to dialog configuration
|
||||
; @param r16 selector to search for
|
||||
; @return CFLAG set if widget found, cleared otherwise
|
||||
; @return r19:r18 resulting widget
|
||||
; @clobbers R16, R17, R18, R19
|
||||
|
||||
CDialog_GetChildBySelector:
|
||||
push zl
|
||||
push zh
|
||||
adiw zh:zl, CDIALOGCFG_HEADER_SIZE
|
||||
; determine child index
|
||||
clr r18
|
||||
CDialog_GetChildBySelector_loop:
|
||||
lpm r17, Z ; CDIALOGCFG_OFFS_WIDGET_TYPE
|
||||
tst r17
|
||||
breq CDialog_GetChildBySelector_popRet
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_SELECTOR
|
||||
lpm r17, Z
|
||||
sbiw zh:zl, CDIALOGCFG_OFFS_WIDGET_SELECTOR
|
||||
cp r17, r16
|
||||
breq CDialog_GetChildBySelector_found
|
||||
inc r18
|
||||
adiw zh:zl, CDIALOGCFG_WIDGET_SIZE
|
||||
rjmp CDialog_GetChildBySelector_loop
|
||||
CDialog_GetChildBySelector_found:
|
||||
bigcall MainWindow_GetFirstChildOfContentWidget
|
||||
brcc CDialog_GetChildBySelector_popRet
|
||||
push yl
|
||||
push yh
|
||||
mov yl, r18
|
||||
mov yh, r19
|
||||
mov r16, r18
|
||||
bigcall OBJ_GetChildAt ; (r16)
|
||||
pop yh
|
||||
pop yl
|
||||
CDialog_GetChildBySelector_popRet:
|
||||
pop zh
|
||||
pop zl
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine cDialogCreateContent
|
||||
;
|
||||
; @param Y pointer to main window
|
||||
; @param X pointer to content window of MainWindow (is a VLayout, becomes parent)
|
||||
; @param Z pointer to dialog configuration
|
||||
; @return CFLAG set of okay, cleared otherwise
|
||||
; @return Y pointer to created content widget
|
||||
|
||||
cDialogCreateContent:
|
||||
push yl ; MainWindow
|
||||
push yh
|
||||
rcall cDialogMkMainWidget
|
||||
mov xl, yl ; layout widget
|
||||
mov xh, yh
|
||||
pop yh ; MainWindow
|
||||
pop yl
|
||||
brcc cDialogCreateContent_ret
|
||||
|
||||
adiw zh:zl, CDIALOGCFG_HEADER_SIZE ; go to first child widget
|
||||
cDialogCreateContent_loop:
|
||||
lpm r16, Z
|
||||
tst r16
|
||||
breq cDialogCreateContent_done
|
||||
push yl
|
||||
push yh
|
||||
push xl
|
||||
push xh
|
||||
rcall cDialogMkChildWidget
|
||||
pop xh
|
||||
pop xl
|
||||
pop yh
|
||||
pop yl
|
||||
brcc cDialogCreateContent_ret
|
||||
adiw zh:zl, CDIALOGCFG_WIDGET_SIZE
|
||||
rjmp cDialogCreateContent_loop
|
||||
cDialogCreateContent_done:
|
||||
sec
|
||||
cDialogCreateContent_ret:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine cDialogMkMainWidget
|
||||
;
|
||||
; @param Y pointer to main window
|
||||
; @param X pointer to content window of MainWindow (is a VLayout, becomes parent)
|
||||
; @param Z pointer to dialog configuration
|
||||
; @return CFLAG set of okay, cleared otherwise
|
||||
; @return Y pointer to created content widget
|
||||
; @clobbers any, !Z
|
||||
|
||||
cDialogMkMainWidget:
|
||||
lpm r16, Z
|
||||
cpi r16, CDIALOGCFG_MAINWIDGET_TYPE_NEXT
|
||||
brcc cDialogMkMainWidget_ret
|
||||
dec r16
|
||||
|
||||
clr r17
|
||||
ldi r18, LOW(cDialogMkMainWidget_table)
|
||||
ldi r19, HIGH(cDialogMkMainWidget_table)
|
||||
add r18, r16
|
||||
adc r19, r17
|
||||
|
||||
; prepare params, opts and pack
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_HEADER_PARAM1
|
||||
lpm r20, Z+
|
||||
lpm r21, Z
|
||||
sbiw zh:zl, (CDIALOGCFG_OFFS_HEADER_PARAM1+1)
|
||||
ldi r16, 0 ; OPTS
|
||||
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT) ; PACK
|
||||
|
||||
push zl
|
||||
push zh
|
||||
rcall cDialogMkMainWidget_callTable
|
||||
pop zh
|
||||
pop zl
|
||||
cDialogMkMainWidget_ret:
|
||||
ret
|
||||
cDialogMkMainWidget_callTable:
|
||||
push r18 ; indirect jump
|
||||
push r19
|
||||
ret
|
||||
cDialogMkMainWidget_table:
|
||||
rjmp cDialogMkMainWidget_hlayout
|
||||
rjmp cDialogMkMainWidget_vlayout
|
||||
rjmp cDialogMkMainWidget_mlayout
|
||||
cDialogMkMainWidget_hlayout:
|
||||
bigjmp HLayout_new
|
||||
cDialogMkMainWidget_vlayout:
|
||||
bigjmp VLayout_new
|
||||
cDialogMkMainWidget_mlayout:
|
||||
bigjmp MCLayout_new
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine cDialogMkChildWidget
|
||||
; @param Y pointer to main window
|
||||
; @param X pointer to parent window
|
||||
; @param Z pointer to current widget configuration
|
||||
; @return CFLAG set of okay, cleared otherwise
|
||||
; @return Y pointer to created widget
|
||||
; @clobbers any, !Z
|
||||
|
||||
cDialogMkChildWidget:
|
||||
lpm r16, Z
|
||||
cpi r16, CDIALOGCFG_WIDGET_TYPE_NEXT
|
||||
brcs cDialogMkChildWidget_typeOk
|
||||
rjmp cDialogMkChildWidget_ret
|
||||
cDialogMkChildWidget_typeOk:
|
||||
dec r16
|
||||
; prepare params
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_PARAM1
|
||||
lpm r20, Z+
|
||||
lpm r21, Z+
|
||||
lpm r22, Z+
|
||||
lpm r23, Z
|
||||
sbiw zh:zl, (CDIALOGCFG_OFFS_WIDGET_PARAM1+3)
|
||||
|
||||
; determine position within jumptable
|
||||
clr r17
|
||||
ldi r18, LOW(cDialogMkChildWidget_table)
|
||||
ldi r19, HIGH(cDialogMkChildWidget_table)
|
||||
add r18, r16
|
||||
adc r19, r17
|
||||
|
||||
; prepare opts and pack mode
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_OPTS
|
||||
lpm r16, Z+
|
||||
lpm r17, Z
|
||||
sbiw zh:zl, (CDIALOGCFG_OFFS_WIDGET_OPTS+1)
|
||||
|
||||
; call table routine
|
||||
push zl
|
||||
push zh
|
||||
push yl
|
||||
push yh
|
||||
rcall cDialogMkChildWidget_callTable
|
||||
pop r21 ; pop Y into r21:r20
|
||||
pop r20
|
||||
pop zh
|
||||
pop zl
|
||||
brcc cDialogMkChildWidget_ret
|
||||
|
||||
; set target and selector
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_SELECTOR
|
||||
lpm r16, Z
|
||||
sbiw zh:zl, CDIALOGCFG_OFFS_WIDGET_SELECTOR
|
||||
std Y+OBJECT_OFFS_SELECTOR, r16
|
||||
std Y+OBJECT_OFFS_TARGET_LO, r20
|
||||
std Y+OBJECT_OFFS_TARGET_HI, r21
|
||||
|
||||
; set style (if any)
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_STYLE_LO
|
||||
lpm r16, Z+
|
||||
lpm r17, Z
|
||||
sbiw zh:zl, (CDIALOGCFG_OFFS_WIDGET_STYLE_LO+1)
|
||||
mov r18, r16
|
||||
or r18, r17
|
||||
breq cDialogMkChildWidget_setminmax
|
||||
std Y+WIDGET_OFFS_STYLE_LO, r16
|
||||
std Y+WIDGET_OFFS_STYLE_HI, r17
|
||||
cDialogMkChildWidget_setminmax:
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_FLAGS
|
||||
lpm r16, Z
|
||||
sbiw zh:zl, CDIALOGCFG_OFFS_WIDGET_FLAGS
|
||||
sbrs r16, CDIALOGCFG_WIDGET_FLAGS_MINMAXVALUES_BIT ; only set min/max if flag set
|
||||
rjmp cDialogMkChildWidget_done
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_MINVALUE_LO
|
||||
lpm xl, Z+
|
||||
lpm xh, Z
|
||||
sbiw zh:zl, (CDIALOGCFG_OFFS_WIDGET_MINVALUE_LO+1)
|
||||
push zl
|
||||
push zh
|
||||
bigcall Widget_SetMinValue
|
||||
pop zh
|
||||
pop zl
|
||||
|
||||
adiw zh:zl, CDIALOGCFG_OFFS_WIDGET_MAXVALUE_LO
|
||||
lpm xl, Z+
|
||||
lpm xh, Z
|
||||
sbiw zh:zl, (CDIALOGCFG_OFFS_WIDGET_MAXVALUE_LO+1)
|
||||
push zl
|
||||
push zh
|
||||
bigcall Widget_SetMaxValue
|
||||
pop zh
|
||||
pop zl
|
||||
cDialogMkChildWidget_done:
|
||||
sec
|
||||
cDialogMkChildWidget_ret:
|
||||
ret
|
||||
cDialogMkChildWidget_callTable:
|
||||
push r18 ; indirect jump
|
||||
push r19
|
||||
ret
|
||||
cDialogMkChildWidget_table:
|
||||
rjmp cDialogMkChildWidget_label
|
||||
rjmp cDialogMkChildWidget_vlabel
|
||||
rjmp cDialogMkChildWidget_imageview
|
||||
rjmp cDialogMkChildWidget_hspinner
|
||||
rjmp cDialogMkChildWidget_textbutton
|
||||
rjmp cDialogMkChildWidget_imagebutton
|
||||
|
||||
cDialogMkChildWidget_label:
|
||||
bigjmp Label_new
|
||||
cDialogMkChildWidget_vlabel:
|
||||
bigjmp ValueLabel_new
|
||||
cDialogMkChildWidget_imageview:
|
||||
bigjmp ImageView_new
|
||||
cDialogMkChildWidget_hspinner:
|
||||
bigjmp HSpinner_new
|
||||
cDialogMkChildWidget_textbutton:
|
||||
bigjmp TextButton_new
|
||||
cDialogMkChildWidget_imagebutton:
|
||||
bigjmp ImageButton_new
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user