Merge pull request #13468 from s-hadinger/openhasp_alpha3

LVGL OpenHASP alpha 3
This commit is contained in:
s-hadinger 2021-10-25 23:01:15 +02:00 committed by GitHub
commit 6ae4c1e358
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 492 additions and 48 deletions

View File

@ -599,6 +599,9 @@ extern int lvbe_spinbox_step_prev(bvm *vm);
extern int lvbe_spinbox_increment(bvm *vm);
extern int lvbe_spinbox_decrement(bvm *vm);
/* `lv_spinner` external functions definitions */
extern int lvbe_spinner_create(bvm *vm);
/* `lv_arc` external functions definitions */
extern int lvbe_arc_create(bvm *vm);
extern int lvbe_arc_set_start_angle(bvm *vm);
@ -819,6 +822,7 @@ extern int be_ntv_lv_led_init(bvm *vm);
extern int be_ntv_lv_meter_init(bvm *vm);
extern int be_ntv_lv_msgbox_init(bvm *vm);
extern int be_ntv_lv_spinbox_init(bvm *vm);
extern int be_ntv_lv_spinner_init(bvm *vm);
extern int be_ntv_lv_arc_init(bvm *vm);
extern int be_ntv_lv_bar_init(bvm *vm);
extern int be_ntv_lv_btn_init(bvm *vm);
@ -1194,6 +1198,28 @@ void be_load_lv_spinbox_class(bvm *vm) {
be_pop(vm, 1);
}
/********************************************************************
** Solidified class: lv_spinner
********************************************************************/
extern const bclass be_class_lv_obj;
be_local_class(lv_spinner,
0,
&be_class_lv_obj,
be_nested_map(2,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_nested_key("_class", -1562820946, 6, -1), be_const_comptr(&lv_spinner_class) },
{ be_nested_key("init", 380752755, 4, -1), be_const_func(be_ntv_lv_spinner_init) },
})),
(be_nested_const_str("lv_spinner", 1612829968, 6))
);
/*******************************************************************/
void be_load_lv_spinner_class(bvm *vm) {
be_pushntvclass(vm, &be_class_lv_spinner);
be_setglobal(vm, "lv_spinner");
be_pop(vm, 1);
}
/********************************************************************
** Solidified class: lv_arc
********************************************************************/

View File

