mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Escher: Get rid of storeSubviewAtIndex
Change-Id: I0e428081caae3ead5b6e6dc16878e5188a3627c1
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ void App::run() {
|
||||
|
||||
focus(rootViewController());
|
||||
|
||||
window.setSubview(rootView, 0);
|
||||
window.setContentView(rootView);
|
||||
rootView->setFrame(window.bounds());
|
||||
|
||||
window.redraw();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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; i<m_dataSource->reusableCellCount(); 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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user