[apps/calculation] Calculation on 2 lines if does not fit when expanded

Scenario: 1+1+1+1+1+1+1+10.5 fits on one line when not expanded, but
when the exact result is displayed not -> we thus always display it on
two lines
This commit is contained in:
Léa Saviot
2020-05-26 10:54:14 +02:00
committed by EmilieNumworks
parent feee0a673c
commit 5535145b51
4 changed files with 75 additions and 43 deletions

View File

@@ -126,6 +126,9 @@ Layout Calculation::createApproximateOutputLayout(Context * context, bool * coul
}
KDCoordinate Calculation::height(Context * context, KDCoordinate verticalMarginBetweenLayouts, 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
@@ -138,12 +141,19 @@ KDCoordinate Calculation::height(Context * context, KDCoordinate verticalMarginB
KDCoordinate inputWidth = inputLayout.layoutSize().width();
KDCoordinate inputBaseline = inputLayout.baseline();
// Get output height
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);
KDCoordinate maxOutputWidth = -1;
{
DisplayOutput displayType = displayOutput(context);
bool displaysExactOnly = displayType == DisplayOutput::ExactOnly;
bool displayApproximateOnly = displayType == DisplayOutput::ApproximateOnly
|| (!expanded
@@ -154,7 +164,8 @@ KDCoordinate Calculation::height(Context * context, KDCoordinate verticalMarginB
KDCoordinate exactOutputBelowBaseline = 0;
// Get exact output info if needed
if (displaysExactOnly || !displayApproximateOnly) {
bool displaysExact = displaysExactOnly || !displayApproximateOnly;
if (displaysExact || shouldComputeMaxOutputWidthForSingleLine) {
bool couldNotCreateExactLayout = false;
Poincare::Layout exactLayout = createExactOutputLayout(&couldNotCreateExactLayout);
if (couldNotCreateExactLayout) {
@@ -170,9 +181,12 @@ KDCoordinate Calculation::height(Context * context, KDCoordinate verticalMarginB
}
} else {
KDSize exactSize = exactLayout.layoutSize();
exactOutputWidth = exactSize.width();
exactOutputBaseline = exactLayout.baseline();
exactOutputBelowBaseline = exactSize.height() - exactOutputBaseline;
maxOutputWidth = exactSize.width();
if (displaysExact) {
exactOutputWidth = exactSize.width();
exactOutputBaseline = exactLayout.baseline();
exactOutputBelowBaseline = exactSize.height() - exactOutputBaseline;
}
}
}
@@ -181,19 +195,24 @@ KDCoordinate Calculation::height(Context * context, KDCoordinate verticalMarginB
KDCoordinate approximateOutputBelowBaseline = 0;
// Get approximate output info if needed
if (displayApproximateOnly || !displaysExactOnly) {
bool displaysApproximate = displayApproximateOnly || !displaysExactOnly;
if (displaysApproximate || shouldComputeMaxOutputWidthForSingleLine) {
bool couldNotCreateApproximateLayout = false;
Layout approximateLayout = createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
Poincare::ExceptionCheckpoint::Raise();
}
KDSize approximateOutputSize = approximateLayout.layoutSize();
approximateOutputWidth = approximateOutputSize.width();
approximateOutputBaseline = approximateLayout.baseline();
approximateOutputBelowBaseline = approximateOutputSize.height() - approximateOutputBaseline;
maxOutputWidth += approximateOutputSize.width();
if (displaysApproximate) {
approximateOutputWidth = approximateOutputSize.width();
approximateOutputBaseline = approximateLayout.baseline();
approximateOutputBelowBaseline = approximateOutputSize.height() - approximateOutputBaseline;
}
}
// Compute the output info
maxOutputWidth += AbstractScrollableMultipleExpressionsView::StandardApproximateViewAndMarginsSize();
outputWidth = exactOutputWidth
+ ((exactOutputWidth > 0 && approximateOutputWidth > 0) ? AbstractScrollableMultipleExpressionsView::StandardApproximateViewAndMarginsSize() : 0)
+ approximateOutputWidth;
@@ -201,7 +220,7 @@ KDCoordinate Calculation::height(Context * context, KDCoordinate verticalMarginB
outputHeightBelowBaseline = std::max(exactOutputBelowBaseline, approximateOutputBelowBaseline);
}
if (forceSingleLine || canBeSingleLine(inputWidth, outputWidth)) {
if (forceSingleLine || canBeSingleLine(inputWidth, maxOutputWidth)) {
result = std::max(inputBaseline, outputBaseline) // Above the baseline
+ std::max(static_cast<KDCoordinate>(inputHeight - inputBaseline), outputHeightBelowBaseline) // Below the baseline
+ 2 * verticalMarginAroundLayouts;

View File

@@ -155,7 +155,6 @@ View * HistoryViewCell::subviewAtIndex(int index) {
}
bool HistoryViewCell::LayoutsCanBeSingleLine(KDCoordinate inputLayoutWidth, KDCoordinate outputLayoutWidth) {
// k_margin is the separation between the input and output.
return ViewsCanBeSingleLine(inputLayoutWidth + 2 * k_inputOutputViewsHorizontalMargin, outputLayoutWidth + 2 * k_inputOutputViewsHorizontalMargin);
}
@@ -175,7 +174,9 @@ void HistoryViewCell::layoutSubviews(bool force) {
KDSize inputSize = m_inputView.minimalSizeForOptimalDisplay();
KDSize outputSize = m_scrollableOutputView.minimalSizeForOptimalDisplay();
m_calculationSingleLine = ViewsCanBeSingleLine(inputSize.width(), outputSize.width());
/* To compute if the calculation is on a single line, use the expanded width
* if there is both an exact and an approximate layout. */
m_calculationSingleLine = ViewsCanBeSingleLine(inputSize.width(), m_scrollableOutputView.minimalSizeForOptimalDisplayFullSize().width());
KDCoordinate inputY = k_margin;
KDCoordinate outputY = k_margin;

View File

@@ -55,37 +55,11 @@ void AbstractScrollableMultipleExpressionsView::ContentCell::reloadTextColor() {
}
KDSize AbstractScrollableMultipleExpressionsView::ContentCell::minimalSizeForOptimalDisplay() const {
KDCoordinate width = 0;
return privateMinimalSizeForOptimalDisplay(false);
}
// Compute baselines
KDCoordinate leftBaseline = 0;
KDCoordinate centerBaseline = 0;
KDCoordinate rightBaseline = 0;
KDCoordinate viewBaseline = baseline(&leftBaseline, &centerBaseline, &rightBaseline);
KDSize leftSize = KDSizeZero;
if (leftExpressionView() && !leftExpressionView()->layout().isUninitialized()) {
leftSize = leftExpressionView()->minimalSizeForOptimalDisplay();
width += leftSize.width() + AbstractScrollableMultipleExpressionsView::k_horizontalMargin;
}
KDSize centerSize = KDSizeZero;
if (displayCenter()) {
centerSize = m_centeredExpressionView.minimalSizeForOptimalDisplay();
width += centerSize.width() + 2 * AbstractScrollableMultipleExpressionsView::k_horizontalMargin + m_approximateSign.minimalSizeForOptimalDisplay().width();
}
KDSize rightSize = m_rightExpressionView.minimalSizeForOptimalDisplay();
width += rightSize.width();
KDCoordinate height = viewBaseline
+ std::max(
std::max(
centerSize.height() - centerBaseline,
rightSize.height() - rightBaseline),
leftSize.height() - leftBaseline);
return KDSize(width, height);
KDSize AbstractScrollableMultipleExpressionsView::ContentCell::minimalSizeForOptimalDisplayFullSize() const {
return privateMinimalSizeForOptimalDisplay(true);
}
void AbstractScrollableMultipleExpressionsView::ContentCell::setSelectedSubviewPosition(AbstractScrollableMultipleExpressionsView::SubviewPosition subviewPosition) {
@@ -147,6 +121,40 @@ KDCoordinate AbstractScrollableMultipleExpressionsView::ContentCell::baseline(KD
return std::max(std::max(leftViewBaseline, centerViewBaseline), rightViewBaseline);
}
KDSize AbstractScrollableMultipleExpressionsView::ContentCell::privateMinimalSizeForOptimalDisplay(bool forceFullDisplay) const {
KDCoordinate width = 0;
// Compute baselines
KDCoordinate leftBaseline = 0;
KDCoordinate centerBaseline = 0;
KDCoordinate rightBaseline = 0;
KDCoordinate viewBaseline = baseline(&leftBaseline, &centerBaseline, &rightBaseline);
KDSize leftSize = KDSizeZero;
if (leftExpressionView() && !leftExpressionView()->layout().isUninitialized()) {
leftSize = leftExpressionView()->minimalSizeForOptimalDisplay();
width += leftSize.width() + AbstractScrollableMultipleExpressionsView::k_horizontalMargin;
}
KDSize centerSize = KDSizeZero;
if (displayCenter() || (forceFullDisplay && !m_centeredExpressionView.layout().isUninitialized())) {
centerSize = m_centeredExpressionView.minimalSizeForOptimalDisplay();
width += centerSize.width() + 2 * AbstractScrollableMultipleExpressionsView::k_horizontalMargin + m_approximateSign.minimalSizeForOptimalDisplay().width();
}
KDSize rightSize = m_rightExpressionView.minimalSizeForOptimalDisplay();
width += rightSize.width();
KDCoordinate height = viewBaseline
+ std::max(
std::max(
centerSize.height() - centerBaseline,
rightSize.height() - rightBaseline),
leftSize.height() - leftBaseline);
return KDSize(width, height);
}
View * AbstractScrollableMultipleExpressionsView::ContentCell::subviewAtIndex(int index) {
bool leftIsVisible = leftExpressionView() != nullptr;
if (leftIsVisible && index == 0) {

View File

@@ -47,6 +47,7 @@ protected:
void setEven(bool even) override;
void reloadTextColor();
KDSize minimalSizeForOptimalDisplay() const override;
KDSize minimalSizeForOptimalDisplayFullSize() const;
virtual ExpressionView * leftExpressionView() const { return nullptr; }
ExpressionView * rightExpressionView() {
return &m_rightExpressionView;
@@ -70,6 +71,7 @@ protected:
private:
constexpr static const KDFont * k_font = KDFont::LargeFont;
const static I18n::Message k_defaultApproximateMessage = I18n::Message::AlmostEqual;
KDSize privateMinimalSizeForOptimalDisplay(bool forceFullDisplay) const;
View * subviewAtIndex(int index) override;
ExpressionView m_rightExpressionView;
MessageTextView m_approximateSign;
@@ -91,7 +93,9 @@ public:
Metric::CommonLargeMargin
);
}
KDSize minimalSizeForOptimalDisplayFullSize() const {
return constContentCell()->minimalSizeForOptimalDisplayFullSize();
}
private:
ContentCell * contentCell() override { return &m_contentCell; };
const ContentCell * constContentCell() const override { return &m_contentCell; };