HASPmota support for page delet and object updates (#22311)

This commit is contained in:
s-hadinger 2024-10-17 22:14:16 +02:00 committed by GitHub
parent ad65448e09
commit 73f755dda2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 1461 additions and 1255 deletions

View File

@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
### Changed
- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 (#22299)
- HASPmota support for page delet and object updates
### Fixed

View File

@ -880,7 +880,7 @@ class lvh_obj : lvh_root
def get_text_color(style_modifier)
return self._lv_obj.get_style_text_color(style_modifier)
end
def set_value_color(t) self.set_text_color(t) end
def set_value_color(t, style_modifier) self.set_text_color(t, style_modifier) end
def get_value_color() return self.get_value_color() end
#====================================================================
@ -2413,6 +2413,39 @@ class lvh_page
end
end
#====================================================================
# `delete` special attribute used to delete the object
#====================================================================
# def set_delete(v)
# raise "type_error", "you cannot assign to 'delete'"
# end
# def get_delete()
# self._delete()
# return def () end
# end
def delete()
# iterate on all objects and try to delete
# we first get a copy of all ids so we can delete and continue iterating
# without fearing about an infinite loop
var page_ids = []
for id: self._obj_id.keys()
page_ids.push(id)
end
# we iterate until the array is empty
var idx = 0
while idx < size(page_ids)
var page_id = page_ids[idx]
if (page_id != 0) && self._obj_id.contains(page_id)
# first check if the id is still in the page - it could have been already removed if it's a sub-object
self._obj_id[page_id].delete()
end
idx += 1
end
self._obj_id = {} # clear map
# remove from page
self._hm._remove_page(self._page_id)
end
#====================================================================
# `show` transition from one page to another
# duration: in ms, default 500 ms
@ -2818,6 +2851,23 @@ class HASPmota
end
end
#====================================================================
# Remove page by id
#
# Should not be called directly. Indirectly called by `p<x>.delete`
#
# Only removes reference to the page at root level
# Change the active page if needed
#====================================================================
def _remove_page(page_id)
# check if we remove the active page
# TODO XXX
# remove object from page object
if self.lvh_pages.contains(page_id)
self.lvh_pages.remove(page_id)
end
end
#====================================================================
# Event CB handling
#====================================================================
@ -2856,65 +2906,70 @@ class HASPmota
#====================================================================
# Parse single object
#
# The object may be pre-existing or brand new
#====================================================================
def parse_obj(jline, page)
import global
import introspect
var obj_id = int(jline.find("id")) # id number or nil
var obj_type = str(jline.find("obj")) # obj class or nil
var obj_lvh # lvgl object created
var lvh_page_cur = self.get_page_cur() # current page object
var obj_type = jline.find("obj") # obj class or nil
obj_type = (obj_type != nil) ? str(obj_type) : nil
var lvh_page_cur = self.get_page_cur() # current page object, cannot be nil
# first run any Berry code embedded
var berry_run = str(jline.find("berry_run"))
var func_compiled
if berry_run != "nil"
try
func_compiled = compile(berry_run)
except .. as e,m
print(format("HSP: unable to compile berry code \"%s\" - '%s' - %s", berry_run, e, m))
# Step 1. Check the id for valid range
# 'obj_id' must be between 1 and 254
if (obj_id != nil) && (obj_id < 0 || obj_id > 254)
if (obj_id != 0) || (obj_type == nil)
# if `obj_id` is not `nil` and not `0`, it must have `obj_type` not set to `nil`
print(f"HSP: invalid 'id': {obj_id} for 'obj': {obj_type}")
return
end
end
# if line contains botn 'obj' and 'id', create the object
if obj_type != "nil" && obj_id != nil
# 'obj_id' must be between 1 and 254
if obj_id < 1 || obj_id > 254
print("HSP: invalid 'id': " + str(obj_id) + " for 'obj':" + obj_type)
return
end
# Step 2. Check if the p<>b<> object already exists
# `prev_obj` contains the pre-existing object, or `nil` if we create a new object
var obj_lvh = lvh_page_cur.get_obj(obj_id) # get reference of object or `nil` if new object
# Step 3. Create object instance if required
if (obj_type != nil) && (obj_id != nil) && (obj_lvh == nil)
# Step 3.a. extract the LVGL parent object to create the object in the appropriate lvgl screen
# Result in `parent_lvgl`
# extract haspmota class, prefix with `lvh_`. Ex: `btn` becomes `lvh_btn`
# extract parent
var parent_lvgl
var parent_id = int(jline.find("parentid"))
var parent_id = int(jline.find("parentid")) # id of parent object, or `nil`
var parent_obj # parent HASPmota object
var parent_lvgl # lvgl object of parent object
var parent_obj
if parent_id != nil
parent_obj = lvh_page_cur.get_obj(parent_id) # get parent object
if parent_obj != nil parent_lvgl = parent_obj._lv_obj end # parent
if parent_obj != nil
parent_lvgl = parent_obj._lv_obj
end # parent
end
if parent_lvgl == nil
parent_lvgl = lvh_page_cur.get_scr() # if not parent, use the current page screen
end
# Step 3.b. Get the HASPmota class object for the `obj` class
# check if a class with the requested name exists
# first look for a class with name `lvh_<name>` exists
var obj_class = introspect.get(self, "lvh_" + obj_type)
var lv_instance = nil # allows to pre-instanciate the object
var lv_instance # allows to pre-instanciate the object
# there is no lvh_X class, try to load the class name from the global namespace
# Step 3.c. if no native `lvh_<obj>` is found, try the class name from the global namespace
if obj_class == nil
# if not found, check if a LVGL class with name `lv_<name>` exists
var lv_cl = introspect.get(global, obj_type)
if lv_cl != nil && type(lv_cl) == 'class'
if (lv_cl != nil) && (type(lv_cl) == 'class')
lv_instance = lv_cl(parent_lvgl)
obj_class = self.lvh_obj # use the basic lvh_obj component to encapsulate
end
end
# still not found, try to load a module with the name of the class
# Step 3.d. if not found, try to load a module with the name of the class
if obj_class == nil
var lv_cl = introspect.module(obj_type)
if lv_cl != nil && type(lv_cl) == 'class'
@ -2923,18 +2978,55 @@ class HASPmota
end
end
# Step 3.e. if none found, raise an error and abort
if obj_class == nil
print("HSP: Cannot find object of type " + str(obj_type))
print(f"HSP: Cannot find object of type {obj_type}")
return
end
# instanciate the object, passing the lvgl screen as parent object
# Step 3.f. instanciate the object, passing the lvgl screen as parent object
obj_lvh = obj_class(parent_lvgl, page, jline, lv_instance, parent_obj)
# add object to page object
# Step 3.g. Add object to page object
lvh_page_cur.add_obj(obj_id, obj_lvh)
end
# Step 4. if "id" is 0, get the screen object
if obj_id == 0
if (obj_type != nil)
print(f"HSP: cannot specify 'obj':'{obj_type}' for 'id':0")
return
end
obj_lvh = self.get_page_cur().get_obj(0) # get object id '0'
end
# Step 5. apply attributes
# set attributes
# try every attribute, if not supported it is silently ignored
if (obj_lvh != nil)
for k:jline.keys()
obj_lvh.(k) = jline[k]
end
end
# Step 6. apply post-config
# finally call 'post_config()' when all attributes are set, which gives an opportunity to clean or refresh
if (obj_lvh != nil)
obj_lvh.post_config()
end
# Step 7. run any Berry code embedded
# `func_compiled` contains compiled code, that will be run once the object is complete, or `nil` if no code
# `berry_run` contains the actual source code, used only for logging
var func_compiled
var berry_run = str(jline.find("berry_run"))
if berry_run != "nil"
try
func_compiled = compile(berry_run)
except .. as e,m
print(format("HSP: unable to compile berry code \"%s\" - '%s' - %s", berry_run, e, m))
end
end
if func_compiled != nil
try
# run the compiled code once
@ -2947,26 +3039,6 @@ class HASPmota
end
end
if obj_id == nil return end # if no object id, ignore line
if obj_id == 0 && obj_type != "nil"
print("HSP: cannot specify 'obj' for 'id':0")
return
end
# if id==0, retrieve the 'scr' object of the current page
if obj_id == 0
obj_lvh = self.get_page_cur().get_obj(0) # get object id '0'
end
# set attributes
# try every attribute, if not supported it is silently ignored
for k:jline.keys()
# introspect.set(obj, k, jline[k])
obj_lvh.(k) = jline[k]
end
# finally call 'post_config()' when all attributes are set, which gives an opportunity to clean or refresh
obj_lvh.post_config()
end
end
haspmota.HASPmota = HASPmota