diff --git a/escher/Makefile b/escher/Makefile index e95ee39a9..5889d1ed6 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -12,7 +12,7 @@ objs += $(addprefix escher/src/,\ responder.o\ scroll_view.o\ scroll_view_indicator.o\ - simple_table_view.o\ + simple_table_view_data_source.o\ solid_color_view.o\ stack_view.o\ stack_view_controller.o\ diff --git a/escher/include/escher.h b/escher/include/escher.h index 38db06028..a071a4f9e 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/escher/include/escher/list_view.h b/escher/include/escher/list_view.h index beba4b84f..99c220989 100644 --- a/escher/include/escher/list_view.h +++ b/escher/include/escher/list_view.h @@ -1,7 +1,7 @@ #ifndef ESCHER_LIST_VIEW_H #define ESCHER_LIST_VIEW_H -#include +#include class ListViewDataSource : public SimpleTableViewDataSource{ public: @@ -11,7 +11,7 @@ public: virtual void willDisplayCellForIndex(View * cell, int index); }; -class ListView : public SimpleTableView { +class ListView : public TableView { public: ListView(ListViewDataSource * dataSource, KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate leftMargin = 0); diff --git a/escher/include/escher/simple_table_view.h b/escher/include/escher/simple_table_view.h deleted file mode 100644 index aac7bf2a2..000000000 --- a/escher/include/escher/simple_table_view.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef ESCHER_SIMPLE_TABLE_VIEW_H -#define ESCHER_SIMPLE_TABLE_VIEW_H - -#include - -class SimpleTableViewDataSource { -public: - virtual int numberOfRows() = 0; - virtual int numberOfColumns() = 0; - virtual void willDisplayCellAtLocation(View * cell, int x, int y); - virtual KDCoordinate cellHeight() = 0; - virtual KDCoordinate cellWidth() = 0; - virtual View * reusableCell(int index) = 0; - virtual int reusableCellCount() = 0; -}; - -class SimpleTableView : public ScrollView { -public: - SimpleTableView(SimpleTableViewDataSource * dataSource, KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, - KDCoordinate bottomMargin = 0, KDCoordinate leftMargin = 0); - - void scrollToCell(int x, int y); - View * cellAtLocation(int x, int y); -protected: -#if ESCHER_VIEW_LOGGING - const char * className() const override; -#endif -private: - class ContentView : public View { - public: - ContentView(SimpleTableView * tableView, SimpleTableViewDataSource * dataSource); - - KDCoordinate height() const; - KDCoordinate width() const; - void scrollToCell(int x, int y) const; - View * cellAtLocation(int x, int y); - protected: -#if ESCHER_VIEW_LOGGING - const char * className() const override; -#endif - private: - int numberOfSubviews() const override; - View * subviewAtIndex(int index) override; - void layoutSubviews() override; - - /* realCellWidth enables to handle list view for which - * TableViewDataSource->cellWidht = 0 */ - KDCoordinate realCellWidth() const; - int numberOfFullyDisplayableRows() const; - int numberOfFullyDisplayableColumns() const; - int numberOfDisplayableRows() const; - int numberOfDisplayableColumns() const; - int rowsScrollingOffset() const; - int columnsScrollingOffset() const; - bool rowAtIndexIsBeforeFullyVisibleRange(int index) const; - bool columnAtIndexIsBeforeFullyVisibleRange(int index) const; - bool rowAtIndexIsAfterFullyVisibleRange(int index) const; - bool columnAtIndexIsAfterFullyVisibleRange(int index) const; - SimpleTableView * m_tableView; - SimpleTableViewDataSource * m_dataSource; - }; - - void layoutSubviews() override; - - ContentView m_contentView; -}; - -#endif diff --git a/escher/include/escher/simple_table_view_data_source.h b/escher/include/escher/simple_table_view_data_source.h new file mode 100644 index 000000000..ae9257183 --- /dev/null +++ b/escher/include/escher/simple_table_view_data_source.h @@ -0,0 +1,23 @@ +#ifndef ESCHER_SIMPLE_TABLE_VIEW_DATA_SOURCE_H +#define ESCHER_SIMPLE_TABLE_VIEW_DATA_SOURCE_H + +#include + +class SimpleTableViewDataSource : public TableViewDataSource { +public: + virtual KDCoordinate cellHeight() = 0; + virtual KDCoordinate cellWidth() = 0; + KDCoordinate columnWidth(int i) override; + KDCoordinate rowHeight(int j) override; + KDCoordinate cumulatedWidthFromIndex(int i) override; + KDCoordinate cumulatedHeightFromIndex(int j) override; + int indexFromCumulatedWidth(KDCoordinate offsetX) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; + virtual View * reusableCell(int index) = 0; + virtual int reusableCellCount() = 0; + View * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + int typeAtLocation(int i, int j) override; +}; + +#endif diff --git a/escher/src/list_view.cpp b/escher/src/list_view.cpp index 0080e3c4d..5d1f2c4d0 100644 --- a/escher/src/list_view.cpp +++ b/escher/src/list_view.cpp @@ -5,8 +5,6 @@ extern "C" { #include } -#define MIN(x,y) ((x)<(y) ? (x) : (y)) - int ListViewDataSource::numberOfColumns() { return 1; } @@ -24,7 +22,7 @@ void ListViewDataSource::willDisplayCellForIndex(View * cell, int index) { ListView::ListView(ListViewDataSource * dataSource, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) : - SimpleTableView(dataSource, topMargin, rightMargin, bottomMargin, leftMargin) + TableView(dataSource, topMargin, rightMargin, bottomMargin, leftMargin) { } diff --git a/escher/src/simple_table_view.cpp b/escher/src/simple_table_view.cpp deleted file mode 100644 index 4f7d3808f..000000000 --- a/escher/src/simple_table_view.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include -#include - -extern "C" { -#include -} - -#define MIN(x,y) ((x)<(y) ? (x) : (y)) - -void SimpleTableViewDataSource::willDisplayCellAtLocation(View * cell, int x, int y) { -} - - -SimpleTableView::SimpleTableView(SimpleTableViewDataSource * dataSource, KDCoordinate topMargin, KDCoordinate rightMargin, - KDCoordinate bottomMargin, KDCoordinate leftMargin) : - ScrollView(&m_contentView, topMargin, rightMargin, bottomMargin, leftMargin), - m_contentView(SimpleTableView::ContentView(this, dataSource)) -{ -} - -// This method computes the minimal scrolling needed to properly display the -// requested cell. -void SimpleTableView::scrollToCell(int x, int y) { - m_contentView.scrollToCell(x, y); -} - -View * SimpleTableView::cellAtLocation(int x, int y) { - return m_contentView.cellAtLocation(x, y); -} - -#if ESCHER_VIEW_LOGGING -const char * SimpleTableView::className() const { - return "SimpleTableView"; -} -#endif - -void SimpleTableView::layoutSubviews() { - // We only have to layout our contentView. - // We will size it here, and ScrollView::layoutSubviews will position it. - - KDRect contentViewFrame(0, 0, m_contentView.width(), m_contentView.height()); - m_contentView.setFrame(contentViewFrame); - - ScrollView::layoutSubviews(); -} - -/* SimpleTableView::ContentView */ - -SimpleTableView::ContentView::ContentView(SimpleTableView * tableView, SimpleTableViewDataSource * dataSource) : - View(), - m_tableView(tableView), - m_dataSource(dataSource) -{ -} - -KDCoordinate SimpleTableView::ContentView::realCellWidth() const { - int cellWidth = m_dataSource->cellWidth(); - cellWidth = cellWidth ? cellWidth : m_tableView->maxContentWidthDisplayableWithoutScrolling(); - return cellWidth; -} - - -KDCoordinate SimpleTableView::ContentView::height() const { - return m_dataSource->numberOfRows() * m_dataSource->cellHeight(); -} - -KDCoordinate SimpleTableView::ContentView::width() const { - return m_dataSource->numberOfColumns() * realCellWidth(); -} - -void SimpleTableView::ContentView::scrollToCell(int x, int y) const { - KDCoordinate contentOffsetX = m_tableView->contentOffset().x(); - KDCoordinate contentOffsetY = m_tableView->contentOffset().y(); - if (columnAtIndexIsBeforeFullyVisibleRange(x)) { - // Let's scroll the tableView to put that cell on the left (while keeping the left margin) - contentOffsetX = x*realCellWidth(); - } else if (columnAtIndexIsAfterFullyVisibleRange(x)) { - // Let's scroll the tableView to put that cell on the right (while keeping the right margin) - contentOffsetX = (x+1)*realCellWidth() - m_tableView->maxContentWidthDisplayableWithoutScrolling(); - } - if (rowAtIndexIsBeforeFullyVisibleRange(y)) { - // Let's scroll the tableView to put that cell on the top (while keeping the top margin) - contentOffsetY = y*m_dataSource->cellHeight(); - } else if (rowAtIndexIsAfterFullyVisibleRange(y)) { - // Let's scroll the tableView to put that cell on the bottom (while keeping the bottom margin) - contentOffsetY = (y+1)*m_dataSource->cellHeight() - m_tableView->maxContentHeightDisplayableWithoutScrolling(); - } - m_tableView->setContentOffset(KDPoint(contentOffsetX, contentOffsetY)); -} - -View * SimpleTableView::ContentView::cellAtLocation(int x, int y) { - int relativeX = x-columnsScrollingOffset(); - int relativeY = y-rowsScrollingOffset(); - return m_dataSource->reusableCell(relativeY*numberOfDisplayableColumns()+relativeX); -} - -#if ESCHER_VIEW_LOGGING -const char * SimpleTableView::ContentView::className() const { - return "TableView::ContentView"; -} -#endif - -int SimpleTableView::ContentView::numberOfSubviews() const { - int result = numberOfDisplayableRows() * numberOfDisplayableColumns(); - assert(result <= m_dataSource->reusableCellCount()); - return result; -} - -View * SimpleTableView::ContentView::subviewAtIndex(int index) { - assert(index >= 0); - assert(index < m_dataSource->reusableCellCount()); - return m_dataSource->reusableCell(index); -} - -void SimpleTableView::ContentView::layoutSubviews() { - int rowOffset = rowsScrollingOffset(); - int columnOffset = columnsScrollingOffset(); - - for (int i=0; icellHeight(); - KDCoordinate cellWidth = realCellWidth(); - KDRect cellFrame((columnOffset+x)*cellWidth, (rowOffset+y)*cellHeight, - cellWidth, cellHeight); - - cell->setFrame(cellFrame); - - m_dataSource->willDisplayCellAtLocation(cell, columnOffset+x, rowOffset+y); - } -} - -int SimpleTableView::ContentView::numberOfFullyDisplayableRows() const { - // The number of displayable rows taking into accounts margins - return m_tableView->maxContentHeightDisplayableWithoutScrolling()/m_dataSource->cellHeight(); -} - -int SimpleTableView::ContentView::numberOfFullyDisplayableColumns() const { - // The number of displayable columns taking into accounts margins - return m_tableView->maxContentWidthDisplayableWithoutScrolling()/m_dataSource->cellHeight(); -} - -int SimpleTableView::ContentView::numberOfDisplayableRows() const { - return MIN( - m_dataSource->numberOfRows(), - m_tableView->bounds().height() / m_dataSource->cellHeight() + 2 - ); -} - -int SimpleTableView::ContentView::numberOfDisplayableColumns() const { - KDCoordinate width = realCellWidth(); - if (width == 0) { - return 0; - } - return MIN( - m_dataSource->numberOfColumns(), - m_tableView->bounds().width() / width + 2 - ); -} - -int SimpleTableView::ContentView::rowsScrollingOffset() const { - /* 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(); -} - -int SimpleTableView::ContentView::columnsScrollingOffset() const { - /* 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 width = realCellWidth(); - if (width == 0) { - return 0; - } - KDCoordinate pixelScrollingOffset = -m_frame.x(); - return pixelScrollingOffset / width; -} - -bool SimpleTableView::ContentView::rowAtIndexIsBeforeFullyVisibleRange(int index) const { - return index <= rowsScrollingOffset(); -} - -bool SimpleTableView::ContentView::columnAtIndexIsBeforeFullyVisibleRange(int index) const { - return index <= columnsScrollingOffset(); -} - -bool SimpleTableView::ContentView::rowAtIndexIsAfterFullyVisibleRange(int index) const { - int relativeIndex = index - rowsScrollingOffset(); - return (relativeIndex >= numberOfFullyDisplayableRows()); -} - -bool SimpleTableView::ContentView::columnAtIndexIsAfterFullyVisibleRange(int index) const { - int relativeIndex = index - columnsScrollingOffset(); - return (relativeIndex >= numberOfFullyDisplayableColumns()); -} diff --git a/escher/src/simple_table_view_data_source.cpp b/escher/src/simple_table_view_data_source.cpp new file mode 100644 index 000000000..d7a8f33e3 --- /dev/null +++ b/escher/src/simple_table_view_data_source.cpp @@ -0,0 +1,52 @@ +#include +#include + +extern "C" { +#include +} + +KDCoordinate SimpleTableViewDataSource::columnWidth(int i) { + return cellWidth(); +} + +KDCoordinate SimpleTableViewDataSource::rowHeight(int j) { + return cellHeight(); +} + +KDCoordinate SimpleTableViewDataSource::cumulatedWidthFromIndex(int i) { + return cellWidth() * i; +} + +KDCoordinate SimpleTableViewDataSource::cumulatedHeightFromIndex(int j) { + return cellHeight() * j; +} + +int SimpleTableViewDataSource::indexFromCumulatedWidth(KDCoordinate offsetX) { + KDCoordinate width = cellWidth(); + if (width == 0) { + return 0; + } + return (offsetX - 1) / width; +} + +int SimpleTableViewDataSource::indexFromCumulatedHeight(KDCoordinate offsetY) { + KDCoordinate height = cellHeight(); + if (height == 0) { + return 0; + } + return (offsetY - 1) / height; +} + +View * SimpleTableViewDataSource::reusableCell(int index, int type) { + assert(type == 0); + return reusableCell(index); +} + +int SimpleTableViewDataSource::reusableCellCount(int type) { + assert(type == 0); + return reusableCellCount(); +} + +int SimpleTableViewDataSource::typeAtLocation(int i, int j) { + return 0; +}