static void offset_widget_msg(msg_event_t* event) { offset_screen_t* s = widget_get_instance_data(event->widget); if (event->msg_id == MSG_SENSOR_SAMPLE) { sensor_msg_t* msg = event->msg_data; if (msg->sensor == SENSOR_1 && s->sensor1_enabled == false) { s->sensor1_enabled = true; rebuild_offset_screen(s); } else if (msg->sensor == SENSOR_2 && s->sensor2_enabled == false) { s->sensor2_enabled = true; rebuild_offset_screen(s); } } else if (event->msg_id == MSG_SENSOR_TIMEOUT) { sensor_timeout_msg_t* msg = event->msg_data; if (msg->sensor == SENSOR_1 && s->sensor1_enabled == true) { s->sensor1_enabled = false; rebuild_offset_screen(s); } else if (msg->sensor == SENSOR_2 && s->sensor2_enabled == true) { s->sensor2_enabled = false; rebuild_offset_screen(s); } } }
static void calib_widget_paint(paint_event_t* event) { calib_screen_t* s = widget_get_instance_data(event->widget); const point_t* marker_pos; if (!s->calib_complete) { marker_pos = &ref_pts[s->ref_pt_idx]; if (s->sample_idx == 0) gfx_set_fg_color(YELLOW); else if (s->sample_idx < NUM_SAMPLES_PER_POINT) gfx_set_fg_color(RED); else gfx_set_fg_color(GREEN); } else { marker_pos = &s->last_touch_pos; gfx_set_fg_color(COBALT); } rect_t r = { marker_pos->x - (MARKER_SIZE / 2), marker_pos->y - (MARKER_SIZE / 2), MARKER_SIZE, MARKER_SIZE}; gfx_fill_rect(r); }
static void listbox_layout(widget_t* w) { int i; listbox_t* l = widget_get_instance_data(w); int visible_items = num_visible_items(w); for (i = 0; i < widget_num_children(w); ++i) { int visible_index = i - l->pos; widget_t* child = widget_get_child(w, i); if (visible_index >= 0 && visible_index < visible_items) { rect_t child_rect = widget_get_rect(child); child_rect.y = (visible_index * l->item_height) + ((l->item_height - child_rect.height) / 2); widget_set_rect(child, child_rect); widget_show(child); } else { widget_hide(child); } } widget_enable(l->up_button, (l->pos > 0)); widget_enable(l->dn_button, (l->pos < (widget_num_children(w) - visible_items))); }
static void textentry_screen_destroy(widget_t* w) { textentry_screen_t* screen = widget_get_instance_data(w); free(screen); }
static int num_visible_items(widget_t* lb) { listbox_t* l = widget_get_instance_data(lb); rect_t rect = widget_get_rect(lb); return rect.height / l->item_height; }
void icon_set_color(widget_t* w, color_t icon_color) { icon_t* i = widget_get_instance_data(w); if (i->icon_color != icon_color) { i->icon_color = icon_color; widget_invalidate(w); } }
static void screen_saver_destroy(widget_t* w) { screen_saver_t* s = widget_get_instance_data(w); gui_msg_unsubscribe(MSG_TOUCH_INPUT, w); free(s); }
void icon_set_image(widget_t* w, const Image_t* image) { icon_t* i = widget_get_instance_data(w); if (i->image != image) { i->image = image; widget_invalidate(w); } }
static void offset_screen_destroy(widget_t* w) { offset_screen_t* s = widget_get_instance_data(w); gui_msg_unsubscribe(MSG_SENSOR_SAMPLE, s->screen); gui_msg_unsubscribe(MSG_SENSOR_TIMEOUT, s->screen); free(s); }
static void calib_widget_msg(msg_event_t* event) { calib_screen_t* s = widget_get_instance_data(event->widget); if (event->msg_id == MSG_TOUCH_INPUT) { touch_msg_t* msg = event->msg_data; calib_raw_touch(s, msg->touch_down, msg->raw); } }
static void calib_widget_touch(touch_event_t* event) { calib_screen_t* s = widget_get_instance_data(event->widget); if (s->calib_complete) { s->last_touch_pos = event->pos; widget_invalidate(event->widget); } }
static void ok_button_clicked(button_event_t* event) { if (event->id == EVT_BUTTON_CLICK) { widget_t* w = widget_get_parent(event->widget); textentry_screen_t* screen = widget_get_instance_data(w); if (screen->text_handler != NULL) screen->text_handler(screen->text, screen->user_data); gui_pop_screen(); } }
static void down_button_clicked(button_event_t* event) { if (event->id == EVT_BUTTON_CLICK) { widget_t* w = widget_get_parent(event->widget); textentry_screen_t* screen = widget_get_instance_data(w); if (screen->row_idx < (int)(screen->num_rows - NUM_VISIBLE_ROWS)) screen->row_idx += NUM_VISIBLE_ROWS; update_input_buttons(screen); } }
static void char_button_clicked(button_event_t* event) { if (event->id == EVT_BUTTON_CLICK) { widget_t* w = widget_get_parent(event->widget); textentry_screen_t* screen = widget_get_instance_data(w); const char* btn_text = button_get_text(event->widget); strncat(screen->text, btn_text, sizeof(screen->text)); label_set_text(screen->text_label, screen->text); } }
widget_t* calib_screen_create() { calib_screen_t* s = calloc(1, sizeof(calib_screen_t)); s->widget = widget_create(NULL, &calib_widget_class, s, display_rect); widget_set_background(s->widget, BLACK); rect_t rect = { .x = 15, .y = 15, .width = 56, .height = 56, }; s->complete_button = button_create(s->widget, rect, img_left, WHITE, BLACK, complete_calib); widget_hide(s->complete_button); button_set_up_bg_color(s->complete_button, BLACK); button_set_up_icon_color(s->complete_button, WHITE); button_set_down_bg_color(s->complete_button, BLACK); button_set_down_icon_color(s->complete_button, LIGHT_GRAY); button_set_disabled_bg_color(s->complete_button, BLACK); button_set_disabled_icon_color(s->complete_button, DARK_GRAY); rect.x = 320 - 56 - 15; rect.y = 240 - 56 - 15; s->recal_button = button_create(s->widget, rect, img_update, WHITE, BLACK, restart_calib); widget_hide(s->recal_button); button_set_up_bg_color(s->recal_button, BLACK); button_set_up_icon_color(s->recal_button, WHITE); button_set_down_bg_color(s->recal_button, BLACK); button_set_down_icon_color(s->recal_button, LIGHT_GRAY); button_set_disabled_bg_color(s->recal_button, BLACK); button_set_disabled_icon_color(s->recal_button, DARK_GRAY); rect.x = 50; rect.y = 100; rect.width = 175; s->lbl_instructions = label_create(s->widget, rect, "Touch and hold the marker until it turns green", font_opensans_regular_18, WHITE, 3); gui_msg_subscribe(MSG_TOUCH_INPUT, s->widget); return s->widget; } static void calib_widget_destroy(widget_t* w) { calib_screen_t* s = widget_get_instance_data(w); gui_msg_unsubscribe(MSG_TOUCH_INPUT, s->widget); free(s); }
static void up_button_event(button_event_t* event) { widget_t* parent = widget_get_parent(event->widget); listbox_t* l = widget_get_instance_data(parent); if (event->id == EVT_BUTTON_CLICK || event->id == EVT_BUTTON_REPEAT) { if (l->pos > 0) { l->pos--; widget_invalidate(l->item_container); } } }
static void backspace_button_clicked(button_event_t* event) { if (event->id == EVT_BUTTON_CLICK) { widget_t* w = widget_get_parent(event->widget); textentry_screen_t* screen = widget_get_instance_data(w); int text_len = strlen(screen->text); if (text_len > 0) { screen->text[text_len - 1] = '\0'; label_set_text(screen->text_label, screen->text); } } }
static void screen_saver_msg(msg_event_t* event) { screen_saver_t* s = widget_get_instance_data(event->widget); switch (event->msg_id) { case MSG_TOUCH_INPUT: dispatch_touch_input(s, event->msg_data); break; default: break; } }
static void down_button_event(button_event_t* event) { widget_t* lb = widget_get_parent(event->widget); listbox_t* l = widget_get_instance_data(lb); if (event->id == EVT_BUTTON_CLICK || event->id == EVT_BUTTON_REPEAT) { if (l->pos < widget_num_children(l->item_container) - num_visible_items(lb)) { l->pos++; widget_invalidate(l->item_container); } } }
void listbox_add_item(widget_t* lb, widget_t* item) { listbox_t* l = widget_get_instance_data(lb); widget_add_child(l->item_container, item); rect_t container_rect = widget_get_rect(l->item_container); rect_t rect = widget_get_rect(item); rect.x = 0; rect.y = 0; rect.width = MIN(rect.width, container_rect.width); rect.height = MIN(rect.height, l->item_height); widget_set_rect(item, rect); widget_invalidate(lb); }
static void click_output_button(button_event_t* event) { if (event->id != EVT_BUTTON_CLICK) return; widget_t* parent = widget_get_parent(event->widget); home_screen_t* s = widget_get_instance_data(parent); const controller_settings_t* controller1_settings = app_cfg_get_controller_settings(CONTROLLER_1); const controller_settings_t* controller2_settings = app_cfg_get_controller_settings(CONTROLLER_2); output_id_t output; if (event->widget == s->outputs[OUTPUT_1].button) output = OUTPUT_1; else output = OUTPUT_2; output_function_t controller_1_function = controller1_settings->output_settings[output].function; output_function_t controller_2_function = controller2_settings->output_settings[output].function; if (controller_1_function == OUTPUT_FUNC_MANUAL || controller_2_function == OUTPUT_FUNC_MANUAL) { if (s->outputs[output].enabled == false) s->outputs[output].enabled = true; else s->outputs[output].enabled = false; set_output_settings(s, output, OUTPUT_FUNC_MANUAL); } else if (controller_1_function == OUTPUT_FUNC_HEATING || controller_1_function == OUTPUT_FUNC_COOLING) { if (s->output_ovrd[output] == true) s->output_ovrd[output] = false; else s->output_ovrd[output] = true; output_ovrd_msg_t msg = { .output = output, .controller = CONTROLLER_1 }; msg_send(MSG_OUTPUT_OVRD, &msg); set_output_icon_color(s, output); } else if (controller_2_function == OUTPUT_FUNC_HEATING ||
static void restart_calib(button_event_t* event) { if (event->id == EVT_BUTTON_CLICK) { widget_t* screen_widget = widget_get_parent(event->widget); calib_screen_t* s = widget_get_instance_data(screen_widget); s->calib_complete = false; s->sample_idx = 0; s->ref_pt_idx = 0; memset(s->sample_count, 0, sizeof(s->sample_count)); widget_show(s->lbl_instructions); widget_hide(s->recal_button); widget_hide(s->complete_button); widget_invalidate(screen_widget); } }
static void click_sensor_button(button_event_t* event) { if (event->id != EVT_BUTTON_CLICK) return; widget_t* parent = widget_get_parent(event->widget); home_screen_t* s = widget_get_instance_data(parent); sensor_id_t sensor; if (event->widget == s->sensors[SENSOR_1].button) sensor = SENSOR_1; else sensor = SENSOR_2; widget_t* settings_screen = controller_settings_screen_create(sensor); gui_push_screen(settings_screen); }
static void icon_paint(paint_event_t* event) { icon_t* i = widget_get_instance_data(event->widget); rect_t rect = widget_get_rect(event->widget); point_t center = rect_center(rect); if (!widget_is_enabled(event->widget)) { gfx_set_bg_color(DARK_GRAY); gfx_clear_rect(rect); } /* draw icon */ if (i->image != NULL) { gfx_set_fg_color(i->icon_color); gfx_draw_bitmap( center.x - (i->image->width / 2), center.y - (i->image->height / 2), i->image); } }
static void home_screen_msg(msg_event_t* event) { home_screen_t* s = widget_get_instance_data(event->widget); switch (event->msg_id) { case MSG_SENSOR_SAMPLE: dispatch_sensor_sample(s, event->msg_data); break; case MSG_SENSOR_TIMEOUT: dispatch_sensor_timeout(s, event->msg_data); break; case MSG_OUTPUT_STATUS: dispatch_output_status(s, event->msg_data); break; case MSG_TEMP_UNIT: dispatch_temp_unit(s, *((unit_t*)event->msg_data)); break; case MSG_NET_STATUS: dispatch_net_status(s, event->msg_data); break; case MSG_API_STATUS: dispatch_api_status(s, event->msg_data); break; case MSG_CONTROLLER_SETTINGS: case MSG_API_CONTROLLER_SETTINGS: dispatch_controller_settings(s, event->msg_data); break; default: break; } }
widget_t* listbox_get_item(widget_t* lb, int i) { listbox_t* l = widget_get_instance_data(lb); return widget_get_child(l->item_container, i); }
int listbox_num_items(widget_t* lb) { listbox_t* l = widget_get_instance_data(lb); return widget_num_children(l->item_container); }
widget_t* home_screen_create() { home_screen_t* s = calloc(1, sizeof(home_screen_t)); s->sample_timestamp = chTimeNow(); s->screen = widget_create(NULL, &home_widget_class, s, display_rect); widget_set_background(s->screen, BLACK); rect_t rect = { .x = TILE_X(0), .y = TILE_Y(0), .width = TILE_SPAN(3), .height = TILE_SPAN(2), }; s->stage_widget = widget_create(s->screen, NULL, NULL, rect); widget_set_background(s->stage_widget, GREEN); rect.x = TILE_X(3); rect.width = TILE_SPAN(1); rect.height = TILE_SPAN(1); s->sensors[SENSOR_1].button = button_create(s->screen, rect, img_temp_med, WHITE, STEEL, click_sensor_button); rect.y = TILE_Y(1); s->sensors[SENSOR_2].button = button_create(s->screen, rect, img_temp_med, WHITE, STEEL, click_sensor_button); rect.x = TILE_X(0); rect.y = TILE_Y(2); s->outputs[OUTPUT_1].button = button_create(s->screen, rect, img_plug, WHITE, STEEL, click_output_button); rect.x = TILE_X(1); s->outputs[OUTPUT_2].button = button_create(s->screen, rect, img_plug, WHITE, STEEL, click_output_button); rect.x = TILE_X(2); s->conn_button = button_create(s->screen, rect, img_signal, RED, STEEL, click_conn_button); rect.x = TILE_X(3); s->settings_button = button_create(s->screen, rect, img_settings, WHITE, COBALT, click_settings_button); rect.x = 0; rect.width = TILE_SPAN(3); s->sensors[SENSOR_1].quantity_widget = quantity_widget_create(s->stage_widget, rect, app_cfg_get_temp_unit()); widget_disable(s->sensors[SENSOR_1].quantity_widget); s->sensors[SENSOR_2].quantity_widget = quantity_widget_create(s->stage_widget, rect, app_cfg_get_temp_unit()); widget_disable(s->sensors[SENSOR_2].quantity_widget); place_quantity_widgets(s); set_output_settings(s, OUTPUT_1, temp_control_get_output_function(OUTPUT_1)); set_output_settings(s, OUTPUT_2, temp_control_get_output_function(OUTPUT_2)); gui_msg_subscribe(MSG_SENSOR_SAMPLE, s->screen); gui_msg_subscribe(MSG_SENSOR_TIMEOUT, s->screen); gui_msg_subscribe(MSG_OUTPUT_STATUS, s->screen); gui_msg_subscribe(MSG_TEMP_UNIT, s->screen); gui_msg_subscribe(MSG_NET_STATUS, s->screen); gui_msg_subscribe(MSG_API_STATUS, s->screen); gui_msg_subscribe(MSG_CONTROLLER_SETTINGS, s->screen); gui_msg_subscribe(MSG_API_CONTROLLER_SETTINGS, s->screen); return s->screen; } void home_screen_destroy(widget_t* w) { home_screen_t* s = widget_get_instance_data(w); gui_msg_unsubscribe(MSG_SENSOR_SAMPLE, s->screen); gui_msg_unsubscribe(MSG_SENSOR_TIMEOUT, s->screen); gui_msg_unsubscribe(MSG_OUTPUT_STATUS, s->screen); gui_msg_unsubscribe(MSG_TEMP_UNIT, s->screen); gui_msg_unsubscribe(MSG_NET_STATUS, s->screen); gui_msg_unsubscribe(MSG_API_STATUS, s->screen); gui_msg_unsubscribe(MSG_CONTROLLER_SETTINGS, s->screen); gui_msg_unsubscribe(MSG_API_CONTROLLER_SETTINGS, s->screen); free(s); }
widget_t* listbox_create(widget_t* parent, rect_t rect, int item_height) { listbox_t* l = calloc(1, sizeof(listbox_t)); widget_t* lb = widget_create(parent, NULL, l, rect); l->pos = 0; l->item_height = item_height; rect_t container_rect = { .x = 0, .y = 0, .width = rect.width - 52, .height = rect.height }; l->item_container = widget_create(lb, &listbox_widget_class, l, container_rect); int button_pad = (rect.height - (2 * 52)) / 3; rect_t button_rect = { .x = rect.width - 52, .y = button_pad, .width = 52, .height = 52 }; l->up_button = button_create(lb, button_rect, img_up, WHITE, BLACK, up_button_event); button_set_up_bg_color(l->up_button, BLACK); button_set_up_icon_color(l->up_button, WHITE); button_set_down_bg_color(l->up_button, BLACK); button_set_down_icon_color(l->up_button, LIGHT_GRAY); button_set_disabled_bg_color(l->up_button, BLACK); button_set_disabled_icon_color(l->up_button, DARK_GRAY); button_rect.y += 52 + button_pad; l->dn_button = button_create(lb, button_rect, img_down, WHITE, BLACK, down_button_event); button_set_up_bg_color(l->dn_button, BLACK); button_set_up_icon_color(l->dn_button, WHITE); button_set_down_bg_color(l->dn_button, BLACK); button_set_down_icon_color(l->dn_button, LIGHT_GRAY); button_set_disabled_bg_color(l->dn_button, BLACK); button_set_disabled_icon_color(l->dn_button, DARK_GRAY); return lb; } void listbox_clear(widget_t* lb) { listbox_t* l = widget_get_instance_data(lb); while (1) { widget_t* w = widget_get_child(l->item_container, 0); if (w == NULL) break; widget_unparent(w); widget_destroy(w); } widget_invalidate(lb); } static void listbox_destroy(widget_t* w) { listbox_t* l = widget_get_instance_data(w); free(l); }
static void controller_settings_screen_destroy(widget_t* w) { controller_settings_screen_t* s = widget_get_instance_data(w); free(s); }