1 /**
2  * @file lv_demo_high_res_app_thermostat.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "lv_demo_high_res_private.h"
11 #if LV_USE_DEMO_HIGH_RES
12 
13 #include "../../src/widgets/image/lv_image.h"
14 #include "../../src/widgets/label/lv_label.h"
15 #include "../../src/widgets/chart/lv_chart.h"
16 #include "../../src/widgets/slider/lv_slider.h"
17 #include "../../src/widgets/scale/lv_scale.h"
18 #include "../../src/widgets/arc/lv_arc.h"
19 
20 /*********************
21  *      DEFINES
22  *********************/
23 
24 /**********************
25  *      TYPEDEFS
26  **********************/
27 
28 /**********************
29  *  STATIC PROTOTYPES
30  **********************/
31 
32 static void back_clicked_cb(lv_event_t * e);
33 static lv_obj_t * widget1_chart_label(lv_demo_high_res_ctx_t * c, lv_obj_t * parent, const char * text);
34 static void create_widget1(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
35 static void widget2_slider_changed_cb(lv_event_t * e);
36 static void widget2_temperature_button_clicked_cb(lv_event_t * e);
37 static lv_obj_t * create_widget2_value(lv_demo_high_res_ctx_t * c, lv_obj_t * parent, const char * title_val,
38                                        const char * range_val, int32_t temperature_val);
39 static void create_widget2(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
40 static lv_obj_t * create_widget3_setting(lv_demo_high_res_ctx_t * c, lv_obj_t * parent, const lv_image_dsc_t * img_dsc,
41                                          const char * text_val, bool active);
42 static void widget3_setting_clicked_cb(lv_event_t * e);
43 static void widget3_scale_and_arc_box_ext_draw_size_event_cb(lv_event_t * e);
44 static void temperature_arc_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
45 static void temperature_arc_changed_cb(lv_event_t * e);
46 static void create_widget3(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
47 
48 /**********************
49  *  STATIC VARIABLES
50  **********************/
51 
52 /**********************
53  *      MACROS
54  **********************/
55 
56 /**********************
57  *   GLOBAL FUNCTIONS
58  **********************/
59 
lv_demo_high_res_app_thermostat(lv_obj_t * base_obj)60 void lv_demo_high_res_app_thermostat(lv_obj_t * base_obj)
61 {
62     lv_demo_high_res_ctx_t * c = lv_obj_get_user_data(base_obj);
63 
64     /* background */
65 
66     lv_obj_t * bg = base_obj;
67     lv_obj_remove_style_all(bg);
68     lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100));
69 
70     lv_obj_t * bg_img = lv_image_create(bg);
71     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_image_src_cb, bg_img,
72                                 &c->imgs[IMG_LIGHT_BG_THERMOSTAT]);
73 
74     lv_obj_t * bg_cont = lv_obj_create(bg);
75     lv_obj_remove_style_all(bg_cont);
76     lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100));
77     lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0);
78     int32_t app_padding = c->sz == &lv_demo_high_res_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10];
79     lv_obj_set_style_pad_bottom(bg_cont, app_padding, 0);
80     lv_obj_set_style_pad_hor(bg_cont, app_padding, 0);
81 
82     /* top margin */
83 
84     lv_obj_t * top_margin = lv_demo_high_res_top_margin_create(bg_cont, 0, true, c);
85 
86     /* app info */
87 
88     lv_obj_t * app_info = lv_demo_high_res_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START);
89     lv_obj_align_to(app_info, top_margin, LV_ALIGN_OUT_BOTTOM_LEFT, 0, c->sz->gap[7]);
90 
91     lv_obj_t * back = lv_demo_high_res_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER);
92     lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL);
93 
94     lv_obj_t * back_icon = lv_image_create(back);
95     lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]);
96     lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0);
97     lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE);
98 
99     lv_obj_t * back_label = lv_label_create(back);
100     lv_label_set_text_static(back_label, "Back");
101     lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0);
102     lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
103     lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0);
104 
105     lv_obj_t * app_label = lv_label_create(app_info);
106     lv_label_set_text_static(app_label, "Thermostat");
107     lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
108     lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0);
109 
110     /* widgets */
111 
112     int32_t widget_gap_padding = c->sz == &lv_demo_high_res_sizes_all[SIZE_SM] ? c->sz->gap[4] : c->sz->gap[7];
113     lv_obj_t * widgets = lv_demo_high_res_simple_container_create(bg_cont, false, widget_gap_padding, LV_FLEX_ALIGN_END);
114     lv_obj_set_align(widgets, LV_ALIGN_BOTTOM_RIGHT);
115 
116     create_widget1(c, widgets);
117     create_widget2(c, widgets);
118     create_widget3(c, widgets);
119 }
120 
121 /**********************
122  *   STATIC FUNCTIONS
123  **********************/
124 
back_clicked_cb(lv_event_t * e)125 static void back_clicked_cb(lv_event_t * e)
126 {
127     lv_obj_t * back = lv_event_get_target_obj(e);
128 
129     lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back)));
130     lv_obj_clean(base_obj);
131     lv_demo_high_res_home(base_obj);
132 }
133 
widget1_chart_label(lv_demo_high_res_ctx_t * c,lv_obj_t * parent,const char * text)134 static lv_obj_t * widget1_chart_label(lv_demo_high_res_ctx_t * c, lv_obj_t * parent, const char * text)
135 {
136     lv_obj_t * label = lv_label_create(parent);
137     lv_label_set_text_static(label, text);
138     lv_obj_add_style(label, &c->fonts[FONT_LABEL_XS], 0);
139     lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
140     lv_obj_set_style_text_opa(label, LV_OPA_40, 0);
141     return label;
142 }
143 
create_widget1(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)144 static void create_widget1(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
145 {
146     lv_obj_t * widget = lv_obj_create(widgets);
147     lv_obj_remove_style_all(widget);
148     lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge);
149     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_obj_bg_image_src_cb, widget,
150                                 &c->imgs[IMG_LIGHT_WIDGET1_BG]);
151     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
152     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
153     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
154     lv_obj_set_style_pad_row(widget, 18, 0);
155     lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE);
156 
157     lv_obj_t * title_label = lv_label_create(widget);
158     lv_label_set_text_static(title_label, "Last 7 days");
159     lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0);
160     lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
161 
162     lv_obj_t * chart_grid = lv_obj_create(widget);
163     lv_obj_remove_style_all(chart_grid);
164     lv_obj_set_size(chart_grid, LV_PCT(100), LV_SIZE_CONTENT);
165     static const int32_t column_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
166     static const int32_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
167     lv_obj_set_style_grid_column_dsc_array(chart_grid, column_dsc, 0);
168     lv_obj_set_style_grid_row_dsc_array(chart_grid, row_dsc, 0);
169     lv_obj_set_layout(chart_grid, LV_LAYOUT_GRID);
170     lv_obj_set_style_pad_column(chart_grid, c->sz->gap[3], 0);
171     lv_obj_set_style_pad_row(chart_grid, 5, 0);
172 
173     lv_obj_t * chart = lv_chart_create(chart_grid);
174     lv_obj_set_height(chart, c->sz->small_chart_height);
175     lv_obj_set_style_bg_opa(chart, LV_OPA_TRANSP, 0);
176     lv_obj_set_style_pad_column(chart, c->sz->gap[1], 0);
177     lv_obj_set_style_radius(chart, c->sz->gap[3], LV_PART_ITEMS);
178     lv_obj_set_style_border_width(chart, 2, 0);
179     lv_obj_set_style_border_color(chart, lv_color_black(), 0);
180     lv_obj_set_style_border_side(chart, LV_BORDER_SIDE_BOTTOM, 0);
181     lv_obj_set_style_border_post(chart, true, 0);
182     lv_obj_set_style_radius(chart, 0, 0);
183     lv_obj_set_style_pad_all(chart, 0, 0);
184     lv_obj_set_grid_cell(chart, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1);
185     lv_chart_set_type(chart, LV_CHART_TYPE_BAR);
186     lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 109);
187     lv_chart_set_div_line_count(chart, 3, 0);
188     lv_obj_set_style_line_opa(chart, LV_OPA_40, 0);
189     lv_obj_set_style_line_color(chart, lv_color_black(), 0);
190     lv_obj_set_style_line_dash_width(chart, 2, 0);
191     lv_obj_set_style_line_dash_gap(chart, 1, 0);
192     lv_chart_series_t * ser = lv_chart_add_series(chart, lv_color_white(), LV_CHART_AXIS_PRIMARY_Y);
193     static const int32_t chart_values[] = {14, 95, 52, 34, 52, 83, 19};
194     lv_chart_set_ext_y_array(chart, ser, (int32_t *)chart_values);
195     lv_chart_set_point_count(chart, sizeof(chart_values) / sizeof(*chart_values));
196     lv_chart_refresh(chart);
197 
198     lv_obj_t * hscale_label_1 = widget1_chart_label(c, chart_grid, "Aug 26");
199     lv_obj_set_grid_cell(hscale_label_1, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 1, 1);
200     lv_obj_t * hscale_label_2 = widget1_chart_label(c, chart_grid, "Sep 1");
201     lv_obj_set_grid_cell(hscale_label_2, LV_GRID_ALIGN_END, 0, 1, LV_GRID_ALIGN_START, 1, 1);
202 
203     lv_obj_t * vscale_label_1 = widget1_chart_label(c, chart_grid, "20\nkWh");
204     lv_obj_set_grid_cell(vscale_label_1, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 0, 1);
205     lv_obj_t * vscale_label_2 = widget1_chart_label(c, chart_grid, "10");
206     lv_obj_set_grid_cell(vscale_label_2, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);
207     lv_obj_t * vscale_label_3 = widget1_chart_label(c, chart_grid, "0");
208     lv_obj_set_grid_cell(vscale_label_3, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_END, 0, 1);
209 
210     lv_obj_t * consumed_box = lv_demo_high_res_simple_container_create(widget, true, c->sz->gap[2], LV_FLEX_ALIGN_START);
211 
212     lv_obj_t * consumed_label = lv_label_create(consumed_box);
213     lv_label_set_text_static(consumed_label, "Total energy consumed");
214     lv_obj_add_style(consumed_label, &c->fonts[FONT_LABEL_SM], 0);
215     lv_obj_add_style(consumed_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
216 
217     lv_obj_t * amount_box = lv_demo_high_res_simple_container_create(consumed_box, false, c->sz->gap[1], LV_FLEX_ALIGN_END);
218 
219     lv_obj_t * amount_number = lv_label_create(amount_box);
220     lv_label_set_text_static(amount_number, "102");
221     lv_obj_add_style(amount_number, &c->fonts[FONT_LABEL_XL], 0);
222     lv_obj_add_style(amount_number, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
223 
224     lv_obj_t * amount_kwh = lv_label_create(amount_box);
225     lv_label_set_text_static(amount_kwh, "kWh");
226     lv_obj_add_style(amount_kwh, &c->fonts[FONT_LABEL_SM], 0);
227     lv_obj_add_style(amount_kwh, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
228     lv_obj_set_style_text_opa(amount_kwh, LV_OPA_40, 0);
229 }
230 
widget2_slider_changed_cb(lv_event_t * e)231 static void widget2_slider_changed_cb(lv_event_t * e)
232 {
233     lv_obj_t * slider = lv_event_get_current_target_obj(e);
234     lv_obj_t * slider_box = lv_obj_get_parent(slider);
235     lv_obj_t * label = lv_event_get_user_data(e);
236     int32_t val = lv_slider_get_value(slider);
237 
238     if(slider == lv_obj_get_child(slider_box, 0)) {
239         lv_label_set_text_fmt(label, "9pm - %"PRId32"am", val != 0 ? val : 12);
240     }
241     else {
242         val = 6 - val + 6;
243         lv_label_set_text_fmt(label, "%"PRId32"%s - 9pm", val, val < 12 ? "am" : "pm");
244     }
245 }
246 
widget2_temperature_button_clicked_cb(lv_event_t * e)247 static void widget2_temperature_button_clicked_cb(lv_event_t * e)
248 {
249     lv_obj_t * button = lv_event_get_current_target_obj(e);
250     lv_obj_t * box = lv_obj_get_parent(button);
251     lv_obj_t * label = lv_obj_get_child(box, 1);
252     int32_t label_val = (int32_t)(intptr_t)lv_obj_get_user_data(label);
253     int32_t change = button == lv_obj_get_child(box, 0) ? -1 : 1;
254     label_val += change;
255     lv_label_set_text_fmt(label, "%"LV_PRId32, label_val);
256     lv_obj_set_user_data(label, (void *)(intptr_t)label_val);
257 }
258 
create_widget2_value(lv_demo_high_res_ctx_t * c,lv_obj_t * parent,const char * title_val,const char * range_val,int32_t temperature_val)259 static lv_obj_t * create_widget2_value(lv_demo_high_res_ctx_t * c, lv_obj_t * parent, const char * title_val,
260                                        const char * range_val, int32_t temperature_val)
261 {
262     lv_obj_t * box = lv_demo_high_res_simple_container_create(parent, true, c->sz->gap[2], LV_FLEX_ALIGN_START);
263     lv_obj_set_flex_grow(box, 1);
264 
265     lv_obj_t * title_label = lv_label_create(box);
266     lv_label_set_text_static(title_label, title_val);
267     lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_SM], 0);
268     lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
269 
270     lv_obj_t * range_label = lv_label_create(box);
271     lv_label_set_text_static(range_label, range_val);
272     lv_obj_add_style(range_label, &c->fonts[FONT_LABEL_SM], 0);
273     lv_obj_add_style(range_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
274     lv_obj_set_style_text_opa(range_label, LV_OPA_40, 0);
275 
276     lv_obj_t * temperature_box = lv_demo_high_res_simple_container_create(box, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER);
277     lv_obj_set_width(temperature_box, LV_PCT(100));
278 
279     lv_obj_t * minus = lv_image_create(temperature_box);
280     lv_image_set_inner_align(minus, LV_IMAGE_ALIGN_CENTER);
281     lv_obj_set_size(minus, c->sz->icon[ICON_MD], c->sz->icon[ICON_MD]);
282     lv_obj_set_style_bg_color(minus, lv_color_white(), 0);
283     lv_obj_set_style_bg_opa(minus, LV_OPA_COVER, 0);
284     lv_obj_set_style_radius(minus, LV_COORD_MAX, 0);
285     lv_obj_add_flag(minus, LV_OBJ_FLAG_CLICKABLE);
286     lv_obj_add_event_cb(minus, widget2_temperature_button_clicked_cb, LV_EVENT_CLICKED, NULL);
287     lv_image_set_src(minus, c->imgs[IMG_MINUS]);
288 
289     lv_obj_t * temperature_label = lv_label_create(temperature_box);
290     lv_obj_set_flex_grow(temperature_label, 1);
291     lv_obj_set_style_text_align(temperature_label, LV_TEXT_ALIGN_CENTER, 0);
292     lv_label_set_text_fmt(temperature_label, "%"LV_PRId32, temperature_val);
293     lv_obj_set_user_data(temperature_label, (void *)(intptr_t)temperature_val);
294     lv_obj_add_style(temperature_label, &c->fonts[FONT_LABEL_XL], 0);
295     lv_obj_add_style(temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
296 
297     lv_obj_t * plus = lv_image_create(temperature_box);
298     lv_image_set_inner_align(plus, LV_IMAGE_ALIGN_CENTER);
299     lv_obj_set_size(plus, c->sz->icon[ICON_MD], c->sz->icon[ICON_MD]);
300     lv_obj_set_style_bg_color(plus, lv_color_white(), 0);
301     lv_obj_set_style_bg_opa(plus, LV_OPA_COVER, 0);
302     lv_obj_set_style_radius(plus, LV_COORD_MAX, 0);
303     lv_obj_add_flag(plus, LV_OBJ_FLAG_CLICKABLE);
304     lv_obj_add_event_cb(plus, widget2_temperature_button_clicked_cb, LV_EVENT_CLICKED, NULL);
305     lv_image_set_src(plus, c->imgs[IMG_PLUS]);
306 
307     return box;
308 }
309 
create_widget2(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)310 static void create_widget2(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
311 {
312     lv_obj_t * widget = lv_obj_create(widgets);
313     lv_obj_remove_style_all(widget);
314     lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge);
315     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_obj_bg_image_src_cb, widget,
316                                 &c->imgs[IMG_LIGHT_WIDGET1_BG]);
317     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
318     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
319     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
320     lv_obj_set_style_pad_row(widget, 0, 0);
321 
322     lv_obj_t * title_label = lv_label_create(widget);
323     lv_label_set_text_static(title_label, "Scheduler");
324     lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0);
325     lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
326 
327     lv_obj_t * outer_slider_box = lv_demo_high_res_simple_container_create(widget, true, c->sz->gap[4],
328                                                                            LV_FLEX_ALIGN_START);
329     lv_obj_set_width(outer_slider_box, LV_PCT(100));
330     lv_obj_set_style_pad_top(outer_slider_box, c->sz->gap[5], 0);
331 
332     lv_obj_t * slider_box = lv_demo_high_res_simple_container_create(outer_slider_box, false, 0, LV_FLEX_ALIGN_CENTER);
333     lv_obj_set_width(slider_box, LV_PCT(100));
334     lv_obj_set_style_radius(slider_box, c->sz->gap[4], 0);
335     lv_obj_set_style_bg_color(slider_box, lv_color_white(), 0);
336     lv_obj_set_style_bg_opa(slider_box, LV_OPA_20, 0);
337 
338     lv_obj_t * slider_left = lv_slider_create(slider_box);
339     lv_slider_set_range(slider_left, 0, 6);
340     lv_slider_set_value(slider_left, 4, LV_ANIM_OFF);
341     lv_obj_set_size(slider_left, LV_PCT(50), c->sz->slider_width);
342     lv_obj_set_style_bg_opa(slider_left, LV_OPA_TRANSP, 0);
343     lv_obj_set_style_bg_color(slider_left, lv_color_white(), LV_PART_INDICATOR);
344     lv_obj_set_style_radius(slider_left, c->sz->gap[4], 0);
345     lv_obj_set_style_radius(slider_left, c->sz->gap[4], LV_PART_INDICATOR);
346     lv_obj_set_style_bg_color(slider_left, lv_color_black(), LV_PART_KNOB);
347     lv_obj_set_style_pad_right(slider_left, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB);
348     lv_obj_set_style_pad_left(slider_left, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB);
349     lv_obj_set_style_pad_ver(slider_left, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB);
350 
351     lv_obj_t * slider_right = lv_slider_create(slider_box);
352     lv_slider_set_range(slider_right, 6, 0);
353     lv_slider_set_value(slider_right, 5, LV_ANIM_OFF);
354     lv_obj_set_size(slider_right, LV_PCT(50), c->sz->slider_width);
355     lv_obj_set_style_bg_opa(slider_right, LV_OPA_TRANSP, 0);
356     lv_obj_set_style_bg_color(slider_right, lv_color_white(), LV_PART_INDICATOR);
357     lv_obj_set_style_radius(slider_right, c->sz->gap[4], 0);
358     lv_obj_set_style_radius(slider_right, c->sz->gap[4], LV_PART_INDICATOR);
359     lv_obj_set_style_bg_color(slider_right, lv_color_black(), LV_PART_KNOB);
360     lv_obj_set_style_pad_right(slider_right, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB);
361     lv_obj_set_style_pad_left(slider_right, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB);
362     lv_obj_set_style_pad_ver(slider_right, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB);
363 
364     lv_obj_t * slider_label_box = lv_obj_create(outer_slider_box);
365     lv_obj_remove_style_all(slider_label_box);
366     lv_obj_set_size(slider_label_box, LV_PCT(100), LV_SIZE_CONTENT);
367     lv_obj_set_flex_flow(slider_label_box, LV_FLEX_FLOW_ROW);
368     lv_obj_set_flex_align(slider_label_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
369 
370     lv_obj_t * slider_label_left = lv_label_create(slider_label_box);
371     lv_label_set_text_static(slider_label_left, "12am");
372     lv_obj_add_style(slider_label_left, &c->fonts[FONT_LABEL_XS], 0);
373     lv_obj_add_style(slider_label_left, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
374     lv_obj_set_style_text_opa(slider_label_left, LV_OPA_40, 0);
375 
376     lv_obj_t * slider_label_right = lv_label_create(slider_label_box);
377     lv_label_set_text_static(slider_label_right, "12pm");
378     lv_obj_add_style(slider_label_right, &c->fonts[FONT_LABEL_XS], 0);
379     lv_obj_add_style(slider_label_right, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
380     lv_obj_set_style_text_opa(slider_label_right, LV_OPA_40, 0);
381 
382     lv_obj_t * values_box = lv_obj_create(outer_slider_box);
383     lv_obj_remove_style_all(values_box);
384     lv_obj_set_size(values_box, LV_PCT(100), LV_SIZE_CONTENT);
385     lv_obj_set_flex_flow(values_box, LV_FLEX_FLOW_ROW);
386     lv_obj_set_flex_align(values_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
387     lv_obj_set_style_pad_top(values_box, c->sz->gap[7], 0);
388     lv_obj_set_style_pad_column(values_box, c->sz->gap[5], 0);
389 
390     lv_obj_t * value1 = create_widget2_value(c, values_box, "Sleep", "9pm - 4am", 21);
391     lv_obj_add_event_cb(slider_left, widget2_slider_changed_cb, LV_EVENT_VALUE_CHANGED, lv_obj_get_child(value1, 1));
392     lv_obj_t * value2 = create_widget2_value(c, values_box, "Home", "7am - 9pm", 23);
393     lv_obj_add_event_cb(slider_right, widget2_slider_changed_cb, LV_EVENT_VALUE_CHANGED, lv_obj_get_child(value2, 1));
394 }
395 
create_widget3_setting(lv_demo_high_res_ctx_t * c,lv_obj_t * parent,const lv_image_dsc_t * img_dsc,const char * text_val,bool active)396 static lv_obj_t * create_widget3_setting(lv_demo_high_res_ctx_t * c, lv_obj_t * parent, const lv_image_dsc_t * img_dsc,
397                                          const char * text_val, bool active)
398 {
399     lv_obj_t * setting = lv_obj_create(parent);
400     lv_obj_remove_style_all(setting);
401     lv_obj_set_height(setting, LV_SIZE_CONTENT);
402     lv_obj_set_flex_flow(setting, LV_FLEX_FLOW_COLUMN);
403     lv_obj_set_flex_align(setting, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
404     lv_obj_set_style_pad_row(setting, c->sz->gap[5], 0);
405     lv_obj_set_flex_grow(setting, 1);
406     lv_obj_set_style_bg_color(setting, lv_color_white(), 0);
407     lv_obj_set_style_bg_opa(setting, active ? LV_OPA_60 : LV_OPA_20, 0);
408     lv_obj_set_style_radius(setting, c->sz->gap[3], 0);
409     lv_obj_set_style_pad_all(setting, c->sz->gap[5], 0);
410     lv_obj_add_flag(setting, LV_OBJ_FLAG_CLICKABLE);
411 
412     lv_obj_t * icon = lv_image_create(setting);
413     lv_image_set_src(icon, img_dsc);
414     lv_image_set_inner_align(icon, LV_IMAGE_ALIGN_CENTER);
415     lv_obj_set_size(icon, c->sz->icon[ICON_XL], c->sz->icon[ICON_XL]);
416     lv_obj_set_style_bg_color(icon, lv_color_white(), 0);
417     lv_obj_set_style_bg_opa(icon, active ? LV_OPA_COVER : LV_OPA_40, 0);
418     lv_obj_set_style_radius(icon, LV_COORD_MAX, 0);
419     lv_obj_set_style_shadow_width(icon, 50, 0);
420     lv_obj_set_style_shadow_opa(icon, 15 * 255 / 100, 0);
421     lv_obj_add_flag(icon, LV_OBJ_FLAG_EVENT_BUBBLE);
422 
423     lv_obj_t * label = lv_label_create(setting);
424     lv_label_set_text_static(label, text_val);
425     lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0);
426     lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
427 
428     return setting;
429 }
430 
widget3_setting_clicked_cb(lv_event_t * e)431 static void widget3_setting_clicked_cb(lv_event_t * e)
432 {
433     lv_obj_t * setting = lv_event_get_target_obj(e);
434     lv_obj_t * setting_box = lv_obj_get_parent(setting);
435     lv_obj_t * setting1 = lv_obj_get_child(setting_box, 0);
436     lv_obj_t * setting2 = lv_obj_get_child(setting_box, 1);
437     lv_obj_t * setting3 = lv_obj_get_child(setting_box, 2);
438     if(setting == setting1) {
439         lv_obj_set_style_bg_opa(setting1, LV_OPA_60, 0);
440         lv_obj_set_style_bg_opa(lv_obj_get_child(setting1, 0), LV_OPA_COVER, 0);
441         lv_obj_set_style_bg_opa(setting2, LV_OPA_20, 0);
442         lv_obj_set_style_bg_opa(lv_obj_get_child(setting2, 0), LV_OPA_40, 0);
443         lv_obj_set_style_bg_opa(setting3, LV_OPA_20, 0);
444         lv_obj_set_style_bg_opa(lv_obj_get_child(setting3, 0), LV_OPA_40, 0);
445     }
446     else if(setting == setting2) {
447         lv_obj_set_style_bg_opa(setting1, LV_OPA_20, 0);
448         lv_obj_set_style_bg_opa(lv_obj_get_child(setting1, 0), LV_OPA_40, 0);
449         lv_obj_set_style_bg_opa(setting2, LV_OPA_60, 0);
450         lv_obj_set_style_bg_opa(lv_obj_get_child(setting2, 0), LV_OPA_COVER, 0);
451         lv_obj_set_style_bg_opa(setting3, LV_OPA_20, 0);
452         lv_obj_set_style_bg_opa(lv_obj_get_child(setting3, 0), LV_OPA_40, 0);
453     }
454     else {
455         lv_obj_set_style_bg_opa(setting1, LV_OPA_20, 0);
456         lv_obj_set_style_bg_opa(lv_obj_get_child(setting1, 0), LV_OPA_40, 0);
457         lv_obj_set_style_bg_opa(setting2, LV_OPA_20, 0);
458         lv_obj_set_style_bg_opa(lv_obj_get_child(setting2, 0), LV_OPA_40, 0);
459         lv_obj_set_style_bg_opa(setting3, LV_OPA_60, 0);
460         lv_obj_set_style_bg_opa(lv_obj_get_child(setting3, 0), LV_OPA_COVER, 0);
461     }
462 }
463 
widget3_scale_and_arc_box_ext_draw_size_event_cb(lv_event_t * e)464 static void widget3_scale_and_arc_box_ext_draw_size_event_cb(lv_event_t * e)
465 {
466     lv_event_set_ext_draw_size(e, 100);
467 }
468 
temperature_arc_observer_cb(lv_observer_t * observer,lv_subject_t * subject)469 static void temperature_arc_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
470 {
471     lv_obj_t * arc = lv_observer_get_target_obj(observer);
472     lv_arc_set_value(arc, (lv_subject_get_int(subject) + 5) / 10);
473 }
474 
temperature_arc_changed_cb(lv_event_t * e)475 static void temperature_arc_changed_cb(lv_event_t * e)
476 {
477     lv_obj_t * arc = lv_event_get_target_obj(e);
478     lv_subject_t * temperature_subject = lv_event_get_user_data(e);
479 
480     int32_t arc_val = lv_arc_get_value(arc);
481     lv_subject_set_int(temperature_subject, arc_val * 10);
482 }
483 
create_widget3(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)484 static void create_widget3(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
485 {
486     lv_obj_t * widget = lv_obj_create(widgets);
487     lv_obj_remove_style_all(widget);
488     lv_obj_set_size(widget, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.w, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.h);
489     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_obj_bg_image_src_cb, widget,
490                                 &c->imgs[IMG_LIGHT_WIDGET5_BG]);
491     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
492     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
493     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
494     lv_obj_set_style_pad_row(widget, c->sz->gap[5], 0);
495     lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE);
496 
497     lv_obj_t * title_label = lv_label_create(widget);
498     lv_obj_set_width(title_label, LV_PCT(100));
499     lv_label_set_text_static(title_label, "Temperature");
500     lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0);
501     lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
502 
503     lv_obj_t * scale_and_arc_box = lv_obj_create(widget);
504     lv_obj_remove_style_all(scale_and_arc_box);
505     lv_obj_set_size(scale_and_arc_box, LV_PCT(100), 57 * c->sz->card_long_edge / 100);
506     lv_obj_add_flag(scale_and_arc_box, LV_OBJ_FLAG_OVERFLOW_VISIBLE);
507     lv_obj_add_event_cb(scale_and_arc_box, widget3_scale_and_arc_box_ext_draw_size_event_cb, LV_EVENT_REFR_EXT_DRAW_SIZE,
508                         c);
509     lv_obj_remove_flag(scale_and_arc_box, LV_OBJ_FLAG_SCROLLABLE);
510 
511     lv_obj_t * scale = lv_scale_create(scale_and_arc_box);
512     lv_obj_set_align(scale, LV_ALIGN_TOP_MID);
513     lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_OUTER);
514     lv_obj_set_size(scale, c->sz->card_long_edge, c->sz->card_long_edge);
515     lv_obj_set_style_arc_opa(scale, LV_OPA_TRANSP, 0);
516     lv_obj_set_style_radial_offset(scale, 12, LV_PART_ITEMS);
517     lv_obj_set_style_line_rounded(scale, true, LV_PART_ITEMS);
518     lv_obj_set_style_line_color(scale, lv_color_white(), LV_PART_ITEMS);
519     lv_obj_set_style_line_width(scale, 4, LV_PART_ITEMS);
520     lv_obj_set_style_length(scale, 1, LV_PART_ITEMS);
521     lv_obj_set_style_radial_offset(scale, 12, LV_PART_INDICATOR);
522     lv_obj_set_style_line_rounded(scale, true, LV_PART_INDICATOR);
523     lv_obj_set_style_line_color(scale, lv_color_white(), LV_PART_INDICATOR);
524     lv_obj_set_style_line_width(scale, 8, LV_PART_INDICATOR);
525     lv_obj_set_style_length(scale, 1, LV_PART_INDICATOR);
526     lv_scale_set_total_tick_count(scale, 16);
527     lv_scale_set_angle_range(scale, 180);
528     lv_scale_set_rotation(scale, 180);
529     lv_scale_set_major_tick_every(scale, 5);
530     lv_scale_set_label_show(scale, false);
531 
532     lv_obj_t * arc = lv_arc_create(scale_and_arc_box);
533     lv_obj_set_align(arc, LV_ALIGN_TOP_MID);
534     lv_obj_set_size(arc, c->sz->card_long_edge, c->sz->card_long_edge);
535     lv_arc_set_rotation(arc, 180);
536     lv_arc_set_bg_angles(arc, 0, 180);
537     lv_arc_set_range(arc, 15, 30);
538 
539     lv_obj_set_style_arc_rounded(arc, false, 0);
540     lv_obj_set_style_arc_rounded(arc, false, LV_PART_INDICATOR);
541     lv_obj_set_style_arc_width(arc, 9, 0);
542     lv_obj_set_style_arc_width(arc, 9, LV_PART_INDICATOR);
543     lv_obj_set_style_arc_color(arc, lv_color_white(), 0);
544     lv_obj_set_style_arc_color(arc, lv_color_white(), LV_PART_INDICATOR);
545     lv_obj_set_style_arc_opa(arc, LV_OPA_20, 0);
546 
547     lv_obj_set_style_bg_color(arc, lv_color_white(), LV_PART_KNOB);
548     lv_obj_set_style_pad_all(arc, (32 - 9) / 2, LV_PART_KNOB);
549     lv_obj_set_style_shadow_width(arc, 24, LV_PART_KNOB);
550     lv_obj_set_style_shadow_opa(arc, 16 * 255 / 100, LV_PART_KNOB);
551 
552     lv_obj_t * current_temperature_box = lv_demo_high_res_simple_container_create(scale_and_arc_box, true, c->sz->gap[2],
553                                                                                   LV_FLEX_ALIGN_CENTER);
554     lv_obj_set_align(current_temperature_box, LV_ALIGN_BOTTOM_MID);
555 
556     lv_obj_t * current_temperature_val_label = lv_label_create(current_temperature_box);
557     lv_obj_add_style(current_temperature_val_label, &c->fonts[FONT_LABEL_2XL], 0);
558     lv_obj_add_style(current_temperature_val_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
559 
560     lv_subject_add_observer_obj(&c->api.subjects.thermostat_target_temperature, temperature_arc_observer_cb, arc, NULL);
561     lv_obj_add_event_cb(arc, temperature_arc_changed_cb, LV_EVENT_VALUE_CHANGED,
562                         &c->api.subjects.thermostat_target_temperature);
563     lv_demo_high_res_label_bind_temperature(current_temperature_val_label, &c->api.subjects.thermostat_target_temperature,
564                                             c);
565 
566     lv_obj_t * current_temperature_label = lv_label_create(current_temperature_box);
567     lv_label_set_text_static(current_temperature_label, "Current\ntemperature");
568     lv_obj_add_style(current_temperature_label, &c->fonts[FONT_LABEL_SM], 0);
569     lv_obj_add_style(current_temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
570     lv_obj_set_style_text_align(current_temperature_label, LV_TEXT_ALIGN_CENTER, 0);
571 
572     lv_obj_t * setting_box = lv_demo_high_res_simple_container_create(widget, false, c->sz->gap[5], LV_FLEX_ALIGN_CENTER);
573     lv_obj_set_width(setting_box, LV_PCT(100));
574     lv_obj_t * setting1 = create_widget3_setting(c, setting_box, c->imgs[IMG_COLD_ICON], "Cold", true);
575     lv_obj_t * setting2 = create_widget3_setting(c, setting_box, c->imgs[IMG_DRY_ICON], "Dry", false);
576     lv_obj_t * setting3 = create_widget3_setting(c, setting_box, c->imgs[IMG_HEAT_ICON], "Heat", false);
577 
578     lv_obj_add_event_cb(setting1, widget3_setting_clicked_cb, LV_EVENT_CLICKED, NULL);
579     lv_obj_add_event_cb(setting2, widget3_setting_clicked_cb, LV_EVENT_CLICKED, NULL);
580     lv_obj_add_event_cb(setting3, widget3_setting_clicked_cb, LV_EVENT_CLICKED, NULL);
581 
582     lv_obj_t * slider_box = lv_demo_high_res_simple_container_create(widget, true, c->sz->gap[4], LV_FLEX_ALIGN_START);
583     lv_obj_set_width(slider_box, LV_PCT(100));
584     lv_obj_set_style_pad_top(slider_box, 16, 0);
585 
586     lv_obj_t * fan_speed_label = lv_label_create(slider_box);
587     lv_label_set_text_static(fan_speed_label, "Fan Speed");
588     lv_obj_add_style(fan_speed_label, &c->fonts[FONT_LABEL_SM], 0);
589     lv_obj_add_style(fan_speed_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
590 
591     lv_obj_t * slider = lv_slider_create(slider_box);
592     lv_obj_set_size(slider, LV_PCT(100), c->sz->slider_width);
593     lv_obj_set_style_bg_color(slider, lv_color_white(), 0);
594     lv_obj_set_style_bg_opa(slider, 30, 0);
595     lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR);
596     lv_obj_set_style_radius(slider, c->sz->gap[4], 0);
597     lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR);
598     lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB);
599     lv_obj_set_style_pad_right(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB);
600     lv_obj_set_style_pad_left(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB);
601     lv_obj_set_style_pad_ver(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB);
602 
603     lv_obj_t * slider_pct_label = lv_label_create(slider);
604     lv_obj_add_style(slider_pct_label, &c->fonts[FONT_LABEL_XS], 0);
605     lv_obj_add_style(slider_pct_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
606     lv_obj_align(slider_pct_label, LV_ALIGN_RIGHT_MID, -10, 0);
607 
608     lv_slider_bind_value(slider, &c->api.subjects.thermostat_fan_speed);
609     lv_label_bind_text(slider_pct_label, &c->api.subjects.thermostat_fan_speed, "%"PRId32"%%");
610 
611     lv_label_set_text_static(slider_pct_label, "40%");
612     lv_slider_set_value(slider, 40, LV_ANIM_OFF);
613 
614     lv_obj_t * slider_volume_img = lv_image_create(slider);
615     lv_image_set_src(slider_volume_img, c->imgs[IMG_FAN]);
616     lv_obj_align(slider_volume_img, LV_ALIGN_LEFT_MID, 8, 0);
617 }
618 
619 #endif /*LV_USE_DEMO_HIGH_RES*/
620