ESPHome  2024.6.1
display_menu_base.cpp
Go to the documentation of this file.
1 #include "display_menu_base.h"
2 #include <algorithm>
3 
4 namespace esphome {
5 namespace display_menu_base {
6 
8  if (this->check_healthy_and_active_()) {
9  bool changed = false;
10 
11  if (this->editing_) {
12  switch (this->mode_) {
13  case MENU_MODE_ROTARY:
14  changed = this->get_selected_item_()->select_prev();
15  break;
16  default:
17  break;
18  }
19  } else {
20  changed = this->cursor_up_();
21  }
22 
23  if (changed)
24  this->draw_and_update();
25  }
26 }
27 
29  if (this->check_healthy_and_active_()) {
30  bool changed = false;
31 
32  if (this->editing_) {
33  switch (this->mode_) {
34  case MENU_MODE_ROTARY:
35  changed = this->get_selected_item_()->select_next();
36  break;
37  default:
38  break;
39  }
40  } else {
41  changed = this->cursor_down_();
42  }
43 
44  if (changed)
45  this->draw_and_update();
46  }
47 }
48 
50  if (this->check_healthy_and_active_()) {
51  bool changed = false;
52 
53  switch (this->get_selected_item_()->get_type()) {
54  case MENU_ITEM_SELECT:
55  case MENU_ITEM_SWITCH:
56  case MENU_ITEM_NUMBER:
57  case MENU_ITEM_CUSTOM:
58  switch (this->mode_) {
59  case MENU_MODE_ROTARY:
60  if (this->editing_) {
61  this->finish_editing_();
62  changed = true;
63  } else {
64  changed = this->leave_menu_();
65  }
66  break;
67  case MENU_MODE_JOYSTICK:
68  if (this->editing_ || this->get_selected_item_()->get_immediate_edit())
69  changed = this->get_selected_item_()->select_prev();
70  break;
71  default:
72  break;
73  }
74  break;
75  case MENU_ITEM_BACK:
76  changed = this->leave_menu_();
77  break;
78  default:
79  break;
80  }
81 
82  if (changed)
83  this->draw_and_update();
84  }
85 }
86 
88  if (this->check_healthy_and_active_()) {
89  bool changed = false;
90 
91  switch (this->get_selected_item_()->get_type()) {
92  case MENU_ITEM_SELECT:
93  case MENU_ITEM_SWITCH:
94  case MENU_ITEM_NUMBER:
95  case MENU_ITEM_CUSTOM:
96  switch (this->mode_) {
97  case MENU_MODE_JOYSTICK:
98  if (this->editing_ || this->get_selected_item_()->get_immediate_edit())
99  changed = this->get_selected_item_()->select_next();
100  default:
101  break;
102  }
103  break;
104  case MENU_ITEM_MENU:
105  changed = this->enter_menu_();
106  break;
107  default:
108  break;
109  }
110 
111  if (changed)
112  this->draw_and_update();
113  }
114 }
115 
117  if (this->check_healthy_and_active_()) {
118  bool changed = false;
119  MenuItem *item = this->get_selected_item_();
120 
121  if (this->editing_) {
122  this->finish_editing_();
123  changed = true;
124  } else {
125  switch (item->get_type()) {
126  case MENU_ITEM_MENU:
127  changed = this->enter_menu_();
128  break;
129  case MENU_ITEM_BACK:
130  changed = this->leave_menu_();
131  break;
132  case MENU_ITEM_SELECT:
133  case MENU_ITEM_SWITCH:
134  case MENU_ITEM_CUSTOM:
135  if (item->get_immediate_edit()) {
136  changed = item->select_next();
137  } else {
138  this->editing_ = true;
139  item->on_enter();
140  changed = true;
141  }
142  break;
143  case MENU_ITEM_NUMBER:
144  // A number cannot be immediate in the rotary mode
145  if (!item->get_immediate_edit() || this->mode_ == MENU_MODE_ROTARY) {
146  this->editing_ = true;
147  item->on_enter();
148  changed = true;
149  }
150  break;
151  case MENU_ITEM_COMMAND:
152  changed = item->select_next();
153  break;
154  default:
155  break;
156  }
157  }
158 
159  if (changed)
160  this->draw_and_update();
161  }
162 }
163 
165  if (this->check_healthy_and_active_())
166  this->draw_menu();
167 }
168 
170  bool disp_changed = false;
171 
172  if (this->is_failed())
173  return;
174 
175  this->process_initial_();
176 
177  this->on_before_show();
178 
179  if (this->active_ && this->editing_)
180  this->finish_editing_();
181 
182  if (this->displayed_item_ != this->root_item_) {
183  this->displayed_item_->on_leave();
184  disp_changed = true;
185  }
186 
187  this->reset_();
188  this->active_ = true;
189 
190  if (disp_changed) {
191  this->displayed_item_->on_enter();
192  }
193 
194  this->draw_and_update();
195 
196  this->on_after_show();
197 }
198 
200  if (this->is_failed())
201  return;
202 
203  this->process_initial_();
204 
205  this->on_before_show();
206 
207  if (!this->active_) {
208  this->active_ = true;
209  this->draw_and_update();
210  }
211 
212  this->on_after_show();
213 }
214 
216  if (this->check_healthy_and_active_()) {
217  this->on_before_hide();
218 
219  if (this->editing_)
220  this->finish_editing_();
221  this->active_ = false;
222  this->update();
223 
224  this->on_after_hide();
225  }
226 }
227 
229  this->displayed_item_ = this->root_item_;
230  this->cursor_index_ = this->top_index_ = 0;
231  this->selection_stack_.clear();
232 }
233 
235  if (!this->root_on_enter_called_) {
236  this->root_item_->on_enter();
237  this->root_on_enter_called_ = true;
238  }
239 }
240 
242  if (this->is_failed())
243  return false;
244 
245  this->process_initial_();
246 
247  return this->active_;
248 }
249 
251  bool changed = false;
252 
253  if (this->cursor_index_ > 0) {
254  changed = true;
255 
256  --this->cursor_index_;
257 
258  if (this->cursor_index_ < this->top_index_)
259  this->top_index_ = this->cursor_index_;
260  }
261 
262  return changed;
263 }
264 
266  bool changed = false;
267 
268  if (this->cursor_index_ + 1 < this->displayed_item_->items_size()) {
269  changed = true;
270 
271  ++this->cursor_index_;
272 
273  if (this->cursor_index_ >= this->top_index_ + this->rows_)
274  this->top_index_ = this->cursor_index_ - this->rows_ + 1;
275  }
276 
277  return changed;
278 }
279 
281  this->displayed_item_->on_leave();
282  this->displayed_item_ = static_cast<MenuItemMenu *>(this->get_selected_item_());
283  this->selection_stack_.push_front({this->top_index_, this->cursor_index_});
284  this->cursor_index_ = this->top_index_ = 0;
285  this->displayed_item_->on_enter();
286 
287  return true;
288 }
289 
291  bool changed = false;
292 
293  if (this->displayed_item_->get_parent() != nullptr) {
294  this->displayed_item_->on_leave();
295  this->displayed_item_ = this->displayed_item_->get_parent();
296  this->top_index_ = this->selection_stack_.front().first;
297  this->cursor_index_ = this->selection_stack_.front().second;
298  this->selection_stack_.pop_front();
299  this->displayed_item_->on_enter();
300  changed = true;
301  }
302 
303  return changed;
304 }
305 
307  switch (this->get_selected_item_()->get_type()) {
308  case MENU_ITEM_SELECT:
309  case MENU_ITEM_NUMBER:
310  case MENU_ITEM_SWITCH:
311  case MENU_ITEM_CUSTOM:
312  this->get_selected_item_()->on_leave();
313  break;
314  default:
315  break;
316  }
317 
318  this->editing_ = false;
319 }
320 
322  for (size_t i = 0; i < this->rows_ && this->top_index_ + i < this->displayed_item_->items_size(); ++i) {
323  this->draw_item(this->displayed_item_->get_item(this->top_index_ + i), i,
324  this->top_index_ + i == this->cursor_index_);
325  }
326 }
327 
328 } // namespace display_menu_base
329 } // namespace esphome
bool is_failed() const
Definition: component.cpp:143
MenuItemType get_type() const
Definition: menu_item.h:45
virtual void draw_item(const MenuItem *item, uint8_t row, bool selected)=0
virtual bool get_immediate_edit() const
Definition: menu_item.h:52
std::forward_list< std::pair< uint8_t, uint8_t > > selection_stack_
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7