CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
PluginUiState.h
Go to the documentation of this file.
1
11
12#pragma once
13
14#include "plugin_manager/Raii.h"
16
18#include "cdc_views/ListView.h"
27
28#include <cstddef>
29#include <cstdint>
30#include <memory>
31#include <string>
32#include <vector>
33
34namespace cdc::plugin_manager {
35
36class PluginUiState {
37public:
38 [[nodiscard]] static PluginUiState& instance() noexcept;
39
40 // View push helpers - return HOST_OK or HOST_ERR_*.
41 // `replace_top` means: if our previous list view is the current top of the
42 // view stack, swap it out (no second push). Lets a plugin "refresh" its
43 // own list without growing the stack.
44 [[nodiscard]] int pushList (const char* title, const ui_item_t* items, uint16_t count,
45 uint32_t select_action_id, uint32_t menu_action_id,
46 bool replace_top = false);
48 [[nodiscard]] int updateListItem(uint16_t index, const ui_item_t* item);
50 [[nodiscard]] int insertListItem(uint16_t index, const ui_item_t* item);
52 [[nodiscard]] int removeListItem(uint16_t index);
53 [[nodiscard]] int pushContextMenu(const char* title, const ui_item_t* items, uint16_t count,
54 uint32_t select_action_id);
55 [[nodiscard]] int pushConfirm(const char* text, uint8_t icon, uint32_t action_id);
56 [[nodiscard]] int pushT9 (const char* title, const char* initial,
57 uint16_t max_len, uint32_t action_id);
58 [[nodiscard]] int pushPin (const char* title, uint8_t max_len, uint8_t max_attempts,
59 uint32_t action_id);
60 [[nodiscard]] int pushSlider (const char* title, int32_t min, int32_t max, int32_t init,
61 int32_t step, const char* unit, uint32_t action_id);
62 [[nodiscard]] int pushDate (const char* title, uint8_t d, uint8_t m, uint16_t y,
63 uint32_t action_id);
64 [[nodiscard]] int pushTime (const char* title, uint8_t h, uint8_t m, uint32_t action_id);
65 [[nodiscard]] int pushColorPicker(uint8_t r, uint8_t g, uint8_t b, uint32_t action_id);
66
67 [[nodiscard]] int pushCanvas (const char* title, uint32_t key_action_id,
68 uint32_t widget_action_id);
69 [[nodiscard]] int setCanvasLongPressAction(uint32_t action_id);
70 [[nodiscard]] cdc::ui::CanvasView* canvasView();
71
72 [[nodiscard]] int acquireExclusive();
73 [[nodiscard]] int releaseExclusive();
74 [[nodiscard]] int setInactivity(uint32_t timeout_ms, uint32_t action_id);
75
76 [[nodiscard]] int consumeInputText(char* out, size_t out_size);
77 [[nodiscard]] int consumeInputInt (int32_t* out);
78 [[nodiscard]] int setViewFooter (const char* hint);
79 [[nodiscard]] int setViewEmpty (const char* text);
82 [[nodiscard]] int setViewLifecycle(uint32_t hide_action_id, uint32_t show_action_id);
83
88 void resetForPluginStop();
89
90private:
91 PluginUiState() = default;
92 ~PluginUiState() = default;
93 PluginUiState(const PluginUiState&) = delete;
94 PluginUiState& operator=(const PluginUiState&) = delete;
95
96 struct ListState {
97 std::unique_ptr<cdc::ui::ListView> view;
98 PsramUniquePtr<cdc::ui::ListItem> items; // capacity-sized
99 PsramUniquePtr<char> title_buf;
100 PsramUniquePtr<char> footer_buf;
101 PsramUniquePtr<char> empty_buf;
102 PsramUniquePtr<uint32_t> item_ids; // capacity-sized
103 // One owned label buffer per row (size == count); items[i].label points
104 // at labels[i]. Kept aligned with items on insert/remove so rows move in
105 // place without rebuilding a packed string pool or re-init'ing the view.
106 std::vector<PsramUniquePtr<char>> labels;
107 uint32_t select_action_id = 0;
108 uint32_t menu_action_id = 0;
109 uint16_t count = 0;
110 uint16_t capacity = 0;
111 };
112 struct ContextMenuState {
113 std::unique_ptr<cdc::ui::ContextMenuView> view;
115 PsramUniquePtr<char> string_pool;
116 PsramUniquePtr<char> title_buf;
118 uint32_t select_action_id = 0;
119 uint16_t count = 0;
120 };
121 struct ConfirmState {
122 std::unique_ptr<cdc::ui::ConfirmView> view;
123 PsramUniquePtr<char> footer_buf;
124 uint32_t action_id = 0;
125 };
126 struct InputState {
127 std::unique_ptr<cdc::ui::T9InputView> t9_view;
128 std::unique_ptr<cdc::ui::PinEntryView> pin_view;
129 std::unique_ptr<cdc::ui::SliderView> slider_view;
130 std::unique_ptr<cdc::ui::DateInputView> date_view;
131 std::unique_ptr<cdc::ui::TimeInputView> time_view;
132 std::unique_ptr<cdc::ui::ColorPickerView> color_view;
133 PsramUniquePtr<char> footer_buf;
134 PsramUniquePtr<char> title_buf;
135 PsramUniquePtr<char> unit_buf;
136 uint32_t action_id = 0;
137 std::string last_text;
138 int32_t last_int = 0;
139 bool has_int = false;
140 uint32_t last_date = 0;
141 uint16_t last_time = 0;
142 };
143 struct CanvasState {
144 std::unique_ptr<cdc::ui::CanvasView> view;
145 PsramUniquePtr<char> title_buf;
146 PsramUniquePtr<char> footer_buf;
147 uint32_t key_action_id = 0;
148 uint32_t widget_action_id = 0;
149 uint32_t long_press_action_id = 0;
150 };
151
152 // Callbacks invoked by ViewStack-managed views. They forward via the
153 // singleton so the underlying cdc::ui types stay unaware of plugins.
154 static void onListSelect(uint16_t index, void* userData);
155 static void onListMenu (uint16_t index, void* userData);
156 static void onConfirmYes(void* userData);
157 static void onConfirmNo (void* userData);
158 static void onT9Save (const char* text);
159 static bool onPinVerify (const char* pin);
160 static void onSliderSave(uint16_t value);
161 static void onDateSave (uint8_t day, uint8_t month, uint16_t year);
162 static void onTimeSave (uint8_t hour, uint8_t minute);
163 static void onColorSave (uint8_t r, uint8_t g, uint8_t b);
164 // Cancel trampolines: onInputCancel for self-popping inputs (T9, slider,
165 // date, time, color); onPinCancel pops the PinEntryView first.
166 static void onInputCancel();
167 static void onPinCancel ();
168 static void onInactivity();
169 static void onViewHide(void* userData);
170 static void onViewShow(void* userData);
171 static void onCanvasKey (char key, uint32_t focused_widget);
172 static void onCanvasLongPress(char key);
173 static void onCanvasWidget (uint32_t widget_id, cdc::ui::CanvasView::WidgetEvent event);
174
177 bool growList(uint16_t need);
178
179public:
180 void dispatchContextSelect(uint8_t idx);
181
182private:
183
184 std::unique_ptr<ListState> list_;
185 ContextMenuState ctxmenu_{};
186 ConfirmState confirm_{};
187 InputState input_{};
188 CanvasState canvas_{};
189 // Earlier ListStates that were superseded by another pushList while still
190 // on the view stack. Destroyed in bulk on plugin stop so views that
191 // ViewStack still references are never freed mid-dispatch.
192 std::vector<std::unique_ptr<ListState>> list_graveyard_;
193 const void* exclusive_token_ = nullptr;
194 uint32_t inactivity_action_ = 0;
195 uint32_t lifecycle_hide_action_ = 0;
196 uint32_t lifecycle_show_action_ = 0;
197};
198
199} // namespace cdc::plugin_manager
int pushPin(const char *title, uint8_t max_len, uint8_t max_attempts, uint32_t action_id)
int setCanvasLongPressAction(uint32_t action_id)
int pushCanvas(const char *title, uint32_t key_action_id, uint32_t widget_action_id)
int setViewLifecycle(uint32_t hide_action_id, uint32_t show_action_id)
int pushContextMenu(const char *title, const ui_item_t *items, uint16_t count, uint32_t select_action_id)
int removeListItem(uint16_t index)
Remove the row at index from the current plugin list (rebuild + partial refresh).
int insertListItem(uint16_t index, const ui_item_t *item)
Insert a row at index into the current plugin list (rebuild + partial refresh).
int pushList(const char *title, const ui_item_t *items, uint16_t count, uint32_t select_action_id, uint32_t menu_action_id, bool replace_top=false)
int pushTime(const char *title, uint8_t h, uint8_t m, uint32_t action_id)
int setViewFooter(const char *hint)
int pushT9(const char *title, const char *initial, uint16_t max_len, uint32_t action_id)
int pushDate(const char *title, uint8_t d, uint8_t m, uint16_t y, uint32_t action_id)
int pushConfirm(const char *text, uint8_t icon, uint32_t action_id)
int updateListItem(uint16_t index, const ui_item_t *item)
Redraw a single row of the current plugin list in place (partial refresh).
cdc::ui::CanvasView * canvasView()
int consumeInputText(char *out, size_t out_size)
int pushSlider(const char *title, int32_t min, int32_t max, int32_t init, int32_t step, const char *unit, uint32_t action_id)
int setInactivity(uint32_t timeout_ms, uint32_t action_id)
static PluginUiState & instance() noexcept
int pushColorPicker(uint8_t r, uint8_t g, uint8_t b, uint32_t action_id)
Generic canvas view exposed to WASM plugins for custom UIs.
Definition CanvasView.h:22
CDC Badge OS plugin host API - canonical C ABI contract.
::cdc::core::PsramUniquePtr< T > PsramUniquePtr
Definition Raii.h:21
Thin alias layer that re-exports cdc::core RAII wrappers in the cdc::plugin_manager namespace for sou...