mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-27 17:50:04 +01:00
[escher/scroll_view] Fix virtuality issues of layoutSubviews
Method contentSize() made virtual and overridden by ScrollableView so that ScrollableView and TableView do not need to setSize themselves and that setSize/setFrame is not called twice over m_contentView.
This commit is contained in:
committed by
EmilieNumworks
parent
c439d6f376
commit
cda88b3c3b
@@ -92,7 +92,7 @@ protected:
|
||||
}
|
||||
KDRect visibleContentRect();
|
||||
void layoutSubviews() override;
|
||||
KDSize contentSize();
|
||||
virtual KDSize contentSize() const { return m_contentView->minimalSizeForOptimalDisplay(); }
|
||||
#if ESCHER_VIEW_LOGGING
|
||||
virtual const char * className() const override;
|
||||
virtual void logAttributes(std::ostream &os) const override;
|
||||
|
||||
@@ -11,7 +11,7 @@ public:
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void reloadScroll(bool forceRelayout = false);
|
||||
protected:
|
||||
void layoutSubviews() override;
|
||||
KDSize contentSize() const override;
|
||||
KDPoint m_manualScrollingOffset;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ protected:
|
||||
void scrollToCell(int i, int j) const;
|
||||
void reloadCellAtLocation(int i, int j);
|
||||
HighlightCell * cellAtLocation(int i, int j);
|
||||
void resizeToFitContent();
|
||||
TableViewDataSource * dataSource();
|
||||
int rowsScrollingOffset() const;
|
||||
int columnsScrollingOffset() const;
|
||||
int numberOfDisplayableRows() const;
|
||||
int numberOfDisplayableColumns() const;
|
||||
void layoutSubviews() override;
|
||||
protected:
|
||||
#if ESCHER_VIEW_LOGGING
|
||||
const char * className() const override;
|
||||
@@ -54,7 +54,6 @@ protected:
|
||||
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews() override;
|
||||
|
||||
/* realCellWidth enables to handle list view for which
|
||||
* TableViewDataSource->cellWidht = 0 */
|
||||
|
||||
@@ -104,10 +104,8 @@ KDRect ScrollView::visibleContentRect() {
|
||||
}
|
||||
|
||||
void ScrollView::layoutSubviews() {
|
||||
// Layout contentView
|
||||
// We're only re-positionning the contentView, not modifying its size.
|
||||
KDPoint absoluteOffset = contentOffset().opposite().translatedBy(KDPoint(m_leftMargin, m_topMargin));
|
||||
KDRect contentFrame = KDRect(absoluteOffset, m_contentView->bounds().size());
|
||||
KDRect contentFrame = KDRect(absoluteOffset, contentSize());
|
||||
m_contentView->setFrame(contentFrame);
|
||||
KDSize content(
|
||||
m_contentView->bounds().width() + m_leftMargin + m_rightMargin,
|
||||
@@ -116,10 +114,6 @@ void ScrollView::layoutSubviews() {
|
||||
decorator()->layoutIndicators(content, contentOffset(), m_frame.size());
|
||||
}
|
||||
|
||||
KDSize ScrollView::contentSize() {
|
||||
return m_contentView->minimalSizeForOptimalDisplay();
|
||||
}
|
||||
|
||||
void ScrollView::setContentOffset(KDPoint offset, bool forceRelayout) {
|
||||
if (m_dataSource->setOffset(offset) || forceRelayout) {
|
||||
layoutSubviews();
|
||||
|
||||
@@ -50,10 +50,9 @@ void ScrollableView::reloadScroll(bool forceReLayout) {
|
||||
setContentOffset(m_manualScrollingOffset, forceReLayout);
|
||||
}
|
||||
|
||||
void ScrollableView::layoutSubviews() {
|
||||
KDSize viewSize = contentSize();
|
||||
KDCoordinate viewWidth = max(viewSize.width(), bounds().width() - leftMargin() - rightMargin());
|
||||
KDCoordinate viewHeight = max(viewSize.height(), bounds().height() - topMargin() - bottomMargin());
|
||||
m_contentView->setSize(KDSize(viewWidth, viewHeight));
|
||||
ScrollView::layoutSubviews();
|
||||
KDSize ScrollableView::contentSize() const {
|
||||
KDSize viewSize = ScrollView::contentSize();
|
||||
KDCoordinate viewWidth = max(viewSize.width(), maxContentWidthDisplayableWithoutScrolling());
|
||||
KDCoordinate viewHeight = max(viewSize.height(), maxContentHeightDisplayableWithoutScrolling());
|
||||
return KDSize(viewWidth, viewHeight);
|
||||
}
|
||||
|
||||
@@ -38,12 +38,20 @@ const char * TableView::className() const {
|
||||
#endif
|
||||
|
||||
void TableView::layoutSubviews() {
|
||||
// We only have to layout our contentView.
|
||||
// We will size it here, and ScrollView::layoutSubviews will position it.
|
||||
|
||||
m_contentView.resizeToFitContent();
|
||||
|
||||
ScrollView::layoutSubviews();
|
||||
m_contentView.layoutSubviews();
|
||||
/* FIXME:
|
||||
* On the one hand, ScrollView::layoutSubviews()
|
||||
* calls setFrame(...) over m_contentView,
|
||||
* which typically calls layoutSubviews() over m_contentView.
|
||||
* However, if the frame happens to be unchanged,
|
||||
* setFrame(...) does not call layoutSubviews.
|
||||
* On the other hand, calling only m_contentView.layoutSubviews()
|
||||
* does not relayout ScrollView when the offset
|
||||
* or the content's size changes.
|
||||
* For those reasons, we call both of them explicitly.
|
||||
* Finally, this solution is not optimal at all since
|
||||
* layoutSubviews is called twice over m_contentView. */
|
||||
}
|
||||
|
||||
void TableView::reloadCellAtLocation(int i, int j) {
|
||||
@@ -75,13 +83,6 @@ KDCoordinate TableView::ContentView::columnWidth(int i) const {
|
||||
return columnWidth;
|
||||
}
|
||||
|
||||
void TableView::ContentView::resizeToFitContent() {
|
||||
if (!(m_tableView->bounds() == KDRectZero)) {
|
||||
layoutSubviews();
|
||||
setSize(KDSize(width(), height()));
|
||||
}
|
||||
}
|
||||
|
||||
KDCoordinate TableView::ContentView::height() const {
|
||||
return m_dataSource->cumulatedHeightFromIndex(m_dataSource->numberOfRows())+m_verticalCellOverlap;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user