avr: more work on gui.

This commit is contained in:
Martin Preuss
2026-04-21 00:01:15 +02:00
parent 8c567c3a87
commit 93aa9b46c3
13 changed files with 1475 additions and 60 deletions

View File

@@ -0,0 +1,86 @@
; ***************************************************************************
; 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_BUTTONGROUP_ASM
#define AQH_AVR_GUI2_BUTTONGROUP_ASM
; ***************************************************************************
; This modules assumes all children to be CheckButton widgets.
; Of those children only one is active at any time.
; When a child gets activated a COMMAND signal will be emitted with the selector
; of the child emitting the signal.
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ***************************************************************************
; signal handlers
ButtonGroup_OnCommand:
tst xl
brne ButtonGroup_OnCommand_done
push r17
rcall buttonGroupDeselectOthers
pop r17 ; re-use selector from original signal
ldi r16, WIDGET_SIGNAL_COMMAND
bigcall OBJ_EmitSignalWithSelector
ButtonGroup_OnCommand_done:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine hbuttonGroupDeselectOthers
;
; @param Y address of widget
; @param r17 selector of the selected child
buttonGroupDeselectOthers:
push yl
push yh
bigcall OBJ_GetFirstChild ; (none)
buttonGroupDeselectOthers_loop:
brcc buttonGroupDeselectOthers_done
mov yl, r18
mov yh, r19
ldd r16, Y+OBJECT_OFFS_SELECTOR
cp r16, r17
breq buttonGroupDeselectOthers_next
push r17
clr r16
bigcall CheckButton_SetState
pop r17
buttonGroupDeselectOthers_next:
bigcall OBJ_GetNext
rjmp buttonGroupDeselectOthers_loop
buttonGroupDeselectOthers_done:
pop yh
pop yl
ret
; @end
#endif

View File

