oveRTOS C++ API
C++20 RAII wrappers for the oveRTOS C API
Loading...
Searching...
No Matches
lvgl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 *
6 * This file is part of oveRTOS.
7 */
8
14#pragma once
15
16#include <ove/lvgl.h>
17#include <cstdarg>
18#include <cstdint>
19#include <cstdio>
20#include <type_traits>
21#include <concepts>
22
63namespace ove::lvgl
64{
65
69/* ================================================================== */
70/* LvglGuard — RAII lock for thread-safe LVGL access */
71/* ================================================================== */
72
92{
93 public:
98 {
99 ove_lvgl_lock();
100 }
101
105 ~LvglGuard() noexcept
106 {
107 ove_lvgl_unlock();
108 }
109
110 LvglGuard(const LvglGuard &) = delete;
111 LvglGuard &operator=(const LvglGuard &) = delete;
112 LvglGuard(LvglGuard &&) = delete;
113 LvglGuard &operator=(LvglGuard &&) = delete;
114};
115
116/* ================================================================== */
117/* ObjectView — non-owning lv_obj_t* wrapper */
118/* ================================================================== */
119
135{
136 public:
140 ObjectView() : obj_(nullptr)
141 {
142 }
143
148 explicit ObjectView(lv_obj_t *obj) : obj_(obj)
149 {
150 }
151
156 lv_obj_t *get() const
157 {
158 return obj_;
159 }
160
165 operator lv_obj_t *() const
166 {
167 return obj_;
168 }
169
174 explicit operator bool() const
175 {
176 return obj_ != nullptr;
177 }
178
184 {
185 return ObjectView(lv_obj_get_parent(obj_));
186 }
187
192 uint32_t child_count() const
193 {
194 return lv_obj_get_child_count(obj_);
195 }
196
202 ObjectView get_child(int32_t idx) const
203 {
204 return ObjectView(lv_obj_get_child(obj_, idx));
205 }
206
211 int32_t get_width() const
212 {
213 return lv_obj_get_width(obj_);
214 }
215
220 int32_t get_height() const
221 {
222 return lv_obj_get_height(obj_);
223 }
224
230 void del()
231 {
232 lv_obj_delete(obj_);
233 obj_ = nullptr;
234 }
235
239 void clean()
240 {
241 lv_obj_clean(obj_);
242 }
243
249 {
250 return ObjectView(lv_screen_active());
251 }
252
253 protected:
255 lv_obj_t *obj_;
256};
257
258static_assert(sizeof(ObjectView) == sizeof(void *), "ObjectView must be pointer-sized");
259
260/* Forward declaration so ObjectMixin::add_style can reference Style,
261 * whose full definition appears further below. */
262class Style;
263
264/* ================================================================== */
265/* ObjectMixin<Derived> — fluent setters via CRTP */
266/* ================================================================== */
267
280template <typename Derived> class ObjectMixin
281{
282 public:
289 Derived &size(int32_t w, int32_t h)
290 {
291 lv_obj_set_size(self().get(), w, h);
292 return self();
293 }
294
300 Derived &width(int32_t w)
301 {
302 lv_obj_set_width(self().get(), w);
303 return self();
304 }
305
311 Derived &height(int32_t h)
312 {
313 lv_obj_set_height(self().get(), h);
314 return self();
315 }
316
323 Derived &pos(int32_t x, int32_t y)
324 {
325 lv_obj_set_pos(self().get(), x, y);
326 return self();
327 }
328
333 Derived &center()
334 {
335 lv_obj_center(self().get());
336 return self();
337 }
338
346 Derived &align(lv_align_t a, int32_t x_ofs = 0, int32_t y_ofs = 0)
347 {
348 lv_obj_align(self().get(), a, x_ofs, y_ofs);
349 return self();
350 }
351
356 Derived &hide()
357 {
358 lv_obj_add_flag(self().get(), LV_OBJ_FLAG_HIDDEN);
359 return self();
360 }
361
366 Derived &show()
367 {
368 lv_obj_remove_flag(self().get(), LV_OBJ_FLAG_HIDDEN);
369 return self();
370 }
371
377 Derived &visible(bool v)
378 {
379 return v ? show() : hide();
380 }
381
387 Derived &add_flag(lv_obj_flag_t f)
388 {
389 lv_obj_add_flag(self().get(), f);
390 return self();
391 }
392
398 Derived &remove_flag(lv_obj_flag_t f)
399 {
400 lv_obj_remove_flag(self().get(), f);
401 return self();
402 }
403
409 Derived &add_state(lv_state_t s)
410 {
411 lv_obj_add_state(self().get(), s);
412 return self();
413 }
414
420 Derived &remove_state(lv_state_t s)
421 {
422 lv_obj_remove_state(self().get(), s);
423 return self();
424 }
425
431 Derived &user_data(void *data)
432 {
433 lv_obj_set_user_data(self().get(), data);
434 return self();
435 }
436
442 Derived &clickable(bool on)
443 {
444 if (on)
445 lv_obj_add_flag(self().get(), LV_OBJ_FLAG_CLICKABLE);
446 else
447 lv_obj_remove_flag(self().get(), LV_OBJ_FLAG_CLICKABLE);
448 return self();
449 }
450
462 Derived &grid_dsc(const int32_t *cols, const int32_t *rows)
463 {
464 lv_obj_set_grid_dsc_array(self().get(), cols, rows);
465 return self();
466 }
467
471 Derived &flex_flow(lv_flex_flow_t flow)
472 {
473 lv_obj_set_flex_flow(self().get(), flow);
474 return self();
475 }
476
480 Derived &flex_align(lv_flex_align_t main, lv_flex_align_t cross, lv_flex_align_t track)
481 {
482 lv_obj_set_flex_align(self().get(), main, cross, track);
483 return self();
484 }
485
489 Derived &flex_grow(uint8_t grow)
490 {
491 lv_obj_set_flex_grow(self().get(), grow);
492 return self();
493 }
494
498 Derived &layout(uint32_t kind)
499 {
500 lv_obj_set_layout(self().get(), kind);
501 return self();
502 }
503
507 Derived &scroll_to_y(int32_t y, bool anim)
508 {
509 lv_obj_scroll_to_y(self().get(), y, anim);
510 return self();
511 }
512
516 Derived &update_layout()
517 {
518 lv_obj_update_layout(self().get());
519 return self();
520 }
521
523 int32_t get_content_width() const
524 {
525 return lv_obj_get_content_width(
526 const_cast<lv_obj_t *>(static_cast<const Derived &>(*this).get()));
527 }
528
530 int32_t get_scroll_bottom() const
531 {
532 return lv_obj_get_scroll_bottom(
533 const_cast<lv_obj_t *>(static_cast<const Derived &>(*this).get()));
534 }
535
538 {
539 lv_obj_remove_style_all(self().get());
540 return self();
541 }
542
553 Derived &grid_cell(lv_grid_align_t col_align, int32_t col_pos, int32_t col_span,
554 lv_grid_align_t row_align, int32_t row_pos, int32_t row_span)
555 {
556 lv_obj_set_grid_cell(self().get(), col_align, col_pos, col_span, row_align, row_pos,
557 row_span);
558 return self();
559 }
560
569 Derived &add_style(Style &style, lv_style_selector_t selector);
570
571 private:
572 Derived &self()
573 {
574 return static_cast<Derived &>(*this);
575 }
576};
577
578/* ================================================================== */
579/* EventMixin<Derived> — type-safe event callbacks via CRTP */
580/* ================================================================== */
581
582namespace detail
583{
584
594template <typename F>
595concept StatelessCallable = std::is_convertible_v<F, void (*)(lv_event_t *)>;
596
597} /* namespace detail */
598
615template <typename Derived> class EventMixin
616{
617 public:
629 template <detail::StatelessCallable F> Derived &on(lv_event_code_t code, F &&fn)
630 {
631 lv_obj_add_event_cb(self().get(), static_cast<lv_event_cb_t>(fn), code, nullptr);
632 return self();
633 }
634
648 template <auto MemFn, typename T> Derived &on(lv_event_code_t code, T *instance)
649 {
650 lv_obj_add_event_cb(
651 self().get(),
652 [](lv_event_t *e) {
653 auto *self = static_cast<T *>(lv_event_get_user_data(e));
654 (self->*MemFn)(e);
655 },
656 code, instance);
657 return self();
658 }
659
666 template <detail::StatelessCallable F> Derived &on_click(F &&fn)
667 {
668 return on(LV_EVENT_CLICKED, static_cast<F &&>(fn));
669 }
670
678 template <auto MemFn, typename T> Derived &on_click(T *instance)
679 {
681 }
682
689 template <detail::StatelessCallable F> Derived &on_value_changed(F &&fn)
690 {
691 return on(LV_EVENT_VALUE_CHANGED, static_cast<F &&>(fn));
692 }
693
701 template <auto MemFn, typename T> Derived &on_value_changed(T *instance)
702 {
704 }
705
706 private:
707 Derived &self()
708 {
709 return static_cast<Derived &>(*this);
710 }
711};
712
713/* ================================================================== */
714/* StyleMixin<Derived> — inline style setters via CRTP */
715/* ================================================================== */
716
729template <typename Derived> class StyleMixin
730{
731 public:
737 Derived &bg_color(lv_color_t c)
738 {
739 lv_obj_set_style_bg_color(self().get(), c, LV_PART_MAIN);
740 return self();
741 }
742
747 Derived &bg_color(lv_color_t c, lv_style_selector_t part)
748 {
749 lv_obj_set_style_bg_color(self().get(), c, part);
750 return self();
751 }
752
758 Derived &bg_opa(lv_opa_t opa)
759 {
760 lv_obj_set_style_bg_opa(self().get(), opa, LV_PART_MAIN);
761 return self();
762 }
763
765 Derived &bg_opa(lv_opa_t opa, lv_style_selector_t part)
766 {
767 lv_obj_set_style_bg_opa(self().get(), opa, part);
768 return self();
769 }
770
776 Derived &border_color(lv_color_t c)
777 {
778 lv_obj_set_style_border_color(self().get(), c, LV_PART_MAIN);
779 return self();
780 }
781
787 Derived &border_width(int32_t w)
788 {
789 lv_obj_set_style_border_width(self().get(), w, LV_PART_MAIN);
790 return self();
791 }
792
794 Derived &border_width(int32_t w, lv_style_selector_t part)
795 {
796 lv_obj_set_style_border_width(self().get(), w, part);
797 return self();
798 }
799
805 Derived &radius(int32_t r)
806 {
807 lv_obj_set_style_radius(self().get(), r, LV_PART_MAIN);
808 return self();
809 }
810
812 Derived &radius(int32_t r, lv_style_selector_t part)
813 {
814 lv_obj_set_style_radius(self().get(), r, part);
815 return self();
816 }
817
823 Derived &pad_all(int32_t p)
824 {
825 lv_obj_set_style_pad_all(self().get(), p, LV_PART_MAIN);
826 return self();
827 }
828
834 Derived &pad_hor(int32_t p)
835 {
836 lv_obj_set_style_pad_hor(self().get(), p, LV_PART_MAIN);
837 return self();
838 }
839
845 Derived &pad_ver(int32_t p)
846 {
847 lv_obj_set_style_pad_ver(self().get(), p, LV_PART_MAIN);
848 return self();
849 }
850
856 Derived &pad_gap(int32_t g)
857 {
858 lv_obj_set_style_pad_gap(self().get(), g, LV_PART_MAIN);
859 return self();
860 }
861
867 Derived &text_color(lv_color_t c)
868 {
869 lv_obj_set_style_text_color(self().get(), c, LV_PART_MAIN);
870 return self();
871 }
872
878 Derived &text_font(const lv_font_t *f)
879 {
880 lv_obj_set_style_text_font(self().get(), f, LV_PART_MAIN);
881 return self();
882 }
883
884 // ---- Per-side paddings + row/column gaps ----
886 Derived &pad_top(int32_t p)
887 {
888 lv_obj_set_style_pad_top(self().get(), p, LV_PART_MAIN);
889 return self();
890 }
892 Derived &pad_bottom(int32_t p)
893 {
894 lv_obj_set_style_pad_bottom(self().get(), p, LV_PART_MAIN);
895 return self();
896 }
898 Derived &pad_left(int32_t p)
899 {
900 lv_obj_set_style_pad_left(self().get(), p, LV_PART_MAIN);
901 return self();
902 }
904 Derived &pad_right(int32_t p)
905 {
906 lv_obj_set_style_pad_right(self().get(), p, LV_PART_MAIN);
907 return self();
908 }
910 Derived &pad_row(int32_t p)
911 {
912 lv_obj_set_style_pad_row(self().get(), p, LV_PART_MAIN);
913 return self();
914 }
916 Derived &pad_column(int32_t p)
917 {
918 lv_obj_set_style_pad_column(self().get(), p, LV_PART_MAIN);
919 return self();
920 }
921
922 // ---- Text alignment + overall opacity ----
924 Derived &text_align(uint32_t align, lv_style_selector_t part = LV_PART_MAIN)
925 {
926 lv_obj_set_style_text_align(self().get(), static_cast<lv_text_align_t>(align),
927 part);
928 return self();
929 }
931 Derived &set_opa(lv_opa_t opa)
932 {
933 lv_obj_set_style_opa(self().get(), opa, LV_PART_MAIN);
934 return self();
935 }
936
937 // ---- Selector variants ----
939 Derived &text_color(lv_color_t c, lv_style_selector_t part)
940 {
941 lv_obj_set_style_text_color(self().get(), c, part);
942 return self();
943 }
945 Derived &border_color(lv_color_t c, lv_style_selector_t part)
946 {
947 lv_obj_set_style_border_color(self().get(), c, part);
948 return self();
949 }
951 Derived &arc_color(lv_color_t c, lv_style_selector_t part)
952 {
953 lv_obj_set_style_arc_color(self().get(), c, part);
954 return self();
955 }
957 Derived &arc_width(int32_t w, lv_style_selector_t part)
958 {
959 lv_obj_set_style_arc_width(self().get(), w, part);
960 return self();
961 }
963 Derived &arc_opa(lv_opa_t opa, lv_style_selector_t part)
964 {
965 lv_obj_set_style_arc_opa(self().get(), opa, part);
966 return self();
967 }
969 Derived &arc_rounded(bool rounded, lv_style_selector_t part)
970 {
971 lv_obj_set_style_arc_rounded(self().get(), rounded, part);
972 return self();
973 }
974
975 // ---- Advanced layout/compositing styles ----
977 Derived &translate_y(int32_t v, lv_style_selector_t part = LV_PART_MAIN)
978 {
979 lv_obj_set_style_translate_y(self().get(), v, part);
980 return self();
981 }
983 Derived &margin_top(int32_t v, lv_style_selector_t part = LV_PART_MAIN)
984 {
985 lv_obj_set_style_margin_top(self().get(), v, part);
986 return self();
987 }
989 Derived &margin_bottom(int32_t v, lv_style_selector_t part = LV_PART_MAIN)
990 {
991 lv_obj_set_style_margin_bottom(self().get(), v, part);
992 return self();
993 }
995 Derived &margin_left(int32_t v, lv_style_selector_t part = LV_PART_MAIN)
996 {
997 lv_obj_set_style_margin_left(self().get(), v, part);
998 return self();
999 }
1001 Derived &margin_right(int32_t v, lv_style_selector_t part = LV_PART_MAIN)
1002 {
1003 lv_obj_set_style_margin_right(self().get(), v, part);
1004 return self();
1005 }
1007 Derived &max_height(int32_t v, lv_style_selector_t part = LV_PART_MAIN)
1008 {
1009 lv_obj_set_style_max_height(self().get(), v, part);
1010 return self();
1011 }
1013 Derived &opa_layered(lv_opa_t opa, lv_style_selector_t part = LV_PART_MAIN)
1014 {
1015 lv_obj_set_style_opa_layered(self().get(), opa, part);
1016 return self();
1017 }
1018
1019 private:
1020 Derived &self()
1021 {
1022 return static_cast<Derived &>(*this);
1023 }
1024};
1025
/* end of ove_lvgl_core */
1027
1031/* ================================================================== */
1032/* Style — RAII style object */
1033/* ================================================================== */
1034
1049{
1050 public:
1055 {
1056 lv_style_init(&style_);
1057 }
1058
1062 ~Style() noexcept
1063 {
1064 lv_style_reset(&style_);
1065 }
1066
1067 Style(const Style &) = delete;
1068 Style &operator=(const Style &) = delete;
1069
1074 Style(Style &&other) noexcept : style_(other.style_)
1075 {
1076 lv_style_init(&other.style_);
1077 }
1078
1084 Style &operator=(Style &&other) noexcept
1085 {
1086 if (this != &other) {
1087 lv_style_reset(&style_);
1088 style_ = other.style_;
1089 lv_style_init(&other.style_);
1090 }
1091 return *this;
1092 }
1093
1098 lv_style_t *get()
1099 {
1100 return &style_;
1101 }
1102
1107 const lv_style_t *get() const
1108 {
1109 return &style_;
1110 }
1111
1117 Style &bg_color(lv_color_t c)
1118 {
1119 lv_style_set_bg_color(&style_, c);
1120 return *this;
1121 }
1122
1128 Style &bg_opa(lv_opa_t opa)
1129 {
1130 lv_style_set_bg_opa(&style_, opa);
1131 return *this;
1132 }
1133
1139 Style &radius(int32_t r)
1140 {
1141 lv_style_set_radius(&style_, r);
1142 return *this;
1143 }
1144
1150 Style &border_color(lv_color_t c)
1151 {
1152 lv_style_set_border_color(&style_, c);
1153 return *this;
1154 }
1155
1162 {
1163 lv_style_set_border_width(&style_, w);
1164 return *this;
1165 }
1166
1172 Style &pad_all(int32_t p)
1173 {
1174 lv_style_set_pad_all(&style_, p);
1175 return *this;
1176 }
1177
1183 Style &text_color(lv_color_t c)
1184 {
1185 lv_style_set_text_color(&style_, c);
1186 return *this;
1187 }
1188
1194 Style &text_font(const lv_font_t *f)
1195 {
1196 lv_style_set_text_font(&style_, f);
1197 return *this;
1198 }
1199
1200 private:
1201 lv_style_t style_;
1202};
1203
1204/* Out-of-line definition: now that `Style` is complete, `style.get()` is
1205 * a valid call. (Declared inside ObjectMixin above.) */
1206template <typename Derived>
1207Derived &ObjectMixin<Derived>::add_style(Style &style, lv_style_selector_t selector)
1208{
1209 lv_obj_add_style(self().get(), style.get(), selector);
1210 return self();
1211}
1212
1213/* ================================================================== */
1214/* State<T> — reactive state (requires LV_USE_OBSERVER) */
1215/* ================================================================== */
1216
1217#if LV_USE_OBSERVER
1218
1235template <std::integral T> class State
1236{
1237 public:
1242 explicit State(T initial = 0)
1243 {
1244 lv_subject_init_int(&subject_, static_cast<int32_t>(initial));
1245 }
1246
1250 ~State() noexcept
1251 {
1252 lv_subject_deinit(&subject_);
1253 }
1254
1255 State(const State &) = delete;
1256 State &operator=(const State &) = delete;
1257
1262 void set(T val)
1263 {
1264 lv_subject_set_int(&subject_, static_cast<int32_t>(val));
1265 }
1266
1271 T get() const
1272 {
1273 return static_cast<T>(lv_subject_get_int(const_cast<lv_subject_t *>(&subject_)));
1274 }
1275
1280 operator T() const
1281 {
1282 return get();
1283 }
1284
1289 State &operator++()
1290 {
1291 set(get() + 1);
1292 return *this;
1293 }
1294
1299 State &operator--()
1300 {
1301 set(get() - 1);
1302 return *this;
1303 }
1304
1309 lv_subject_t *subject()
1310 {
1311 return &subject_;
1312 }
1313
1314 private:
1315 lv_subject_t subject_;
1316};
1317
1318#endif /* LV_USE_OBSERVER */
1319
/* end of ove_lvgl_style */
1321
1325/* ================================================================== */
1326/* Widget wrappers — Label, Bar, Box */
1327/* ================================================================== */
1328
1344class Label : public ObjectView,
1345 public ObjectMixin<Label>,
1346 public EventMixin<Label>,
1347 public StyleMixin<Label>
1348{
1349 public:
1355 {
1356 }
1357
1364 {
1365 return Label(lv_label_create(parent));
1366 }
1367
1373 Label &text(const char *txt)
1374 {
1376 return *this;
1377 }
1378
1388 Label &text_static(const char *txt)
1389 {
1391 return *this;
1392 }
1393
1404 Label &text_fmt(const char *fmt, ...)
1405 {
1406 va_list args;
1407 va_start(args, fmt);
1408 /* LVGL doesn't have a va_list variant, use snprintf + set */
1409 char buf[128];
1410 vsnprintf(buf, sizeof(buf), fmt, args);
1411 va_end(args);
1413 return *this;
1414 }
1415
1422 {
1424 return *this;
1425 }
1426
1433 {
1435 return *this;
1436 }
1437
1444 {
1446 return *this;
1447 }
1448
1449#if LV_USE_OBSERVER
1463 template <std::integral T> Label &bind_text(State<T> &state, const char *fmt)
1464 {
1465 lv_label_bind_text(obj_, state.subject(), fmt);
1466 return *this;
1467 }
1468#endif
1469};
1470
1471static_assert(sizeof(Label) == sizeof(void *), "Label must be pointer-sized");
1472
1487class Bar : public ObjectView,
1488 public ObjectMixin<Bar>,
1489 public EventMixin<Bar>,
1490 public StyleMixin<Bar>
1491{
1492 public:
1498 {
1499 }
1500
1507 {
1508 return Bar(lv_bar_create(parent));
1509 }
1510
1517 {
1519 return *this;
1520 }
1521
1529 {
1531 return *this;
1532 }
1533
1541 {
1543 return *this;
1544 }
1545
1556
1563 {
1565 return *this;
1566 }
1567
1568 /* Note: lv_bar_bind_value() does NOT exist in LVGL 9.2-9.3 */
1569};
1570
1571static_assert(sizeof(Bar) == sizeof(void *), "Bar must be pointer-sized");
1572
1586class Box : public ObjectView,
1587 public ObjectMixin<Box>,
1588 public EventMixin<Box>,
1589 public StyleMixin<Box>
1590{
1591 public:
1597 {
1598 }
1599
1611};
1612
1613static_assert(sizeof(Box) == sizeof(void *), "Box must be pointer-sized");
1614
1623class Button : public ObjectView,
1624 public ObjectMixin<Button>,
1625 public EventMixin<Button>,
1626 public StyleMixin<Button>
1627{
1628 public:
1631 {
1632 }
1633
1636 {
1638 }
1639
1645 {
1646 if (on)
1648 else
1650 return *this;
1651 }
1652
1655 {
1656 if (v)
1658 else
1660 return *this;
1661 }
1662
1664 bool is_checked() const
1665 {
1667 }
1668};
1669
1670static_assert(sizeof(Button) == sizeof(void *), "Button must be pointer-sized");
1671
1679class Slider : public ObjectView,
1680 public ObjectMixin<Slider>,
1681 public EventMixin<Slider>,
1682 public StyleMixin<Slider>
1683{
1684 public:
1687 {
1688 }
1689
1692 {
1694 }
1695
1698 {
1700 return *this;
1701 }
1702
1705 {
1707 return *this;
1708 }
1709
1712 {
1714 return *this;
1715 }
1716
1719 {
1720 return lv_slider_get_value(obj_);
1721 }
1722
1729
1732 {
1734 return *this;
1735 }
1736};
1737
1738static_assert(sizeof(Slider) == sizeof(void *), "Slider must be pointer-sized");
1739
1747class Switch : public ObjectView,
1748 public ObjectMixin<Switch>,
1749 public EventMixin<Switch>,
1750 public StyleMixin<Switch>
1751{
1752 public:
1755 {
1756 }
1757
1760 {
1762 }
1763
1766 {
1767 if (v)
1769 else
1771 return *this;
1772 }
1773
1775 bool is_checked() const
1776 {
1778 }
1779};
1780
1781static_assert(sizeof(Switch) == sizeof(void *), "Switch must be pointer-sized");
1782
1790class Checkbox : public ObjectView,
1791 public ObjectMixin<Checkbox>,
1792 public EventMixin<Checkbox>,
1793 public StyleMixin<Checkbox>
1794{
1795 public:
1798 {
1799 }
1800
1803 {
1805 }
1806
1808 Checkbox &text(const char *txt)
1809 {
1811 return *this;
1812 }
1813
1816 {
1818 return *this;
1819 }
1820
1823 {
1824 if (v)
1826 else
1828 return *this;
1829 }
1830
1832 bool is_checked() const
1833 {
1835 }
1836};
1837
1838static_assert(sizeof(Checkbox) == sizeof(void *), "Checkbox must be pointer-sized");
1839
1849class Arc : public ObjectView,
1850 public ObjectMixin<Arc>,
1851 public EventMixin<Arc>,
1852 public StyleMixin<Arc>
1853{
1854 public:
1857 {
1858 }
1859
1862 {
1863 return Arc(lv_arc_create(parent));
1864 }
1865
1868 {
1870 return *this;
1871 }
1872
1875 {
1877 return *this;
1878 }
1879
1882 {
1883 lv_arc_set_bg_angles(obj_, start, end);
1884 return *this;
1885 }
1886
1889 {
1890 lv_arc_set_angles(obj_, start, end);
1891 return *this;
1892 }
1893
1896 {
1898 return *this;
1899 }
1900
1903 {
1904 return lv_arc_get_value(obj_);
1905 }
1906
1909 {
1911 return *this;
1912 }
1913
1920
1923 {
1925 return *this;
1926 }
1927
1930 {
1932 return *this;
1933 }
1934};
1935
1936static_assert(sizeof(Arc) == sizeof(void *), "Arc must be pointer-sized");
1937
1946class Image : public ObjectView,
1947 public ObjectMixin<Image>,
1948 public EventMixin<Image>,
1949 public StyleMixin<Image>
1950{
1951 public:
1954 {
1955 }
1956
1959 {
1960 return Image(lv_image_create(parent));
1961 }
1962
1964 Image &src(const void *src)
1965 {
1967 return *this;
1968 }
1969
1972 {
1974 return *this;
1975 }
1976
1979 {
1981 return *this;
1982 }
1983
1986 {
1988 return *this;
1989 }
1990
1993 {
1995 return *this;
1996 }
1997};
1998
1999static_assert(sizeof(Image) == sizeof(void *), "Image must be pointer-sized");
2000
2010class Msgbox : public ObjectView,
2011 public ObjectMixin<Msgbox>,
2012 public EventMixin<Msgbox>,
2013 public StyleMixin<Msgbox>
2014{
2015 public:
2018 {
2019 }
2020
2024 {
2026 }
2027
2029 Msgbox &add_title(const char *txt)
2030 {
2032 return *this;
2033 }
2034
2036 Msgbox &add_text(const char *txt)
2037 {
2039 return *this;
2040 }
2041
2044 {
2046 return *this;
2047 }
2048
2056
2059 {
2061 }
2062
2065 {
2067 }
2068
2071 {
2073 }
2074
2076 void close()
2077 {
2079 }
2080};
2081
2082static_assert(sizeof(Msgbox) == sizeof(void *), "Msgbox must be pointer-sized");
2083
2091class Spinner : public ObjectView,
2092 public ObjectMixin<Spinner>,
2093 public EventMixin<Spinner>,
2094 public StyleMixin<Spinner>
2095{
2096 public:
2099 {
2100 }
2101
2104 {
2106 }
2107
2118};
2119
2120static_assert(sizeof(Spinner) == sizeof(void *), "Spinner must be pointer-sized");
2121
2126class Led : public ObjectView,
2127 public ObjectMixin<Led>,
2128 public EventMixin<Led>,
2129 public StyleMixin<Led>
2130{
2131 public:
2134 {
2135 }
2136
2139 {
2140 return Led(lv_led_create(parent));
2141 }
2142
2145 {
2147 return *this;
2148 }
2149
2152 {
2154 return *this;
2155 }
2156
2159 {
2160 lv_led_on(obj_);
2161 return *this;
2162 }
2163
2166 {
2168 return *this;
2169 }
2170
2173 {
2175 return *this;
2176 }
2177
2180 {
2182 }
2183};
2184
2185static_assert(sizeof(Led) == sizeof(void *), "Led must be pointer-sized");
2186
2195class Textarea : public ObjectView,
2196 public ObjectMixin<Textarea>,
2197 public EventMixin<Textarea>,
2198 public StyleMixin<Textarea>
2199{
2200 public:
2203 {
2204 }
2205
2208 {
2210 }
2211
2213 Textarea &text(const char *txt)
2214 {
2216 return *this;
2217 }
2218
2220 Textarea &add_text(const char *txt)
2221 {
2223 return *this;
2224 }
2225
2228 {
2230 return *this;
2231 }
2232
2235 {
2237 return *this;
2238 }
2239
2242 {
2244 return *this;
2245 }
2246
2249 {
2251 return *this;
2252 }
2253
2256 {
2258 return *this;
2259 }
2260
2263 {
2265 return *this;
2266 }
2267
2270 {
2272 return *this;
2273 }
2274
2276 const char *get_text() const
2277 {
2278 return lv_textarea_get_text(obj_);
2279 }
2280
2283 {
2285 }
2286
2288 bool is_password_mode() const
2289 {
2291 }
2292
2294 bool is_one_line() const
2295 {
2297 }
2298
2301 {
2303 return *this;
2304 }
2305
2308 {
2310 return *this;
2311 }
2312};
2313
2314static_assert(sizeof(Textarea) == sizeof(void *), "Textarea must be pointer-sized");
2315
2323class Dropdown : public ObjectView,
2324 public ObjectMixin<Dropdown>,
2325 public EventMixin<Dropdown>,
2326 public StyleMixin<Dropdown>
2327{
2328 public:
2331 {
2332 }
2333
2336 {
2338 }
2339
2341 Dropdown &options(const char *opts)
2342 {
2344 return *this;
2345 }
2346
2349 {
2351 return *this;
2352 }
2353
2356 {
2358 return *this;
2359 }
2360
2363 {
2365 return *this;
2366 }
2367
2370 {
2372 return *this;
2373 }
2374
2377 {
2379 return *this;
2380 }
2381
2383 Dropdown &symbol(const void *sym)
2384 {
2386 return *this;
2387 }
2388
2391 {
2393 }
2394
2397 {
2399 }
2400
2403 {
2405 }
2406
2408 const char *get_options() const
2409 {
2411 }
2412
2414 bool is_open() const
2415 {
2416 return lv_dropdown_is_open(const_cast<lv_obj_t *>(obj_));
2417 }
2418
2420 void open()
2421 {
2423 }
2424
2426 void close()
2427 {
2429 }
2430};
2431
2432static_assert(sizeof(Dropdown) == sizeof(void *), "Dropdown must be pointer-sized");
2433
2442class Roller : public ObjectView,
2443 public ObjectMixin<Roller>,
2444 public EventMixin<Roller>,
2445 public StyleMixin<Roller>
2446{
2447 public:
2450 {
2451 }
2452
2455 {
2457 }
2458
2461 {
2463 return *this;
2464 }
2465
2472
2479
2482 {
2484 }
2485
2488 {
2490 }
2491
2494 {
2496 }
2497
2499 const char *get_options() const
2500 {
2502 }
2503};
2504
2505static_assert(sizeof(Roller) == sizeof(void *), "Roller must be pointer-sized");
2506
2515class Spinbox : public ObjectView,
2516 public ObjectMixin<Spinbox>,
2517 public EventMixin<Spinbox>,
2518 public StyleMixin<Spinbox>
2519{
2520 public:
2523 {
2524 }
2525
2528 {
2530 }
2531
2534 {
2536 return *this;
2537 }
2538
2541 {
2543 return *this;
2544 }
2545
2548 {
2550 return *this;
2551 }
2552
2563
2566 {
2568 return *this;
2569 }
2570
2573 {
2575 return *this;
2576 }
2577
2580 {
2581 return lv_spinbox_get_value(const_cast<lv_obj_t *>(obj_));
2582 }
2583
2586 {
2587 return lv_spinbox_get_step(const_cast<lv_obj_t *>(obj_));
2588 }
2589
2592 {
2594 return *this;
2595 }
2596
2599 {
2601 return *this;
2602 }
2603};
2604
2605static_assert(sizeof(Spinbox) == sizeof(void *), "Spinbox must be pointer-sized");
2606
2615class Keyboard : public ObjectView,
2616 public ObjectMixin<Keyboard>,
2617 public EventMixin<Keyboard>,
2618 public StyleMixin<Keyboard>
2619{
2620 public:
2623 {
2624 }
2625
2628 {
2630 }
2631
2634 {
2636 return *this;
2637 }
2638
2641 {
2643 return *this;
2644 }
2645
2648 {
2650 return *this;
2651 }
2652
2658};
2659
2660static_assert(sizeof(Keyboard) == sizeof(void *), "Keyboard must be pointer-sized");
2661
2673class Chart : public ObjectView,
2674 public ObjectMixin<Chart>,
2675 public EventMixin<Chart>,
2676 public StyleMixin<Chart>
2677{
2678 public:
2681 {
2682 public:
2683 Series() : chart_(nullptr), ser_(nullptr)
2684 {
2685 }
2688 {
2689 }
2690
2693 {
2694 return ser_;
2695 }
2697 explicit operator bool() const
2698 {
2699 return ser_ != nullptr;
2700 }
2701
2704 {
2705 lv_chart_set_next_value(chart_, ser_, v);
2706 return *this;
2707 }
2708
2711 {
2712 lv_chart_set_value_by_id(chart_, ser_, idx, v);
2713 return *this;
2714 }
2715
2716 private:
2717 lv_obj_t *chart_;
2718 lv_chart_series_t *ser_;
2719 };
2720
2723 {
2724 }
2725
2728 {
2729 return Chart(lv_chart_create(parent));
2730 }
2731
2734 {
2736 return *this;
2737 }
2738
2741 {
2743 return *this;
2744 }
2745
2748 {
2750 return *this;
2751 }
2752
2755 {
2757 return *this;
2758 }
2759
2766
2773
2776 {
2778 return *this;
2779 }
2780};
2781
2782static_assert(sizeof(Chart) == sizeof(void *), "Chart must be pointer-sized");
2783
2791class Table : public ObjectView,
2792 public ObjectMixin<Table>,
2793 public EventMixin<Table>,
2794 public StyleMixin<Table>
2795{
2796 public:
2799 {
2800 }
2801
2804 {
2805 return Table(lv_table_create(parent));
2806 }
2807
2810 {
2812 return *this;
2813 }
2814
2817 {
2819 return *this;
2820 }
2821
2824 {
2826 return *this;
2827 }
2828
2831 {
2833 return *this;
2834 }
2835
2838 {
2840 }
2841
2844 {
2846 }
2847
2850 {
2852 }
2853
2859};
2860
2861static_assert(sizeof(Table) == sizeof(void *), "Table must be pointer-sized");
2862
2870class Tabview : public ObjectView,
2871 public ObjectMixin<Tabview>,
2872 public EventMixin<Tabview>,
2873 public StyleMixin<Tabview>
2874{
2875 public:
2878 {
2879 }
2880
2887 {
2889 }
2890
2892 ObjectView add_tab(const char *name)
2893 {
2894 return ObjectView(lv_tabview_add_tab(obj_, name));
2895 }
2896
2898 Tabview &rename_tab(uint32_t idx, const char *name)
2899 {
2901 return *this;
2902 }
2903
2910
2913 {
2915 return *this;
2916 }
2917
2920 {
2922 return *this;
2923 }
2924
2927 {
2929 }
2930
2933 {
2935 }
2936
2939 {
2941 }
2942};
2943
2944static_assert(sizeof(Tabview) == sizeof(void *), "Tabview must be pointer-sized");
2945
2953class List : public ObjectView,
2954 public ObjectMixin<List>,
2955 public EventMixin<List>,
2956 public StyleMixin<List>
2957{
2958 public:
2961 {
2962 }
2963
2966 {
2967 return List(lv_list_create(parent));
2968 }
2969
2971 ObjectView add_text(const char *text)
2972 {
2973 return ObjectView(lv_list_add_text(obj_, text));
2974 }
2975
2977 ObjectView add_button(const void *icon, const char *text)
2978 {
2979 return ObjectView(lv_list_add_button(obj_, icon, text));
2980 }
2981
2983 const char *get_button_text(ObjectView btn) const
2984 {
2986 }
2987};
2988
2989static_assert(sizeof(List) == sizeof(void *), "List must be pointer-sized");
2990
3004class Canvas : public ObjectView,
3005 public ObjectMixin<Canvas>,
3006 public EventMixin<Canvas>,
3007 public StyleMixin<Canvas>
3008{
3009 public:
3012 {
3013 }
3014
3017 {
3019 }
3020
3023 {
3025 return *this;
3026 }
3027
3030 {
3031 lv_canvas_fill_bg(obj_, color, opa);
3032 return *this;
3033 }
3034
3037 {
3039 return *this;
3040 }
3041
3050 {
3052 return *this;
3053 }
3054
3057 {
3059 return *this;
3060 }
3061};
3062
3063static_assert(sizeof(Canvas) == sizeof(void *), "Canvas must be pointer-sized");
3064
3074class Calendar : public ObjectView,
3075 public ObjectMixin<Calendar>,
3076 public EventMixin<Calendar>,
3077 public StyleMixin<Calendar>
3078{
3079 public:
3082 {
3083 }
3084
3087 {
3089 }
3090
3097
3100 {
3102 return *this;
3103 }
3104
3108 {
3110 return *this;
3111 }
3112
3118
3124
3130};
3131
3132static_assert(sizeof(Calendar) == sizeof(void *), "Calendar must be pointer-sized");
3133
/* end of ove_lvgl_widgets */
3135
3139/* ================================================================== */
3140/* Layout helpers */
3141/* ================================================================== */
3142
3148inline Box vbox(ObjectView parent)
3149{
3150 auto b = Box::create(parent);
3151 lv_obj_set_flex_flow(b.get(), LV_FLEX_FLOW_COLUMN);
3152 lv_obj_set_size(b.get(), LV_SIZE_CONTENT, LV_SIZE_CONTENT);
3153 return b;
3154}
3155
3161inline Box hbox(ObjectView parent)
3162{
3163 auto b = Box::create(parent);
3164 lv_obj_set_flex_flow(b.get(), LV_FLEX_FLOW_ROW);
3165 lv_obj_set_size(b.get(), LV_SIZE_CONTENT, LV_SIZE_CONTENT);
3166 return b;
3167}
3168
3169/* ================================================================== */
3170/* Group — keyboard / encoder focus groups */
3171/* ================================================================== */
3172
3186{
3187 public:
3188 Group() : group_(nullptr)
3189 {
3190 }
3192 explicit Group(lv_group_t *g) : group_(g)
3193 {
3194 }
3195
3196 ~Group() noexcept
3197 {
3198 if (group_)
3199 lv_group_delete(group_);
3200 }
3201
3202 Group(const Group &) = delete;
3203 Group &operator=(const Group &) = delete;
3204
3206 Group(Group &&other) noexcept : group_(other.group_)
3207 {
3208 other.group_ = nullptr;
3209 }
3210
3212 Group &operator=(Group &&other) noexcept
3213 {
3214 if (this != &other) {
3215 if (group_)
3216 lv_group_delete(group_);
3217 group_ = other.group_;
3218 other.group_ = nullptr;
3219 }
3220 return *this;
3221 }
3222
3224 static Group create()
3225 {
3226 return Group(lv_group_create());
3227 }
3228
3230 static lv_group_t *get_default()
3231 {
3232 return lv_group_get_default();
3233 }
3234
3236 lv_group_t *get() const
3237 {
3238 return group_;
3239 }
3240
3244 {
3245 lv_group_set_default(group_);
3246 return *this;
3247 }
3248
3251 {
3252 lv_group_add_obj(group_, obj);
3253 return *this;
3254 }
3255
3258 {
3259 lv_group_remove_all_objs(group_);
3260 return *this;
3261 }
3262
3265 {
3266 lv_group_focus_next(group_);
3267 return *this;
3268 }
3269
3272 {
3273 lv_group_focus_prev(group_);
3274 return *this;
3275 }
3276
3278 Group &focus_freeze(bool freeze)
3279 {
3280 lv_group_focus_freeze(group_, freeze);
3281 return *this;
3282 }
3283
3286 {
3287 return ObjectView(lv_group_get_focused(group_));
3288 }
3289
3291 Group &edit_mode(bool enable)
3292 {
3293 lv_group_set_editing(group_, enable);
3294 return *this;
3295 }
3296
3298 bool is_editing() const
3299 {
3300 return lv_group_get_editing(group_);
3301 }
3302
3304 uint32_t obj_count() const
3305 {
3306 return lv_group_get_obj_count(group_);
3307 }
3308
3311 static void focus_obj(ObjectView obj)
3312 {
3313 lv_group_focus_obj(obj);
3314 }
3315
3317 static void remove_obj(ObjectView obj)
3318 {
3319 lv_group_remove_obj(obj);
3320 }
3321
3322 private:
3323 lv_group_t *group_;
3324};
3325
3326/* ================================================================== */
3327/* Screen — top-level display root with load/load_anim */
3328/* ================================================================== */
3329
3343class Screen : public ObjectView,
3344 public ObjectMixin<Screen>,
3345 public EventMixin<Screen>,
3346 public StyleMixin<Screen>
3347{
3348 public:
3351 {
3352 }
3353
3356 {
3357 return Screen(lv_obj_create(nullptr));
3358 }
3359
3362 {
3363 return Screen(lv_screen_active());
3364 }
3365
3367 void load()
3368 {
3370 }
3371
3382 bool auto_del = false)
3383 {
3385 }
3386};
3387
3388static_assert(sizeof(Screen) == sizeof(void *), "Screen must be pointer-sized");
3389
/* end of ove_lvgl_layout */
3391
3395/* ================================================================== */
3396/* Timer — RAII wrapper around lv_timer_t */
3397/* ================================================================== */
3398
3415{
3416 public:
3418 Timer() : timer_(nullptr)
3419 {
3420 }
3421
3428 Timer(lv_timer_cb_t cb, uint32_t period_ms, void *user_data = nullptr)
3429 : timer_(lv_timer_create(cb, period_ms, user_data))
3430 {
3431 }
3432
3433 ~Timer() noexcept
3434 {
3435 if (timer_)
3436 lv_timer_delete(timer_);
3437 }
3438
3439 Timer(const Timer &) = delete;
3440 Timer &operator=(const Timer &) = delete;
3441
3443 Timer(Timer &&other) noexcept : timer_(other.timer_)
3444 {
3445 other.timer_ = nullptr;
3446 }
3447
3449 Timer &operator=(Timer &&other) noexcept
3450 {
3451 if (this != &other) {
3452 if (timer_)
3453 lv_timer_delete(timer_);
3454 timer_ = other.timer_;
3455 other.timer_ = nullptr;
3456 }
3457 return *this;
3458 }
3459
3461 lv_timer_t *get() const
3462 {
3463 return timer_;
3464 }
3465
3467 explicit operator bool() const
3468 {
3469 return timer_ != nullptr;
3470 }
3471
3473 Timer &period(uint32_t ms)
3474 {
3475 if (timer_)
3476 lv_timer_set_period(timer_, ms);
3477 return *this;
3478 }
3479
3482 {
3483 if (timer_)
3484 lv_timer_pause(timer_);
3485 return *this;
3486 }
3487
3490 {
3491 if (timer_)
3492 lv_timer_resume(timer_);
3493 return *this;
3494 }
3495
3500 Timer &repeat_count(int32_t count)
3501 {
3502 if (timer_)
3503 lv_timer_set_repeat_count(timer_, count);
3504 return *this;
3505 }
3506
3509 {
3510 if (timer_)
3511 lv_timer_reset(timer_);
3512 return *this;
3513 }
3514
3517 {
3518 if (timer_)
3519 lv_timer_ready(timer_);
3520 return *this;
3521 }
3522
3523 private:
3524 lv_timer_t *timer_;
3525};
3526
3527/* ================================================================== */
3528/* Animation — builder for lv_anim_t */
3529/* ================================================================== */
3530
3547{
3548 public:
3549 Animation()
3550 {
3551 lv_anim_init(&anim_);
3552 }
3553
3555 Animation &target(void *var)
3556 {
3557 lv_anim_set_var(&anim_, var);
3558 return *this;
3559 }
3560
3563 {
3564 return target(obj.get());
3565 }
3566
3568 Animation &values(int32_t from, int32_t to)
3569 {
3570 lv_anim_set_values(&anim_, from, to);
3571 return *this;
3572 }
3573
3575 Animation &duration(uint32_t ms)
3576 {
3577 lv_anim_set_duration(&anim_, ms);
3578 return *this;
3579 }
3580
3582 Animation &delay(uint32_t ms)
3583 {
3584 lv_anim_set_delay(&anim_, ms);
3585 return *this;
3586 }
3587
3589 Animation &path(lv_anim_path_cb_t cb)
3590 {
3591 lv_anim_set_path_cb(&anim_, cb);
3592 return *this;
3593 }
3594
3596 Animation &repeat_count(uint32_t count)
3597 {
3598 lv_anim_set_repeat_count(&anim_, count);
3599 return *this;
3600 }
3601
3604 {
3605 lv_anim_set_repeat_delay(&anim_, ms);
3606 return *this;
3607 }
3608
3611 {
3612 lv_anim_set_playback_duration(&anim_, ms);
3613 return *this;
3614 }
3615
3618 {
3619 lv_anim_set_playback_delay(&anim_, ms);
3620 return *this;
3621 }
3622
3627 Animation &exec_cb(lv_anim_exec_xcb_t cb)
3628 {
3629 lv_anim_set_exec_cb(&anim_, cb);
3630 return *this;
3631 }
3632
3634 Animation &ready_cb(lv_anim_ready_cb_t cb)
3635 {
3636 lv_anim_set_ready_cb(&anim_, cb);
3637 return *this;
3638 }
3639
3644 void start()
3645 {
3646 lv_anim_start(&anim_);
3647 }
3648
3650 static bool stop(void *var, lv_anim_exec_xcb_t exec_cb)
3651 {
3652 return lv_anim_delete(var, exec_cb);
3653 }
3654
3656 static uint32_t duration_for_speed(uint32_t speed)
3657 {
3658 return lv_anim_speed(speed);
3659 }
3660
3661 private:
3662 lv_anim_t anim_;
3663};
3664
3666inline void animate_x(ObjectView obj, int32_t to, uint32_t duration_ms)
3667{
3668 Animation()
3669 .target(obj)
3670 .values(lv_obj_get_x(obj), to)
3671 .duration(duration_ms)
3672 .path(lv_anim_path_ease_out)
3673 .exec_cb(reinterpret_cast<lv_anim_exec_xcb_t>(lv_obj_set_x))
3674 .start();
3675}
3676
3678inline void animate_y(ObjectView obj, int32_t to, uint32_t duration_ms)
3679{
3680 Animation()
3681 .target(obj)
3682 .values(lv_obj_get_y(obj), to)
3683 .duration(duration_ms)
3684 .path(lv_anim_path_ease_out)
3685 .exec_cb(reinterpret_cast<lv_anim_exec_xcb_t>(lv_obj_set_y))
3686 .start();
3687}
3688
3690inline void animate_width(ObjectView obj, int32_t to, uint32_t duration_ms)
3691{
3692 Animation()
3693 .target(obj)
3694 .values(lv_obj_get_width(obj), to)
3695 .duration(duration_ms)
3696 .path(lv_anim_path_ease_out)
3697 .exec_cb(reinterpret_cast<lv_anim_exec_xcb_t>(lv_obj_set_width))
3698 .start();
3699}
3700
3701namespace detail
3702{
3703inline void anim_set_opa_shim(void *var, int32_t v)
3704{
3705 lv_obj_set_style_opa(static_cast<lv_obj_t *>(var), static_cast<lv_opa_t>(v), LV_PART_MAIN);
3706}
3707} // namespace detail
3708
3710inline void animate_opa(ObjectView obj, lv_opa_t to, uint32_t duration_ms)
3711{
3712 lv_opa_t from = lv_obj_get_style_opa(obj, LV_PART_MAIN);
3713 Animation()
3714 .target(obj)
3715 .values(from, to)
3716 .duration(duration_ms)
3717 .path(lv_anim_path_ease_in_out)
3718 .exec_cb(detail::anim_set_opa_shim)
3719 .start();
3720}
3721
3722/* ================================================================== */
3723/* Component<Derived> — CRTP UI composition base */
3724/* ================================================================== */
3725
3747template <typename Derived> class Component
3748{
3749 public:
3751 Component() = default;
3752 ~Component() = default;
3753
3754 Component(const Component &) = delete;
3755 Component &operator=(const Component &) = delete;
3756
3767 void mount(ObjectView parent)
3768 {
3769 if (root_)
3770 return;
3771 root_ = static_cast<Derived *>(this)->build(parent);
3772 /* Store 'this' in root's user data for from_event() */
3773 lv_obj_set_user_data(root_.get(), this);
3774 /* Track external deletion (e.g. screen auto_del) */
3775 lv_obj_add_event_cb(root_.get(), delete_cb, LV_EVENT_DELETE, this);
3776 }
3777
3785 void unmount()
3786 {
3787 if (!root_)
3788 return;
3789 /* Remove the delete callback before we delete, to avoid
3790 * the callback nulling root_ and then us using it. */
3791 lv_obj_t *obj = root_.get();
3792 root_ = ObjectView();
3793 lv_obj_delete(obj);
3794 }
3795
3800 bool is_mounted() const
3801 {
3802 return static_cast<bool>(root_);
3803 }
3804
3810 {
3811 return root_;
3812 }
3813
3817 void hide()
3818 {
3819 if (root_)
3820 lv_obj_add_flag(root_.get(), LV_OBJ_FLAG_HIDDEN);
3821 }
3822
3826 void show()
3827 {
3828 if (root_)
3829 lv_obj_remove_flag(root_.get(), LV_OBJ_FLAG_HIDDEN);
3830 }
3831
3842 static Derived *from_event(lv_event_t *e)
3843 {
3844 lv_obj_t *target = static_cast<lv_obj_t *>(lv_event_get_target(e));
3845 while (target) {
3846 void *ud = lv_obj_get_user_data(target);
3847 if (ud)
3848 return static_cast<Derived *>(static_cast<Component *>(ud));
3849 target = lv_obj_get_parent(target);
3850 }
3851 return nullptr;
3852 }
3853
3854 protected:
3857
3858 private:
3864 static void delete_cb(lv_event_t *e)
3865 {
3866 auto *self = static_cast<Component *>(lv_event_get_user_data(e));
3867 /* Object is being deleted externally — just clear our ref */
3868 self->root_ = ObjectView();
3869 }
3870};
3871
3872/* ================================================================== */
3873/* Display info + top layer helpers */
3874/* ================================================================== */
3875
3877inline int32_t display_width()
3878{
3879 return lv_display_get_horizontal_resolution(nullptr);
3880}
3881
3883inline int32_t display_height()
3884{
3885 return lv_display_get_vertical_resolution(nullptr);
3886}
3887
3889inline int32_t display_dpi()
3890{
3891 return lv_display_get_dpi(nullptr);
3892}
3893
3896{
3897 return ObjectView(lv_layer_top());
3898}
3899
/* end of ove_lvgl_animation */
3901
3902} /* namespace ove::lvgl */
RAII wrapper around an oveRTOS software timer.
Definition timer.hpp:49
Fluent builder for LVGL animations (lv_anim_t).
Definition lvgl.hpp:3547
Animation & target(ObjectView obj)
Sets the target as an LVGL object.
Definition lvgl.hpp:3562
Animation & playback_duration(uint32_t ms)
Sets the duration of the playback (reverse) phase.
Definition lvgl.hpp:3610
Animation & exec_cb(lv_anim_exec_xcb_t cb)
Sets the exec callback invoked on every frame.
Definition lvgl.hpp:3627
Animation & path(lv_anim_path_cb_t cb)
Sets the easing curve. Use lv_anim_path_linear, _ease_out, etc.
Definition lvgl.hpp:3589
Animation & values(int32_t from, int32_t to)
Sets the start and end values.
Definition lvgl.hpp:3568
Animation & repeat_delay(uint32_t ms)
Sets the delay between repeats.
Definition lvgl.hpp:3603
Animation & playback_delay(uint32_t ms)
Sets the delay before the playback phase.
Definition lvgl.hpp:3617
Animation & duration(uint32_t ms)
Sets the animation duration in milliseconds.
Definition lvgl.hpp:3575
Animation & target(void *var)
Sets the target variable pointer (typically an lv_obj_t *).
Definition lvgl.hpp:3555
Animation & repeat_count(uint32_t count)
Sets the repeat count; use LV_ANIM_REPEAT_INFINITE for endless.
Definition lvgl.hpp:3596
static uint32_t duration_for_speed(uint32_t speed)
Computes the duration (ms) needed to animate at the given speed.
Definition lvgl.hpp:3656
void start()
Starts the animation. LVGL copies the state into its internal list, so this Animation can be destruct...
Definition lvgl.hpp:3644
Animation & ready_cb(lv_anim_ready_cb_t cb)
Sets the ready callback invoked when the animation finishes.
Definition lvgl.hpp:3634
static bool stop(void *var, lv_anim_exec_xcb_t exec_cb)
Stops any animations matching (var, exec_cb).
Definition lvgl.hpp:3650
Animation & delay(uint32_t ms)
Sets the delay before the animation starts, in milliseconds.
Definition lvgl.hpp:3582
C++ wrapper for an LVGL arc widget (circular slider / gauge).
Definition lvgl.hpp:1853
Arc & range(int32_t min, int32_t max)
Sets the min/max range.
Definition lvgl.hpp:1874
Arc & track_color(lv_color_t c)
Sets the track arc colour (LV_PART_MAIN).
Definition lvgl.hpp:1908
Arc(lv_obj_t *obj)
Wraps an existing LVGL arc object (non-owning).
Definition lvgl.hpp:1856
Arc & indicator_color(lv_color_t c)
Sets the indicator arc colour (LV_PART_INDICATOR).
Definition lvgl.hpp:1915
int32_t get_value() const
Returns the current value.
Definition lvgl.hpp:1902
Arc & indicator_width(int32_t w)
Sets the indicator arc width (LV_PART_INDICATOR).
Definition lvgl.hpp:1922
static Arc create(ObjectView parent)
Creates a new arc as a child of parent.
Definition lvgl.hpp:1861
Arc & bg_angles(uint32_t start, uint32_t end)
Sets the background arc start/end angles in degrees.
Definition lvgl.hpp:1881
Arc & rotation(uint32_t rot)
Sets the rotation offset of the arc in degrees.
Definition lvgl.hpp:1895
Arc & angles(uint32_t start, uint32_t end)
Sets the foreground indicator start/end angles in degrees.
Definition lvgl.hpp:1888
Arc & value(int32_t val)
Sets the current value.
Definition lvgl.hpp:1867
Arc & knob_color(lv_color_t c)
Sets the knob colour (LV_PART_KNOB).
Definition lvgl.hpp:1929
C++ wrapper for an LVGL progress-bar widget.
Definition lvgl.hpp:1491
static Bar create(ObjectView parent)
Factory method — creates a new LVGL bar as a child of parent.
Definition lvgl.hpp:1506
Bar & range(int32_t min, int32_t max)
Sets the minimum and maximum values for the bar.
Definition lvgl.hpp:1540
Bar & indicator_color(lv_color_t c)
Sets the background color of the indicator (filled) part.
Definition lvgl.hpp:1551
Bar & bar_color(lv_color_t c)
Sets the background color of the bar track (unfilled) part.
Definition lvgl.hpp:1562
Bar & value(int32_t val)
Sets the current value of the bar with animation enabled.
Definition lvgl.hpp:1516
Bar(lv_obj_t *obj)
Constructs a Bar wrapping an existing LVGL bar object.
Definition lvgl.hpp:1497
Bar & value(int32_t val, lv_anim_enable_t anim)
Sets the current value of the bar with explicit animation control.
Definition lvgl.hpp:1528
C++ wrapper for a generic LVGL container object with scrolling disabled.
Definition lvgl.hpp:1590
static Box create(ObjectView parent)
Factory method — creates a new LVGL container with scrolling disabled.
Definition lvgl.hpp:1605
Box(lv_obj_t *obj)
Constructs a Box wrapping an existing LVGL object.
Definition lvgl.hpp:1596
C++ wrapper for an LVGL button widget.
Definition lvgl.hpp:1627
Button & checked(bool v)
Sets the checked state explicitly.
Definition lvgl.hpp:1654
Button(lv_obj_t *obj)
Wraps an existing LVGL button object (non-owning).
Definition lvgl.hpp:1630
bool is_checked() const
Returns true if the button is currently in the checked state.
Definition lvgl.hpp:1664
Button & toggle_mode(bool on)
Enables or disables toggle (checkable) behaviour.
Definition lvgl.hpp:1644
static Button create(ObjectView parent)
Creates a new button as a child of parent.
Definition lvgl.hpp:1635
C++ wrapper for LVGL's month-grid date picker.
Definition lvgl.hpp:3078
Calendar & today(uint32_t year, uint32_t month, uint32_t day)
Sets today's date (highlighted in the grid).
Definition lvgl.hpp:3092
ObjectView add_header_dropdown()
Adds a dropdown-header navigation bar as a child.
Definition lvgl.hpp:3126
bool get_pressed_date(lv_calendar_date_t *out) const
Returns the last date the user pressed in the grid.
Definition lvgl.hpp:3114
static Calendar create(ObjectView parent)
Creates a new calendar as a child of parent.
Definition lvgl.hpp:3086
ObjectView add_header_arrow()
Adds an arrow-header navigation bar as a child.
Definition lvgl.hpp:3120
Calendar & showed(uint32_t year, uint32_t month)
Sets the currently visible month (year/month).
Definition lvgl.hpp:3099
Calendar & highlighted_dates(lv_calendar_date_t *dates, size_t count)
Highlights a list of dates with a visual accent. LVGL retains the pointer — the array must outlive th...
Definition lvgl.hpp:3107
Calendar(lv_obj_t *obj)
Wraps an existing LVGL calendar object (non-owning).
Definition lvgl.hpp:3081
C++ wrapper for LVGL's user-buffer drawing surface.
Definition lvgl.hpp:3008
Canvas & buffer(void *buf, int32_t w, int32_t h, lv_color_format_t cf)
Attaches a pixel buffer of the given geometry and format.
Definition lvgl.hpp:3022
Canvas & init_layer(lv_layer_t *layer)
Begins a draw sequence on the canvas layer.
Definition lvgl.hpp:3049
Canvas & set_pixel(int32_t x, int32_t y, lv_color_t color)
Sets a single pixel to the given colour.
Definition lvgl.hpp:3036
Canvas(lv_obj_t *obj)
Wraps an existing LVGL canvas object (non-owning).
Definition lvgl.hpp:3011
static Canvas create(ObjectView parent)
Creates a new canvas as a child of parent.
Definition lvgl.hpp:3016
Canvas & finish_layer(lv_layer_t *layer)
Finishes a draw sequence started by init_layer().
Definition lvgl.hpp:3056
Canvas & fill_bg(lv_color_t color, lv_opa_t opa)
Fills the entire canvas with a solid color + opacity.
Definition lvgl.hpp:3029
Lightweight handle to an lv_chart_series_t *.
Definition lvgl.hpp:2681
lv_chart_series_t * get() const
Returns the underlying lv_chart_series_t *.
Definition lvgl.hpp:2692
Series(lv_obj_t *chart, lv_chart_series_t *ser)
Binds the handle to an existing chart + series pointer pair.
Definition lvgl.hpp:2687
Series & next_value(int32_t v)
Pushes a new value using the current update mode.
Definition lvgl.hpp:2703
Series & set_value_by_idx(uint32_t idx, int32_t v)
Sets a specific point index to v.
Definition lvgl.hpp:2710
C++ wrapper for an LVGL chart (line / bar / scatter).
Definition lvgl.hpp:2677
Chart(lv_obj_t *obj)
Wraps an existing LVGL chart object (non-owning).
Definition lvgl.hpp:2722
Chart & remove_series(Series s)
Removes a series from the chart.
Definition lvgl.hpp:2775
Chart & update_mode(lv_chart_update_mode_t mode)
Sets how next_value() updates the point array.
Definition lvgl.hpp:2754
Chart & range(lv_chart_axis_t axis, int32_t min, int32_t max)
Sets the min/max range for the given axis.
Definition lvgl.hpp:2747
static Chart create(ObjectView parent)
Creates a new chart as a child of parent.
Definition lvgl.hpp:2727
Series add_series(lv_color_t color, lv_chart_axis_t axis)
Adds a new series with the given colour and axis binding.
Definition lvgl.hpp:2768
Chart & point_count(uint32_t count)
Sets the number of data points per series.
Definition lvgl.hpp:2740
Chart & type(lv_chart_type_t t)
Sets the chart type (line / bar / scatter / none).
Definition lvgl.hpp:2733
Chart & div_line_count(uint8_t hdiv, uint8_t vdiv)
Sets the horizontal/vertical division line count.
Definition lvgl.hpp:2761
C++ wrapper for an LVGL checkbox (labelled binary toggle).
Definition lvgl.hpp:1794
Checkbox & text(const char *txt)
Sets the label text (copies into LVGL-owned memory).
Definition lvgl.hpp:1808
Checkbox & text_static(const char *txt)
Sets the label text from a persistent static string (no copy).
Definition lvgl.hpp:1815
bool is_checked() const
Returns true if the checkbox is ticked.
Definition lvgl.hpp:1832
Checkbox(lv_obj_t *obj)
Wraps an existing LVGL checkbox object (non-owning).
Definition lvgl.hpp:1797
static Checkbox create(ObjectView parent)
Creates a new checkbox as a child of parent.
Definition lvgl.hpp:1802
Checkbox & checked(bool v)
Sets the checked state.
Definition lvgl.hpp:1822
CRTP base class for reusable, self-contained LVGL UI components.
Definition lvgl.hpp:3748
bool is_mounted() const
Returns true if the component is currently mounted.
Definition lvgl.hpp:3800
void mount(ObjectView parent)
Builds and mounts the component under the given parent.
Definition lvgl.hpp:3767
Component()=default
Default constructor — component starts in the unmounted state.
void show()
Shows the component's root widget if mounted.
Definition lvgl.hpp:3826
ObjectView root_
Non-owning view of the component's root LVGL widget.
Definition lvgl.hpp:3856
void unmount()
Unmounts and deletes the component's widget subtree.
Definition lvgl.hpp:3785
static Derived * from_event(lv_event_t *e)
Walks up the LVGL object tree from the event target to find the Derived component instance.
Definition lvgl.hpp:3842
void hide()
Hides the component's root widget if mounted.
Definition lvgl.hpp:3817
ObjectView root() const
Returns an ObjectView of the component's root widget.
Definition lvgl.hpp:3809
C++ wrapper for an LVGL click-to-open dropdown list.
Definition lvgl.hpp:2327
Dropdown & selected(uint32_t sel)
Sets the currently selected option index.
Definition lvgl.hpp:2369
Dropdown & options_static(const char *opts)
Sets options from a persistent \n-separated string (no copy).
Definition lvgl.hpp:2348
void open()
Expands the popup list.
Definition lvgl.hpp:2420
Dropdown & add_option(const char *opt, uint32_t pos)
Inserts a single option at pos.
Definition lvgl.hpp:2355
Dropdown(lv_obj_t *obj)
Wraps an existing LVGL dropdown object (non-owning).
Definition lvgl.hpp:2330
void get_selected_str(char *buf, uint32_t size) const
Fills buf with the currently selected option text.
Definition lvgl.hpp:2402
Dropdown & dir(lv_dir_t d)
Sets the popup direction.
Definition lvgl.hpp:2376
const char * get_options() const
Returns the entire option list as a \n-separated string.
Definition lvgl.hpp:2408
bool is_open() const
Returns true if the popup list is currently expanded.
Definition lvgl.hpp:2414
void close()
Collapses the popup list.
Definition lvgl.hpp:2426
Dropdown & options(const char *opts)
Sets options from a \n-separated string (LVGL copies it).
Definition lvgl.hpp:2341
uint32_t get_selected() const
Returns the currently selected option index.
Definition lvgl.hpp:2390
uint32_t get_option_count() const
Returns the total option count.
Definition lvgl.hpp:2396
Dropdown & clear_options()
Clears the entire option list.
Definition lvgl.hpp:2362
Dropdown & symbol(const void *sym)
Sets the dropdown-arrow icon (image dsc or symbol string).
Definition lvgl.hpp:2383
static Dropdown create(ObjectView parent)
Creates a new dropdown as a child of parent.
Definition lvgl.hpp:2335
CRTP mixin that adds type-safe LVGL event registration to widget classes.
Definition lvgl.hpp:616
Derived & on_click(F &&fn)
Registers a stateless click callback (shorthand for on(LV_EVENT_CLICKED, fn)).
Definition lvgl.hpp:666
Derived & on_value_changed(F &&fn)
Registers a stateless value-changed callback (shorthand for on(LV_EVENT_VALUE_CHANGED,...
Definition lvgl.hpp:689
Derived & on_click(T *instance)
Registers a member function click callback.
Definition lvgl.hpp:678
Derived & on(lv_event_code_t code, F &&fn)
Registers a stateless callback for the given event code.
Definition lvgl.hpp:629
Derived & on_value_changed(T *instance)
Registers a member function value-changed callback.
Definition lvgl.hpp:701
Derived & on(lv_event_code_t code, T *instance)
Registers a member function pointer as an event callback — minimal-overhead trampoline.
Definition lvgl.hpp:648
RAII wrapper for an LVGL input focus group (lv_group_t).
Definition lvgl.hpp:3186
static Group create()
Creates a fresh focus group.
Definition lvgl.hpp:3224
Group & operator=(Group &&other) noexcept
Move-assignment — releases current group, then takes other's.
Definition lvgl.hpp:3212
ObjectView focused() const
Returns the currently focused widget, or a null view.
Definition lvgl.hpp:3285
Group & remove_all()
Removes all widgets from this group.
Definition lvgl.hpp:3257
Group & edit_mode(bool enable)
Enables/disables edit mode (relevant for encoder input).
Definition lvgl.hpp:3291
Group & set_as_default()
Marks this group as the default — new focusable widgets will auto-join it at creation time.
Definition lvgl.hpp:3243
static lv_group_t * get_default()
Returns the default group (set via set_as_default()).
Definition lvgl.hpp:3230
bool is_editing() const
Returns the current edit-mode flag.
Definition lvgl.hpp:3298
Group & focus_freeze(bool freeze)
Freezes/unfreezes focus movement.
Definition lvgl.hpp:3278
Group & add(ObjectView obj)
Adds a widget to the group's focusable list.
Definition lvgl.hpp:3250
lv_group_t * get() const
Raw lv_group_t * for FFI interop.
Definition lvgl.hpp:3236
Group(Group &&other) noexcept
Move constructor — transfers ownership; source becomes empty.
Definition lvgl.hpp:3206
static void focus_obj(ObjectView obj)
Static helper: focus a specific widget regardless of its group membership.
Definition lvgl.hpp:3311
Group & focus_next()
Moves focus to the next member.
Definition lvgl.hpp:3264
uint32_t obj_count() const
Returns the number of widgets in the group.
Definition lvgl.hpp:3304
Group(lv_group_t *g)
Takes ownership of an existing lv_group_t *.
Definition lvgl.hpp:3192
Group & focus_prev()
Moves focus to the previous member.
Definition lvgl.hpp:3271
static void remove_obj(ObjectView obj)
Static helper: remove a widget from whatever group it's in.
Definition lvgl.hpp:3317
C++ wrapper for an LVGL image widget.
Definition lvgl.hpp:1950
Image & inner_align(lv_image_align_t align)
Sets how the image is aligned within its own coordinates.
Definition lvgl.hpp:1992
Image(lv_obj_t *obj)
Wraps an existing LVGL image object (non-owning).
Definition lvgl.hpp:1953
static Image create(ObjectView parent)
Creates a new image as a child of parent.
Definition lvgl.hpp:1958
Image & scale(uint32_t zoom)
Sets the zoom factor (256 = 1.0x, 512 = 2.0x).
Definition lvgl.hpp:1978
Image & pivot(int32_t x, int32_t y)
Sets the rotation/scale pivot point.
Definition lvgl.hpp:1985
Image & rotation(int32_t angle)
Sets the rotation angle in 0.1 degree units (0–3600).
Definition lvgl.hpp:1971
Image & src(const void *src)
Sets the image source (descriptor, symbol, or path).
Definition lvgl.hpp:1964
C++ wrapper for LVGL's on-screen keyboard.
Definition lvgl.hpp:2619
Keyboard & attach(Textarea ta)
Attaches to a Textarea so typed keys flow to it.
Definition lvgl.hpp:2633
Keyboard & mode(lv_keyboard_mode_t m)
Switches keyboard mode (lowercase/upper/special/number).
Definition lvgl.hpp:2640
ObjectView get_textarea() const
Returns the currently attached Textarea, or a null view.
Definition lvgl.hpp:2654
Keyboard(lv_obj_t *obj)
Wraps an existing LVGL keyboard object (non-owning).
Definition lvgl.hpp:2622
Keyboard & popovers(bool en)
Enables or disables on-press popovers for letter keys.
Definition lvgl.hpp:2647
static Keyboard create(ObjectView parent)
Creates a new keyboard as a child of parent.
Definition lvgl.hpp:2627
C++ wrapper for an LVGL label widget.
Definition lvgl.hpp:1348
Label & font(const lv_font_t *f)
Sets the font used to render the label text.
Definition lvgl.hpp:1421
Label & color(lv_color_t c)
Sets the text color.
Definition lvgl.hpp:1432
Label & text(const char *txt)
Sets the label text by copying the string (LVGL allocates internally).
Definition lvgl.hpp:1373
Label & long_mode(lv_label_long_mode_t mode)
Sets the long-text mode (wrap, scroll, clip, etc.).
Definition lvgl.hpp:1443
Label(lv_obj_t *obj)
Constructs a Label wrapping an existing LVGL label object.
Definition lvgl.hpp:1354
Label & text_fmt(const char *fmt,...)
Sets the label text using a printf-style format string.
Definition lvgl.hpp:1404
static Label create(ObjectView parent)
Factory method — creates a new LVGL label as a child of parent.
Definition lvgl.hpp:1363
Label & text_static(const char *txt)
Sets the label text to a static string (no copy — pointer must remain valid).
Definition lvgl.hpp:1388
C++ wrapper for LVGL's LED widget — a colored indicator circle.
Definition lvgl.hpp:2130
uint8_t get_brightness() const
Returns the current brightness.
Definition lvgl.hpp:2179
Led & brightness(uint8_t bright)
Sets the LED brightness (0–255).
Definition lvgl.hpp:2151
Led(lv_obj_t *obj)
Wraps an existing LVGL LED object (non-owning).
Definition lvgl.hpp:2133
Led & on()
Turns the LED on (full brightness).
Definition lvgl.hpp:2158
Led & color(lv_color_t c)
Sets the LED base colour.
Definition lvgl.hpp:2144
Led & toggle()
Toggles between on/off.
Definition lvgl.hpp:2172
Led & off()
Turns the LED off.
Definition lvgl.hpp:2165
static Led create(ObjectView parent)
Creates a new LED as a child of parent.
Definition lvgl.hpp:2138
C++ wrapper for LVGL's scrollable list of buttons/text.
Definition lvgl.hpp:2957
const char * get_button_text(ObjectView btn) const
Returns the text of a list button.
Definition lvgl.hpp:2983
ObjectView add_text(const char *text)
Adds a text heading row. Returns the label object.
Definition lvgl.hpp:2971
static List create(ObjectView parent)
Creates a new list as a child of parent.
Definition lvgl.hpp:2965
ObjectView add_button(const void *icon, const char *text)
Adds a button row with icon and text. Returns the button.
Definition lvgl.hpp:2977
List(lv_obj_t *obj)
Wraps an existing LVGL list object (non-owning).
Definition lvgl.hpp:2960
RAII scoped lock for thread-safe access to the LVGL rendering context.
Definition lvgl.hpp:92
LvglGuard()
Acquires the LVGL lock, blocking until it is available.
Definition lvgl.hpp:97
~LvglGuard() noexcept
Releases the LVGL lock.
Definition lvgl.hpp:105
C++ wrapper for an LVGL message-box (modal dialog).
Definition lvgl.hpp:2014
ObjectView get_header() const
Returns the header container.
Definition lvgl.hpp:2064
void close()
Closes and deletes the msgbox.
Definition lvgl.hpp:2076
ObjectView get_footer() const
Returns the footer container.
Definition lvgl.hpp:2070
Msgbox & add_text(const char *txt)
Adds body text. Chainable — returns *this.
Definition lvgl.hpp:2036
ObjectView get_content() const
Returns the content container (where body widgets live).
Definition lvgl.hpp:2058
Msgbox(lv_obj_t *obj)
Wraps an existing LVGL msgbox object (non-owning).
Definition lvgl.hpp:2017
ObjectView add_footer_button(const char *txt)
Adds a footer button with the given text. Returns an ObjectView wrapping the created button so caller...
Definition lvgl.hpp:2052
Msgbox & add_close_button()
Adds a close (X) button in the header.
Definition lvgl.hpp:2043
static Msgbox create(ObjectView parent)
Creates a new modal msgbox. Passing a null parent centers it on the active screen.
Definition lvgl.hpp:2023
Msgbox & add_title(const char *txt)
Adds a title in the header. Chainable — returns *this.
Definition lvgl.hpp:2029
CRTP mixin that adds fluent layout and visibility setters to widget classes.
Definition lvgl.hpp:281
Derived & hide()
Hides the object by adding LV_OBJ_FLAG_HIDDEN.
Definition lvgl.hpp:356
Derived & user_data(void *data)
Stores an arbitrary user data pointer on the LVGL object.
Definition lvgl.hpp:431
Derived & show()
Shows the object by removing LV_OBJ_FLAG_HIDDEN.
Definition lvgl.hpp:366
Derived & height(int32_t h)
Sets the height of the object.
Definition lvgl.hpp:311
Derived & clickable(bool on)
Enables or disables click events on the object.
Definition lvgl.hpp:442
Derived & width(int32_t w)
Sets the width of the object.
Definition lvgl.hpp:300
Derived & size(int32_t w, int32_t h)
Sets both width and height of the object.
Definition lvgl.hpp:289
int32_t get_content_width() const
Definition lvgl.hpp:523
Derived & remove_style_all()
Definition lvgl.hpp:537
Derived & align(lv_align_t a, int32_t x_ofs=0, int32_t y_ofs=0)
Aligns the object to an anchor with an optional offset.
Definition lvgl.hpp:346
Derived & add_state(lv_state_t s)
Adds one or more object states.
Definition lvgl.hpp:409
Derived & visible(bool v)
Conditionally shows or hides the object.
Definition lvgl.hpp:377
Derived & flex_grow(uint8_t grow)
Set this child's flex grow factor (0 disables growing).
Definition lvgl.hpp:489
Derived & scroll_to_y(int32_t y, bool anim)
Scroll the object so y is visible. anim enables animated scrolling.
Definition lvgl.hpp:507
Derived & pos(int32_t x, int32_t y)
Sets the position of the object relative to its parent.
Definition lvgl.hpp:323
Derived & flex_align(lv_flex_align_t main, lv_flex_align_t cross, lv_flex_align_t track)
Set flex alignment for main axis, cross axis (items), and cross axis (tracks).
Definition lvgl.hpp:480
Derived & grid_cell(lv_grid_align_t col_align, int32_t col_pos, int32_t col_span, lv_grid_align_t row_align, int32_t row_pos, int32_t row_span)
Places this object into a cell of its parent grid.
Definition lvgl.hpp:553
Derived & center()
Centers the object within its parent.
Definition lvgl.hpp:333
Derived & remove_flag(lv_obj_flag_t f)
Removes one or more object flags.
Definition lvgl.hpp:398
int32_t get_scroll_bottom() const
Definition lvgl.hpp:530
Derived & update_layout()
Force a layout recomputation (needed before get_content_width/get_scroll_bottom).
Definition lvgl.hpp:516
Derived & add_flag(lv_obj_flag_t f)
Adds one or more object flags.
Definition lvgl.hpp:387
Derived & remove_state(lv_state_t s)
Removes one or more object states.
Definition lvgl.hpp:420
Derived & grid_dsc(const int32_t *cols, const int32_t *rows)
Configures this object as a grid container.
Definition lvgl.hpp:462
Derived & flex_flow(lv_flex_flow_t flow)
Configure this object as a flex container with the given flow.
Definition lvgl.hpp:471
Derived & layout(uint32_t kind)
Switch the object's layout engine (None / Flex / Grid).
Definition lvgl.hpp:498
Non-owning, pointer-sized wrapper around an lv_obj_t*.
Definition lvgl.hpp:135
ObjectView(lv_obj_t *obj)
Constructs an ObjectView wrapping the given lv_obj_t*.
Definition lvgl.hpp:148
uint32_t child_count() const
Returns the number of direct children of this object.
Definition lvgl.hpp:192
void clean()
Deletes all children of this object without deleting the object itself.
Definition lvgl.hpp:239
static ObjectView screen_active()
Returns an ObjectView wrapping the currently active screen.
Definition lvgl.hpp:248
int32_t get_width() const
Returns the current rendered width of this object.
Definition lvgl.hpp:211
int32_t get_height() const
Returns the current rendered height of this object.
Definition lvgl.hpp:220
ObjectView get_child(int32_t idx) const
Returns an ObjectView wrapping the child at the given index.
Definition lvgl.hpp:202
lv_obj_t * get() const
Returns the raw lv_obj_t* pointer.
Definition lvgl.hpp:156
ObjectView()
Constructs a null ObjectView (no associated LVGL object).
Definition lvgl.hpp:140
lv_obj_t * obj_
Raw pointer to the wrapped LVGL object.
Definition lvgl.hpp:255
void del()
Deletes the LVGL object and all its children, then nulls the pointer.
Definition lvgl.hpp:230
ObjectView parent() const
Returns an ObjectView wrapping the parent of this object.
Definition lvgl.hpp:183
C++ wrapper for LVGL's iOS-picker-style scrollable option wheel.
Definition lvgl.hpp:2446
Roller & options(const char *opts, lv_roller_mode_t mode=LV_ROLLER_MODE_NORMAL)
Sets options (newline-separated) and scroll mode.
Definition lvgl.hpp:2460
Roller & selected(uint32_t sel, lv_anim_enable_t anim=LV_ANIM_OFF)
Sets the currently selected option index.
Definition lvgl.hpp:2467
const char * get_options() const
Returns the entire option list as a \n-separated string.
Definition lvgl.hpp:2499
static Roller create(ObjectView parent)
Creates a new roller as a child of parent.
Definition lvgl.hpp:2454
void get_selected_str(char *buf, uint32_t size) const
Fills buf with the currently selected option text.
Definition lvgl.hpp:2493
Roller & visible_row_count(uint32_t rows)
Sets how many rows are visible in the wheel at once.
Definition lvgl.hpp:2474
Roller(lv_obj_t *obj)
Wraps an existing LVGL roller object (non-owning).
Definition lvgl.hpp:2449
uint32_t get_option_count() const
Returns the total option count.
Definition lvgl.hpp:2487
uint32_t get_selected() const
Returns the currently selected option index.
Definition lvgl.hpp:2481
Top-level LVGL screen — a display root without a parent.
Definition lvgl.hpp:3347
Screen(lv_obj_t *obj)
Wraps an existing LVGL screen object (non-owning).
Definition lvgl.hpp:3350
void load_anim(lv_screen_load_anim_t anim, uint32_t time_ms, uint32_t delay_ms=0, bool auto_del=false)
Loads this screen with an animated transition.
Definition lvgl.hpp:3381
static Screen create()
Creates a new top-level screen with no parent.
Definition lvgl.hpp:3355
static Screen active()
Returns the currently active screen.
Definition lvgl.hpp:3361
void load()
Instantly loads this screen as the active one.
Definition lvgl.hpp:3367
C++ wrapper for an LVGL slider widget (interactive bar).
Definition lvgl.hpp:1683
int32_t get_value() const
Returns the current value.
Definition lvgl.hpp:1718
Slider & value(int32_t val, lv_anim_enable_t anim)
Sets the current value with explicit animation control.
Definition lvgl.hpp:1704
static Slider create(ObjectView parent)
Creates a new slider as a child of parent.
Definition lvgl.hpp:1691
Slider & indicator_color(lv_color_t c)
Sets the filled indicator colour (LV_PART_INDICATOR).
Definition lvgl.hpp:1724
Slider & knob_color(lv_color_t c)
Sets the knob colour (LV_PART_KNOB).
Definition lvgl.hpp:1731
Slider(lv_obj_t *obj)
Wraps an existing LVGL slider object (non-owning).
Definition lvgl.hpp:1686
Slider & value(int32_t val)
Sets the current value (animated).
Definition lvgl.hpp:1697
Slider & range(int32_t min, int32_t max)
Sets the min/max range.
Definition lvgl.hpp:1711
C++ wrapper for an LVGL numeric stepper (+ / − buttons).
Definition lvgl.hpp:2519
Spinbox & step(uint32_t s)
Sets the increment/decrement step size.
Definition lvgl.hpp:2547
Spinbox & cursor_pos(uint32_t pos)
Sets the cursor to edit a specific digit.
Definition lvgl.hpp:2572
Spinbox & digit_format(uint32_t digit_count, uint32_t sep_pos)
Configures how the numeric value is displayed.
Definition lvgl.hpp:2558
int32_t get_step() const
Returns the current step size.
Definition lvgl.hpp:2585
Spinbox & increment()
Increments the value by one step.
Definition lvgl.hpp:2591
Spinbox & decrement()
Decrements the value by one step.
Definition lvgl.hpp:2598
Spinbox(lv_obj_t *obj)
Wraps an existing LVGL spinbox object (non-owning).
Definition lvgl.hpp:2522
Spinbox & value(int32_t v)
Sets the current integer value (scaled by digit_format).
Definition lvgl.hpp:2533
Spinbox & range(int32_t min, int32_t max)
Sets min/max bounds.
Definition lvgl.hpp:2540
Spinbox & rollover(bool on)
Enables wrap-around at min/max bounds.
Definition lvgl.hpp:2565
static Spinbox create(ObjectView parent)
Creates a new spinbox as a child of parent.
Definition lvgl.hpp:2527
int32_t get_value() const
Returns the current integer value.
Definition lvgl.hpp:2579
C++ wrapper for LVGL's circular loading indicator.
Definition lvgl.hpp:2095
Spinner(lv_obj_t *obj)
Wraps an existing LVGL spinner object (non-owning).
Definition lvgl.hpp:2098
Spinner & anim_params(uint32_t time_ms, uint32_t angle_deg)
Sets the animation parameters.
Definition lvgl.hpp:2113
static Spinner create(ObjectView parent)
Creates a new spinner as a child of parent.
Definition lvgl.hpp:2103
CRTP mixin that adds inline per-object style setters to widget classes.
Definition lvgl.hpp:730
Derived & pad_right(int32_t p)
Sets right padding in pixels.
Definition lvgl.hpp:904
Derived & radius(int32_t r)
Sets the corner radius.
Definition lvgl.hpp:805
Derived & pad_gap(int32_t g)
Sets the gap between children in flex/grid layouts.
Definition lvgl.hpp:856
Derived & max_height(int32_t v, lv_style_selector_t part=LV_PART_MAIN)
Sets the maximum height (in pixels) on the given part.
Definition lvgl.hpp:1007
Derived & margin_top(int32_t v, lv_style_selector_t part=LV_PART_MAIN)
Sets top margin (outer spacing) on the given part.
Definition lvgl.hpp:983
Derived & pad_top(int32_t p)
Sets top padding in pixels.
Definition lvgl.hpp:886
Derived & margin_right(int32_t v, lv_style_selector_t part=LV_PART_MAIN)
Sets right margin (outer spacing) on the given part.
Definition lvgl.hpp:1001
Derived & pad_column(int32_t p)
Sets the column gap between children in flex/grid layouts.
Definition lvgl.hpp:916
Derived & margin_bottom(int32_t v, lv_style_selector_t part=LV_PART_MAIN)
Sets bottom margin (outer spacing) on the given part.
Definition lvgl.hpp:989
Derived & pad_left(int32_t p)
Sets left padding in pixels.
Definition lvgl.hpp:898
Derived & pad_hor(int32_t p)
Sets horizontal (left + right) padding.
Definition lvgl.hpp:834
Derived & border_width(int32_t w)
Sets the border width in pixels.
Definition lvgl.hpp:787
Derived & border_color(lv_color_t c, lv_style_selector_t part)
Sets border color on a specific part.
Definition lvgl.hpp:945
Derived & text_font(const lv_font_t *f)
Sets the font used to render text.
Definition lvgl.hpp:878
Derived & pad_all(int32_t p)
Sets uniform padding on all four sides.
Definition lvgl.hpp:823
Derived & bg_color(lv_color_t c)
Sets the background color of the object.
Definition lvgl.hpp:737
Derived & margin_left(int32_t v, lv_style_selector_t part=LV_PART_MAIN)
Sets left margin (outer spacing) on the given part.
Definition lvgl.hpp:995
Derived & pad_row(int32_t p)
Sets the row gap between children in flex/grid layouts.
Definition lvgl.hpp:910
Derived & set_opa(lv_opa_t opa)
Sets the overall object opacity (0–255, or LV_OPA_*).
Definition lvgl.hpp:931
Derived & arc_opa(lv_opa_t opa, lv_style_selector_t part)
Sets arc opacity on a specific part.
Definition lvgl.hpp:963
Derived & bg_opa(lv_opa_t opa, lv_style_selector_t part)
Sets the background opacity on a specific part.
Definition lvgl.hpp:765
Derived & translate_y(int32_t v, lv_style_selector_t part=LV_PART_MAIN)
Sets a vertical translation (post-layout offset) on the given part.
Definition lvgl.hpp:977
Derived & opa_layered(lv_opa_t opa, lv_style_selector_t part=LV_PART_MAIN)
Sets the layered opacity (applied after compositing) on the given part.
Definition lvgl.hpp:1013
Derived & pad_ver(int32_t p)
Sets vertical (top + bottom) padding.
Definition lvgl.hpp:845
Derived & radius(int32_t r, lv_style_selector_t part)
Sets the corner radius on a specific part.
Definition lvgl.hpp:812
Derived & bg_color(lv_color_t c, lv_style_selector_t part)
Sets the background color of a specific part (e.g. LV_PART_INDICATOR, LV_PART_KNOB,...
Definition lvgl.hpp:747
Derived & text_align(uint32_t align, lv_style_selector_t part=LV_PART_MAIN)
Sets the horizontal text alignment on the given part.
Definition lvgl.hpp:924
Derived & border_width(int32_t w, lv_style_selector_t part)
Sets the border width on a specific part.
Definition lvgl.hpp:794
Derived & border_color(lv_color_t c)
Sets the border color.
Definition lvgl.hpp:776
Derived & pad_bottom(int32_t p)
Sets bottom padding in pixels.
Definition lvgl.hpp:892
Derived & arc_color(lv_color_t c, lv_style_selector_t part)
Sets arc color on a specific part.
Definition lvgl.hpp:951
Derived & text_color(lv_color_t c)
Sets the text color.
Definition lvgl.hpp:867
Derived & text_color(lv_color_t c, lv_style_selector_t part)
Sets text color on a specific part.
Definition lvgl.hpp:939
Derived & arc_rounded(bool rounded, lv_style_selector_t part)
Enables/disables rounded arc end caps on a specific part.
Definition lvgl.hpp:969
Derived & arc_width(int32_t w, lv_style_selector_t part)
Sets arc stroke width on a specific part.
Definition lvgl.hpp:957
Derived & bg_opa(lv_opa_t opa)
Sets the background opacity.
Definition lvgl.hpp:758
RAII wrapper around an lv_style_t object.
Definition lvgl.hpp:1049
const lv_style_t * get() const
Returns a const pointer to the underlying lv_style_t.
Definition lvgl.hpp:1107
Style & pad_all(int32_t p)
Sets uniform padding on all four sides.
Definition lvgl.hpp:1172
Style & border_color(lv_color_t c)
Sets the border color.
Definition lvgl.hpp:1150
Style & bg_opa(lv_opa_t opa)
Sets the background opacity.
Definition lvgl.hpp:1128
Style()
Constructs and initialises an empty LVGL style.
Definition lvgl.hpp:1054
Style & operator=(Style &&other) noexcept
Move-assignment operator — transfers the style data and reinitialises the source.
Definition lvgl.hpp:1084
Style & border_width(int32_t w)
Sets the border width in pixels.
Definition lvgl.hpp:1161
Style & bg_color(lv_color_t c)
Sets the background color.
Definition lvgl.hpp:1117
~Style() noexcept
Destroys the style, releasing any resources held by LVGL.
Definition lvgl.hpp:1062
Style & text_color(lv_color_t c)
Sets the text color.
Definition lvgl.hpp:1183
Style & text_font(const lv_font_t *f)
Sets the font used to render text.
Definition lvgl.hpp:1194
lv_style_t * get()
Returns a mutable pointer to the underlying lv_style_t.
Definition lvgl.hpp:1098
Style & radius(int32_t r)
Sets the corner radius.
Definition lvgl.hpp:1139
Style(Style &&other) noexcept
Move constructor — transfers the style data and reinitialises the source.
Definition lvgl.hpp:1074
C++ wrapper for an LVGL switch widget (binary toggle).
Definition lvgl.hpp:1751
bool is_checked() const
Returns true if the switch is on.
Definition lvgl.hpp:1775
Switch(lv_obj_t *obj)
Wraps an existing LVGL switch object (non-owning).
Definition lvgl.hpp:1754
Switch & checked(bool v)
Sets the checked (on) state.
Definition lvgl.hpp:1765
static Switch create(ObjectView parent)
Creates a new switch as a child of parent.
Definition lvgl.hpp:1759
C++ wrapper for LVGL's 2D data table widget.
Definition lvgl.hpp:2795
static Table create(ObjectView parent)
Creates a new table as a child of parent.
Definition lvgl.hpp:2803
uint32_t get_row_count() const
Returns the total row count.
Definition lvgl.hpp:2843
Table & column_width(uint32_t col, int32_t w)
Sets the width of a specific column in pixels.
Definition lvgl.hpp:2830
Table(lv_obj_t *obj)
Wraps an existing LVGL table object (non-owning).
Definition lvgl.hpp:2798
int32_t get_column_width(uint32_t col) const
Returns the width of a specific column in pixels.
Definition lvgl.hpp:2855
Table & row_count(uint32_t n)
Sets the row count (grows/shrinks the table).
Definition lvgl.hpp:2816
Table & column_count(uint32_t n)
Sets the column count.
Definition lvgl.hpp:2823
uint32_t get_column_count() const
Returns the total column count.
Definition lvgl.hpp:2849
Table & cell_value(uint32_t row, uint32_t col, const char *txt)
Sets a cell's text (LVGL copies the string).
Definition lvgl.hpp:2809
const char * get_cell_value(uint32_t row, uint32_t col) const
Returns the text at (row, col).
Definition lvgl.hpp:2837
C++ wrapper for LVGL's tabbed container with swipeable pages.
Definition lvgl.hpp:2874
Tabview & set_active_tab(uint32_t idx, lv_anim_enable_t anim)
Sets the active tab index with optional animation.
Definition lvgl.hpp:2905
uint32_t get_tab_count() const
Returns the number of tabs.
Definition lvgl.hpp:2926
uint32_t get_tab_active() const
Returns the currently active tab index.
Definition lvgl.hpp:2932
ObjectView add_tab(const char *name)
Adds a new tab and returns its content container.
Definition lvgl.hpp:2892
ObjectView get_content() const
Returns the content container (all tabs live here).
Definition lvgl.hpp:2938
Tabview(lv_obj_t *obj)
Wraps an existing LVGL tabview object (non-owning).
Definition lvgl.hpp:2877
Tabview & rename_tab(uint32_t idx, const char *name)
Renames an existing tab.
Definition lvgl.hpp:2898
static Tabview create(ObjectView parent)
Creates a tabview with default bar position/size. Call tab_bar_position() / tab_bar_size() to customi...
Definition lvgl.hpp:2886
Tabview & tab_bar_size(int32_t size)
Sets the tab bar size in pixels.
Definition lvgl.hpp:2919
Tabview & tab_bar_position(lv_dir_t dir)
Sets the tab bar position (TOP/BOTTOM/LEFT/RIGHT).
Definition lvgl.hpp:2912
C++ wrapper for an LVGL text-entry widget.
Definition lvgl.hpp:2199
Textarea & placeholder(const char *txt)
Sets the placeholder shown while the textarea is empty.
Definition lvgl.hpp:2227
static Textarea create(ObjectView parent)
Creates a new textarea as a child of parent.
Definition lvgl.hpp:2207
Textarea & delete_char()
Deletes the character before the cursor.
Definition lvgl.hpp:2307
Textarea & accepted_chars(const char *list)
Restricts input to characters in list; nullptr = any.
Definition lvgl.hpp:2255
uint32_t get_cursor_pos() const
Returns the current cursor position.
Definition lvgl.hpp:2282
Textarea & cursor_pos(int32_t pos)
Moves the cursor to the given character position.
Definition lvgl.hpp:2262
Textarea & one_line(bool en)
Toggles single-line mode (enter fires LV_EVENT_READY).
Definition lvgl.hpp:2234
Textarea(lv_obj_t *obj)
Wraps an existing LVGL textarea object (non-owning).
Definition lvgl.hpp:2202
Textarea & password_mode(bool en)
Enables password masking.
Definition lvgl.hpp:2241
bool is_one_line() const
Returns true if single-line mode is enabled.
Definition lvgl.hpp:2294
Textarea & max_length(uint32_t n)
Sets the maximum character count (0 = unlimited).
Definition lvgl.hpp:2248
Textarea & add_text(const char *txt)
Appends text to the end.
Definition lvgl.hpp:2220
const char * get_text() const
Returns the current text (pointer owned by LVGL).
Definition lvgl.hpp:2276
Textarea & cursor_click_pos(bool en)
Enables moving the cursor by clicking.
Definition lvgl.hpp:2269
bool is_password_mode() const
Returns true if password mode is enabled.
Definition lvgl.hpp:2288
Textarea & text(const char *txt)
Replaces the current text (LVGL copies the string).
Definition lvgl.hpp:2213
Textarea & add_char(uint32_t c)
Appends a single Unicode codepoint to the text.
Definition lvgl.hpp:2300
RAII wrapper for LVGL's built-in timer system.
Definition lvgl.hpp:3415
Timer()
Constructs a null (inactive) timer.
Definition lvgl.hpp:3418
Timer(Timer &&other) noexcept
Move constructor — transfers ownership; source becomes empty.
Definition lvgl.hpp:3443
Timer & pause()
Pauses the timer (can be resumed).
Definition lvgl.hpp:3481
Timer & period(uint32_t ms)
Updates the timer period in milliseconds.
Definition lvgl.hpp:3473
Timer & reset()
Resets the internal elapsed-time counter.
Definition lvgl.hpp:3508
Timer(lv_timer_cb_t cb, uint32_t period_ms, void *user_data=nullptr)
Creates and starts an LVGL timer.
Definition lvgl.hpp:3428
Timer & operator=(Timer &&other) noexcept
Move-assignment — deletes the current timer, then takes other's.
Definition lvgl.hpp:3449
Timer & repeat_count(int32_t count)
Sets the number of times the timer should fire.
Definition lvgl.hpp:3500
Timer & resume()
Resumes a paused timer.
Definition lvgl.hpp:3489
lv_timer_t * get() const
Returns the raw lv_timer_t * for FFI interop.
Definition lvgl.hpp:3461
Timer & ready()
Makes the timer ready to fire on the next lv_timer_handler() pass.
Definition lvgl.hpp:3516
Concept satisfied by callables that are directly convertible to void(*)(lv_event_t*).
Definition lvgl.hpp:595
int32_t display_height()
Vertical resolution (pixels) of the default LVGL display.
Definition lvgl.hpp:3883
void animate_width(ObjectView obj, int32_t to, uint32_t duration_ms)
Helper: animate an object's width.
Definition lvgl.hpp:3690
int32_t display_width()
Horizontal resolution (pixels) of the default LVGL display.
Definition lvgl.hpp:3877
void animate_opa(ObjectView obj, lv_opa_t to, uint32_t duration_ms)
Helper: fade an object's main-part opacity from current → to.
Definition lvgl.hpp:3710
ObjectView layer_top()
Returns the top layer (for overlays that should render above screens).
Definition lvgl.hpp:3895
void animate_y(ObjectView obj, int32_t to, uint32_t duration_ms)
Helper: animate an object's Y position with ease-out.
Definition lvgl.hpp:3678
void animate_x(ObjectView obj, int32_t to, uint32_t duration_ms)
Helper: animate an object's X position with ease-out.
Definition lvgl.hpp:3666
int32_t display_dpi()
DPI of the default LVGL display.
Definition lvgl.hpp:3889
Box hbox(ObjectView parent)
Creates a horizontal flex container (LV_FLEX_FLOW_ROW) sized to its content.
Definition lvgl.hpp:3161
Box vbox(ObjectView parent)
Creates a vertical flex container (LV_FLEX_FLOW_COLUMN) sized to its content.
Definition lvgl.hpp:3148
Derived & add_style(Style &style, lv_style_selector_t selector)
Applies a reusable Style to this object for the given selector.
Definition lvgl.hpp:1207
Result< void > set(unsigned int port, unsigned int pin, int value) noexcept
Drives a GPIO output pin to the specified logic level.
Definition gpio.hpp:55
Result< int > get(unsigned int port, unsigned int pin) noexcept
Reads the current logic level of a GPIO pin.
Definition gpio.hpp:67
C++ abstractions for the LVGL embedded GUI library.
ove_pm_state_t State
System power state (active / sleep / deep-sleep / off).
Definition pm.hpp:37