Numworks Epsilon  1.4.1
Graphing Calculator Operating System
controller.cpp
Go to the documentation of this file.
1 #include "controller.h"
2 #include "../apps_container.h"
3 extern "C" {
4 #include <assert.h>
5 }
6 
7 namespace Home {
8 
9 Controller::ContentView::ContentView(Controller * controller, SelectableTableViewDataSource * selectionDataSource) :
10  m_selectableTableView(controller, controller, selectionDataSource, controller)
11 {
12  m_selectableTableView.setVerticalCellOverlap(0);
13  m_selectableTableView.setMargins(0, k_sideMargin, 0, k_sideMargin);
14  m_selectableTableView.setColorsBackground(false);
15  m_selectableTableView.setIndicatorThickness(k_indicatorThickness);
16  m_selectableTableView.horizontalScrollIndicator()->setMargin(k_indicatorMargin);
17  m_selectableTableView.verticalScrollIndicator()->setMargin(k_indicatorMargin);
18 }
19 
20 SelectableTableView * Controller::ContentView::selectableTableView() {
21  return &m_selectableTableView;
22 }
23 
24 void Controller::ContentView::drawRect(KDContext * ctx, KDRect rect) const {
25  ctx->fillRect(bounds(), KDColorWhite);
26 }
27 
28 void Controller::ContentView::reloadBottomRightCorner(SimpleTableViewDataSource * dataSource) {
29  /* We mark the bottom right corner (where an empty space can be) as dirty. */
30  markRectAsDirty(KDRect(dataSource->cellWidth()*2, dataSource->cellHeight(), dataSource->cellWidth(), dataSource->cellHeight()));
31 }
32 
33 int Controller::ContentView::numberOfSubviews() const {
34  return 1;
35 }
36 
37 View * Controller::ContentView::subviewAtIndex(int index) {
38  assert(index == 0);
39  return &m_selectableTableView;
40 }
41 
42 void Controller::ContentView::layoutSubviews() {
43  m_selectableTableView.setFrame(bounds());
44 }
45 
46 Controller::Controller(Responder * parentResponder, ::AppsContainer * container, SelectableTableViewDataSource * selectionDataSource) :
47  ViewController(parentResponder),
48  m_container(container),
49  m_view(this, selectionDataSource),
50  m_selectionDataSource(selectionDataSource)
51 {
52 }
53 
55  if (event == Ion::Events::OK || event == Ion::Events::EXE) {
56  m_container->switchTo(m_container->appSnapshotAtIndex(m_selectionDataSource->selectedRow()*k_numberOfColumns+m_selectionDataSource->selectedColumn()+1));
57  return true;
58  }
59 
60  if (event == Ion::Events::Home || event == Ion::Events::Back) {
61  return m_view.selectableTableView()->selectCellAtLocation(0,0);
62  }
63 
64  return false;
65 }
66 
68  if (m_selectionDataSource->selectedRow() == -1) {
69  m_selectionDataSource->selectCellAtLocation(0, 0);
70  } else {
71  m_selectionDataSource->selectCellAtLocation(m_selectionDataSource->selectedColumn(), m_selectionDataSource->selectedRow());
72  }
73  app()->setFirstResponder(m_view.selectableTableView());
74 }
75 
77 }
78 
80  return &m_view;
81 }
82 
84  return ((numberOfIcons()-1)/k_numberOfColumns)+1;
85 }
86 
88  return k_numberOfColumns;
89 }
90 
92  return k_cellHeight;
93 }
94 
96  return k_cellWidth;
97 }
98 
100  return &m_cells[index];
101 }
102 
104  return k_maxNumberOfCells;
105 }
106 
108  AppCell * appCell = (AppCell *)cell;
109  int appIndex = (j*k_numberOfColumns+i)+1;
110  if (appIndex >= m_container->numberOfApps()) {
111  appCell->setVisible(false);
112  } else {
113  appCell->setVisible(true);
114  ::App::Descriptor * descriptor = m_container->appSnapshotAtIndex((j*k_numberOfColumns+i)+1)->descriptor();
115  appCell->setAppDescriptor(descriptor);
116  }
117 }
118 
119 int Controller::numberOfIcons() {
120  assert(m_container->numberOfApps() > 0);
121  return m_container->numberOfApps() - 1;
122 }
123 
124 void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
125  /* If the number of apps (including home) is odd, when we display the
126  * rightest icon, the icon below is empty. As no icon is thus redrawn on the
127  * previous one, the cell is not cleaned. We need to redraw a white rect on
128  * the cell to hide the dirtyness below. Ideally, we would have redrawn all
129  * the background in white and then redraw visible cells. However, the
130  * redrawing takes time and is visible at scrolling. Here, we avoid the
131  * background complete redrawing but the code is a bit
132  * clumsy. */
133  if (m_container->numberOfApps()%2 == 0 && t->selectedColumn() == k_numberOfColumns -1) {
134  m_view.reloadBottomRightCorner(this);
135  }
136  /* To prevent the selectable table view to select cells that are unvisible,
137  * we reselect the previous selected cell as soon as the selected cell is
138  * unvisible. This trick does not create an endless loop as we ensure not to
139  * stay on a unvisible cell and to initialize the first cell on a visible one
140  * (so the previous one is always visible). */
141  int appIndex = (t->selectedRow()*k_numberOfColumns+t->selectedColumn())+1;
142  if (appIndex >= m_container->numberOfApps()) {
143  t->selectCellAtLocation(previousSelectedCellX, previousSelectedCellY);
144  }
145 }
146 
147 }
virtual HighlightCell * reusableCell(int index) override
Definition: controller.cpp:99
#define assert(e)
Definition: assert.h:9
virtual int numberOfColumns() override
Definition: controller.cpp:87
virtual App::Snapshot * appSnapshotAtIndex(int index)=0
void switchTo(App::Snapshot *snapshot) override
constexpr Event EXE
Definition: events.h:114
int16_t KDCoordinate
Definition: coordinate.h:6
View * view() override
Definition: controller.cpp:79
constexpr Event Home
Definition: events.h:68
virtual KDCoordinate cellHeight()=0
void didBecomeFirstResponder() override
Definition: controller.cpp:67
bool selectCellAtLocation(int i, int j, bool setFirstResponder=true)
virtual int numberOfRows() override
Definition: controller.cpp:83
constexpr Event Back
Definition: events.h:66
void viewWillAppear() override
Definition: controller.cpp:76
virtual KDCoordinate cellWidth()=0
bool handleEvent(Ion::Events::Event event) override
Definition: controller.cpp:54
constexpr KDColor KDColorWhite
Definition: color.h:42
virtual KDCoordinate cellHeight() override
Definition: controller.cpp:91
Definition: app.cpp:9
void willDisplayCellAtLocation(HighlightCell *cell, int i, int j) override
Definition: controller.cpp:107
virtual int numberOfApps()=0
Definition: rect.h:26
void fillRect(KDRect rect, KDColor color)
Definition: context_rect.cpp:8
void setVisible(bool visible)
Definition: app_cell.cpp:40
virtual Descriptor * descriptor()=0
virtual int reusableCellCount() override
Definition: controller.cpp:103
void setFirstResponder(Responder *responder)
Definition: app.cpp:62
Definition: view.h:23
Controller(Responder *parentResponder, ::AppsContainer *container, SelectableTableViewDataSource *selectionDataSource)
Definition: controller.cpp:46
virtual KDCoordinate cellWidth() override
Definition: controller.cpp:95
App * app()
Definition: responder.cpp:77
constexpr Event OK
Definition: events.h:65
void setAppDescriptor(::App::Descriptor *appDescriptor)
Definition: app_cell.cpp:34
void tableViewDidChangeSelection(SelectableTableView *t, int previousSelectedCellX, int previousSelectedCellY) override
Definition: controller.cpp:124