diff --git a/escher/include/escher/childless_view.h b/escher/include/escher/childless_view.h index 9f9d7c7b8..02b71f46e 100644 --- a/escher/include/escher/childless_view.h +++ b/escher/include/escher/childless_view.h @@ -7,9 +7,9 @@ class ChildlessView : public View { using View::View; protected: int numberOfSubviews() const override; - View * subview(int index) override; - void storeSubviewAtIndex(View * v, int index) override; void layoutSubviews() override; +private: + View * subviewAtIndex(int index) override; }; #endif diff --git a/escher/include/escher/scroll_view.h b/escher/include/escher/scroll_view.h index 447ca7268..50a9b1697 100644 --- a/escher/include/escher/scroll_view.h +++ b/escher/include/escher/scroll_view.h @@ -9,8 +9,6 @@ public: ScrollView(View * contentView); int numberOfSubviews() const override; - View * subview(int index) override; - void storeSubviewAtIndex(View * view, int index) override; void layoutSubviews() override; void setContentOffset(KDPoint offset); @@ -21,6 +19,7 @@ protected: virtual void logAttributes(std::ostream &os) const override; #endif private: + View * subviewAtIndex(int index) override; KDPoint m_offset; View * m_contentView; ScrollViewIndicator m_verticalScrollIndicator; diff --git a/escher/include/escher/tab_view.h b/escher/include/escher/tab_view.h index 2452c1197..393bb8359 100644 --- a/escher/include/escher/tab_view.h +++ b/escher/include/escher/tab_view.h @@ -13,7 +13,6 @@ public: // View void drawRect(KDRect rect) const override; int numberOfSubviews() const override; - View * subview(int index) override; void layoutSubviews() override; void addTabNamed(const char * name); @@ -24,8 +23,8 @@ protected: const char * className() const override; void logAttributes(std::ostream &os) const override; #endif - void storeSubviewAtIndex(View * view, int index) override; private: + View * subviewAtIndex(int index) override; static constexpr uint8_t k_maxNumberOfTabs = 4; TabViewCell m_cells[k_maxNumberOfTabs]; uint8_t m_numberOfTabs; diff --git a/escher/include/escher/tab_view_controller.h b/escher/include/escher/tab_view_controller.h index 49aefd888..18dbb15f6 100644 --- a/escher/include/escher/tab_view_controller.h +++ b/escher/include/escher/tab_view_controller.h @@ -22,8 +22,6 @@ private: ContentView(); int numberOfSubviews() const override; - View * subview(int index) override; - void storeSubviewAtIndex(View * view, int index) override; void layoutSubviews() override; void setActiveView(View * view); @@ -33,6 +31,7 @@ private: const char * className() const override; #endif private: + View * subviewAtIndex(int index) override; View * m_activeView; }; diff --git a/escher/include/escher/table_view.h b/escher/include/escher/table_view.h index 8a8b4902a..8aab5d586 100644 --- a/escher/include/escher/table_view.h +++ b/escher/include/escher/table_view.h @@ -28,11 +28,9 @@ protected: private: class ContentView : public View { public: - ContentView(TableViewDataSource * dataSource); + ContentView(TableView * tableView, TableViewDataSource * dataSource); int numberOfSubviews() const override; - View * subview(int index) override; - void storeSubviewAtIndex(View * view, int index) override; void layoutSubviews() override; KDCoordinate height() const; @@ -43,10 +41,12 @@ private: const char * className() const override; #endif private: + View * subviewAtIndex(int index) override; int numberOfDisplayableCells() const; int cellScrollingOffset() const; bool cellAtIndexIsBeforeFullyVisibleRange(int index) const; bool cellAtIndexIsAfterFullyVisibleRange(int index) const; + TableView * m_tableView; TableViewDataSource * m_dataSource; }; diff --git a/escher/include/escher/view.h b/escher/include/escher/view.h index 1714a0c7d..063e56a44 100644 --- a/escher/include/escher/view.h +++ b/escher/include/escher/view.h @@ -39,8 +39,14 @@ public: void redraw() const; */ - void setSubview(View * v, int index); + //void setSubview(View * v, int index); --> Remove this, it's annoying + // Also this allows us to remove storeSubviewAtIndex + //void layoutSubviews should not be purely virtual. + + KDRect bounds() const; + + View * subview(int index); #if ESCHER_VIEW_LOGGING friend std::ostream &operator<<(std::ostream &os, View &view); #endif @@ -51,16 +57,15 @@ protected: #endif virtual const Window * window() const; virtual int numberOfSubviews() const = 0; - virtual View * subview(int index) = 0; - virtual void storeSubviewAtIndex(View * v, int index) = 0; virtual void layoutSubviews() = 0; - View * m_superview; KDRect m_frame; private: + virtual View * subviewAtIndex(int index) = 0; void redraw(KDRect rect); KDPoint absoluteOrigin() const; KDRect absoluteVisibleFrame() const; + View * m_superview; bool m_needsRedraw; //TODO: We may want a dynamic size at some point /* diff --git a/escher/include/escher/window.h b/escher/include/escher/window.h index dc53e43b1..89ea44a1a 100644 --- a/escher/include/escher/window.h +++ b/escher/include/escher/window.h @@ -7,16 +7,16 @@ class Window : public View { public: Window(); void redraw(); + void setContentView(View * contentView); protected: #if ESCHER_VIEW_LOGGING const char * className() const override; #endif const Window * window() const override; int numberOfSubviews() const override; - View * subview(int index) override; void layoutSubviews() override; - void storeSubviewAtIndex(View * view, int index) override; private: + View * subviewAtIndex(int index) override; View * m_contentView; }; diff --git a/escher/src/app.cpp b/escher/src/app.cpp index 4d9119d62..f0432f72d 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -20,7 +20,7 @@ void App::run() { focus(rootViewController()); - window.setSubview(rootView, 0); + window.setContentView(rootView); rootView->setFrame(window.bounds()); window.redraw(); diff --git a/escher/src/childless_view.cpp b/escher/src/childless_view.cpp index 01395f11c..0f897798b 100644 --- a/escher/src/childless_view.cpp +++ b/escher/src/childless_view.cpp @@ -7,14 +7,10 @@ int ChildlessView::numberOfSubviews() const { return 0; } -View * ChildlessView::subview(int index) { +View * ChildlessView::subviewAtIndex(int index) { assert(false); return nullptr; } void ChildlessView::layoutSubviews() { } - -void ChildlessView::storeSubviewAtIndex(View * v, int index) { - assert(false); -} diff --git a/escher/src/scroll_view.cpp b/escher/src/scroll_view.cpp index 966091316..b1b19c1bc 100644 --- a/escher/src/scroll_view.cpp +++ b/escher/src/scroll_view.cpp @@ -11,15 +11,15 @@ ScrollView::ScrollView(View * contentView) : m_contentView(contentView), m_verticalScrollIndicator(ScrollViewIndicator(ScrollViewIndicator::Direction::Vertical)) { - setSubview(m_contentView, 0); - setSubview(&m_verticalScrollIndicator, 1); + //setSubview(m_contentView, 0); + //setSubview(&m_verticalScrollIndicator, 1); } int ScrollView::numberOfSubviews() const { return 2; } -View * ScrollView::subview(int index) { +View * ScrollView::subviewAtIndex(int index) { switch(index) { case 0: return m_contentView; @@ -30,17 +30,6 @@ View * ScrollView::subview(int index) { return nullptr; } -void ScrollView::storeSubviewAtIndex(View * view, int index) { - switch (index) { - case 0: - m_contentView = view; - break; - case 1: - assert(view == &m_verticalScrollIndicator); - break; - } -} - void ScrollView::layoutSubviews() { // Layout indicators KDRect verticalIndicatorFrame; diff --git a/escher/src/tab_view.cpp b/escher/src/tab_view.cpp index 9388bbebe..e47be00e6 100644 --- a/escher/src/tab_view.cpp +++ b/escher/src/tab_view.cpp @@ -21,7 +21,7 @@ void TabView::addTabNamed(const char * name) { uint8_t tabIndex = m_numberOfTabs; m_cells[tabIndex].setName(name); m_numberOfTabs++; - setSubview(&m_cells[tabIndex], tabIndex); + //setSubview(&m_cells[tabIndex], tabIndex); markAsNeedingRedraw(); } @@ -39,7 +39,7 @@ int TabView::numberOfSubviews() const { return m_numberOfTabs; } -View * TabView::subview(int index) { +View * TabView::subviewAtIndex(int index) { assert(index < m_numberOfTabs); return &m_cells[index]; } @@ -57,11 +57,6 @@ void TabView::layoutSubviews() { } } -void TabView::storeSubviewAtIndex(View * view, int index) { - // We're not doing anything here, because we already store all the subviews we ever wanna have - assert(&m_cells[index] == view); -} - #if ESCHER_VIEW_LOGGING const char * TabView::className() const { return "TabView"; diff --git a/escher/src/tab_view_controller.cpp b/escher/src/tab_view_controller.cpp index cc64876fb..1b190bfc5 100644 --- a/escher/src/tab_view_controller.cpp +++ b/escher/src/tab_view_controller.cpp @@ -8,11 +8,10 @@ TabViewController::ContentView::ContentView() : View(), m_activeView(nullptr) { - setSubview(&m_tabView, 0); }; void TabViewController::ContentView::setActiveView(View * view) { - setSubview(view, 1); + m_activeView = view; layoutSubviews(); view->markAsNeedingRedraw(); } @@ -39,7 +38,7 @@ int TabViewController::ContentView::numberOfSubviews() const { return 2; } -View * TabViewController::ContentView::subview(int index) { +View * TabViewController::ContentView::subviewAtIndex(int index) { if (index == 0) { return &m_tabView; } else { @@ -48,12 +47,6 @@ View * TabViewController::ContentView::subview(int index) { } } -void TabViewController::ContentView::storeSubviewAtIndex(View * view, int index) { - if (index == 1) { - m_activeView = view; - } -} - #if ESCHER_VIEW_LOGGING const char * TabViewController::ContentView::className() const { return "TabViewController::ContentView"; diff --git a/escher/src/table_view.cpp b/escher/src/table_view.cpp index 41ec2197d..4cc4f6019 100644 --- a/escher/src/table_view.cpp +++ b/escher/src/table_view.cpp @@ -7,9 +7,8 @@ extern "C" { TableView::TableView(TableViewDataSource * dataSource) : ScrollView(&m_contentView), - m_contentView(TableView::ContentView(dataSource)) + m_contentView(TableView::ContentView(this, dataSource)) { - setSubview(&m_contentView, 0); } // This method computes the minimal scrolling needed to properly display the @@ -43,29 +42,23 @@ const char * TableView::className() const { /* TableView::ContentView */ -TableView::ContentView::ContentView(TableViewDataSource * dataSource) : +TableView::ContentView::ContentView(TableView * tableView, TableViewDataSource * dataSource) : View(), + m_tableView(tableView), m_dataSource(dataSource) { - for (int i=0; ireusableCellCount(); i++) { - setSubview(m_dataSource->reusableCell(i), i); - } } int TableView::ContentView::numberOfSubviews() const { return MIN(m_dataSource->numberOfCells(), numberOfDisplayableCells()); } -View * TableView::ContentView::subview(int index) { +View * TableView::ContentView::subviewAtIndex(int index) { assert(index >= 0); assert(index < m_dataSource->reusableCellCount()); return m_dataSource->reusableCell(index); } -void TableView::ContentView::storeSubviewAtIndex(View * view, int index) { - // Do nothing! -} - void TableView::ContentView::layoutSubviews() { int cellOffset = cellScrollingOffset(); @@ -94,21 +87,20 @@ KDCoordinate TableView::ContentView::height() const { } void TableView::ContentView::scrollToRow(int index) const { - TableView * superview = (TableView *)m_superview; if (cellAtIndexIsBeforeFullyVisibleRange(index)) { // Let's scroll the tableView to put that cell on the top KDPoint contentOffset; contentOffset.x = 0; contentOffset.y = index*m_dataSource->cellHeight(); - superview->setContentOffset(contentOffset); + m_tableView->setContentOffset(contentOffset); return; } if (cellAtIndexIsAfterFullyVisibleRange(index)) { // Let's scroll the tableView to put that cell on the bottom KDPoint contentOffset; contentOffset.x = 0; - contentOffset.y = (index+1)*m_dataSource->cellHeight() - superview->bounds().height; - superview->setContentOffset(contentOffset); + contentOffset.y = (index+1)*m_dataSource->cellHeight() - m_tableView->bounds().height; + m_tableView->setContentOffset(contentOffset); return; } // Nothing to do if the cell is already visible! @@ -121,13 +113,13 @@ const char * TableView::ContentView::className() const { #endif int TableView::ContentView::numberOfDisplayableCells() const { - int result = m_superview->bounds().height / m_dataSource->cellHeight() + 1; + int result = m_tableView->bounds().height / m_dataSource->cellHeight() + 1; assert(result <= m_dataSource->reusableCellCount()); return result; } int TableView::ContentView::cellScrollingOffset() const { - /* Here, we want to translate the offset at which our superview is displaying + /* Here, we want to translate the offset at which our tableView is displaying * us into an integer offset we can use to ask cells to our data source. */ KDCoordinate pixelScrollingOffset = -m_frame.y; return pixelScrollingOffset / m_dataSource->cellHeight(); diff --git a/escher/src/view.cpp b/escher/src/view.cpp index 596e79ec9..c703f210e 100644 --- a/escher/src/view.cpp +++ b/escher/src/view.cpp @@ -62,6 +62,8 @@ void View::redraw(KDRect rect) { if (subview == nullptr) { continue; } + assert(subview->m_superview == this); + if (KDRectIntersect(rect, subview->m_frame)) { KDRect intersection = KDRectIntersection(rect, subview->m_frame); // Let's express intersection in subview's coordinates @@ -75,12 +77,23 @@ void View::redraw(KDRect rect) { m_needsRedraw = false; } -void View::setSubview(View * view, int index) { +View * View::subview(int index) { + assert(index < numberOfSubviews()); + View * subview = subviewAtIndex(index); + if (subview != nullptr) { + subview->m_superview = this; + } + return subview; +} + +/* + void View::setSubview(View * view, int index) { view->m_superview = this; storeSubviewAtIndex(view, index); assert(subview(index) == view); view->markAsNeedingRedraw(); } +*/ /* void View::addSubview(View * subview) { @@ -129,6 +142,7 @@ void View::setFrame(KDRect frame) { m_superview->markAsNeedingRedraw(); } layoutSubviews(); + markAsNeedingRedraw(); } diff --git a/escher/src/window.cpp b/escher/src/window.cpp index 7057463b8..ae2570fda 100644 --- a/escher/src/window.cpp +++ b/escher/src/window.cpp @@ -12,6 +12,10 @@ void Window::redraw() { View::redraw(bounds()); } +void Window::setContentView(View * contentView) { + m_contentView = contentView; +}; + const Window * Window::window() const { return this; } @@ -20,7 +24,7 @@ int Window::numberOfSubviews() const { return (m_contentView == nullptr ? 0 : 1); } -View * Window::subview(int index) { +View * Window::subviewAtIndex(int index) { assert(m_contentView != nullptr && index == 0); return m_contentView; } @@ -31,11 +35,6 @@ void Window::layoutSubviews() { } } -void Window::storeSubviewAtIndex(View * view, int index) { - assert(index == 0); - m_contentView = view; -} - #if ESCHER_VIEW_LOGGING const char * Window::className() const { return "Window";