ESPHome  2023.11.6
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  }
64  break;
65  case MENU_MODE_JOYSTICK:
66  if (this->editing_ || this->get_selected_item_()->get_immediate_edit())
67  changed = this->get_selected_item_()->select_prev();
68  break;
69  default:
70  break;
71  }
72  break;
73  case MENU_ITEM_BACK:
74  changed = this->leave_menu_();
75  break;
76  default:
77  break;
78  }
79 
80  if (changed)
81  this->draw_and_update();
82  }
83 }
84 
86  if (this->check_healthy_and_active_()) {
87  bool changed = false;
88 
89  switch (this->get_selected_item_()->get_type()) {
90  case MENU_ITEM_SELECT:
91  case MENU_ITEM_SWITCH:
92  case MENU_ITEM_NUMBER:
93  case MENU_ITEM_CUSTOM:
94  switch (this->mode_) {
95  case MENU_MODE_JOYSTICK:
96  if (this->editing_ || this->get_selected_item_()->get_immediate_edit())
97  changed = this->get_selected_item_()->select_next();
98  default:
99  break;
100  }
101  break;
102  case MENU_ITEM_MENU:
103  changed = this->enter_menu_();
104  break;
105  default:
106  break;
107  }
108 
109  if (changed)
110  this->draw_and_update();
111  }
112 }
113 
115  if (this->check_healthy_and_active_()) {
116  bool changed = false;
117  MenuItem *item = this->get_selected_item_();
118 
119  if (this->editing_) {
120  this->finish_editing_();
121  changed = true;
122  } else {
123  switch (item->get_type()) {
124  case MENU_ITEM_MENU:
125  changed = this->enter_menu_();
126  break;
127  case MENU_ITEM_BACK:
128  changed = this->leave_menu_();
129  break;
130  case MENU_ITEM_SELECT:
131  case MENU_ITEM_SWITCH:
132  case MENU_ITEM_CUSTOM:
133  if (item->get_immediate_edit()) {
134  changed = item->select_next();
135  } else {
136  this->editing_ = true;
137  item->on_enter();
138  changed = true;
139  }
140  break;
141  case MENU_ITEM_NUMBER:
142  // A number cannot be immediate in the rotary mode
143  if (!item->get_immediate_edit() || this->mode_ == MENU_MODE_ROTARY) {
144  this->editing_ = true;
145  item->on_enter();
146  changed = true;
147  }
148  break;
149  case MENU_ITEM_COMMAND:
150  changed = item->select_next();
151  break;
152  default:
153  break;
154  }
155  }
156 
157  if (changed)
158  this->draw_and_update();
159  }
160 }
161 
163  if (this->check_healthy_and_active_())
164  this->draw_menu();
165 }
166 
168  bool disp_changed = false;
169 
170  if (this->is_failed())
171  return;
172 
173  this->process_initial_();
174 
175  if (this->active_ && this->editing_)
176  this->finish_editing_();
177 
178  if (this->displayed_item_ != this->root_item_) {
179  this->displayed_item_->on_leave();
180  disp_changed = true;
181  }
182 
183  this->reset_();
184  this->active_ = true;
185 
186  if (disp_changed) {
187  this->displayed_item_->on_enter();
188  }
189 
190  this->draw_and_update();
191 }
192 
194  if (this->is_failed())
195  return;
196 
197  this->process_initial_();
198 
199  if (!this->active_) {
200  this->active_ = true;
201  this->draw_and_update();
202  }
203 }
204 
206  if (this->check_healthy_and_active_()) {
207  if (this->editing_)
208  this->finish_editing_();
209  this->active_ = false;
210  this->update();
211  }
212 }
213 
215  this->displayed_item_ = this->root_item_;
216  this->cursor_index_ = this->top_index_ = 0;
217  this->selection_stack_.clear();
218 }
219 
221  if (!this->root_on_enter_called_) {
222  this->root_item_->on_enter();
223  this->root_on_enter_called_ = true;
224  }
225 }
226 
228  if (this->is_failed())
229  return false;
230 
231  this->process_initial_();
232 
233  return this->active_;
234 }
235 
237  bool changed = false;
238 
239  if (this->cursor_index_ > 0) {
240  changed = true;
241 
242  --this->cursor_index_;
243 
244  if (this->cursor_index_ < this->top_index_)
245  this->top_index_ = this->cursor_index_;
246  }
247 
248  return changed;
249 }
250 
252  bool changed = false;
253 
254  if (this->cursor_index_ + 1 < this->displayed_item_->items_size()) {
255  changed = true;
256 
257  ++this->cursor_index_;
258 
259  if (this->cursor_index_ >= this->top_index_ + this->rows_)
260  this->top_index_ = this->cursor_index_ - this->rows_ + 1;
261  }
262 
263  return changed;
264 }
265 
267  this->displayed_item_->on_leave();
268  this->displayed_item_ = static_cast<MenuItemMenu *>(this->get_selected_item_());
269  this->selection_stack_.push_front({this->top_index_, this->cursor_index_});
270  this->cursor_index_ = this->top_index_ = 0;
271  this->displayed_item_->on_enter();
272 
273  return true;
274 }
275 
277  bool changed = false;
278 
279  if (this->displayed_item_->get_parent() != nullptr) {
280  this->displayed_item_->on_leave();
281  this->displayed_item_ = this->displayed_item_->get_parent();
282  this->top_index_ = this->selection_stack_.front().first;
283  this->cursor_index_ = this->selection_stack_.front().second;
284  this->selection_stack_.pop_front();
285  this->displayed_item_->on_enter();
286  changed = true;
287  }
288 
289  return changed;
290 }
291 
293  switch (this->get_selected_item_()->get_type()) {
294  case MENU_ITEM_SELECT:
295  case MENU_ITEM_NUMBER:
296  case MENU_ITEM_SWITCH:
297  case MENU_ITEM_CUSTOM:
298  this->get_selected_item_()->on_leave();
299  break;
300  default:
301  break;
302  }
303 
304  this->editing_ = false;
305 }
306 
308  for (size_t i = 0; i < this->rows_ && this->top_index_ + i < this->displayed_item_->items_size(); ++i) {
309  this->draw_item(this->displayed_item_->get_item(this->top_index_ + i), i,
310  this->top_index_ + i == this->cursor_index_);
311  }
312 }
313 
314 } // namespace display_menu_base
315 } // namespace esphome
MenuItemType get_type() const
Definition: menu_item.h:41
virtual void draw_item(const MenuItem *item, uint8_t row, bool selected)=0
virtual bool get_immediate_edit() const
Definition: menu_item.h:48
std::forward_list< std::pair< uint8_t, uint8_t > > selection_stack_
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7