Files
mongoose-touch/src/widget.c
2017-12-02 23:34:16 +01:00

188 lines
4.3 KiB
C

#include "mgos.h"
#include "widget.h"
#include "frozen/frozen.h"
#include "common/queue.h"
static void widget_event_timer(void *arg) {
struct widget_t *widget = (struct widget_t *) arg;
if (!widget)
return;
if (widget->handler)
widget->handler(EV_WIDGET_TIMER, widget, NULL);
}
void widget_destroy(struct widget_t **widget) {
if (!*widget)
return;
if ((*widget)->handler)
(*widget)->handler(EV_WIDGET_DESTROY, *widget, NULL);
if ((*widget)->_timer_id)
mgos_clear_timer((*widget)->_timer_id);
if ((*widget)->user_data)
free((*widget)->user_data);
if ((*widget)->name)
free((*widget)->name);
if ((*widget)->label)
free((*widget)->label);
if ((*widget)->img)
free((*widget)->img);
free(*widget);
*widget=NULL;
}
struct widget_t *widget_create(char *name, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
struct widget_t *widget;
widget = (struct widget_t *) calloc(1, sizeof(*widget));
if (!widget)
return NULL;
widget->name=strdup(name);
widget->x=x;
widget->y=y;
widget->w=w;
widget->h=h;
widget->type=WIDGET_TYPE_NONE;
widget->label=NULL;
widget->img=NULL;
widget->user_data = NULL;
widget->handler = NULL;
widget->timer_msec = 0;
widget->_timer_id = 0;
widget->create_called = false;
return widget;
}
struct widget_t *widget_create_from_json(const char *json) {
struct widget_t *widget=NULL;
int x, y, w, h;
int type = 0;
char *name = NULL;
char *label = NULL;
char *img = NULL;
char *screen = NULL;
if (json_scanf(json, strlen(json), "{name:%Q,x:%d,y:%d,w:%d,h:%d}", &name, &x, &y, &w, &h) != 5) {
LOG(LL_ERROR, ("Incomplete JSON: require 'x', 'y', 'w', 'h' and 'name' fields"));
return NULL;
}
widget = widget_create(name, x, y, w, h);
free(name);
json_scanf(json, strlen(json), "{type:%d,label:%Q,img:%Q}", &type, &label, &img);
widget->type=type;
widget->label=label;
widget->img=img;
// Load widget-specific attributes
if (type == WIDGET_TYPE_LOADSCREEN) {
if (json_scanf(json, strlen(json), "{screen:%Q}", &screen) != 1) {
LOG(LL_WARN, ("Widget '%s' is of type LOADSCREEN but does not have attribute 'screen'", widget->name));
} else {
if (widget->user_data) free(widget->user_data);
widget->user_data = screen;
}
} else if (type == WIDGET_TYPE_MQTT_BUTTON) {
char *mqtt = NULL;
if (json_scanf(json, strlen(json), "{mqtt:%Q}", &mqtt) != 1) {
LOG(LL_WARN, ("Widget '%s' is of type MQTT_BUTTON but does not have attribute 'mqtt'", widget->name));
} else {
if (widget->user_data) free(widget->user_data);
widget->user_data=mqtt;
}
}
return widget;
}
struct widget_t *widget_create_from_file(const char *fn) {
char *json;
struct widget_t *widget=NULL;
if (!(json = json_fread(fn))) {
LOG(LL_ERROR, ("%s: Could not json_fread()", fn));
return NULL;
}
widget = widget_create_from_json(json);
free(json);
return widget;
}
void widget_set_handler(struct widget_t *w, widget_event_fn handler) {
if (!w)
return;
w->handler = handler;
if (!w->create_called && w->handler)
handler(EV_WIDGET_CREATE, w, NULL);
return;
}
void widget_delete_handler(struct widget_t *w) {
if (!w)
return;
w->handler = NULL;
return;
}
void widget_set_timer(struct widget_t *w, uint32_t timer_msec) {
if (!w)
return;
if (w->_timer_id)
mgos_clear_timer(w->_timer_id);
w->timer_msec=timer_msec;
if (timer_msec == 0)
w->_timer_id = 0;
else
w->_timer_id = mgos_set_timer(timer_msec, MGOS_TIMER_REPEAT, widget_event_timer, w);
return;
}
void widget_delete_timer(struct widget_t *w) {
if (!w)
return;
widget_set_timer(w, 0);
return;
}
void widget_ev_to_str(int ev, char *s, int slen) {
switch(ev) {
case EV_WIDGET_CREATE:
strncpy(s, "CREATE", slen);
break;
case EV_WIDGET_DRAW:
strncpy(s, "DRAW", slen);
break;
case EV_WIDGET_REDRAW:
strncpy(s, "REDRAW", slen);
break;
case EV_WIDGET_TIMER:
strncpy(s, "TIMER", slen);
break;
case EV_WIDGET_TOUCH_UP:
strncpy(s, "TOUCH_UP", slen);
break;
case EV_WIDGET_TOUCH_DOWN:
strncpy(s, "TOUCH_DOWN", slen);
break;
case EV_WIDGET_DESTROY:
strncpy(s, "DESTROY", slen);
break;
default: // EV_WIDGET_NONE
snprintf(s, slen, "EV%d", ev);
break;
}
}