Files
aqhomecontrol/avr/modules/lcd2/gui/base/cwidget.asm
2026-05-08 12:20:43 +02:00

336 lines
8.9 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_GUI_BASE_CWIDGET_ASM
#define AQH_AVR_GUI_BASE_CWIDGET_ASM
; ***************************************************************************
; defines
; CWIDGET dialog configuration
.equ CWIDGETCFG_MAINWIDGET_TYPE_HLAYOUT = 1
.equ CWIDGETCFG_MAINWIDGET_TYPE_VLAYOUT = 2
.equ CWIDGETCFG_MAINWIDGET_TYPE_MLAYOUT = 3
.equ CWIDGETCFG_MAINWIDGET_TYPE_NEXT = 4
.equ CWIDGETCFG_WIDGET_TYPE_LABEL = 1
.equ CWIDGETCFG_WIDGET_TYPE_VALUELABEL = 2
.equ CWIDGETCFG_WIDGET_TYPE_IMAGEVIEW = 3
.equ CWIDGETCFG_WIDGET_TYPE_HSPINNER = 4
.equ CWIDGETCFG_WIDGET_TYPE_TEXTBUTTON = 5
.equ CWIDGETCFG_WIDGET_TYPE_IMAGEBUTTON = 6
.equ CWIDGETCFG_WIDGET_TYPE_NEXT = 7
.equ CWIDGETCFG_WIDGET_FLAGS_MINMAXVALUES_BIT = 0
.equ CWIDGETCFG_OFFS_HEADER_TYPE = 0 ; HLAYOUT, VLAYOUT, MLAYOUT
.equ CWIDGETCFG_OFFS_HEADER_FLAGS = 1
.equ CWIDGETCFG_OFFS_HEADER_STYLE_LO = 2
.equ CWIDGETCFG_OFFS_HEADER_STYLE_HI = 3
.equ CWIDGETCFG_OFFS_HEADER_PARAM1 = 4 ; R20
.equ CWIDGETCFG_OFFS_HEADER_PARAM2 = 5 ; R21
.equ CWIDGETCFG_HEADER_SIZE = 6
.equ CWIDGETCFG_OFFS_WIDGET_TYPE = 0 ; 0=end
.equ CWIDGETCFG_OFFS_WIDGET_FLAGS = 1
.equ CWIDGETCFG_OFFS_WIDGET_SELECTOR = 2
.equ CWIDGETCFG_OFFS_WIDGET_RESERVED = 3
.equ CWIDGETCFG_OFFS_WIDGET_OPTS = 4
.equ CWIDGETCFG_OFFS_WIDGET_PACK = 5
.equ CWIDGETCFG_OFFS_WIDGET_STYLE_LO = 6
.equ CWIDGETCFG_OFFS_WIDGET_STYLE_HI = 7
.equ CWIDGETCFG_OFFS_WIDGET_PARAM1 = 8 ; R20
.equ CWIDGETCFG_OFFS_WIDGET_PARAM2 = 9 ; R21
.equ CWIDGETCFG_OFFS_WIDGET_PARAM3 = 10 ; R22
.equ CWIDGETCFG_OFFS_WIDGET_PARAM4 = 11 ; R23
.equ CWIDGETCFG_OFFS_WIDGET_MINVALUE_LO = 12
.equ CWIDGETCFG_OFFS_WIDGET_MINVALUE_HI = 13
.equ CWIDGETCFG_OFFS_WIDGET_MAXVALUE_LO = 14
.equ CWIDGETCFG_OFFS_WIDGET_MAXVALUE_HI = 15
.equ CWIDGETCFG_WIDGET_SIZE = 16
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine CWidget_Create
;
; @param Y pointer to target object for signals emitted by child widgets
; @param X pointer to window to become parent for the new widget
; @param Z pointer to dialog configuration
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @return CFLAG set of okay, cleared otherwise
; @return Y pointer to created content widget
CWidget_Create:
push yl ; target
push yh
rcall cWidgetMkMainWidget
mov xl, yl ; layout widget
mov xh, yh
pop yh ; target
pop yl
brcc CWidget_Create_ret
adiw zh:zl, CWIDGETCFG_HEADER_SIZE ; go to first child widget
rcall CWidget_CreateChildWidgets
CWidget_Create_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine CWidget_CreateChildWidgets @global
;
; @param Y pointer to target window for signals emitted by created widgets
; @param X pointer to window to become parent to created widgets
; @param Z pointer to dialog configuration (ptr to first widget, not to header!)
; @return CFLAG set of okay, cleared otherwise
; @clobbers any, !X, !Y
CWidget_CreateChildWidgets:
CWidget_CreateChildWidgets_loop:
lpm r16, Z
tst r16
breq CWidget_CreateChildWidgets_done
push yl
push yh
push xl
push xh
rcall cWidgetMkChildWidget
pop xh
pop xl
pop yh
pop yl
brcc CWidget_CreateChildWidgets_ret
adiw zh:zl, CWIDGETCFG_WIDGET_SIZE
rjmp CWidget_CreateChildWidgets_loop
CWidget_CreateChildWidgets_done:
sec
CWidget_CreateChildWidgets_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine cWidgetMkMainWidget
;
; @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
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @return CFLAG set of okay, cleared otherwise
; @return Y pointer to created content widget
; @clobbers any, !Z
cWidgetMkMainWidget:
lpm r18, Z
cpi r18, CWIDGETCFG_MAINWIDGET_TYPE_NEXT
brcc cWidgetMkMainWidget_ret
dec r18
; determine location in calltable
clr r19
ldi r20, LOW(cWidgetMkMainWidget_table)
ldi r21, HIGH(cWidgetMkMainWidget_table)
add r18, r20
adc r19, r21
; prepare params
adiw zh:zl, CWIDGETCFG_OFFS_HEADER_PARAM1
lpm r20, Z+
lpm r21, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_HEADER_PARAM1+1)
push zl
push zh
rcall cWidgetMkMainWidget_callTable
pop zh
pop zl
brcc cWidgetMkMainWidget_ret
; set style (if any)
adiw zh:zl, CWIDGETCFG_OFFS_HEADER_STYLE_LO
lpm xl, Z+
lpm xh, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_HEADER_STYLE_LO+1)
mov r18, xl
or r18, xh
sec
breq cWidgetMkMainWidget_ret
push zl
push zh
bigcall Widget_SetStyle
pop zh
pop zl
cWidgetMkMainWidget_ret:
ret
cWidgetMkMainWidget_callTable:
push r18 ; indirect jump
push r19
ret
cWidgetMkMainWidget_table:
rjmp cWidgetMkMainWidget_hlayout
rjmp cWidgetMkMainWidget_vlayout
rjmp cWidgetMkMainWidget_mlayout
cWidgetMkMainWidget_hlayout:
bigjmp HLayout_new
cWidgetMkMainWidget_vlayout:
bigjmp VLayout_new
cWidgetMkMainWidget_mlayout:
bigjmp MCLayout_new
; @end
; ---------------------------------------------------------------------------
; @routine cWidgetMkChildWidget
; @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
cWidgetMkChildWidget:
lpm r16, Z
cpi r16, CWIDGETCFG_WIDGET_TYPE_NEXT
brcs cWidgetMkChildWidget_typeOk
rjmp cWidgetMkChildWidget_ret
cWidgetMkChildWidget_typeOk:
dec r16
; prepare params
adiw zh:zl, CWIDGETCFG_OFFS_WIDGET_PARAM1
lpm r20, Z+
lpm r21, Z+
lpm r22, Z+
lpm r23, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_WIDGET_PARAM1+3)
; determine position within jumptable
clr r17
ldi r18, LOW(cWidgetMkChildWidget_table)
ldi r19, HIGH(cWidgetMkChildWidget_table)
add r18, r16
adc r19, r17
; prepare opts and pack mode
adiw zh:zl, CWIDGETCFG_OFFS_WIDGET_OPTS
lpm r16, Z+
lpm r17, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_WIDGET_OPTS+1)
; call table routine
push zl
push zh
push yl
push yh
rcall cWidgetMkChildWidget_callTable
pop r21 ; pop Y into r21:r20
pop r20
pop zh
pop zl
brcc cWidgetMkChildWidget_ret
; set target and selector
adiw zh:zl, CWIDGETCFG_OFFS_WIDGET_SELECTOR
lpm r16, Z
sbiw zh:zl, CWIDGETCFG_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, CWIDGETCFG_OFFS_WIDGET_STYLE_LO
lpm xl, Z+
lpm xh, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_WIDGET_STYLE_LO+1)
mov r18, xl
or r18, xh
breq cWidgetMkChildWidget_setminmax
push zl
push zh
bigcall Widget_SetStyle
pop zh
pop zl
cWidgetMkChildWidget_setminmax:
adiw zh:zl, CWIDGETCFG_OFFS_WIDGET_FLAGS
lpm r16, Z
sbiw zh:zl, CWIDGETCFG_OFFS_WIDGET_FLAGS
sbrs r16, CWIDGETCFG_WIDGET_FLAGS_MINMAXVALUES_BIT ; only set min/max if flag set
rjmp cWidgetMkChildWidget_done
adiw zh:zl, CWIDGETCFG_OFFS_WIDGET_MINVALUE_LO
lpm xl, Z+
lpm xh, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_WIDGET_MINVALUE_LO+1)
push zl
push zh
bigcall Widget_SetMinValue
pop zh
pop zl
adiw zh:zl, CWIDGETCFG_OFFS_WIDGET_MAXVALUE_LO
lpm xl, Z+
lpm xh, Z
sbiw zh:zl, (CWIDGETCFG_OFFS_WIDGET_MAXVALUE_LO+1)
push zl
push zh
bigcall Widget_SetMaxValue
pop zh
pop zl
cWidgetMkChildWidget_done:
sec
cWidgetMkChildWidget_ret:
ret
cWidgetMkChildWidget_callTable:
push r18 ; indirect jump
push r19
ret
cWidgetMkChildWidget_table:
rjmp cWidgetMkChildWidget_label
rjmp cWidgetMkChildWidget_vlabel
rjmp cWidgetMkChildWidget_imageview
rjmp cWidgetMkChildWidget_hspinner
rjmp cWidgetMkChildWidget_textbutton
rjmp cWidgetMkChildWidget_imagebutton
cWidgetMkChildWidget_label:
bigjmp Label_new
cWidgetMkChildWidget_vlabel:
bigjmp ValueLabel_new
cWidgetMkChildWidget_imageview:
bigjmp ImageView_new
cWidgetMkChildWidget_hspinner:
bigjmp HSpinner_new
cWidgetMkChildWidget_textbutton:
bigjmp TextButton_new
cWidgetMkChildWidget_imagebutton:
bigjmp ImageButton_new
; @end
#endif