diff --git a/escher/Makefile b/escher/Makefile index 7c5f07c5f..f8ff5bc3b 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -10,6 +10,7 @@ objs += $(addprefix escher/src/,\ tab_view.o\ tab_view_cell.o\ tab_view_controller.o\ + table_view.o\ text_view.o\ view.o\ view_controller.o\ diff --git a/escher/include/escher/table_view.h b/escher/include/escher/table_view.h index 9bdc1f45f..70ac44d39 100644 --- a/escher/include/escher/table_view.h +++ b/escher/include/escher/table_view.h @@ -1,22 +1,41 @@ #ifndef ESCHER_TABLE_VIEW_H #define ESCHER_TABLE_VIEW_H -#include +#include class TableViewDataSource { +public: virtual int numberOfCells() = 0; - View * cellAtIndex(int index) = 0; - void tableWillDisplayCellAtIndex(int index) = 0; + virtual View * cellAtIndex(int index) = 0; + virtual void willDisplayCellAtIndex(int index) = 0; + virtual KDCoordinate cellHeight() = 0; }; -class TableView : public View { +class TableView : public ScrollView { public: - TableView(); - void drawRect(KDRect rect) override; + TableView(TableViewDataSource * dataSource); void scrollToRow(int index); + void layoutSubviews() override; private: - const char * m_text; + class ContentView : public View { + public: + ContentView(TableViewDataSource * dataSource); + + int numberOfSubviews() const override; + View * subview(int index) override; + void storeSubviewAtIndex(View * view, int index) override; + void layoutSubviews() override; + protected: +#if ESCHER_VIEW_LOGGING + const char * className() const override; +#endif + private: + int cellScrollingOffset(); + TableViewDataSource * m_dataSource; + }; + + ContentView m_contentView; }; #endif diff --git a/escher/src/table_view.cpp b/escher/src/table_view.cpp new file mode 100644 index 000000000..3d25b672c --- /dev/null +++ b/escher/src/table_view.cpp @@ -0,0 +1,69 @@ +#include +extern "C" { +#include +} + +#define MIN(x,y) ((x)>(y) ? (x) : (y)) + +TableView::TableView(TableViewDataSource * dataSource) : + ScrollView(&m_contentView), + m_contentView(TableView::ContentView(dataSource)) +{ +} + +void TableView::layoutSubviews() { + KDRect frame; + frame.x = 0; + frame.y = 0; + frame.width = m_frame.width; + frame.height = 9999; // Depends on the datasource, actually... + m_contentView.setFrame(frame); + + ScrollView::layoutSubviews(); +} + +/* TableView::ContentView */ + +TableView::ContentView::ContentView(TableViewDataSource * dataSource) : + m_dataSource(dataSource) +{ +} + +int TableView::ContentView::numberOfSubviews() const { + int numberOfDisplayableCells = m_frame.height / m_dataSource->cellHeight(); + return MIN(m_dataSource->numberOfCells(), numberOfDisplayableCells); +} + +View * TableView::ContentView::subview(int index) { + int offset = cellScrollingOffset(); + return m_dataSource->cellAtIndex(offset+index); +} + +void TableView::ContentView::storeSubviewAtIndex(View * view, int index) { + // Do nothing! +} + +void TableView::ContentView::layoutSubviews() { + int cellOffset = cellScrollingOffset(); + for (int i=0; icellHeight(); + cellFrame.x = 0; + cellFrame.y = (cellOffset+i)*cellHeight; + cellFrame.width = m_frame.width; + cellFrame.height = cellHeight; + + cell->setFrame(cellFrame); + } +} + +// Index of the topmost cell +int TableView::ContentView::cellScrollingOffset() { + /* Here, we want to translate the offset at which our superview 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(); +}