@@ -0,0 +1,219 @@
; ***************************************************************************
; 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_CHECKBOX_ASM
#define AQH_AVR_GUI_CHECKBOX_ASM
; ***************************************************************************
; This module uses two ressources to show a boolean state:
; - RESSOURCE_IMG_CHECKBOX_UNCHECKED: image showing an unchecked checkbox
; - RESSOURCE_IMG_CHECKBOX_CHECKED: image showing a checked checkbox
;
; The current state can be set with @ref CheckBox_SetState and retrieved
; with @ref CheckBox_GetState.
; ***************************************************************************
; ***************************************************************************
; defines
.equ CHECKBOX_OFFS_BEGIN = IMAGEVIEW_SIZE
.equ CHECKBOX_OFFS_STATE = CHECKBOX_OFFS_BEGIN+0
.equ CHECKBOX_SIZE = CHECKBOX_OFFS_BEGIN+1
; checkbutton states
.equ CHECKBOX_STATE_UNCHECKED = 0
.equ CHECKBOX_STATE_CHECKED = 1
; values
.equ CHECKBOX_VALUE_STATE = IMAGEVIEW_VALUE_NEXTFREE+0
.equ CHECKBOX_VALUE_NEXTFREE = IMAGEVIEW_VALUE_NEXTFREE+1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine CheckBox_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
CheckBox_new:
ldi r24, LOW(CHECKBOX_SIZE)
ldi r25, HIGH(CHECKBOX_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
brcc CheckBox_new_ret
rcall CheckBox_Init ; (r16, r17, X)
sec
CheckBox_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckBox_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
; @clobbers r16, r17, X
CheckBox_Init:
; call base class
ldi r20, LOW(RESSOURCE_IMG_CHECKBOX_UNCHECKED)
ldi r21, HIGH(RESSOURCE_IMG_CHECKBOX_UNCHECKED)
bigcall ImageView_Init
; set default signal map
ldi r16, LOW(CheckBox_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(CheckBox_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckBox_SetState @global
;
; @param Y address of widget
; @param r16 new state
; @clobbers any, !Y
CheckBox_SetState:
mov xl, r16
ldi r17, CHECKBOX_VALUE_STATE
bigjmp Widget_SetValue
; @end
; ---------------------------------------------------------------------------
; @routine CheckBox_GetState @global
;
; @param Y address of widget
; @return r16 state
; @clobbers any, !Y
CheckBox_GetState:
ldi r16, WIDGET_SIGNAL_GETVALUE
ldi r17, CHECKBOX_VALUE_STATE
bigcall OBJ_HandleSignal
mov r16, r18
brcs CheckBox_GetState_ret
clr r16
CheckBox_GetState_ret:
ret
; @end
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine CheckBox_OnSetValueState @global
;
; @param Y address of widget
; @param XL new state to set
; @clobbers any, !Y
CheckBox_OnSetValueState:
mov r16, xl
rcall checkBoxSetState
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckBox_OnGetValueState @global
;
; @param Y address of widget
; @return r18 current state
; @clobbers any, !Y
CheckBox_OnGetValueState:
ldd r18, Y+CHECKBOX_OFFS_STATE
clr r19
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine checkBoxSetState @global
;
; @param Y address of widget
; @clobbers any, !Y
; @param r16 new state to set
checkBoxSetState:
std Y+CHECKBOX_OFFS_STATE, r16
ldi xl, LOW(RESSOURCE_IMG_CHECKBOX_UNCHECKED)
ldi xh, HIGH(RESSOURCE_IMG_CHECKBOX_UNCHECKED)
ldd r17, Y+OBJECT_OFFS_FLAGS
cpi r16, CHECKBOX_STATE_UNCHECKED
breq checkBoxSetState_set
ldi xl, LOW(RESSOURCE_IMG_CHECKBOX_CHECKED)
ldi xh, HIGH(RESSOURCE_IMG_CHECKBOX_CHECKED)
checkBoxSetState_set:
sbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
bigjmp ImageView_SetRessourceId ; (r16, r17, r18, r19)
; @end
; ***************************************************************************
; data in FLASH
CheckBox_DefaultSignalmap:
; header
.dw ImageView_DefaultSignalmap*2 ; next table to use
; entries
.db CHECKBOX_VALUE_STATE, WIDGET_SIGNAL_SETVALUE, LOW(CheckBox_OnSetValueState), HIGH(CheckBox_OnSetValueState)
.db CHECKBOX_VALUE_STATE, WIDGET_SIGNAL_GETVALUE, LOW(CheckBox_OnGetValueState), HIGH(CheckBox_OnGetValueState)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,355 @@
; ***************************************************************************
; 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_CHECKBUTTON_ASM
#define AQH_AVR_GUI_CHECKBUTTON_ASM
; ***************************************************************************
; This module uses a horizontal layout with two children:
; - a checkBox
; - a label
;
; The current state can be set with @ref CheckButton_SetState and retrieved
; with @ref CheckButton_GetState.
; ***************************************************************************
; ***************************************************************************
; defines
.equ CHECKBUTTON_OFFS_BEGIN = BUTTON_SIZE
.equ CHECKBUTTON_OFFS_CHECKBOX_LO = CHECKBUTTON_OFFS_BEGIN+0
.equ CHECKBUTTON_OFFS_CHECKBOX_HI = CHECKBUTTON_OFFS_BEGIN+1
.equ CHECKBUTTON_OFFS_MODE = CHECKBUTTON_OFFS_BEGIN+2
.equ CHECKBUTTON_SIZE = CHECKBUTTON_OFFS_BEGIN+3
; modes
.equ CHECKBUTTON_MODE_TOGGLE = 0
.equ CHECKBUTTON_MODE_ONLYON = 1
; values
.equ CHECKBUTTON_VALUE_STATE = IMAGEVIEW_VALUE_NEXTFREE+0
.equ CHECKBUTTON_VALUE_NEXTFREE = IMAGEVIEW_VALUE_NEXTFREE+1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine CheckButton_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 r21:r20 label text ressource
; @param r22 mode (see @ref BUTTON_MODE_NORMAL)
; @clobbers any
CheckButton_new:
push r20
push r21
push r22
ldi r24, LOW(CHECKBUTTON_SIZE)
ldi r25, HIGH(CHECKBUTTON_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r22
pop r21
pop r20
brcc CheckButton_new_ret
rcall CheckButton_Init ; (r16, r17, X)
sec
CheckButton_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckButton_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 r21:r20 label text ressource
; @param r22 mode (see @ref BUTTON_MODE_NORMAL)
; @clobbers r16, r17, X
CheckButton_Init:
push r20
push r21
mov r20, r22 ; mode
; call base class
bigcall Button_Init
pop r21
pop r20
brcc CheckButton_Init_ret
; set default signal map
ldi r16, LOW(CheckButton_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(CheckButton_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
rcall checkButtonCreateChildren
CheckButton_Init_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine checkButtonCreateChildren
;
; @param Y address of widget
; @param r21:r20 label text ressource
; @clobbers any, !Y
checkButtonCreateChildren:
push yl
push yh
push r20
push r21
; create HLayout
ldi r20, VLAYOUT_MODE_EXPAND
mov xl, yl ; use THIS as parent
mov xh, yh
ldi r16, 0
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_BEGIN<<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall HLayout_New
pop r21
pop r20
brcc checkButtonCreateChildren_popRet
mov xl, yl ; HLayout, use as new parent
mov xh, yh
; create checkBox
push r20
push r21
push xl
push xh
ldi r16, 0
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_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall CheckBox_new
pop xh
pop xl
pop r21
pop r20
brcc checkButtonCreateChildren_popRet
mov r18, yl
mov r19, yh
pop yh
pop yl
std Y+CHECKBUTTON_OFFS_CHECKBOX_LO, r18
std Y+CHECKBUTTON_OFFS_CHECKBOX_HI, r19
; create label
push yl
push yh
ldi r16, 0
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_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall Label_new
checkButtonCreateChildren_popRet:
pop yh
pop yl
checkButtonCreateChildren_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine checkButtonToggle
;
; @param Y address of widget
; @clobbers any, !Y
checkButtonToggle:
rcall CheckButton_GetState ; r16=current state
cpi r16, CHECKBOX_STATE_UNCHECKED
breq checkButtonToggle_wasUnchecked
ldi r16, CHECKBOX_STATE_UNCHECKED
rjmp checkButtonToggle_set
checkButtonToggle_wasUnchecked:
ldi r16, CHECKBOX_STATE_CHECKED
checkButtonToggle_set:
push r16
rcall CheckButton_SetState
pop xl ; pop new state into XL
ldi r16, WIDGET_SIGNAL_COMMAND
bigjmp OBJ_EmitSignal ; (any, !Y)
; @end
; ---------------------------------------------------------------------------
; @routine checkButtonSetOn
;
; @param Y address of widget
; @clobbers any, !Y
checkButtonSetOn:
ldi r16, CHECKBOX_STATE_CHECKED
push r16
rcall CheckButton_SetState
pop xl ; pop new state into XL
ldi r16, WIDGET_SIGNAL_COMMAND
bigjmp OBJ_EmitSignal ; (any, !Y)
; @end
; ---------------------------------------------------------------------------
; @routine CheckButton_SetState @global
;
; Set state of checkbox without emitting a signal.
;
; @param Y address of widget
; @param r16 new state
; @clobbers any, !Y
CheckButton_SetState:
ldd r18, Y+CHECKBUTTON_OFFS_CHECKBOX_LO
ldd r19, Y+CHECKBUTTON_OFFS_CHECKBOX_HI
mov r17, r18
or r17, r19
breq CheckButton_SetState_ret
push yl
push yh
mov yl, r18
mov yh, r19
bigcall CheckBox_SetState
pop yh
pop yl
CheckButton_SetState_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckButton_GetState @global
;
; @param Y address of widget
; @return r16 state
; @clobbers any, !Y
CheckButton_GetState:
ldd r18, Y+CHECKBUTTON_OFFS_CHECKBOX_LO
ldd r19, Y+CHECKBUTTON_OFFS_CHECKBOX_HI
mov r17, r18
or r17, r19
breq CheckButton_GetState_ret ; defaults to r18=0
push yl
push yh
mov yl, r18
mov yh, r19
bigcall CheckBox_GetState
pop yh
pop yl
CheckButton_GetState_ret:
ret
; @end
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine CheckButton_OnTouchEnd @global
;
; @param Y address of widget
; @clobbers any, !Y
CheckButton_OnTouchEnd:
bigcall Button_OnTouchEnd
ldd r16, Y+CHECKBUTTON_OFFS_MODE
cpi r16, CHECKBUTTON_MODE_TOGGLE
breq CheckButton_OnTouchEnd_toggle
cpi r16, CHECKBUTTON_MODE_ONLYON
breq CheckButton_OnTouchEnd_onlyOn
rjmp CheckButton_OnTouchEnd_done
CheckButton_OnTouchEnd_onlyOn:
rcall checkButtonSetOn
rjmp CheckButton_OnTouchEnd_done
CheckButton_OnTouchEnd_toggle:
rcall checkButtonToggle
CheckButton_OnTouchEnd_done:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckButton_OnSetValueState @global
;
; @param Y address of widget
; @param XL new state to set
; @clobbers any, !Y
CheckButton_OnSetValueState:
; TODO
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine CheckButton_OnGetValueState @global
;
; @param Y address of widget
; @return r18 current state
; @clobbers any, !Y
CheckButton_OnGetValueState:
; TODO
sec
ret
; @end
; ***************************************************************************
; data in FLASH
CheckButton_DefaultSignalmap:
; header
.dw Button_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_TOUCH_END, LOW(CheckButton_OnTouchEnd), HIGH(CheckButton_OnTouchEnd)
.db CHECKBUTTON_VALUE_STATE, WIDGET_SIGNAL_SETVALUE, LOW(CheckButton_OnSetValueState), HIGH(CheckButton_OnSetValueState)
.db CHECKBUTTON_VALUE_STATE, WIDGET_SIGNAL_GETVALUE, LOW(CheckButton_OnGetValueState), HIGH(CheckButton_OnGetValueState)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,106 @@
; ***************************************************************************
; 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_HBUTTONGROUP_ASM
#define AQH_AVR_GUI2_HBUTTONGROUP_ASM
; ***************************************************************************
; This modules is an implementation of the ButtonGroup module using a HLayout
; as base widget.
; It assumes all children to be CheckButton widgets.
; ***************************************************************************
; ***************************************************************************
; defines
.equ HBUTTONGRP_OFFS_BEGIN = HLAYOUT_SIZE
.equ HBUTTONGRP_SIZE = HBUTTONGRP_OFFS_BEGIN+0
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine HButtonGroup_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 layout mode (HLAYOUT_MODE_EXPAND, HLAYOUT_MODE_SPREAD)
; @clobbers any
HButtonGroup_new:
push r20
push r21
ldi r24, LOW(HBUTTONGRP_SIZE)
ldi r25, HIGH(HBUTTONGRP_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc HButtonGroup_new_ret
rcall HButtonGroup_Init ; (r16, r17, X)
sec
HButtonGroup_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine HButtonGroup_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 layout mode (HLAYOUT_MODE_EXPAND, HLAYOUT_MODE_SPREAD)
; @clobbers r16, r17, X
HButtonGroup_Init:
; call base class
bigcall HLayout_Init ; (r16, r17, X)
; set default signal map
ldi r16, LOW(HButtonGroup_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(HButtonGroup_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ***************************************************************************
; data in FLASH
HButtonGrp_DefaultSignalmap:
; header
.dw HLayout_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_COMMAND, LOW(ButtonGroup_OnCommand), HIGH(ButtonGroup_OnCommand)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -241,39 +241,6 @@ vLayoutReadLayoutWriteVertical_setSize:
; pack
bigcall LayoutCtx_PackYContiguous ; (R16, r18, r19, Z)
ret
; read positions and flags into new layout context
bigcall LayoutCtx_ReadYDimsContiguous ; (R16, r18, r19, Z)
; layout
bigcall LayoutCtx_GetMaxSize ; r19:r18=max default size (r18, r19, r20, r21, r24)
bigcall LayoutCtx_SetFixedSize ; (r24)
adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
ld r18, X
clr r19
sbiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
bigcall LayoutCtx_SetFixedPos ; (r24)
; pack
bigcall LayoutCtx_PackYContiguous ; (R16, r18, r19, Z)
; write back dims
; bigcall LayoutCtx_WriteYDimsContiguous ; (R16, r18, r19, Z)
ret
; @end

View File

@@ -105,12 +105,13 @@ ImageView_Init:
ImageView_SetRessourceId:
std Y+IMAGEVIEW_OFFS_RESSOURCEID_LO, xl
std Y+IMAGEVIEW_OFFS_RESSOURCEID_HI, xh
; force redraw
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
; ; force layout of this and all parent widgets
; ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
; bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
ret
; @end

View File

@@ -17,7 +17,14 @@
.equ LABEL_OFFS_BEGIN = WIDGET_SIZE
.equ LABEL_OFFS_TEXTRES_LO = LABEL_OFFS_BEGIN+0
.equ LABEL_OFFS_TEXTRES_HI = LABEL_OFFS_BEGIN+1
.equ LABEL_SIZE = LABEL_OFFS_BEGIN+2
.equ LABEL_OFFS_MINWIDTH_LO = LABEL_OFFS_BEGIN+2
.equ LABEL_OFFS_MINWIDTH_HI = LABEL_OFFS_BEGIN+3
.equ LABEL_SIZE = LABEL_OFFS_BEGIN+4
; values
.equ LABEL_VALUE_TEXTRES = 1
.equ LABEL_VALUE_MINWIDTH = 2
@@ -150,9 +157,6 @@ Label_OnDraw_ret:
; @routine Label_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
@@ -161,6 +165,14 @@ Label_OnGetDefaultWidth:
rcall labelCalcTextWidth
mov r18, r12
mov r19, r13
ldd r16, Y+LABEL_OFFS_MINWIDTH_LO
ldd r17, Y+LABEL_OFFS_MINWIDTH_HI
cp r18, r16
cpc r19, r17
brcc Label_OnGetDefaultWidth_addBorders
mov r18, r16
mov r19, r17
Label_OnGetDefaultWidth_addBorders:
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
@@ -190,7 +202,57 @@ Label_OnGetDefaultHeight:
; ---------------------------------------------------------------------------
; @routine Label_OnDraw @global
; @routine Label_OnSetValueTextRes @global
;
; @param Y address of widget
; @param X id of text ressource
; @clobbers r16, r17, r18, r19
Label_OnSetValueTextRes:
std Y+LABEL_OFFS_TEXTRES_LO, xl
std Y+LABEL_OFFS_TEXTRES_HI, xh
; set dirty flag
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnSetValueMinWidth @global
;
; @param Y address of widget
; @param X id of text ressource
; @clobbers r16, r17, r18, r19
Label_OnSetValueMinWidth:
std Y+LABEL_OFFS_MINWIDTH_LO, xl
std Y+LABEL_OFFS_MINWIDTH_HI, xh
; set dirty flag
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine labelWriteText
;
; @param Y address of widget
; @clobbers any, !Y
@@ -262,6 +324,9 @@ Label_DefaultSignalmap:
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Label_OnDraw), HIGH(Label_OnDraw)
.db LABEL_VALUE_TEXTRES, WIDGET_SIGNAL_SETVALUE, LOW(Label_OnSetValueTextRes), HIGH(Label_OnSetValueTextRes)
.db LABEL_VALUE_MINWIDTH, WIDGET_SIGNAL_SETVALUE, LOW(Label_OnSetValueMinWidth), HIGH(Label_OnSetValueMinWidth)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(Label_OnGetDefaultWidth), HIGH(Label_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(Label_OnGetDefaultHeight), HIGH(Label_OnGetDefaultHeight)

View File

@@ -0,0 +1,309 @@
; ***************************************************************************
; 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_TILE_ASM
#define AQH_AVR_GUI_TILE_ASM
; ***************************************************************************
; defines
.equ TILE_OFFS_BEGIN = WIDGET_SIZE
.equ TILE_OFFS_WIDTH_LO = TILE_OFFS_BEGIN+0
.equ TILE_OFFS_WIDTH_HI = TILE_OFFS_BEGIN+1
.equ TILE_OFFS_HEIGHT_LO = TILE_OFFS_BEGIN+2
.equ TILE_OFFS_HEIGHT_HI = TILE_OFFS_BEGIN+3
.equ TILE_OFFS_COLOR_LO = TILE_OFFS_BEGIN+4
.equ TILE_OFFS_COLOR_HI = TILE_OFFS_BEGIN+5
.equ TILE_SIZE = TILE_OFFS_BEGIN+6
; values
.equ TILE_VALUE_WIDTH = WIDGET_VALUE_NEXTFREE+0
.equ TILE_VALUE_HEIGHT = WIDGET_VALUE_NEXTFREE+1
.equ TILE_VALUE_COLOR = WIDGET_VALUE_NEXTFREE+2
.equ TILE_VALUE_NEXTFREE = WIDGET_VALUE_NEXTFREE+3
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Tile_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
Tile_new:
ldi r24, LOW(TILE_SIZE)
ldi r25, HIGH(TILE_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
brcc Tile_new_ret
rcall Tile_Init ; (r16, r17, X)
sec
Tile_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_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
; @clobbers any, !Y
Tile_Init:
; call base class
bigcall Widget_Init
; set default signal map
ldi r16, LOW(Tile_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(Tile_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_SetWidth @global
;
; @param Y address of widget
; @param X new value
; @clobbers any, !Y
Tile_SetWidth:
ldi r16, WIDGET_SIGNAL_SETVALUE
ldi r17, TILE_VALUE_WIDTH
bigjmp OBJ_HandleSignal
; @end
; ---------------------------------------------------------------------------
; @routine Tile_SetHeight @global
;
; @param Y address of widget
; @param X new value
; @clobbers any, !Y
Tile_SetHeight:
ldi r16, WIDGET_SIGNAL_SETVALUE
ldi r17, TILE_VALUE_HEIGHT
bigjmp OBJ_HandleSignal
; @end
; ---------------------------------------------------------------------------
; @routine Tile_SetColor @global
;
; @param Y address of widget
; @param X new value
; @clobbers any, !Y
Tile_SetColor:
ldi r16, WIDGET_SIGNAL_SETVALUE
ldi r17, TILE_VALUE_COLOR
bigjmp OBJ_HandleSignal
; @end
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine Tile_OnGetDefaultWidth @global
;
; @param Y address of widget
; @return r19:r18 default width
; @clobbers any, !Y
Tile_OnGetDefaultWidth:
ldd r18, Y+TILE_OFFS_WIDTH_LO
ldd r19, Y+TILE_OFFS_WIDTH_HI
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_OnGetDefaultHeight @global
;
; @param Y address of widget
; @return r19:r18 default height
; @clobbers any, !Y
Tile_OnGetDefaultHeight:
ldd r18, Y+TILE_OFFS_HEIGHT_LO
ldd r19, Y+TILE_OFFS_HEIGHT_HI
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_OnSetValueWidth @global
;
; @param Y address of widget
; @param X new value
; @clobbers any, !Y
Tile_OnSetValueWidth:
std Y+TILE_OFFS_WIDTH_LO, xl
std Y+TILE_OFFS_WIDTH_HI, xh
; set dirty bit
sbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_OnSetValueHeight @global
;
; @param Y address of widget
; @param X new value
; @clobbers any, !Y
Tile_OnSetValueHeight:
std Y+TILE_OFFS_HEIGHT_LO, xl
std Y+TILE_OFFS_HEIGHT_HI, xh
; set dirty bit
sbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_OnSetValueColor @global
;
; @param Y address of widget
; @param X new value
; @clobbers any, !Y
Tile_OnSetValueColor:
std Y+TILE_OFFS_COLOR_LO, xl
std Y+TILE_OFFS_COLOR_HI, xh
; set dirty bit
sbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tile_OnDraw @global
;
; @param Y address of widget
; @clobbers any, !Y
Tile_OnDraw:
ldd r17, Y+OBJECT_OFFS_FLAGS
; check whether widget is visible
sbrs r17, WIDGET_FLAGS_VISIBLE_BIT
rjmp Tile_OnDraw_ret
; check whether widget is dirty
sbrs r17, WIDGET_FLAGS_DIRTY_BIT
rjmp Tile_OnDraw_ret
; clear dirty bit
cbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
; fill background with stored color
rcall Widget_LoadDimsForFullWidget ; (none)
rcall Widget_MakeAbsPos ; (r16, r17, r18, r19)
rcall Widget_ValidateDims ; (r16, r17)
ldd r2, Y+TILE_OFFS_COLOR_LO
ldd r3, Y+TILE_OFFS_COLOR_HI
bigcall Display_FillRect
; maybe draw border
ldd r17, Y+OBJECT_OFFS_OPTS
sbrs r17, WIDGET_OPTS_BORDER_BIT
rjmp Tile_OnDraw_ret
bigcall Widget_DrawBorder
Tile_OnDraw_ret:
sec
ret
; @end
; ***************************************************************************
; data in FLASH
Tile_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Tile_OnDraw), HIGH(Tile_OnDraw)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(Tile_OnGetDefaultWidth), HIGH(Tile_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(Tile_OnGetDefaultHeight), HIGH(Tile_OnGetDefaultHeight)
.db TILE_VALUE_WIDTH, WIDGET_SIGNAL_SETVALUE, LOW(Tile_OnSetValueWidth), HIGH(Tile_OnSetValueWidth)
.db TILE_VALUE_HEIGHT, WIDGET_SIGNAL_SETVALUE, LOW(Tile_OnSetValueHeight), HIGH(Tile_OnSetValueHeight)
.db TILE_VALUE_COLOR, WIDGET_SIGNAL_SETVALUE, LOW(Tile_OnSetValueColor), HIGH(Tile_OnSetValueColor)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -99,7 +99,8 @@
.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
.equ WIDGET_SIGNAL_DIALOG_END = OBJECT_SIGNAL_NEXTFREE+13
.equ WIDGET_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+14
; values for signals WIDGET_SIGNAL_SETVALUE and WIDGET_SIGNAL_GETVALUE
.equ WIDGET_VALUE_DEFAULT_WIDTH = 1