From a56a73b0ba1c425b815591e6fe681d3275927343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 26 May 2020 17:23:06 +0200 Subject: [PATCH] [apps/calculation] Fix calculation height computation It was done in two places before, which created inconsistencies --- .../illustrated_list_controller.cpp | 8 +- .../scrollable_three_expressions_cell.cpp | 11 ++ .../scrollable_three_expressions_cell.h | 9 +- apps/calculation/calculation.cpp | 121 +----------------- apps/calculation/calculation.h | 4 +- apps/calculation/history_controller.cpp | 14 +- apps/calculation/history_view_cell.cpp | 62 ++++++--- apps/calculation/history_view_cell.h | 5 +- .../scrollable_multiple_expressions_view.cpp | 79 ++++++++---- .../scrollable_multiple_expressions_view.h | 1 + escher/src/scroll_view.cpp | 3 + kandinsky/src/rect.cpp | 2 +- 12 files changed, 141 insertions(+), 178 deletions(-) diff --git a/apps/calculation/additional_outputs/illustrated_list_controller.cpp b/apps/calculation/additional_outputs/illustrated_list_controller.cpp index ba792c161..3fd481ee6 100644 --- a/apps/calculation/additional_outputs/illustrated_list_controller.cpp +++ b/apps/calculation/additional_outputs/illustrated_list_controller.cpp @@ -78,7 +78,13 @@ KDCoordinate IllustratedListController::rowHeight(int j) { return 0; } Shared::ExpiringPointer calculation = m_calculationStore.calculationAtIndex(calculationIndex); - return calculation->height(App::app()->localContext(), Metric::CommonSmallMargin, ScrollableThreeExpressionsView::k_margin, true, true) + Metric::CellSeparatorThickness; + constexpr bool expanded = true; + KDCoordinate result = calculation->memoizedHeight(expanded); + if (result < 0) { + result = ScrollableThreeExpressionsCell::Height(calculation.pointer()); + calculation->setMemoizedHeight(expanded, result); + } + return result + Metric::CellSeparatorThickness; } int IllustratedListController::typeAtLocation(int i, int j) { diff --git a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp index d90fc628d..3c77fb2ed 100644 --- a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp +++ b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp @@ -65,6 +65,17 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) { layoutSubviews(); } +KDCoordinate ScrollableThreeExpressionsCell::Height(Calculation * calculation) { + ScrollableThreeExpressionsCell cell; + cell.setCalculation(calculation); + KDRect leftFrame = KDRectZero; + KDRect centerFrame = KDRectZero; + KDRect approximateSignFrame = KDRectZero; + KDRect rightFrame = KDRectZero; + cell.subviewFrames(&leftFrame, ¢erFrame, &approximateSignFrame, &rightFrame); + return leftFrame.unionedWith(centerFrame).unionedWith(rightFrame).height(); +} + void ScrollableThreeExpressionsCell::didBecomeFirstResponder() { reinitSelection(); Container::activeApp()->setFirstResponder(&m_view); diff --git a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h index a7836d7f7..e8daa7f26 100644 --- a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h +++ b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h @@ -17,6 +17,9 @@ public: } void resetMemoization(); void setCalculation(Calculation * calculation); + void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) { + return m_contentCell.subviewFrames(leftFrame, centerFrame, approximateSignFrame, rightFrame); + } private: class ContentCell : public Shared::AbstractScrollableMultipleExpressionsView::ContentCell { public: @@ -29,12 +32,13 @@ private: }; ContentCell * contentCell() override { return &m_contentCell; }; - const ContentCell * constContentCell() const override { return &m_contentCell; }; + const ContentCell * constContentCell() const override { return &m_contentCell; }; ContentCell m_contentCell; }; class ScrollableThreeExpressionsCell : public TableCell, public Responder { public: + static KDCoordinate Height(Calculation * calculation); ScrollableThreeExpressionsCell() : Responder(nullptr), m_view(this) {} @@ -59,6 +63,9 @@ public: void setSelectedSubviewPosition(ScrollableThreeExpressionsView::SubviewPosition subviewPosition) { m_view.setSelectedSubviewPosition(subviewPosition); } void reinitSelection(); + void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) { + return m_view.subviewFrames(leftFrame, centerFrame, approximateSignFrame, rightFrame); + } private: // Remove label margin added by TableCell because they're already handled by ScrollableThreeExpressionsView KDCoordinate labelMargin() const override { return 0; } diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index d490e1412..fe3f09f2f 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -125,125 +125,12 @@ Layout Calculation::createApproximateOutputLayout(Context * context, bool * coul } } -KDCoordinate Calculation::height(Context * context, KDCoordinate topBottomMargin, KDCoordinate verticalMarginAroundLayouts, bool expanded, bool forceSingleLine, LayoutsCanBeSingleLineFunction canBeSingleLine) { - /* WARNING: this method must return the same result as - * Calculation::HistoryViewCell::layoutSubviews. */ - - KDCoordinate result = expanded ? m_expandedHeight : m_height; - if (result >= 0) { - // Height already computed - return result; - } - - // Get input information - Layout inputLayout = createInputLayout(); - KDCoordinate inputHeight = inputLayout.layoutSize().height(); - KDCoordinate inputWidth = inputLayout.layoutSize().width(); - KDCoordinate inputBaseline = inputLayout.baseline(); - - // Get output information - KDCoordinate outputWidth; - KDCoordinate outputBaseline; - KDCoordinate outputHeightBelowBaseline; - - DisplayOutput displayType = displayOutput(context); - /* If the display output is ExactAndApproximateToggle, we want to use the - * expanded width to compute if the calculaton is in single line or not. */ - bool shouldComputeMaxOutputWidthForSingleLine = !forceSingleLine && (!expanded && displayType == DisplayOutput::ExactAndApproximateToggle); - - { - bool displaysExactOnly = displayType == DisplayOutput::ExactOnly; - bool displayApproximateOnly = displayType == DisplayOutput::ApproximateOnly - || (!expanded - && (displayType == DisplayOutput::ExactAndApproximateToggle)); - - KDCoordinate exactOutputWidth = 0; - KDCoordinate exactOutputBaseline = 0; - KDCoordinate exactOutputBelowBaseline = 0; - - // Get exact output info if needed - bool displaysExact = displaysExactOnly || !displayApproximateOnly; - if (displaysExact || shouldComputeMaxOutputWidthForSingleLine) { - bool couldNotCreateExactLayout = false; - Poincare::Layout exactLayout = createExactOutputLayout(&couldNotCreateExactLayout); - if (couldNotCreateExactLayout) { - if (!displaysExactOnly) { - displayType = DisplayOutput::ApproximateOnly; - forceDisplayOutput(displayType); - displaysExactOnly = false; - displayApproximateOnly = true; - shouldComputeMaxOutputWidthForSingleLine = false; - outputWidth = 0; - } else { - /* We should only display the exact result, but we cannot create it - * -> raise an exception. */ - ExceptionCheckpoint::Raise(); - } - } else { - KDSize exactSize = exactLayout.layoutSize(); - outputWidth = exactSize.width(); - if (displaysExact) { - exactOutputWidth = exactSize.width(); - exactOutputBaseline = exactLayout.baseline(); - exactOutputBelowBaseline = exactSize.height() - exactOutputBaseline; - } - } - } - - KDCoordinate approximateOutputWidth = 0; - KDCoordinate approximateOutputBaseline = 0; - KDCoordinate approximateOutputBelowBaseline = 0; - - // Get approximate output info if needed - bool displaysApproximate = displayApproximateOnly || !displaysExactOnly; - if (displaysApproximate || shouldComputeMaxOutputWidthForSingleLine) { - bool couldNotCreateApproximateLayout = false; - Layout approximateLayout = createApproximateOutputLayout(context, &couldNotCreateApproximateLayout); - if (couldNotCreateApproximateLayout) { - Poincare::ExceptionCheckpoint::Raise(); - } - KDSize approximateOutputSize = approximateLayout.layoutSize(); - outputWidth += approximateOutputSize.width(); - if (displaysApproximate) { - approximateOutputWidth = approximateOutputSize.width(); - approximateOutputBaseline = approximateLayout.baseline(); - approximateOutputBelowBaseline = approximateOutputSize.height() - approximateOutputBaseline; - } - } - - // Compute the output info - if (shouldComputeMaxOutputWidthForSingleLine || (exactOutputWidth > 0 && approximateOutputWidth > 0)) { - outputWidth += AbstractScrollableMultipleExpressionsView::StandardApproximateViewAndMarginsSize(); - } - outputBaseline = std::max(exactOutputBaseline, approximateOutputBaseline); - outputHeightBelowBaseline = std::max(exactOutputBelowBaseline, approximateOutputBelowBaseline); - } - - if (forceSingleLine || canBeSingleLine(inputWidth, outputWidth)) { - result = std::max(inputBaseline, outputBaseline) // Above the baseline - + std::max(static_cast(inputHeight - inputBaseline), outputHeightBelowBaseline) // Below the baseline - + 2 * verticalMarginAroundLayouts; +void Calculation::setMemoizedHeight(bool expanded, KDCoordinate height) { + if (expanded) { + m_expandedHeight = height; } else { - result = inputHeight + outputBaseline + outputHeightBelowBaseline + 4 * verticalMarginAroundLayouts; + m_height = height; } - - // Add the top and bottom margins - result += 2 * topBottomMargin; - - /* For all display outputs except ExactAndApproximateToggle, the selected - * height and the usual height are identical. We update both heights in - * theses cases. */ - if (displayOutput(context) != DisplayOutput::ExactAndApproximateToggle) { - m_height = result; - m_expandedHeight = result; - } else { - if (expanded) { - m_expandedHeight = result; - } else { - m_height = result; - } - } - return result; } Calculation::DisplayOutput Calculation::displayOutput(Context * context) { diff --git a/apps/calculation/calculation.h b/apps/calculation/calculation.h index 6f6050e45..dc1646657 100644 --- a/apps/calculation/calculation.h +++ b/apps/calculation/calculation.h @@ -84,8 +84,8 @@ public: Poincare::Layout createApproximateOutputLayout(Poincare::Context * context, bool * couldNotCreateApproximateLayout); // Memoization of height - typedef bool (*LayoutsCanBeSingleLineFunction)(KDCoordinate inputWidth, KDCoordinate outputWidth); - KDCoordinate height(Poincare::Context * context, KDCoordinate topBottomMargin, KDCoordinate verticalMarginAroundLayouts, bool expanded, bool forceSingleLine, LayoutsCanBeSingleLineFunction canbeSingleLine = [](KDCoordinate inputLayoutWidth, KDCoordinate outputLayoutWidth) { assert(false); return true; }); + KDCoordinate memoizedHeight(bool expanded) { return expanded ? m_expandedHeight : m_height; } + void setMemoizedHeight(bool expanded, KDCoordinate height); // Displayed output DisplayOutput displayOutput(Poincare::Context * context); diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 3fca09d90..5fca0aa98 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -206,13 +206,13 @@ KDCoordinate HistoryController::rowHeight(int j) { return 0; } Shared::ExpiringPointer calculation = calculationAtIndex(j); - return calculation->height( - App::app()->localContext(), - HistoryViewCell::k_margin, - HistoryViewCell::k_inputOutputViewsVerticalMargin, - j == selectedRow() && selectedSubviewType() == SubviewType::Output, - false, - &HistoryViewCell::LayoutsCanBeSingleLine); + bool expanded = j == selectedRow() && selectedSubviewType() == SubviewType::Output; + KDCoordinate result = calculation->memoizedHeight(expanded); + if (result < 0) { + result = HistoryViewCell::Height(calculation.pointer(), expanded); + calculation->setMemoizedHeight(expanded, result); + } + return result; } int HistoryController::typeAtLocation(int i, int j) { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 981a34018..239529aff 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -34,12 +34,22 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType, /* HistoryViewCell */ +KDCoordinate HistoryViewCell::Height(Calculation * calculation, bool expanded) { + HistoryViewCell cell(nullptr); + cell.setCalculation(calculation, expanded); + KDRect ellipsisFrame = KDRectZero; + KDRect inputFrame = KDRectZero; + KDRect outputFrame = KDRectZero; + cell.computeSubviewFrames(Ion::Display::Width, KDCOORDINATE_MAX, &ellipsisFrame, &inputFrame, &outputFrame); + return k_margin + inputFrame.unionedWith(outputFrame).height() + k_margin; +} + HistoryViewCell::HistoryViewCell(Responder * parentResponder) : Responder(parentResponder), m_calculationCRC32(0), m_calculationDisplayOutput(Calculation::DisplayOutput::Unknown), m_calculationAdditionInformation(Calculation::AdditionalInformationType::None), - m_inputView(this, k_inputOutputViewsHorizontalMargin, k_inputOutputViewsVerticalMargin), + m_inputView(this, k_inputViewHorizontalMargin, k_inputOutputViewsVerticalMargin), m_scrollableOutputView(this), m_calculationExpanded(false), m_calculationSingleLine(false) @@ -154,23 +164,37 @@ View * HistoryViewCell::subviewAtIndex(int index) { return views[index]; } -bool HistoryViewCell::LayoutsCanBeSingleLine(KDCoordinate inputLayoutWidth, KDCoordinate outputLayoutWidth) { - return ViewsCanBeSingleLine(inputLayoutWidth + 2 * k_inputOutputViewsHorizontalMargin, outputLayoutWidth + 2 * k_inputOutputViewsHorizontalMargin); -} - bool HistoryViewCell::ViewsCanBeSingleLine(KDCoordinate inputViewWidth, KDCoordinate outputViewWidth) { // k_margin is the separation between the input and output. return (inputViewWidth + k_margin + outputViewWidth) < Ion::Display::Width - Metric::EllipsisCellWidth; } void HistoryViewCell::layoutSubviews(bool force) { - KDCoordinate maxFrameWidth = bounds().width(); - if (displayedEllipsis()) { - m_ellipsis.setFrame(KDRect(maxFrameWidth - Metric::EllipsisCellWidth, 0, Metric::EllipsisCellWidth, bounds().height()), force); - maxFrameWidth -= Metric::EllipsisCellWidth; - } else { - m_ellipsis.setFrame(KDRectZero, force); // Required to mark previous rect as dirty + KDRect frameBounds = bounds(); + if (bounds().width() <= 0 || bounds().height() <= 0) { + // TODO Make this behaviour in a non-virtual layoutSublviews, and all layout subviews should become privateLayoutSubviews + return; } + KDRect ellipsisFrame = KDRectZero; + KDRect inputFrame = KDRectZero; + KDRect outputFrame = KDRectZero; + computeSubviewFrames(frameBounds.width(), frameBounds.height(), &ellipsisFrame, &inputFrame, &outputFrame); + + m_ellipsis.setFrame(ellipsisFrame, force); // Required even if ellipsisFrame is KDRectZero, to mark previous rect as dirty + m_inputView.setFrame(inputFrame,force); + m_scrollableOutputView.setFrame(outputFrame, force); +} + +void HistoryViewCell::computeSubviewFrames(KDCoordinate frameWidth, KDCoordinate frameHeight, KDRect * ellipsisFrame, KDRect * inputFrame, KDRect * outputFrame) { + assert(ellipsisFrame != nullptr && inputFrame != nullptr && outputFrame != nullptr); + + if (displayedEllipsis()) { + *ellipsisFrame = KDRect(frameWidth - Metric::EllipsisCellWidth, 0, Metric::EllipsisCellWidth, frameHeight); + frameWidth -= Metric::EllipsisCellWidth; + } else { + *ellipsisFrame = KDRectZero; + } + KDSize inputSize = m_inputView.minimalSizeForOptimalDisplay(); KDSize outputSize = m_scrollableOutputView.minimalSizeForOptimalDisplay(); @@ -193,18 +217,16 @@ void HistoryViewCell::layoutSubviews(bool force) { outputY += inputSize.height(); } - m_inputView.setFrame(KDRect( + *inputFrame = KDRect( 0, inputY, - std::min(maxFrameWidth, inputSize.width()), - inputSize.height()), - force); - m_scrollableOutputView.setFrame(KDRect( - std::max(0, maxFrameWidth - outputSize.width()), + std::min(frameWidth, inputSize.width()), + inputSize.height()); + *outputFrame = KDRect( + std::max(0, frameWidth - outputSize.width()), outputY, - std::min(maxFrameWidth, outputSize.width()), - outputSize.height()), - force); + std::min(frameWidth, outputSize.width()), + outputSize.height()); } void HistoryViewCell::resetMemoization() { diff --git a/apps/calculation/history_view_cell.h b/apps/calculation/history_view_cell.h index 664f9e6ee..2cca12b62 100644 --- a/apps/calculation/history_view_cell.h +++ b/apps/calculation/history_view_cell.h @@ -33,9 +33,9 @@ class HistoryViewCell : public ::EvenOddCell, public Responder { public: constexpr static KDCoordinate k_margin = Metric::CommonSmallMargin; constexpr static KDCoordinate k_inputOutputViewsVerticalMargin = k_margin; - constexpr static KDCoordinate k_inputOutputViewsHorizontalMargin = Shared::AbstractScrollableMultipleExpressionsView::k_horizontalMargin; + constexpr static KDCoordinate k_inputViewHorizontalMargin = Shared::AbstractScrollableMultipleExpressionsView::k_horizontalMargin; + static KDCoordinate Height(Calculation * calculation, bool expanded); HistoryViewCell(Responder * parentResponder = nullptr); - static bool LayoutsCanBeSingleLine(KDCoordinate inputLayoutWidth, KDCoordinate outputLayoutWidth); static bool ViewsCanBeSingleLine(KDCoordinate inputViewWidth, KDCoordinate outputViewWidth); void cellDidSelectSubview(HistoryViewCellDataSource::SubviewType type, HistoryViewCellDataSource::SubviewType previousType = HistoryViewCellDataSource::SubviewType::None); void setEven(bool even) override; @@ -58,6 +58,7 @@ public: Calculation::AdditionalInformationType additionalInformationType() const { return m_calculationAdditionInformation; } private: constexpr static KDCoordinate k_resultWidth = 80; + void computeSubviewFrames(KDCoordinate frameWidth, KDCoordinate frameHeight, KDRect * ellipsisFrame, KDRect * inputFrame, KDRect * outputFrame); void reloadScroll(); void reloadOutputSelection(HistoryViewCellDataSource::SubviewType previousType); bool displayedEllipsis() const { diff --git a/apps/shared/scrollable_multiple_expressions_view.cpp b/apps/shared/scrollable_multiple_expressions_view.cpp index 789b0e42a..ea57f98a4 100644 --- a/apps/shared/scrollable_multiple_expressions_view.cpp +++ b/apps/shared/scrollable_multiple_expressions_view.cpp @@ -121,6 +121,41 @@ KDCoordinate AbstractScrollableMultipleExpressionsView::ContentCell::baseline(KD return std::max(std::max(leftViewBaseline, centerViewBaseline), rightViewBaseline); } +void AbstractScrollableMultipleExpressionsView::ContentCell::subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) { + // Subviews sizes + KDSize leftSize = leftExpressionView() ? leftExpressionView()->minimalSizeForOptimalDisplay() : KDSizeZero; + KDSize centerSize = displayCenter() ? m_centeredExpressionView.minimalSizeForOptimalDisplay() : KDSizeZero; + KDSize rightSize = m_rightExpressionView.minimalSizeForOptimalDisplay(); + + // Compute baselines + KDCoordinate leftBaseline = 0; + KDCoordinate centerBaseline = 0; + KDCoordinate rightBaseline = 0; + KDCoordinate viewBaseline = baseline(&leftBaseline, ¢erBaseline, &rightBaseline); + + // Layout left view + KDCoordinate currentWidth = 0; + if (leftExpressionView()) { + assert(leftFrame != nullptr); + *leftFrame = KDRect(currentWidth, viewBaseline - leftBaseline, leftSize); + currentWidth += leftSize.width() + AbstractScrollableMultipleExpressionsView::k_horizontalMargin; + } + + // Layout center expression + if (displayCenter()) { + assert(centerFrame != nullptr && approximateSignFrame != nullptr); + KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay(); + *centerFrame = KDRect(currentWidth, viewBaseline - centerBaseline, centerSize); + currentWidth += AbstractScrollableMultipleExpressionsView::k_horizontalMargin + centerSize.width(); + *approximateSignFrame = KDRect(currentWidth, viewBaseline - approximateSignSize.height()/2, approximateSignSize); + currentWidth += AbstractScrollableMultipleExpressionsView::k_horizontalMargin + approximateSignSize.width(); + } + + // Layout right expression + assert(rightFrame != nullptr); + *rightFrame = KDRect(currentWidth, viewBaseline - rightBaseline, rightSize); +} + KDSize AbstractScrollableMultipleExpressionsView::ContentCell::privateMinimalSizeForOptimalDisplay(bool forceFullDisplay) const { KDCoordinate width = 0; @@ -169,35 +204,25 @@ KDCoordinate AbstractScrollableMultipleExpressionsView::ContentCell::StandardApp } void AbstractScrollableMultipleExpressionsView::ContentCell::layoutSubviews(bool force) { - // Subviews sizes - KDSize leftSize = leftExpressionView() ? leftExpressionView()->minimalSizeForOptimalDisplay() : KDSizeZero; - KDSize centerSize = displayCenter() ? m_centeredExpressionView.minimalSizeForOptimalDisplay() : KDSizeZero; - KDSize rightSize = m_rightExpressionView.minimalSizeForOptimalDisplay(); - - // Compute baselines - KDCoordinate leftBaseline = 0; - KDCoordinate centerBaseline = 0; - KDCoordinate rightBaseline = 0; - KDCoordinate viewBaseline = baseline(&leftBaseline, ¢erBaseline, &rightBaseline); - - // Layout left view - KDCoordinate currentWidth = 0; - if (leftExpressionView()) { - leftExpressionView()->setFrame(KDRect(currentWidth, viewBaseline - leftBaseline, leftSize), force); - currentWidth += leftSize.width() + AbstractScrollableMultipleExpressionsView::k_horizontalMargin; + if (bounds().width() <= 0 || bounds().height() <= 0) { + // TODO Make this behaviour in a non-virtual layoutSublviews, and all layout subviews should become privateLayoutSubviews + return; } - - // Layout center expression - if (displayCenter()) { - KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay(); - m_centeredExpressionView.setFrame(KDRect(currentWidth, viewBaseline - centerBaseline, centerSize), force); - currentWidth += AbstractScrollableMultipleExpressionsView::k_horizontalMargin + centerSize.width(); - m_approximateSign.setFrame(KDRect(currentWidth, viewBaseline - approximateSignSize.height()/2, approximateSignSize), force); - currentWidth += AbstractScrollableMultipleExpressionsView::k_horizontalMargin + approximateSignSize.width(); + KDRect leftFrame = KDRectZero; + KDRect centerFrame = KDRectZero; + KDRect approximateSignFrame = KDRectZero; + KDRect rightFrame = KDRectZero; + subviewFrames(&leftFrame, ¢erFrame, &approximateSignFrame, &rightFrame); + if (leftExpressionView() != nullptr) { + leftExpressionView()->setFrame(leftFrame, force); + } + if (centeredExpressionView() != nullptr) { + centeredExpressionView()->setFrame(centerFrame, force); + } + m_approximateSign.setFrame(approximateSignFrame, force); + if (rightExpressionView() != nullptr) { + rightExpressionView()->setFrame(rightFrame, force); } - - // Layout right expression - m_rightExpressionView.setFrame(KDRect(currentWidth, viewBaseline - rightBaseline, rightSize), force); } AbstractScrollableMultipleExpressionsView::AbstractScrollableMultipleExpressionsView(Responder * parentResponder, View * contentCell) : diff --git a/apps/shared/scrollable_multiple_expressions_view.h b/apps/shared/scrollable_multiple_expressions_view.h index 5e4574415..89dc76b16 100644 --- a/apps/shared/scrollable_multiple_expressions_view.h +++ b/apps/shared/scrollable_multiple_expressions_view.h @@ -68,6 +68,7 @@ protected: int numberOfSubviews() const override; virtual Poincare::Layout layout() const override; KDCoordinate baseline(KDCoordinate * leftBaseline = nullptr, KDCoordinate * centerBaseline = nullptr, KDCoordinate * rightBaseline = nullptr) const; + void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame); private: constexpr static const KDFont * k_font = KDFont::LargeFont; const static I18n::Message k_defaultApproximateMessage = I18n::Message::AlmostEqual; diff --git a/escher/src/scroll_view.cpp b/escher/src/scroll_view.cpp index 35b049198..294ec5350 100644 --- a/escher/src/scroll_view.cpp +++ b/escher/src/scroll_view.cpp @@ -117,6 +117,9 @@ KDRect ScrollView::visibleContentRect() { } void ScrollView::layoutSubviews(bool force) { + if (bounds().isEmpty()) { + return; + } KDRect r1 = KDRectZero; KDRect r2 = KDRectZero; KDRect innerFrame = decorator()->layoutIndicators(minimalSizeForOptimalDisplay(), contentOffset(), bounds(), &r1, &r2, force); diff --git a/kandinsky/src/rect.cpp b/kandinsky/src/rect.cpp index f99a09076..4b4be21c4 100644 --- a/kandinsky/src/rect.cpp +++ b/kandinsky/src/rect.cpp @@ -174,5 +174,5 @@ KDRect KDRect::movedTo(KDPoint p) const { } bool KDRect::isEmpty() const { - return (width() == 0 || height() == 0); + return (width() == 0 || height() == 0); //TODO <= 0 }