Numworks Epsilon  1.4.1
Graphing Calculator Operating System
tab_view.cpp
Go to the documentation of this file.
1 #include <escher/tab_view.h>
3 extern "C" {
4 #include <assert.h>
5 }
6 
8  View(),
9  m_numberOfTabs(0),
10  m_activeTabIndex(-1),
11  m_selectedTabIndex(-1)
12 {
13 }
14 
15 int TabView::numberOfTabs() const {
16  return m_numberOfTabs;
17 }
18 
19 void TabView::drawRect(KDContext * ctx, KDRect rect) const {
20  KDCoordinate height = bounds().height();
21  KDCoordinate width = bounds().width();
22  // Draw a separator with the content
23  ctx->fillRect(KDRect(0, height-k_activeTabHeight, width, k_activeTabHeight), KDColorWhite);
24 }
25 
26 void TabView::addTab(ViewController * controller) {
27  assert(m_numberOfTabs < k_maxNumberOfTabs);
28  uint8_t tabIndex = m_numberOfTabs;
29  m_cells[tabIndex].setNamedController(controller);
30  m_numberOfTabs++;
32 }
33 
34 void TabView::setActiveIndex(int index) {
35  assert(index < m_numberOfTabs);
36  if (m_activeTabIndex == index) {
37  return;
38  }
39  if (m_activeTabIndex >= 0) {
40  m_cells[m_activeTabIndex].setActive(false);
41  }
42  m_activeTabIndex = index;
43  m_cells[m_activeTabIndex].setActive(true);
44 }
45 
46 void TabView::setSelectedIndex(int index) {
47  assert(index < m_numberOfTabs);
48  if (m_selectedTabIndex == index) {
49  return;
50  }
51  if (m_selectedTabIndex >= 0) {
52  m_cells[m_selectedTabIndex].setSelected(false);
53  }
54  m_selectedTabIndex = index;
55  if (m_selectedTabIndex >= 0) {
56  m_cells[m_selectedTabIndex].setSelected(true);
57  }
58 }
59 
60 int TabView::numberOfSubviews() const {
61  return m_numberOfTabs;
62 }
63 
64 View * TabView::subviewAtIndex(int index) {
65  assert(index < m_numberOfTabs);
66  return &m_cells[index];
67 }
68 
69 void TabView::layoutSubviews() {
70  KDCoordinate emptyWidth = bounds().width();
71  for (int i=0; i<m_numberOfTabs; i++) {
72  emptyWidth -= m_cells[i].minimalSizeForOptimalDisplay().width();
73  }
74  KDCoordinate widthUsed = 0;
75  for (int i=0; i<m_numberOfTabs; i++) {
76  KDCoordinate tabWidth = m_cells[i].minimalSizeForOptimalDisplay().width() + emptyWidth/m_numberOfTabs;
77  /* Avoid a unused one-pixel-width vertical on the left due to rounding error */
78  if (i == m_numberOfTabs - 1) {
79  tabWidth = bounds().width() - widthUsed;
80  }
81  KDRect cellFrame = KDRect(
82  widthUsed, 0,
83  tabWidth, m_frame.height() - k_activeTabHeight
84  );
85  m_cells[i].setFrame(cellFrame);
86  widthUsed += tabWidth;
87  }
88 }
89 
90 #if ESCHER_VIEW_LOGGING
91 const char * TabView::className() const {
92  return "TabView";
93 }
94 
95 void TabView::logAttributes(std::ostream &os) const {
96  View::logAttributes(os);
97  os << " numberOfTabs=\"" << (int)m_numberOfTabs << "\"";
98  os << " activeTabIndex=\"" << (int)m_activeTabIndex << "\"";
99 }
100 #endif
#define assert(e)
Definition: assert.h:9
void setFrame(KDRect frame)
Definition: view.cpp:125
int16_t KDCoordinate
Definition: coordinate.h:6
constexpr KDCoordinate width() const
Definition: size.h:10
void markRectAsDirty(KDRect rect)
Definition: view.cpp:39
unsigned char uint8_t
Definition: stdint.h:4
TabView()
Definition: tab_view.cpp:7
void setSelected(bool selected)
KDRect m_frame
Definition: view.h:66
constexpr KDColor KDColorWhite
Definition: color.h:42
KDSize minimalSizeForOptimalDisplay() const override
void setActiveIndex(int index)
Definition: tab_view.cpp:34
int numberOfTabs() const
Definition: tab_view.cpp:15
Definition: rect.h:26
void fillRect(KDRect rect, KDColor color)
Definition: context_rect.cpp:8
Definition: view.h:23
void setSelectedIndex(int index)
Definition: tab_view.cpp:46
KDCoordinate width() const
Definition: rect.h:39
void setNamedController(ViewController *controller)
void drawRect(KDContext *ctx, KDRect rect) const override
Definition: tab_view.cpp:19
KDCoordinate height() const
Definition: rect.h:40
KDRect bounds() const
Definition: view.cpp:157
void addTab(ViewController *controller)
Definition: tab_view.cpp:26
void setActive(bool active)