Skip to content

Commit afd3c1e

Browse files
authored
Merge pull request #73 from baba-dev/codex/update-ui_page_cctv-with-new-ui-components
feat: rebuild cctv page layout
2 parents d2e8ca3 + e40453d commit afd3c1e

1 file changed

Lines changed: 226 additions & 30 deletions

File tree

custom/ui/pages/ui_page_cctv.c

Lines changed: 226 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,66 +5,262 @@
55
*/
66
#include "ui_page_cctv.h"
77

8+
#include "../ui_theme.h"
89
#include "../ui_wallpaper.h"
10+
#include "../widgets/ui_room_card.h"
911

10-
static void ui_page_cctv_delete_cb(lv_event_t *event)
12+
static void ui_page_cctv_delete_cb(lv_event_t* event)
1113
{
12-
ui_wallpaper_t *wallpaper = (ui_wallpaper_t *)lv_event_get_user_data(event);
14+
ui_wallpaper_t* wallpaper = (ui_wallpaper_t*)lv_event_get_user_data(event);
1315
ui_wallpaper_detach(wallpaper);
1416
}
1517

16-
static lv_obj_t *ui_page_create_content(lv_obj_t *page, const char *title_text)
18+
static lv_obj_t* ui_page_create_content(lv_obj_t* page, const char* title_text)
1719
{
18-
lv_obj_t *content = lv_obj_create(page);
20+
lv_obj_t* content = lv_obj_create(page);
1921
lv_obj_remove_style_all(content);
2022
lv_obj_set_size(content, LV_PCT(100), LV_PCT(100));
2123
lv_obj_set_style_bg_opa(content, LV_OPA_TRANSP, LV_PART_MAIN);
2224
lv_obj_set_style_pad_left(content, 192, LV_PART_MAIN);
2325
lv_obj_set_style_pad_right(content, 48, LV_PART_MAIN);
24-
lv_obj_set_style_pad_top(content, 40, LV_PART_MAIN);
25-
lv_obj_set_style_pad_bottom(content, 40, LV_PART_MAIN);
26-
lv_obj_set_style_pad_row(content, 32, LV_PART_MAIN);
26+
lv_obj_set_style_pad_top(content, 48, LV_PART_MAIN);
27+
lv_obj_set_style_pad_bottom(content, 48, LV_PART_MAIN);
28+
lv_obj_set_style_pad_gap(content, 32, LV_PART_MAIN);
2729
lv_obj_set_flex_flow(content, LV_FLEX_FLOW_COLUMN);
2830
lv_obj_set_flex_align(content, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
2931

30-
lv_obj_t *title = lv_obj_create(content);
31-
lv_obj_remove_style_all(title);
32-
lv_obj_set_width(title, LV_PCT(100));
33-
lv_obj_set_style_bg_color(title, lv_color_hex(0x141e28), LV_PART_MAIN);
34-
lv_obj_set_style_bg_opa(title, LV_OPA_80, LV_PART_MAIN);
35-
lv_obj_set_style_radius(title, 16, LV_PART_MAIN);
36-
lv_obj_set_style_shadow_width(title, 24, LV_PART_MAIN);
37-
lv_obj_set_style_shadow_opa(title, LV_OPA_50, LV_PART_MAIN);
38-
lv_obj_set_style_shadow_ofs_y(title, 10, LV_PART_MAIN);
39-
lv_obj_set_style_border_width(title, 0, LV_PART_MAIN);
40-
lv_obj_set_style_pad_all(title, 28, LV_PART_MAIN);
41-
42-
lv_obj_t *label = lv_label_create(title);
43-
lv_label_set_text(label, title_text);
44-
lv_obj_set_width(label, LV_PCT(100));
45-
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN);
46-
lv_obj_set_style_text_font(label, &lv_font_montserrat_32, LV_PART_MAIN);
47-
lv_obj_set_style_text_color(label, lv_color_hex(0xf1f5f9), LV_PART_MAIN);
32+
lv_obj_t* title = lv_label_create(content);
33+
lv_label_set_text(title, title_text);
34+
lv_obj_set_style_text_font(title, &lv_font_montserrat_32, LV_PART_MAIN);
35+
lv_obj_set_style_text_color(title, ui_theme_color_on_surface(), LV_PART_MAIN);
36+
37+
lv_obj_t* toolbar = lv_obj_create(content);
38+
lv_obj_remove_style_all(toolbar);
39+
lv_obj_set_width(toolbar, LV_PCT(100));
40+
lv_obj_set_style_bg_color(toolbar, ui_theme_color_surface(), LV_PART_MAIN);
41+
lv_obj_set_style_bg_opa(toolbar, LV_OPA_70, LV_PART_MAIN);
42+
lv_obj_set_style_border_width(toolbar, 0, LV_PART_MAIN);
43+
lv_obj_set_style_radius(toolbar, 24, LV_PART_MAIN);
44+
lv_obj_set_style_pad_all(toolbar, 24, LV_PART_MAIN);
45+
lv_obj_set_style_pad_gap(toolbar, 20, LV_PART_MAIN);
46+
lv_obj_set_style_shadow_width(toolbar, 12, LV_PART_MAIN);
47+
lv_obj_set_style_shadow_ofs_y(toolbar, 10, LV_PART_MAIN);
48+
lv_obj_set_style_shadow_opa(toolbar, LV_OPA_30, LV_PART_MAIN);
49+
lv_obj_set_style_shadow_color(toolbar, ui_theme_color_outline(), LV_PART_MAIN);
50+
lv_obj_set_flex_flow(toolbar, LV_FLEX_FLOW_ROW);
51+
lv_obj_set_flex_align(toolbar, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
52+
53+
lv_obj_t* prev_btn = lv_btn_create(toolbar);
54+
lv_obj_remove_style_all(prev_btn);
55+
lv_obj_set_style_bg_color(prev_btn, ui_theme_color_outline(), LV_PART_MAIN);
56+
lv_obj_set_style_bg_opa(prev_btn, LV_OPA_40, LV_PART_MAIN);
57+
lv_obj_set_style_radius(prev_btn, 20, LV_PART_MAIN);
58+
lv_obj_set_style_pad_hor(prev_btn, 20, LV_PART_MAIN);
59+
lv_obj_set_style_pad_ver(prev_btn, 12, LV_PART_MAIN);
60+
lv_obj_set_style_text_color(prev_btn, ui_theme_color_on_surface(), LV_PART_MAIN);
61+
62+
lv_obj_t* prev_label = lv_label_create(prev_btn);
63+
lv_label_set_text(prev_label, LV_SYMBOL_LEFT " Prev");
64+
lv_obj_set_style_text_font(prev_label, &lv_font_montserrat_18, LV_PART_MAIN);
65+
66+
lv_obj_t* camera_label = lv_label_create(toolbar);
67+
lv_label_set_text(camera_label, "Camera 2 of 6");
68+
lv_obj_set_style_text_font(camera_label, &lv_font_montserrat_20, LV_PART_MAIN);
69+
lv_obj_set_style_text_color(camera_label, ui_theme_color_on_surface(), LV_PART_MAIN);
70+
71+
lv_obj_t* next_btn = lv_btn_create(toolbar);
72+
lv_obj_remove_style_all(next_btn);
73+
lv_obj_set_style_bg_color(next_btn, ui_theme_color_outline(), LV_PART_MAIN);
74+
lv_obj_set_style_bg_opa(next_btn, LV_OPA_40, LV_PART_MAIN);
75+
lv_obj_set_style_radius(next_btn, 20, LV_PART_MAIN);
76+
lv_obj_set_style_pad_hor(next_btn, 20, LV_PART_MAIN);
77+
lv_obj_set_style_pad_ver(next_btn, 12, LV_PART_MAIN);
78+
lv_obj_set_style_text_color(next_btn, ui_theme_color_on_surface(), LV_PART_MAIN);
79+
80+
lv_obj_t* next_label = lv_label_create(next_btn);
81+
lv_label_set_text(next_label, "Next " LV_SYMBOL_RIGHT);
82+
lv_obj_set_style_text_font(next_label, &lv_font_montserrat_18, LV_PART_MAIN);
83+
84+
lv_obj_t* quality_btn = lv_btn_create(toolbar);
85+
lv_obj_remove_style_all(quality_btn);
86+
lv_obj_set_style_bg_color(quality_btn, ui_theme_color_surface(), LV_PART_MAIN);
87+
lv_obj_set_style_bg_opa(quality_btn, LV_OPA_80, LV_PART_MAIN);
88+
lv_obj_set_style_radius(quality_btn, 20, LV_PART_MAIN);
89+
lv_obj_set_style_pad_hor(quality_btn, 22, LV_PART_MAIN);
90+
lv_obj_set_style_pad_ver(quality_btn, 12, LV_PART_MAIN);
91+
lv_obj_set_style_border_width(quality_btn, 1, LV_PART_MAIN);
92+
lv_obj_set_style_border_color(quality_btn, ui_theme_color_outline(), LV_PART_MAIN);
93+
lv_obj_set_style_text_color(quality_btn, ui_theme_color_on_surface(), LV_PART_MAIN);
94+
95+
lv_obj_t* quality_label = lv_label_create(quality_btn);
96+
lv_label_set_text(quality_label, "Quality ▾");
97+
lv_obj_set_style_text_font(quality_label, &lv_font_montserrat_18, LV_PART_MAIN);
98+
99+
lv_obj_t* mute_btn = lv_btn_create(toolbar);
100+
lv_obj_remove_style_all(mute_btn);
101+
lv_obj_set_style_bg_color(mute_btn, ui_theme_color_surface(), LV_PART_MAIN);
102+
lv_obj_set_style_bg_opa(mute_btn, LV_OPA_60, LV_PART_MAIN);
103+
lv_obj_set_style_radius(mute_btn, 20, LV_PART_MAIN);
104+
lv_obj_set_style_pad_hor(mute_btn, 22, LV_PART_MAIN);
105+
lv_obj_set_style_pad_ver(mute_btn, 12, LV_PART_MAIN);
106+
lv_obj_set_style_border_width(mute_btn, 1, LV_PART_MAIN);
107+
lv_obj_set_style_border_color(mute_btn, ui_theme_color_outline(), LV_PART_MAIN);
108+
lv_obj_set_style_text_color(mute_btn, ui_theme_color_on_surface(), LV_PART_MAIN);
109+
110+
lv_obj_t* mute_label = lv_label_create(mute_btn);
111+
lv_label_set_text(mute_label, LV_SYMBOL_AUDIO " Mute");
112+
lv_obj_set_style_text_font(mute_label, &lv_font_montserrat_18, LV_PART_MAIN);
113+
114+
ui_room_card_config_t camera_config = {
115+
.room_id = "cctv_main",
116+
.title = "Backyard Camera",
117+
.icon_text = LV_SYMBOL_EYE,
118+
};
119+
120+
ui_room_card_t* camera_card = ui_room_card_create(content, &camera_config);
121+
lv_obj_t* camera_card_obj = ui_room_card_get_obj(camera_card);
122+
lv_obj_set_style_pad_gap(camera_card_obj, 24, LV_PART_MAIN);
123+
124+
lv_obj_t* camera_toggle = ui_room_card_get_toggle(camera_card);
125+
if (camera_toggle != NULL)
126+
{
127+
lv_obj_add_flag(camera_toggle, LV_OBJ_FLAG_HIDDEN);
128+
}
129+
130+
lv_obj_t* camera_specs = lv_obj_get_child(camera_card_obj, -1);
131+
if (camera_specs != NULL)
132+
{
133+
lv_label_set_text(camera_specs, "Streaming · 1080p60");
134+
}
135+
136+
lv_obj_t* video = lv_obj_create(camera_card_obj);
137+
lv_obj_remove_style_all(video);
138+
lv_obj_set_width(video, LV_PCT(100));
139+
lv_obj_set_height(video, 280);
140+
lv_obj_set_style_bg_color(video, ui_theme_color_outline(), LV_PART_MAIN);
141+
lv_obj_set_style_bg_opa(video, LV_OPA_30, LV_PART_MAIN);
142+
lv_obj_set_style_radius(video, 18, LV_PART_MAIN);
143+
lv_obj_set_style_border_width(video, 0, LV_PART_MAIN);
144+
lv_obj_set_style_pad_all(video, 24, LV_PART_MAIN);
145+
146+
lv_obj_t* video_label = lv_label_create(video);
147+
lv_label_set_text(video_label, "Live feed (stub)");
148+
lv_obj_set_style_text_font(video_label, &lv_font_montserrat_22, LV_PART_MAIN);
149+
lv_obj_set_style_text_color(video_label, ui_theme_color_on_surface(), LV_PART_MAIN);
150+
lv_obj_center(video_label);
151+
152+
lv_obj_t* events_row = lv_obj_create(content);
153+
lv_obj_remove_style_all(events_row);
154+
lv_obj_set_width(events_row, LV_PCT(100));
155+
lv_obj_set_style_bg_opa(events_row, LV_OPA_TRANSP, LV_PART_MAIN);
156+
lv_obj_set_style_pad_gap(events_row, 24, LV_PART_MAIN);
157+
lv_obj_set_flex_flow(events_row, LV_FLEX_FLOW_ROW_WRAP);
158+
lv_obj_set_flex_align(
159+
events_row, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
160+
161+
static const struct
162+
{
163+
const char* room_id;
164+
const char* title;
165+
const char* description;
166+
const char* timestamp;
167+
} k_event_cards[] = {
168+
{"door", "Front Door", "Person @ Door – 2m", "Today · 12:42"},
169+
{"garage", "Garage", "Motion – 5m", "Today · 12:37"},
170+
{"yard", "Backyard", "Person @ Gate – 8m", "Today · 12:20"},
171+
{"drive", "Driveway", "Vehicle Detected", "Today · 11:58"},
172+
};
173+
174+
for (size_t i = 0; i < LV_ARRAY_SIZE(k_event_cards); i++)
175+
{
176+
ui_room_card_config_t event_config = {
177+
.room_id = k_event_cards[i].room_id,
178+
.title = k_event_cards[i].title,
179+
.icon_text = LV_SYMBOL_VIDEO,
180+
};
181+
182+
ui_room_card_t* event_card = ui_room_card_create(events_row, &event_config);
183+
lv_obj_t* event_obj = ui_room_card_get_obj(event_card);
184+
lv_obj_set_width(event_obj, 280);
185+
lv_obj_set_style_pad_gap(event_obj, 16, LV_PART_MAIN);
186+
187+
lv_obj_t* event_toggle = ui_room_card_get_toggle(event_card);
188+
if (event_toggle != NULL)
189+
{
190+
lv_obj_add_flag(event_toggle, LV_OBJ_FLAG_HIDDEN);
191+
}
192+
193+
lv_obj_t* event_description = lv_label_create(event_obj);
194+
lv_label_set_text(event_description, k_event_cards[i].description);
195+
lv_obj_set_style_text_font(event_description, &lv_font_montserrat_18, LV_PART_MAIN);
196+
lv_obj_set_style_text_color(event_description, ui_theme_color_on_surface(), LV_PART_MAIN);
197+
lv_label_set_long_mode(event_description, LV_LABEL_LONG_WRAP);
198+
lv_obj_set_width(event_description, LV_PCT(100));
199+
200+
lv_obj_t* event_time = lv_obj_get_child(event_obj, -1);
201+
if (event_time != NULL)
202+
{
203+
lv_label_set_text(event_time, k_event_cards[i].timestamp);
204+
lv_obj_set_style_text_color(event_time, ui_theme_color_muted(), LV_PART_MAIN);
205+
}
206+
}
207+
208+
lv_obj_t* actions_row = lv_obj_create(content);
209+
lv_obj_remove_style_all(actions_row);
210+
lv_obj_set_width(actions_row, LV_PCT(100));
211+
lv_obj_set_style_bg_opa(actions_row, LV_OPA_TRANSP, LV_PART_MAIN);
212+
lv_obj_set_style_pad_gap(actions_row, 24, LV_PART_MAIN);
213+
lv_obj_set_flex_flow(actions_row, LV_FLEX_FLOW_ROW_WRAP);
214+
lv_obj_set_flex_align(
215+
actions_row, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
216+
217+
static const char* k_actions[] = {
218+
"Open Gate",
219+
"Talk",
220+
"Snapshot",
221+
"Timeline ▾",
222+
};
223+
224+
for (size_t i = 0; i < LV_ARRAY_SIZE(k_actions); i++)
225+
{
226+
lv_obj_t* action_btn = lv_btn_create(actions_row);
227+
lv_obj_remove_style_all(action_btn);
228+
lv_obj_set_style_bg_color(action_btn, ui_theme_color_surface(), LV_PART_MAIN);
229+
lv_obj_set_style_bg_opa(action_btn, LV_OPA_80, LV_PART_MAIN);
230+
lv_obj_set_style_radius(action_btn, 26, LV_PART_MAIN);
231+
lv_obj_set_style_border_width(action_btn, 1, LV_PART_MAIN);
232+
lv_obj_set_style_border_color(action_btn, ui_theme_color_outline(), LV_PART_MAIN);
233+
lv_obj_set_style_pad_hor(action_btn, 28, LV_PART_MAIN);
234+
lv_obj_set_style_pad_ver(action_btn, 16, LV_PART_MAIN);
235+
lv_obj_set_style_shadow_width(action_btn, 0, LV_PART_MAIN);
236+
lv_obj_set_style_text_color(action_btn, ui_theme_color_on_surface(), LV_PART_MAIN);
237+
238+
lv_obj_t* action_label = lv_label_create(action_btn);
239+
lv_label_set_text(action_label, k_actions[i]);
240+
lv_obj_set_style_text_font(action_label, &lv_font_montserrat_18, LV_PART_MAIN);
241+
}
48242

49243
return content;
50244
}
51245

52-
lv_obj_t *ui_page_cctv_create(lv_obj_t *parent)
246+
lv_obj_t* ui_page_cctv_create(lv_obj_t* parent)
53247
{
54-
if (parent == NULL) {
248+
if (parent == NULL)
249+
{
55250
return NULL;
56251
}
57252

58-
lv_obj_t *page = lv_obj_create(parent);
253+
lv_obj_t* page = lv_obj_create(parent);
59254
lv_obj_remove_style_all(page);
60255
lv_obj_set_size(page, LV_PCT(100), LV_PCT(100));
61256
lv_obj_set_style_bg_opa(page, LV_OPA_TRANSP, LV_PART_MAIN);
62257
lv_obj_set_scroll_dir(page, LV_DIR_VER);
63258
lv_obj_set_scrollbar_mode(page, LV_SCROLLBAR_MODE_OFF);
64259
lv_obj_add_flag(page, LV_OBJ_FLAG_CLICKABLE);
65260

66-
ui_wallpaper_t *wallpaper = ui_wallpaper_attach(page);
67-
if (wallpaper != NULL) {
261+
ui_wallpaper_t* wallpaper = ui_wallpaper_attach(page);
262+
if (wallpaper != NULL)
263+
{
68264
lv_obj_add_event_cb(page, ui_page_cctv_delete_cb, LV_EVENT_DELETE, wallpaper);
69265
}
70266

0 commit comments

Comments
 (0)