Numworks Epsilon  1.4.1
Graphing Calculator Operating System
tab_view_controller.cpp
Go to the documentation of this file.
1 extern "C" {
2 #include <assert.h>
3 }
5 #include <escher/metric.h>
6 #include <escher/app.h>
7 
8 TabViewController::ContentView::ContentView() :
9  View(),
10  m_activeView(nullptr)
11 {
12 };
13 
14 void TabViewController::ContentView::setActiveView(View * view) {
15  m_activeView = view;
16  layoutSubviews();
17  markRectAsDirty(bounds());
18 }
19 
20 void TabViewController::ContentView::layoutSubviews() {
21  KDRect tabViewFrame = KDRect(
22  0, 0,
23  m_frame.width(), Metric::TabHeight
24  );
25  m_tabView.setFrame(tabViewFrame);
26  if (m_activeView) {
27  KDRect activeViewFrame = KDRect(
29  m_frame.width(),
30  m_frame.height() - Metric::TabHeight
31  );
32  m_activeView->setFrame(activeViewFrame);
33  }
34 }
35 
36 int TabViewController::ContentView::numberOfSubviews() const {
37  return 2;
38 }
39 
40 View * TabViewController::ContentView::subviewAtIndex(int index) {
41  if (index == 0) {
42  return &m_tabView;
43  } else {
44  assert(index == 1);
45  return m_activeView;
46  }
47 }
48 
49 #if ESCHER_VIEW_LOGGING
50 const char * TabViewController::ContentView::className() const {
51  return "TabViewController::ContentView";
52 }
53 #endif
54 
56  ViewController(parentResponder),
57  m_dataSource(dataSource)
58 {
59  assert(one != nullptr);
60  assert(two != nullptr || (three == nullptr && four == nullptr));
61  assert(three != nullptr || four == nullptr);
62  m_children[0] = one;
63  m_children[1] = two;
64  m_children[2] = three;
65  m_children[3] = four;
66 
67  m_numberOfChildren = 0;
68  while (m_numberOfChildren < k_maxNumberOfChildren && m_children[m_numberOfChildren] != nullptr) {
69  m_numberOfChildren++;
70  }
71 }
72 
74  return m_dataSource->activeTab();
75 }
76 
78  if (event == Ion::Events::Back) {
79  if (app()->firstResponder() != this) {
80  app()->setFirstResponder(this);
81  return true;
82  }
83  return false;
84  }
85  if (app()->firstResponder() != this) {
86  return false;
87  }
88  if (event == Ion::Events::Left) {
89  if (m_dataSource->selectedTab() > 0) {
90  setSelectedTab(m_dataSource->selectedTab()-1);
91  }
92  return true;
93  }
94  if (event == Ion::Events::Right) {
95  if (m_dataSource->selectedTab() < m_numberOfChildren-1) {
96  setSelectedTab(m_dataSource->selectedTab()+1);
97  }
98  return true;
99  }
100  if (event == Ion::Events::Down) {
101  setActiveTab(m_dataSource->activeTab());
102  return true;
103  }
104  if (event == Ion::Events::OK || event == Ion::Events::EXE) {
105  setActiveTab(m_dataSource->selectedTab());
106  return true;
107  }
108  return false;
109 }
110 
112  assert(i >= 0 && i < m_numberOfChildren);
113  ViewController * activeVC = m_children[i];
114  if (i != m_dataSource->activeTab()) {
115  m_view.setActiveView(activeVC->view());
116  m_children[i]->viewWillAppear();
117  m_view.m_tabView.setActiveIndex(i);
118  }
119  app()->setFirstResponder(activeVC);
120  if (i != m_dataSource->activeTab()) {
121  m_children[m_dataSource->activeTab()]->viewDidDisappear();
122  m_dataSource->setActiveTab(i);
123  }
124 }
125 
127  if (i == m_dataSource->selectedTab()) {
128  return;
129  }
130  m_view.m_tabView.setSelectedIndex(i);
131  m_dataSource->setSelectedTab(i);
132 }
133 
135  app()->setFirstResponder(activeViewController());
136 }
137 
139  setSelectedTab(m_dataSource->activeTab());
140 }
141 
143  setSelectedTab(-1);
144 }
145 
146 
148  return &m_view;
149 }
150 
152  return m_numberOfChildren;
153 }
154 
155 const char * TabViewController::tabName(uint8_t index) {
156  return m_children[index]->title();
157 }
158 
160  if (m_view.m_tabView.numberOfTabs() != m_numberOfChildren) {
161  for (int i=0; i<m_numberOfChildren; i++) {
162  m_view.m_tabView.addTab(m_children[i]);
163  }
164  }
165  if (m_dataSource->activeTab() < 0) {
166  m_dataSource->setActiveTab(0);
167  }
168  m_view.setActiveView(m_children[m_dataSource->activeTab()]->view());
169  activeViewController()->viewWillAppear();
170  m_view.m_tabView.setActiveIndex(m_dataSource->activeTab());
171 }
172 
174  activeViewController()->viewDidDisappear();
175 }
176 
177 ViewController * TabViewController::activeViewController() {
178  assert(m_dataSource->activeTab() >= 0 && m_dataSource->activeTab() < m_numberOfChildren);
179  return m_children[m_dataSource->activeTab()];
180 }
TabViewController(Responder *parentResponder, TabViewDataSource *dataSource, ViewController *one, ViewController *two, ViewController *three, ViewController *four=nullptr)
void willResignFirstResponder() override
View * view() override
#define assert(e)
Definition: assert.h:9
void setActiveTab(int8_t index)
static constexpr KDCoordinate TabHeight
Definition: metric.h:19
void didEnterResponderChain(Responder *previousResponder) override
constexpr Event EXE
Definition: events.h:114
constexpr Event Down
Definition: events.h:63
#define one
Definition: k_tan.c:68
void viewWillAppear() override
virtual View * view()=0
unsigned char uint8_t
Definition: stdint.h:4
bool handleEvent(Ion::Events::Event event) override
constexpr Event Back
Definition: events.h:66
void didBecomeFirstResponder() override
virtual void viewWillAppear()
const char * tabName(uint8_t index)
signed char int8_t
Definition: stdint.h:9
constexpr Event Left
Definition: events.h:61
Definition: rect.h:26
virtual const char * title()
void setFirstResponder(Responder *responder)
Definition: app.cpp:62
void setSelectedTab(int8_t index)
Definition: view.h:23
constexpr Event Right
Definition: events.h:64
void setSelectedTab(int index)
virtual void viewDidDisappear()
App * app()
Definition: responder.cpp:77
constexpr Event OK
Definition: events.h:65
void setActiveTab(int index)
void viewDidDisappear() override