Tasmota/tasmota/xdrv_52_3_berry_lvlg.ino

594 lines
16 KiB
C++

/*
xdrv_52_3_berry_native.ino - Berry scripting language, native fucnctions
Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_BERRY
#ifdef USE_LVGL
#include <berry.h>
#include "lvgl.h"
#include "Adafruit_LvGL_Glue.h"
extern Adafruit_LvGL_Glue * glue;
/********************************************************************
* Generated code, don't edit
*******************************************************************/
// Configuration
#ifndef BE_LV_WIDGET_ARC
#define BE_LV_WIDGET_ARC 1
#endif
#ifndef BE_LV_WIDGET_BAR
#define BE_LV_WIDGET_BAR 1
#endif
#ifndef BE_LV_WIDGET_BTN
#define BE_LV_WIDGET_BTN 1
#endif
#ifndef BE_LV_WIDGET_BTNMATRIX
#define BE_LV_WIDGET_BTNMATRIX 1
#endif
#ifndef BE_LV_WIDGET_CALENDAR
#define BE_LV_WIDGET_CALENDAR 1
#endif
#ifndef BE_LV_WIDGET_CANVAS
#define BE_LV_WIDGET_CANVAS 1
#endif
#ifndef BE_LV_WIDGET_CHART
#define BE_LV_WIDGET_CHART 1
#endif
#ifndef BE_LV_WIDGET_CHECKBOX
#define BE_LV_WIDGET_CHECKBOX 1
#endif
#ifndef BE_LV_WIDGET_CONT
#define BE_LV_WIDGET_CONT 1
#endif
#ifndef BE_LV_WIDGET_CPICKER
#define BE_LV_WIDGET_CPICKER 1
#endif
#ifndef BE_LV_WIDGET_DROPDOWN
#define BE_LV_WIDGET_DROPDOWN 1
#endif
#ifndef BE_LV_WIDGET_GAUGE
#define BE_LV_WIDGET_GAUGE 1
#endif
#ifndef BE_LV_WIDGET_IMG
#define BE_LV_WIDGET_IMG 1
#endif
#ifndef BE_LV_WIDGET_IMGBTN
#define BE_LV_WIDGET_IMGBTN 1
#endif
#ifndef BE_LV_WIDGET_KEYBOARD
#define BE_LV_WIDGET_KEYBOARD 1
#endif
#ifndef BE_LV_WIDGET_LABEL
#define BE_LV_WIDGET_LABEL 1
#endif
#ifndef BE_LV_WIDGET_LED
#define BE_LV_WIDGET_LED 1
#endif
#ifndef BE_LV_WIDGET_LINE
#define BE_LV_WIDGET_LINE 1
#endif
#ifndef BE_LV_WIDGET_LINEMETER
#define BE_LV_WIDGET_LINEMETER 1
#endif
#ifndef BE_LV_WIDGET_LIST
#define BE_LV_WIDGET_LIST 1
#endif
#ifndef BE_LV_WIDGET_MSGBOX
#define BE_LV_WIDGET_MSGBOX 1
#endif
#ifndef BE_LV_WIDGET_OBJMASK
#define BE_LV_WIDGET_OBJMASK 1
#endif
#ifndef BE_LV_WIDGET_TEMPL
#define BE_LV_WIDGET_TEMPL 1
#endif
#ifndef BE_LV_WIDGET_PAGE
#define BE_LV_WIDGET_PAGE 1
#endif
#ifndef BE_LV_WIDGET_ROLLER
#define BE_LV_WIDGET_ROLLER 1
#endif
#ifndef BE_LV_WIDGET_SLIDER
#define BE_LV_WIDGET_SLIDER 1
#endif
#ifndef BE_LV_WIDGET_SPINBOX
#define BE_LV_WIDGET_SPINBOX 1
#endif
#ifndef BE_LV_WIDGET_SPINNER
#define BE_LV_WIDGET_SPINNER 1
#endif
#ifndef BE_LV_WIDGET_SWITCH
#define BE_LV_WIDGET_SWITCH 1
#endif
#ifndef BE_LV_WIDGET_TABLE
#define BE_LV_WIDGET_TABLE 1
#endif
#ifndef BE_LV_WIDGET_TABVIEW
#define BE_LV_WIDGET_TABVIEW 1
#endif
#ifndef BE_LV_WIDGET_TEXTAREA
#define BE_LV_WIDGET_TEXTAREA 1
#endif
#ifndef BE_LV_WIDGET_TILEVIEW
#define BE_LV_WIDGET_TILEVIEW 1
#endif
#ifndef BE_LV_WIDGET_WIN
#define BE_LV_WIDGET_WIN 1
#endif
/********************************************************************/
extern void start_lvgl(const char * uconfig);
extern void lv_ex_get_started_1(void);
/*********************************************************************************************\
* Native functions mapped to Berry functions
*
* import power
*
* power.read() -> map
*
\*********************************************************************************************/
extern "C" {
#include "be_exec.h"
#include "be_vm.h"
#include "be_mem.h"
/*********************************************************************************************\
* Support for lv_color
\*********************************************************************************************/
inline lv_color_t lv_color_from_uint32(uint32_t ucol) {
lv_color_t * col = (lv_color_t*) &ucol;
return *col;
}
inline uint32_t lv_color_to_uint32(lv_color_t col) {
uint32_t *p = (uint32_t*) &col;
return *p;
}
// lv_color
int lco_init(bvm *vm) {
int argc = be_top(vm);
uint32_t color = 0x0000; // default to black
if (argc > 1 && be_isint(vm, 2)) {
color = be_toint(vm, 2);
}
lv_color_t lv_color = lv_color_hex(color);
be_pushint(vm, lv_color_to_uint32(lv_color));
be_setmember(vm, 1, ".p");
be_return_nil(vm);
}
int lco_tostring(bvm *vm) {
lv_color_t lv_color = {};
be_getmember(vm, 1, ".p");
lv_color = lv_color_from_uint32(be_toint(vm, -1));
uint32_t color = lv_color_to32(lv_color);
be_pop(vm, 1); // remove attribute
char s[32];
snprintf(s, sizeof(s), "lv_color(0x%x)", color);
be_pushnstring(vm, s, strlen(s)); /* make escape string from buffer */
be_return(vm);
}
/*********************************************************************************************\
* Support for lv
\*********************************************************************************************/
// Get the `.p` member of instance at `index`
void * lv_get_arg(bvm *vm, int index) {
void * ret = nullptr;
if (be_isinstance(vm, index)) {
be_getmember(vm, index, ".p");
ret = be_tocomptr(vm, -1);
be_pop(vm, 1); // remove .p attribute
}
return ret;
}
// called during init, set the `.p` member with the pointer
void lv_init_set_member(bvm *vm, int index, void * ptr) {
if (ptr == nullptr) {
be_throw(vm, BE_MALLOC_FAIL);
}
be_pushcomptr(vm, ptr);
be_setmember(vm, index, ".p");
be_pop(vm, 1);
}
// function is (void) -> lv_obt_t*
typedef lv_obj_t* (*fn_lvobj__void)(void); // f() -> newly created lv_obj()
int lv0_lvobj__void_call(bvm *vm, fn_lvobj__void func) {
lv_obj_t * obj = (*func)();
be_getglobal(vm, LV_OBJ_CLASS); // stack = class
be_pushcomptr(vm, (void*) -1); // stack = class, -1
be_pushcomptr(vm, (void*) obj); // stack = class, -1, ptr
be_call(vm, 2); // instanciate, stack = instance (don't call init() )
be_pop(vm, 2); // stack = instance
be_return(vm);
}
int lv0_load_font(bvm *vm) {
int argc = be_top(vm);
if (argc == 1 && be_isstring(vm, 1)) {
lv_font_t * font = lv_font_load(be_tostring(vm, 1));
if (font != nullptr) {
be_getglobal(vm, "lv_font");
be_pushcomptr(vm, font);
be_call(vm, 1);
be_pop(vm, 1);
be_return(vm);
} else {
be_return_nil(vm);
}
}
be_raise(vm, kTypeError, nullptr);
}
int lv0_load_montserrat_font(bvm *vm) {
int argc = be_top(vm);
if (argc == 1 && be_isint(vm, 1)) {
lv_font_t * font = nullptr;
int32_t font_size = be_toindex(vm, 1);
switch (font_size) {
#if LV_FONT_MONTSERRAT_8
case 8:
font = &lv_font_montserrat_8;
break;
#endif
#if LV_FONT_MONTSERRAT_10
case 10:
font = &lv_font_montserrat_10;
break;
#endif
#if LV_FONT_MONTSERRAT_12
case 12:
font = &lv_font_montserrat_12;
break;
#endif
#if LV_FONT_MONTSERRAT_14
case 14:
font = &lv_font_montserrat_14;
break;
#endif
#if LV_FONT_MONTSERRAT_16
case 16:
font = &lv_font_montserrat_16;
break;
#endif
#if LV_FONT_MONTSERRAT_18
case 18:
font = &lv_font_montserrat_18;
break;
#endif
#if LV_FONT_MONTSERRAT_20
case 20:
font = &lv_font_montserrat_20;
break;
#endif
#if LV_FONT_MONTSERRAT_22
case 22:
font = &lv_font_montserrat_22;
break;
#endif
#if LV_FONT_MONTSERRAT_24
case 24:
font = &lv_font_montserrat_24;
break;
#endif
#if LV_FONT_MONTSERRAT_26
case 26:
font = &lv_font_montserrat_26;
break;
#endif
#if LV_FONT_MONTSERRAT_28
case 28:
font = &lv_font_montserrat_28;
break;
#endif
#if LV_FONT_MONTSERRAT_30
case 30:
font = &lv_font_montserrat_30;
break;
#endif
#if LV_FONT_MONTSERRAT_32
case 32:
font = &lv_font_montserrat_32;
break;
#endif
#if LV_FONT_MONTSERRAT_34
case 34:
font = &lv_font_montserrat_34;
break;
#endif
#if LV_FONT_MONTSERRAT_36
case 36:
font = &lv_font_montserrat_36;
break;
#endif
#if LV_FONT_MONTSERRAT_38
case 38:
font = &lv_font_montserrat_38;
break;
#endif
#if LV_FONT_MONTSERRAT_40
case 40:
font = &lv_font_montserrat_40;
break;
#endif
#if LV_FONT_MONTSERRAT_42
case 42:
font = &lv_font_montserrat_42;
break;
#endif
#if LV_FONT_MONTSERRAT_44
case 44:
font = &lv_font_montserrat_44;
break;
#endif
#if LV_FONT_MONTSERRAT_46
case 46:
font = &lv_font_montserrat_46;
break;
#endif
#if LV_FONT_MONTSERRAT_48
case 48:
font = &lv_font_montserrat_48;
break;
#endif
#if LV_FONT_MONTSERRAT_28_COMPRESSED
case 28:
font = &lv_font_montserrat_28_compressed;
break;
#endif
default:
break;
}
if (font != nullptr) {
be_getglobal(vm, "lv_font");
be_pushcomptr(vm, font);
be_call(vm, 1);
be_pop(vm, 1);
be_return(vm);
} else {
be_return_nil(vm);
}
}
be_raise(vm, kTypeError, nullptr);
}
int lv0_load_seg7_font(bvm *vm) {
int argc = be_top(vm);
if (argc == 1 && be_isint(vm, 1)) {
lv_font_t * font = nullptr;
int32_t font_size = be_toindex(vm, 1);
switch (font_size) {
case 8: font = &seg7_8; break;
case 10: font = &seg7_10; break;
case 12: font = &seg7_12; break;
case 14: font = &seg7_14; break;
case 16: font = &seg7_16; break;
case 18: font = &seg7_18; break;
case 20: font = &seg7_20; break;
case 24: font = &seg7_24; break;
case 28: font = &seg7_28; break;
case 36: font = &seg7_36; break;
case 48: font = &seg7_48; break;
default: break;
}
if (font != nullptr) {
be_getglobal(vm, "lv_font");
be_pushcomptr(vm, font);
be_call(vm, 1);
be_pop(vm, 1);
be_return(vm);
} else {
be_return_nil(vm);
}
}
be_raise(vm, kTypeError, nullptr);
}
#include "lvgl_berry/tasmota_logo_64_truecolor_alpha.h"
void lv_img_set_tasmota_logo(lv_obj_t * img) {
lv_img_set_src(img, &tasmota_logo_64_truecolor);
}
// lv.start(instance, instance) -> nil
int lv0_start(bvm *vm);
int lv0_start(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc == 1 && be_isstring(vm, 1)) {
const char * uconfig = be_tostring(vm, 1);
start_lvgl(uconfig);
be_return_nil(vm);
}
be_raise(vm, kTypeError, nullptr);
}
// lv.demo() -> nil
int lv0_demo(bvm *vm);
int lv0_demo(bvm *vm) {
lv_ex_get_started_1();
be_return_nil(vm);
}
// lv.scr_act() -> lv_obj() instance
int lv0_scr_act(bvm *vm) { return lv0_lvobj__void_call(vm, &lv_scr_act); }
int lv0_layer_top(bvm *vm) { return lv0_lvobj__void_call(vm, &lv_layer_top); }
int lv0_layer_sys(bvm *vm) { return lv0_lvobj__void_call(vm, &lv_layer_sys); }
int lv0_get_hor_res(bvm *vm) {
be_pushint(vm, lv_disp_get_hor_res(lv_disp_get_default()));
be_return(vm);
}
int lv0_get_ver_res(bvm *vm) {
be_pushint(vm, lv_disp_get_ver_res(lv_disp_get_default()));
be_return(vm);
}
/*********************************************************************************************\
* Support for lv_obj
\*********************************************************************************************/
int lvx_init(bvm *vm);
int lvx_init(bvm *vm) {
int argc = be_top(vm);
lv_obj_t * obj = nullptr;
if (argc > 1) {
obj = (lv_obj_t*) be_convert_single_elt(vm, 2);
}
// AddLog(LOG_LEVEL_INFO, "argc %d lv_obj %p", argc, obj);
if (obj == nullptr) {
obj = lv_obj_create(nullptr, nullptr);
}
// AddLog(LOG_LEVEL_INFO, "lv_obj final %p", obj);
lv_init_set_member(vm, 1, obj);
be_return_nil(vm);
}
int lvx_init_2(bvm *vm, void * func, const char * return_type, const char * arg_type = nullptr);
int lvx_init_2(bvm *vm, void * func, const char * return_type, const char * arg_type) {
int argc = be_top(vm);
lv_obj_t * obj1 = nullptr;
lv_obj_t * obj2 = nullptr;
if (argc > 1) {
obj1 = (lv_obj_t*) be_convert_single_elt(vm, 2);
}
if (argc > 2) {
obj2 = (lv_obj_t*) be_convert_single_elt(vm, 3);
}
// AddLog(LOG_LEVEL_INFO, "argc %d lv_obj %p", argc, obj);
fn_any_callable f = (fn_any_callable) func;
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func(%p) - %p,%p,%p,%p,%p", f, p[0], p[1], p[2], p[3], p[4]);
lv_obj_t * obj;
if ((int32_t)obj1 == -1) { // special semantics of first ptr is -1, then just encapsulate
obj = obj2;
} else { // otherwise call the LVGL creator
obj = (lv_obj_t*) (*f)((int32_t)obj1, (int32_t)obj2, 0, 0, 0);
}
lv_init_set_member(vm, 1, obj);
be_return_nil(vm);
}
int lvx_tostring(bvm *vm) {
lv_obj_t * obj = (lv_obj_t*) lv_get_arg(vm, 1);
const char * classname = be_classname(vm, 1);
char s[32];
snprintf(s, sizeof(s), "<instance: %s(0x%08X)>", classname, obj);
be_pushnstring(vm, s, strlen(s)); /* make escape string from buffer */
be_return(vm);
}
/*********************************************************************************************\
* Support for lv_style
\*********************************************************************************************/
int lvs_init(bvm *vm) {
int argc = be_top(vm);
lv_style_t * style = nullptr;
if (argc > 1) {
style = (lv_style_t*) be_convert_single_elt(vm, 2);
}
if (style == nullptr) {
style = (lv_style_t*) be_malloc(vm, sizeof(lv_style_t));
if (style != nullptr) {
lv_style_init(style);
}
}
lv_init_set_member(vm, 1, style);
be_return_nil(vm);
}
int lvs_tostring(bvm *vm) {
lv_style_t * style1 = (lv_style_t*) lv_get_arg(vm, 1);
char s[32];
snprintf(s, sizeof(s), "<instance: lv_style(0x%08X)>", style1);
be_pushnstring(vm, s, strlen(s)); /* make escape string from buffer */
be_return(vm);
}
/*********************************************************************************************\
* Screenshot in raw format
\********************************************************************************************/
int lv0_screenshot(bvm *vm);
int lv0_screenshot(bvm *vm) {
if (!glue) { be_return_nil(vm); }
char fname[32];
snprintf(fname, sizeof(fname), "/screenshot-%d.raw", Rtc.utc_time);
File f = dfsp->open(fname, "w");
if (f) {
glue->setScreenshotFile(&f);
// redraw screen
lv_obj_invalidate(lv_scr_act());
lv_refr_now(lv_disp_get_default());
glue->stopScreenshot();
f.close();
}
be_pushstring(vm, fname);
be_return(vm);
}
}
#include "lvgl_berry/be_lv_c_mapping.h"
#else // USE_LVGL
// // define weak aliases
// int32_t b_nrg_read(struct bvm *vm) __attribute__ ((weak, alias ("b_wire_energymissing")));
#endif // USE_LVGL
#endif // USE_BERRY