@ -13,9 +13,13 @@ vres = lv.get_ver_res() # should be 240
scr = lv.scr_act() # default screean object
#f20 = lv.montserrat_font(20) # load embedded Montserrat 20
r20 = lv.font_robotocondensed_latin1(20)
r16 = lv.font_robotocondensed_latin1(16)
th2 = lv.theme_openhasp_init(0, lv.color(0xFF0000), lv.color(0xFFFF00), true, r20)
th2 = lv.theme_openhasp_init(0, lv.color(0xFF00FF), lv.color(0x303030), false, r16)
scr.get_disp().set_theme(th2)
# TODO
scr.set_style_bg_color(lv.color(lv.COLOR_WHITE),0)
# apply theme to layer_top, but keep it transparent
lv.theme_apply(lv.layer_top())
lv.layer_top().set_style_bg_opa(0,0)
@ -41,6 +45,23 @@ def parse_hex(s)
return val
end
def parse_color(s)
s = str(s)
if s[0] == '#'
return lv.color(parse_hex(s))
else
import string
import introspect
var col_name = "COLOR_" + string.toupper(s)
var col_try = introspect.get(lv, col_name)
if col_try != nil
return lv.color(col_try)
end
end
# fail safe with black color
return lv.color(0x000000)
end
#- ------------------------------------------------------------
Class `lvh_obj` encapsulating `lv_obj``
@ -52,7 +73,15 @@ end
class lvh_obj
# _lv_class refers to the lvgl class encapsulated, and is overriden by subclasses
static _lv_class = lv.obj
static _lv_part2_selector # selector for secondary part (like knob of arc)
# attributes to ignore when set at object level (they are managed by page)
static _attr_ignore = [
"id",
"obj",
"page",
"comment",
]
#- mapping from OpenHASP attribute to LVGL attribute -#
#- if mapping is null, we use set_X and get_X from our own class -#
static _attr_map = {
@ -60,18 +89,56 @@ class lvh_obj
"y": "y",
"w": "width",
"h": "height",
"radius": "radius",
"border_side": "border_side",
"text": nil, # apply to self
# arc
"asjustable": nil,
"mode": nil,
"start_angle": "bg_start_angle",
"start_angle1": "start_angle",
"end_angle": "bg_end_angle",
"end_angle1": "end_angle",
"radius": "style_radius",
"border_side": "style_border_side",
"bg_opa": "style_bg_opa",
"border_width": "style_border_width",
"action": nil, # store the action in self._action
"hidden": nil, # apply to self
"enabled": nil, # apply to self
"enabled": nil, # apply to self
"click": nil, # synonym to enabled
"toggle": nil,
"bg_color": nil,
"bg_color": "style_bg_color",
"bg_grad_color": "style_bg_grad_color",
"type": nil,
# below automatically create a sub-label
"text": nil, # apply to self
"value_str": nil, # synonym to 'text'
"align": nil,
"text_font": nil,
"value_font": nil, # synonym to text_font
"text_color": nil,
"value_color": nil, # synonym to text_color
"value_ofs_x": nil,
"value_ofs_y": nil,
#
"min": nil,
"max": nil,
"val": "value",
"rotation": "rotation",
# img
"src": "src",
"image_recolor": "style_img_recolor",
"image_recolor_opa": "style_img_recolor_opa",
# padding of knob
"pad_top2": nil,
"pad_bottom2": nil,
"pad_left2": nil,
"pad_right2": nil,
"pad_all2": nil,
"radius2": nil,
}
var _lv_obj # native lvgl object
var _lv_label # sub-label if exists
var _action # action for OpenHASP
# init
# - create the LVGL encapsulated object
@ -90,6 +157,13 @@ class lvh_obj
return self._lv_obj
end
def set_action(t)
self._action = str(t)
end
def get_action()
return self._action()
end
#- ------------------------------------------------------------
Mapping of synthetic attributes
- text
@ -121,6 +195,9 @@ class lvh_obj
def get_enabled()
return self._lv_obj.has_flag(lv.OBJ_FLAG_CLICKABLE)
end
# click is synonym to enabled
def set_click(t) self.set_enabled(t) end
def get_click() return self.get_enabled() end
#- `toggle` attributes mapped to STATE_CHECKED -#
def set_toggle(t)
@ -137,35 +214,47 @@ class lvh_obj
return self._lv_obj.has_state(lv.STATE_CHECKED)
end
def set_adjustable(t)
if t
self._lv_obj.add_flag(lv.OBJ_FLAG_CLICKABLE)
else
self._lv_obj.clear_flag(lv.OBJ_FLAG_CLICKABLE)
end
end
def get_adjustable()
return self._lv_obj.has_flag(lv.OBJ_FLAG_CLICKABLE)
end
#- set_text: create a `lv_label` sub object to the current object -#
#- (default case, may be overriden by object that directly take text) -#
def check_label()
if self._lv_label == nil
self._lv_label = lv.label(self.get_obj())
self._lv_label.set_align(lv.ALIGN_CENTER);
end
end
def set_text(t)
self.check_label()
self._lv_label.set_text(t)
end
def set_value_str(t) self.set_text(t) end
def get_text()
if self._lv_label == nil return nil end
return self._lv_label.get_text()
end
def get_value_str() return self.get_text() end
def set_align(t)
var align
self.check_label()
if t == 0 || t == "left"
align = lv.TEXT_ALIGN_LEFT
elif t == 1 || t == "center"
align = lv.TEXT_ALIGN_CENTER
elif t == 2 || t == "right"
align = lv.TEXT_ALIGN_RIGHT
else
align = lv.TEXT_ALIGN_auto
end
self._lv_label.set_style_text_align(align, lv.PART_MAIN | lv.STATE_DEFAULT)
end
@ -184,13 +273,105 @@ class lvh_obj
end
end
def set_bg_color(t)
var color = lv.color(parse_hex(t))
self._lv_obj.set_style_bg_color(color, lv.PART_MAIN | lv.STATE_DEFAULT)
def set_text_font(t)
self.check_label()
var f = lv.font_robotocondensed_latin1(int(t))
if f != nil
self._lv_label.set_style_text_font(f, lv.PART_MAIN | lv.STATE_DEFAULT)
else
print("HSP: Unsupported font size: robotocondensed-latin1", self._text_font)
end
end
def get_text_font()
return self._text_font
end
def set_value_font(t) self.set_text_font(t) end
def get_value_font() return self.get_text_font() end
def set_text_color(t)
self.check_label()
self._lv_label.set_style_text_color(parse_color(t), lv.PART_MAIN | lv.STATE_DEFAULT)
end
def get_text_color()
return self._text_color
end
def set_value_color(t) self.set_text_color(t) end
def get_value_color() return self.get_value_color() end
def set_value_ofs_x(t)
self.check_label()
self._lv_label.set_x(int(t))
end
def get_value_ofs_x()
return self._lv_label.get_x()
end
def set_value_ofs_y(t)
self.check_label()
self._lv_label.set_y(int(t))
end
def get_value_ofs_y()
return self._lv_label.get_y()
end
def get_bg_color()
return self._lv_obj.get_style_bg_color(lv.PART_MAIN | lv.STATE_DEFAULT)
# secondary element
def set_pad_top2(t)
if self._lv_part2_selector != nil
self._lv_obj.set_style_pad_top(int(t), self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def set_pad_bottom2(t)
if self._lv_part2_selector != nil
self._lv_obj.set_style_pad_bottom(int(t), self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def set_pad_left2(t)
if self._lv_part2_selector != nil
self._lv_obj.set_style_pad_left(int(t), self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def set_pad_right2(t)
if self._lv_part2_selector != nil
self._lv_obj.set_style_pad_right(int(t), self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def set_pad_all2(t)
if self._lv_part2_selector != nil
self._lv_obj.set_style_pad_all(int(t), self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def get_pad_top()
if self._lv_part2_selector != nil
return self._lv_obj.get_style_pad_top(self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def get_pad_bottomo()
if self._lv_part2_selector != nil
return self._lv_obj.get_style_pad_bottom(self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def get_pad_left()
if self._lv_part2_selector != nil
return self._lv_obj.get_style_pad_left(self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def get_pad_right()
if self._lv_part2_selector != nil
return self._lv_obj.get_style_pad_right(self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def get_pad_all()
end
def set_radius2(t)
if self._lv_part2_selector != nil
self._lv_obj.set_style_radius(int(t), self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
def get_radius2()
if self._lv_part2_selector != nil
return self._lv_obj.get_style_radius(self._lv_part2_selector | lv.STATE_DEFAULT)
end
end
#- ------------------------------------------------------------
@ -202,8 +383,9 @@ class lvh_obj
#
if self._attr_map.has(k)
import introspect
if self._attr_map[k]
var f = introspect.get(self._lv_obj, "get_" + self._attr_map[k])
var kv = self._attr_map[k]
if kv
var f = introspect.get(self._lv_obj, "get_" + kv)
if type(f) == 'function'
return f(self._lv_obj)
end
@ -219,16 +401,31 @@ class lvh_obj
end
def setmember(k, v)
import string
# print(">> setmember", k, v)
# print(">>", classname(self), self._attr_map)
if self._attr_map.has(k)
if self._attr_ignore.find(k) != nil
return
elif self._attr_map.has(k)
import introspect
if self._attr_map[k]
var f = introspect.get(self._lv_obj, "set_" + self._attr_map[k])
# print("f=", f)
var kv = self._attr_map[k]
if kv
var f = introspect.get(self._lv_obj, "set_" + kv)
# if the attribute contains 'color', convert to lv_color
if type(kv) == 'string' && string.find(kv, "color") + 5 == size(kv) # endswith 'color'
v = parse_color(v)
end
# print("f=", f, v, kv, self._lv_obj, self)
if type(f) == 'function'
f(self._lv_obj, v)
if string.find(kv, "style_") == 0
# style function need a selector as second parameter
f(self._lv_obj, v, lv.PART_MAIN | lv.STATE_DEFAULT)
else
f(self._lv_obj, v)
end
return
else
print("HSP: Could not find function set_"+kv)
end
else
# call self method
@ -240,6 +437,8 @@ class lvh_obj
end
end
else
print("HSP: unknown attribute:", k)
end
# silently ignore if the attribute name is not supported
end
@ -250,13 +449,63 @@ class lvh_label : lvh_obj
# label do not need a sub-label
def post_init()
self._lv_label = self._lv_obj
# label don't have opaque background by default
self._lv_obj.set_style_bg_opa(lv.OPA_COVER, lv.PART_MAIN | lv.STATE_DEFAULT)
end
end
class lvh_arc : lvh_obj
static _lv_class = lv.arc
static _lv_part2_selector = lv.PART_KNOB
def set_min(t)
self._lv_obj.set_range(int(t), self.get_max())
end
def set_max(t)
self._lv_obj.set_range(self.get_min(), int(t))
end
def get_min()
return self._lv_obj.get_min_value()
end
def get_max()
return self._lv_obj.get_max_value()
end
def set_type(t)
var mode
if t == 0 mode = lv.ARC_MODE_NORMAL
elif t == 1 mode = lv.ARC_MODE_REVERSE
elif t == 2 mode = lv.ARC_MODE_SYMMETRICAL
end
if mode != nil
self._lv_obj.set_mode(mode)
end
end
def get_type()
return self._lv_obj.get_mode()
end
# mode
def set_mode(t)
var mode
if mode == "expand" self._lv_obj.set_width(lv.SIZE_CONTENT)
elif mode == "break" mode = lv.LABEL_LONG_WRAP
elif mode == "dots" mode = lv.LABEL_LONG_DOT
elif mode == "scroll" mode = lv.LABEL_LONG_SCROLL
elif mode == "loop" mode = lv.LABEL_LONG_SCROLL_CIRCULAR
elif mode == "crop" mode = lv.LABEL_LONG_CLIP
end
if mode != nil
self._lv_obj.lv_label_set_long_mode(mode)
end
end
def get_mode()
end
end
class lvh_switch : lvh_obj
static _lv_class = lv.switch
static _lv_part2_selector = lv.PART_KNOB
end
#- creat sub-classes of lvh_obj and map the LVGL class in static '_lv_class' attribute -#
class lvh_arc : lvh_obj static _lv_class = lv.arc end
class lvh_bar : lvh_obj static _lv_class = lv.bar end
class lvh_btn : lvh_obj static _lv_class = lv.btn end
class lvh_btnmatrix : lvh_obj static _lv_class = lv.btnmatrix end
@ -266,8 +515,7 @@ class lvh_img : lvh_obj static _lv_class = lv.img end
class lvh_line : lvh_obj static _lv_class = lv.line end
class lvh_roller : lvh_obj static _lv_class = lv.roller end
class lvh_slider : lvh_obj static _lv_class = lv.slider end
class lvh_slider : lvh_obj static _lv_class = lv.slider end
class lvh_switch : lvh_obj static _lv_class = lv.switch end
class lvh_spinner : lvh_obj static _lv_class = lv.spinner end
class lvh_textarea : lvh_obj static _lv_class = lv.textarea end
#- ----------------------------------------------------------------------------
@ -294,7 +542,7 @@ class lvh_page
self._lv_scr = lv.layer_top() # top layer, visible over all screens
else
self._lv_scr = lv.obj(0) # allocate a new screen
self._lv_scr.set_style_bg_color(lv_color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT) # set black background
self._lv_scr.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT) # set black background
end
# create a global for this page of form p<page_number>, ex p1
@ -311,6 +559,9 @@ class lvh_page
def set_obj(id, o)
self._obj_id[id] = o
end
def get_obj(id)
return self._obj_id.find(id)
end
#- return id of this page -#
def id()
@ -382,6 +633,19 @@ def parse_obj(jline, page)
# extract openhasp class, prefix with `lvh_`. Ex: `btn` becomes `lvh_btn`
var obj_type = jline["obj"]
# extract parent
var parent
var parent_id = int(jline.find("parentid"))
if parent_id != nil
var parent_obj = lvh_page_cur.get_obj(parent_id)
if parent_obj != nil
parent = parent_obj._lv_obj
end
end
if parent == nil
parent = page.get_scr()
end
# check if a class with the requested name exists
var obj_class = introspect.get(global, "lvh_" + obj_type)
if obj_class == nil
@ -389,15 +653,15 @@ def parse_obj(jline, page)
end
# instanciate the object, passing the lvgl screen as paren object
var obj = obj_class(page.get_scr())
var obj = obj_class(parent)
# add object to page object
lvh_page_cur.set_obj(obj_id, obj)
# set attributes
# try every attribute, if not supported it is silently ignored
for k:jline.keys()
introspect.set(obj, k, jline[k])
# obj.(k) = jline[k]
# introspect.set(obj, k, jline[k])
obj.(k) = jline[k]
end
# create a global variable for this object of form p<page>b<id>, ex p1b2

View File

@ -0,0 +1,23 @@
{"page":1,"comment":"---------- Page 1 ----------"}
{"page":1,"id":0,"bg_color":"#FFFFFF","bg_grad_color":"#FFFFFF","text_color":"#000000","radius":0,"border_side":0}
{"page":1,"id":1,"obj":"btn","x":0,"y":0,"w":240,"h":30,"text":"LIVING ROOM","value_font":22,"bg_color":"#2C3E50","bg_grad_color":"#2C3E50","text_color":"#FFFFFF","radius":0,"border_side":0}
{"page":1,"id":2,"obj":"arc","x":20,"y":65,"w":80,"h":100,"max":40,"border_side":0,"type":0,"rotation":0,"start_angle":180,"end_angle":0,"start_angle1":180,"value_font":12,"value_ofs_x":0,"value_ofs_y":-14,"bg_opa":0,"text":"21.2°C","min":-20,"max":50,"val":21}
{"page":1,"id":3,"obj":"arc","x":140,"y":65,"w":80,"h":100,"max":100,"border_side":0,"type":0,"start_angle":180,"end_angle":0,"start_angle1":180,"value_font":12,"value_color":"#000000","value_ofs_x":0,"value_ofs_y":-14,"bg_opa":0,"text":"44%","val":44}
{"page":1,"id":4,"obj":"label","x":0,"y":120,"w":240,"h":20,"text":"CO2 levels: 1483 ppm","radius":0,"border_side":0,"align":1}
{"page":1,"id":5,"obj":"label","x":2,"y":35,"w":140,"text":"Temperature","align":1}
{"page":1,"id":6,"obj":"label","x":140,"y":35,"w":95,"text":"Humidity","align":1}
{"page":1,"id":7,"obj":"btn","x":0,"y":160,"w":240,"h":20,"text":"LIGHTS","bg_color":"#F1C40F","text_color":"#FFFFFF","radius":0,"border_side":0}
{"page":1,"id":8,"obj":"label","x":20,"y":190,"w":140,"h":20,"text":"Ceiling Light"}
{"page":1,"id":9,"obj":"switch","x":160,"y":190,"w":40,"h":20,"toggle":"TRUE"}
{"page":1,"id":10,"obj":"label","x":20,"y":215,"w":140,"h":20,"text":"Wall Light"}
{"page":1,"id":11,"obj":"switch","x":160,"y":215,"w":40,"h":20,"toggle":"TRUE"}
{"page":1,"id":12,"obj":"label","x":20,"y":240,"w":200,"h":20,"text":"Ambient Light"}
{"page":1,"id":13,"obj":"slider","x":30,"y":265,"w":200,"h":10}
{"page":0,"comment":"---------- All pages ----------"}
{"page":0,"id":11,"obj":"btn","action":"prev","x":0,"y":290,"w":79,"h":32,"bg_color":"#34495E","text":"\uE141","text_color":"#CCCCCC","radius":0,"border_side":0,"text_font":32}
{"page":0,"id":12,"obj":"btn","action":"back","x":80,"y":290,"w":80,"h":32,"bg_color":"#34495E","text":"\uE2DC","text_color":"#CCCCCC","radius":0,"border_side":0,"text_font":24}
{"page":0,"id":13,"obj":"btn","action":"next","x":161,"y":290,"w":79,"h":32,"bg_color":"#34495E","text":"\uE142","text_color":"#CCCCCC","radius":0,"border_side":0,"text_font":32}

View File

@ -0,0 +1,35 @@
{"page":1,"id":1,"obj":"btn","x":0,"y":0,"w":240,"h":30,"text":"ENTITIES","value_font":22,"bg_color":"#2C3E50","text_color":"#FFFFFF","radius":0,"border_side":0,"click":0}
{"page":1,"id":2,"obj":"obj","x":5,"y":35,"w":230,"h":250,"click":0}
{"page":1,"id":11,"obj":"label","x":8,"y":33,"w":35,"h":35,"text":"\uE004","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":12,"obj":"label","x":48,"y":43,"w":130,"h":30,"text":"Presence override","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":13,"obj":"switch","x":177,"y":40,"w":50,"h":25,"radius":25,"radius2":15}
{"page":1,"id":21,"obj":"label","x":8,"y":69,"w":35,"h":35,"text":"\uF020","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":22,"obj":"label","x":48,"y":79,"w":130,"h":30,"text":"Front door light","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":23,"obj":"switch","x":177,"y":74,"w":50,"h":25,"radius":25,"radius2":15}
{"page":1,"id":31,"obj":"label","x":8,"y":103,"w":35,"h":35,"text":"\uF054","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":32,"obj":"label","x":48,"y":113,"w":130,"h":30,"text":"Back yard lights","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":33,"obj":"switch","x":177,"y":110,"w":50,"h":25,"radius":25,"radius2":15}
{"page":1,"id":41,"obj":"label","x":8,"y":138,"w":35,"h":35,"text":"\uEA7A","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":42,"obj":"label","x":48,"y":148,"w":130,"h":30,"text":"Trash service","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":43,"obj":"label","x":97,"y":148,"w":130,"h":30,"text":"in 6 days","align":2,"text_color":"black"}
{"page":1,"id":51,"obj":"label","x":8,"y":173,"w":35,"h":35,"text":"\uF39D","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":52,"obj":"label","x":48,"y":183,"w":130,"h":30,"text":"Selective trash","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":53,"obj":"label","x":97,"y":183,"w":130,"h":30,"text":"in 10 days","align":2,"text_color":"black"}
{"page":1,"id":61,"obj":"label","x":8,"y":208,"w":35,"h":35,"text":"\uE32A","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":62,"obj":"label","x":48,"y":218,"w":130,"h":30,"text":"Green energy active","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":63,"obj":"label","x":97,"y":218,"w":130,"h":30,"text":"Yes :)","align":2,"text_color":"black"}
{"page":1,"id":71,"obj":"label","x":8,"y":243,"w":35,"h":35,"text":"\uE957","align":1,"text_font":32,"text_color":"black"}
{"page":1,"id":72,"obj":"label","x":48,"y":253,"w":130,"h":30,"text":"Air quality","align":0,"text_font":16,"text_color":"black"}
{"page":1,"id":73,"obj":"label","x":97,"y":253,"w":130,"h":30,"text":"OK (29.58 µg/m³)","align":2,"text_color":"black"}
{"page":0,"comment":"---------- All pages ----------"}
{"page":0,"id":11,"obj":"btn","action":"prev","x":0,"y":290,"w":79,"h":32,"bg_color":"#34495E","text":"\uE141","text_color":"#CCCCCC","radius":0,"border_side":0,"text_font":32}
{"page":0,"id":12,"obj":"btn","action":"back","x":80,"y":290,"w":80,"h":32,"bg_color":"#34495E","text":"\uE2DC","text_color":"#CCCCCC","radius":0,"border_side":0,"text_font":24}
{"page":0,"id":13,"obj":"btn","action":"next","x":161,"y":290,"w":79,"h":32,"bg_color":"#34495E","text":"\uE142","text_color":"#CCCCCC","radius":0,"border_side":0,"text_font":32}

View File

@ -87,7 +87,7 @@
res = ibinop(op, a, b); \
} else if (var_isnumber(a) && var_isnumber(b)) { \
res = var2real(a) op var2real(b); \
} else if (var_isinstance(a)) { \
} else if (var_isinstance(a) && !var_isnil(b)) { \
res = object_eqop(vm, #op, iseq, a, b); \
} else if (var_type(a) == var_type(b)) { /* same types */ \
if (var_isnil(a)) { /* nil op nil */ \

View File

@ -137,7 +137,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
*-----------*/
/*Enable the log module*/
#define LV_USE_LOG 0
#define LV_USE_LOG 0 // change to 0 in normal conditions
#if LV_USE_LOG
/*How important log should be added:

View File

@ -35,6 +35,66 @@
#define PAD_SMALL (disp_size == DISP_LARGE ? lv_disp_dpx(theme.disp, 14) : disp_size == DISP_MEDIUM ? lv_disp_dpx(theme.disp, 12) : lv_disp_dpx(theme.disp, 10))
#define PAD_TINY (disp_size == DISP_LARGE ? lv_disp_dpx(theme.disp, 8) : disp_size == DISP_MEDIUM ? lv_disp_dpx(theme.disp, 6) : lv_disp_dpx(theme.disp, 2))
// OpenHASP specific
/*BUTTON*/
#define COLOR_BTN (lv_color_lighten(HUE_COLOR, LV_OPA_30))
#define COLOR_BTN_GRAD (lv_color_darken(HUE_COLOR, LV_OPA_30))
#define COLOR_BTN_PR (lv_color_darken(COLOR_BTN_CHK, LV_OPA_20))
#define COLOR_BTN_PR_GRAD lv_color_darken(COLOR_BTN_GRAD, LV_OPA_20)
#define COLOR_BTN_CHK lv_color_darken(COLOR_BTN_GRAD, LV_OPA_20)
#define COLOR_BTN_CHK_GRAD lv_color_darken(COLOR_BTN_GRAD, LV_OPA_10)
#define COLOR_BTN_CHK_PR (lv_color_darken(COLOR_BTN_CHK, LV_OPA_20))
#define COLOR_BTN_CHK_PR_GRAD (lv_color_darken(COLOR_BTN_CHK_GRAD, LV_OPA_30))
#define COLOR_BTN_DIS (IS_LIGHT ? lv_color_hex3(0xccc) : lv_color_hex3(0x888))
#define COLOR_BTN_BORDER (IS_LIGHT ? (lv_color_darken(HUE_COLOR, LV_OPA_50)) : (lv_color_lighten(HUE_COLOR, LV_OPA_40)))
#define COLOR_BTN_BORDER_PR (IS_LIGHT ? lv_color_hex3(0xccc) : lv_color_hex(0x5f656e))
#define COLOR_BTN_BORDER_CHK (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0x5f656e))
#define COLOR_BTN_BORDER_CHK_PR (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0x5f656e))
#define COLOR_BTN_BORDER_INA (IS_LIGHT ? lv_color_hex3(0x888) : lv_color_hex(0x404040))
/*BACKGROUND*/
#define COLOR_BG COLOR_BTN
#define COLOR_BG_PR COLOR_BTN_PR
#define COLOR_BG_CHK COLOR_BTN_CHK
#define COLOR_BG_PR_CHK COLOR_BTN_CHK_PR
#define COLOR_BG_DIS COLOR_BG
#define COLOR_BG_BORDER (IS_LIGHT ? lv_color_hex(0xd6dde3) : lv_color_hex(0x808a97)) /*dfe7ed*/
#define COLOR_BG_BORDER_PR (IS_LIGHT ? lv_color_hex3(0xccc) : lv_color_hex(0x5f656e))
#define COLOR_BG_BORDER_CHK (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0x5f656e))
#define COLOR_BG_BORDER_CHK_PR (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0x5f656e))
#define COLOR_BG_BORDER_DIS (IS_LIGHT ? lv_color_hex(0xd6dde3) : lv_color_hex(0x5f656e))
#define COLOR_BG_TEXT lv_color_hex(0xeeeeee)
#define COLOR_BG_TEXT_PR LV_COLOR_WHITE
#define COLOR_BG_TEXT_CHK LV_COLOR_WHITE
#define COLOR_BG_TEXT_CHK_PR LV_COLOR_WHITE
#define COLOR_BG_TEXT_DIS (IS_LIGHT ? lv_color_hex3(0xaaa) : lv_color_hex3(0x999))
/*SECONDARY BACKGROUND*/
#define COLOR_BG_SEC lv_color_lighten(theme.color_primary, LV_OPA_30)
#define COLOR_BG_GRAD COLOR_BTN_GRAD
#define COLOR_BG_SEC_BORDER (IS_LIGHT ? lv_color_hex(0xdfe7ed) : lv_color_hex(0x404040))
#define COLOR_BG_SEC_TEXT (IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xa5a8ad))
#define COLOR_BG_SEC_TEXT_DIS (IS_LIGHT ? lv_color_hex(0xaaaaaa) : lv_color_hex(0xa5a8ad))
// #define TRANSITION_TIME 0 /*((theme.flags & LV_THEME_HASP_FLAG_NO_TRANSITION) ? 0 : 150)*/
// #define BORDER_WIDTH HASP_DPX(2)
// #define BORDER_COLOR ((theme.flags & IS_LIGHT) ? lv_color_make(0x40, 0x40, 0x40) : lv_color_make(0xb0, 0xb0, 0xb0))
// #define OUTLINE_WIDTH ((theme.flags & LV_THEME_HASP_FLAG_NO_FOCUS) ? 0 : HASP_DPX(3))
// #define OUTLINE_COLOR ((theme.flags & LV_THEME_HASP_FLAG_NO_FOCUS) ? BORDER_COLOR : theme.color_secondary)
// #define IS_LIGHT (theme.flags & LV_THEME_HASP_FLAG_LIGHT)
// #define NO_FOCUS (theme.flags & LV_THEME_HASP_FLAG_NO_FOCUS)
// #define PAD_DEF (lv_disp_get_size_category(NULL) <= 720 ? HASP_DPX(15) : (HASP_DPX(30))) // TODO
/*SCROLLBAR*/
#define SCROLLBAR_COLOR \
(IS_LIGHT ? lv_color_mix(theme.color_primary, lv_color_hex3(0x999), LV_OPA_10) \
: lv_color_mix(theme.color_primary, lv_color_hex3(0x999), LV_OPA_10))
/**********************
* TYPEDEFS
**********************/
@ -80,6 +140,7 @@ typedef struct {
#if LV_USE_ARC
lv_style_t arc_indic;
lv_style_t arc_indic_primary;
lv_style_t arc_knob; // knob for arc with zero
#endif
#if LV_USE_CHART
@ -245,7 +306,7 @@ static void style_init(void)
style_init_reset(&styles->card);
lv_style_set_radius(&styles->card, RADIUS_DEFAULT);
lv_style_set_bg_opa(&styles->card, LV_OPA_COVER);
lv_style_set_bg_opa(&styles->card, LV_OPA_TRANSP); // OpenHASP
lv_style_set_bg_color(&styles->card, color_card);
lv_style_set_border_color(&styles->card, color_grey);
lv_style_set_border_width(&styles->card, BORDER_WIDTH);
@ -272,11 +333,11 @@ static void style_init(void)
lv_style_set_radius(&styles->btn, (disp_size == DISP_LARGE ? lv_disp_dpx(theme.disp, 16) : disp_size == DISP_MEDIUM ? lv_disp_dpx(theme.disp, 12) : lv_disp_dpx(theme.disp, 8)));
lv_style_set_bg_opa(&styles->btn, LV_OPA_COVER);
lv_style_set_bg_color(&styles->btn, color_grey);
if(!(theme.flags & MODE_DARK)) {
lv_style_set_shadow_color(&styles->btn, lv_palette_lighten(LV_PALETTE_GREY, 3));
lv_style_set_shadow_width(&styles->btn, 1);
lv_style_set_shadow_ofs_y(&styles->btn, lv_disp_dpx(theme.disp, 4));
}
// if(!(theme.flags & MODE_DARK)) { // OpenHASP
// lv_style_set_shadow_color(&styles->btn, lv_palette_lighten(LV_PALETTE_GREY, 3));
// lv_style_set_shadow_width(&styles->btn, 1);
// lv_style_set_shadow_ofs_y(&styles->btn, lv_disp_dpx(theme.disp, 4));
// }
lv_style_set_text_color(&styles->btn, color_text);
lv_style_set_pad_hor(&styles->btn, PAD_DEF);
lv_style_set_pad_ver(&styles->btn, PAD_SMALL);
@ -384,11 +445,18 @@ static void style_init(void)
#if LV_USE_ARC
style_init_reset(&styles->arc_indic);
lv_style_set_arc_color(&styles->arc_indic, color_grey);
lv_style_set_arc_width(&styles->arc_indic, lv_disp_dpx(theme.disp, 15));
lv_style_set_arc_width(&styles->arc_indic, lv_disp_dpx(theme.disp, 18)); // OpenHASP
lv_style_set_arc_rounded(&styles->arc_indic, true);
style_init_reset(&styles->arc_indic_primary);
lv_style_set_arc_color(&styles->arc_indic_primary, theme.color_primary);
// OpenHASP
style_init_reset(&styles->arc_knob);
lv_style_set_bg_color(&styles->arc_knob, theme.color_primary);
lv_style_set_bg_opa(&styles->arc_knob, LV_OPA_COVER);
lv_style_set_pad_all(&styles->arc_knob, lv_disp_dpx(theme.disp, 4));
lv_style_set_radius(&styles->arc_knob, LV_RADIUS_CIRCLE);
#endif
#if LV_USE_DROPDOWN
@ -840,7 +908,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
lv_obj_add_style(obj, &styles->arc_indic, 0);
lv_obj_add_style(obj, &styles->arc_indic, LV_PART_INDICATOR);
lv_obj_add_style(obj, &styles->arc_indic_primary, LV_PART_INDICATOR);
lv_obj_add_style(obj, &styles->knob, LV_PART_KNOB);
lv_obj_add_style(obj, &styles->arc_knob, LV_PART_KNOB); // OpenHASP
}
#endif

View File

@ -18,6 +18,12 @@ extern "C" {
/*********************
* DEFINES
*********************/
typedef enum {
LV_THEME_HASP_FLAG_DARK = 0x01,
LV_THEME_HASP_FLAG_LIGHT = 0x02,
LV_THEME_HASP_FLAG_NO_TRANSITION = 0x10,
LV_THEME_HASP_FLAG_NO_FOCUS = 0x20,
} lv_theme_hasp_flag_t;
/**********************
* TYPEDEFS

View File

@ -615,6 +615,12 @@ const lvbe_call_c_t lv_spinbox_func[] = {
};
#endif // BE_LV_WIDGET_SPINBOX
/* `lv_spinner` methods */
#ifdef BE_LV_WIDGET_SPINNER
const lvbe_call_c_t lv_spinner_func[] = {
};
#endif // BE_LV_WIDGET_SPINNER
/* `lv_arc` methods */
#ifdef BE_LV_WIDGET_ARC
const lvbe_call_c_t lv_arc_func[] = {
@ -886,6 +892,7 @@ extern const bclass be_class_lv_obj;
extern const bclass be_class_lv_roller;
extern const bclass be_class_lv_slider;
extern const bclass be_class_lv_spinbox;
extern const bclass be_class_lv_spinner;
extern const bclass be_class_lv_style;
extern const bclass be_class_lv_switch;
extern const bclass be_class_lv_table;
@ -958,6 +965,9 @@ const lvbe_call_c_classes_t lv_classes[] = {
#ifdef BE_LV_WIDGET_SPINBOX
{ "lv_spinbox", &be_class_lv_spinbox, lv_spinbox_func, sizeof(lv_spinbox_func) / sizeof(lv_spinbox_func[0]) },
#endif // BE_LV_WIDGET_SPINBOX
#ifdef BE_LV_WIDGET_SPINNER
{ "lv_spinner", &be_class_lv_spinner, lv_spinner_func, sizeof(lv_spinner_func) / sizeof(lv_spinner_func[0]) },
#endif // BE_LV_WIDGET_SPINNER
{ "lv_style", &be_class_lv_style, lv_style_func, sizeof(lv_style_func) / sizeof(lv_style_func[0]) },
#ifdef BE_LV_WIDGET_SWITCH
{ "lv_switch", &be_class_lv_switch, lv_switch_func, sizeof(lv_switch_func) / sizeof(lv_switch_func[0]) },
@ -1014,6 +1024,10 @@ const size_t lv_classes_size = sizeof(lv_classes) / sizeof(lv_classes[0]);
#ifdef BE_LV_WIDGET_SPINBOX
int be_ntv_lv_spinbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinbox_create, "+lv.lv_spinbox", "(lv.lv_obj)"); }
#endif // BE_LV_WIDGET_SPINBOX
/* `lv_spinner` methods */
#ifdef BE_LV_WIDGET_SPINNER
int be_ntv_lv_spinner_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinner_create, "+lv.lv_spinner", "(lv.lv_obj)ii"); }
#endif // BE_LV_WIDGET_SPINNER
/* `lv_arc` methods */
#ifdef BE_LV_WIDGET_ARC
int be_ntv_lv_arc_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_arc_create, "+lv.lv_arc", "(lv.lv_obj)"); }

View File

@ -138,7 +138,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
*-----------*/
/*Enable the log module*/
#define LV_USE_LOG 1
#define LV_USE_LOG 0
#if LV_USE_LOG
/*How important log should be added:
@ -148,7 +148,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
*LV_LOG_LEVEL_USER Only logs added by the user
*LV_LOG_LEVEL_NONE Do not log anything*/
# define LV_LOG_LEVEL LV_LOG_LEVEL_ERROR
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
/*1: Print the log with 'printf';
*0: User need to register a callback with `lv_log_register_print_cb()`*/
@ -327,11 +327,11 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
#define ROBOTOCONDENSED_REGULAR_12_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_14_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_16_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_20_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_20_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_22_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_24_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_28_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_32_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_24_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_28_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_32_LATIN1 1
#define ROBOTOCONDENSED_REGULAR_36_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_38_LATIN1 0
#define ROBOTOCONDENSED_REGULAR_40_LATIN1 0

View File

@ -1005,6 +1005,7 @@
// -- LVGL Graphics Library ---------------------------------
//#define USE_LVGL // LVGL Engine, requires Berry (+382KB)
#define USE_LVGL_PSRAM // Allocate LVGL memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
#define USE_LVGL_OPENHASP // Enable OpenHASP template compatiblity (adds LVGL template and some fonts)
#define USE_LVGL_MAX_SLEEP 10 // max sleep in ms when LVGL is enabled, more than 10ms will make display less responsive
#define USE_LVGL_PNG_DECODER // include a PNG image decoder from file system (+16KB)
//#define USE_LVGL_FREETYPE // Use the FreeType renderer to display fonts using native TTF files in file system (+77KB flash)
@ -1039,6 +1040,7 @@
#define BE_LV_WIDGET_METER
#define BE_LV_WIDGET_MSGBOX
#define BE_LV_WIDGET_SPINBOX
#define BE_LV_WIDGET_SPINNER
#endif // ESP32

View File

@ -646,6 +646,7 @@ extern "C" {
}
int lv0_load_robotocondensed_latin1_font(bvm *vm) {
#ifdef USE_LVGL_OPENHASP
int argc = be_top(vm);
if (argc == 1 && be_isint(vm, 1)) {
const lv_font_t * font = nullptr;
@ -704,6 +705,7 @@ extern "C" {
be_return_nil(vm);
}
}
#endif // USE_LVGL_OPENHASP
be_raise(vm, kTypeError, nullptr);
}

View File

@ -411,7 +411,7 @@ void start_lvgl(const char * uconfig) {
#ifdef USE_UFILESYS
// Add file system mapping
lv_fs_drv_t drv; // can be on heap, LVGL creates a copy
static lv_fs_drv_t drv; // LVGL8, needs to be static and not on stack
lv_fs_drv_init(&drv); /*Basic initialization*/
drv.letter = 'A'; /*An uppercase letter to identify the drive */

View File

@ -153,7 +153,7 @@ lv_widgets = ['arc', 'bar', 'btn', 'btnmatrix', 'canvas', 'checkbox',
'switch', 'table', 'textarea' ]
# extra widgets
lv_widgets = lv_widgets + [ 'chart', 'colorwheel', 'imgbtn', 'led', 'meter', 'msgbox', 'spinbox' ]
lv_widgets = lv_widgets + [ 'chart', 'colorwheel', 'imgbtn', 'led', 'meter', 'msgbox', 'spinbox', 'spinner' ]
lv_prefix = ['obj', 'group', 'style', 'indev', 'disp'] + lv_widgets
def try_int(s):

View File

@ -601,6 +601,9 @@ void lv_spinbox_step_prev(lv_obj_t * obj)
void lv_spinbox_increment(lv_obj_t * obj)
void lv_spinbox_decrement(lv_obj_t * obj)
// ../../lib/libesp32_lvgl/LVGL8/src/extra/widgets/spinner/lv_spinner.h
lv_obj_t * lv_spinner_create(lv_obj_t * parent, uint32_t time, uint32_t arc_length)
// ../../lib/libesp32_lvgl/LVGL8/src/misc/lv_style_gen.h
void lv_style_set_width(lv_style_t * style, lv_coord_t value)
void lv_style_set_min_width(lv_style_t * style, lv_coord_t value)

View File

@ -59,6 +59,7 @@ lv_fun_globs = [
"extra/widgets/meter/*.h",
"extra/widgets/msgbox/*.h",
"extra/widgets/spinbox/*.h",
"extra/widgets/spinner/*.h",
"extra/themes/default/*.h",
"core/*.h",
"draw/*.h",