mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps/calc] Display ApproximateOnly if exact layout cannot be created
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "scrollable_input_exact_approximate_expressions_cell.h"
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
#include "../app.h"
|
||||
|
||||
namespace Calculation {
|
||||
@@ -17,9 +18,20 @@ void ScrollableInputExactApproximateExpressionsView::setCalculation(Calculation
|
||||
contentCell()->leftExpressionView()->setLayout(Poincare::Layout());
|
||||
setLayouts(Poincare::Layout(), Poincare::Layout());
|
||||
|
||||
Calculation::DisplayOutput displayOutput = calculation->displayOutput(context);
|
||||
contentCell()->leftExpressionView()->setLayout(calculation->createInputLayout());
|
||||
Poincare::Layout leftOutputLayout = calculation->createExactOutputLayout();
|
||||
Poincare::Layout leftOutputLayout = Poincare::Layout();
|
||||
if (Calculation::DisplaysExact(calculation->displayOutput(context))) {
|
||||
bool couldNotCreateExactLayout = false;
|
||||
leftOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout);
|
||||
if (couldNotCreateExactLayout) {
|
||||
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ExactOnly) {
|
||||
Poincare::ExceptionCheckpoint::Raise();
|
||||
} else {
|
||||
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
Calculation::DisplayOutput displayOutput = calculation->displayOutput(context);
|
||||
Poincare::Layout rightOutputLayout = (displayOutput == Calculation::DisplayOutput::ExactOnly) ? leftOutputLayout :
|
||||
calculation->createApproximateOutputLayout(context);
|
||||
setLayouts(rightOutputLayout, leftOutputLayout);
|
||||
|
||||
@@ -72,33 +72,67 @@ Layout Calculation::createInputLayout() {
|
||||
return input().createLayout(Preferences::PrintFloatMode::Decimal, PrintFloat::k_numberOfStoredSignificantDigits);
|
||||
}
|
||||
|
||||
Layout Calculation::createExactOutputLayout() {
|
||||
return PoincareHelpers::CreateLayout(exactOutput());
|
||||
Layout Calculation::createExactOutputLayout(bool * couldNotCreateExactLayout) {
|
||||
Poincare::ExceptionCheckpoint ecp;
|
||||
if (ExceptionRun(ecp)) {
|
||||
return PoincareHelpers::CreateLayout(exactOutput());
|
||||
} else {
|
||||
*couldNotCreateExactLayout = true;
|
||||
return Layout();
|
||||
}
|
||||
}
|
||||
|
||||
Layout Calculation::createApproximateOutputLayout(Context * context) {
|
||||
return PoincareHelpers::CreateLayout(approximateOutput(context));
|
||||
Poincare::ExceptionCheckpoint ecp;
|
||||
if (ExceptionRun(ecp)) {
|
||||
return PoincareHelpers::CreateLayout(approximateOutput(context));
|
||||
} else {
|
||||
return Layout();
|
||||
}
|
||||
}
|
||||
|
||||
KDCoordinate Calculation::height(Context * context, bool expanded, bool allExpressionsInline) {
|
||||
KDCoordinate result = expanded ? m_expandedHeight : m_height;
|
||||
if (result < 0) {
|
||||
DisplayOutput display = displayOutput(context);
|
||||
Layout inputLayout = createInputLayout();
|
||||
KDCoordinate inputHeight = inputLayout.layoutSize().height();
|
||||
KDCoordinate inputBaseline = inputLayout.baseline();
|
||||
if (display == DisplayOutput::ExactOnly) {
|
||||
Layout exactLayout = createExactOutputLayout();
|
||||
KDCoordinate exactOutputHeight = exactLayout.layoutSize().height();
|
||||
if (allExpressionsInline) {
|
||||
KDCoordinate exactOutputBaseline = exactLayout.baseline();
|
||||
result = maxCoordinate(inputBaseline, exactOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, exactOutputHeight-exactOutputBaseline);
|
||||
KDCoordinate result = expanded ? m_expandedHeight : m_height;
|
||||
if (result >= 0) {
|
||||
// Height already computed
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get input height
|
||||
Layout inputLayout = createInputLayout();
|
||||
KDCoordinate inputHeight = inputLayout.layoutSize().height();
|
||||
KDCoordinate inputBaseline = inputLayout.baseline();
|
||||
|
||||
// Get exact output height if needed
|
||||
Poincare::Layout exactLayout;
|
||||
bool couldNotCreateExactLayout = false;
|
||||
if (DisplaysExact(displayOutput(context))) {
|
||||
// Create the exact output layout
|
||||
exactLayout = createExactOutputLayout(&couldNotCreateExactLayout);
|
||||
if (couldNotCreateExactLayout) {
|
||||
if (displayOutput(context) != DisplayOutput::ExactOnly) {
|
||||
forceDisplayOutput(DisplayOutput::ApproximateOnly);
|
||||
} else {
|
||||
result = inputHeight+exactOutputHeight;
|
||||
/* We should only display the exact result, but we cannot create it
|
||||
* -> raise an exception. */
|
||||
ExceptionCheckpoint::Raise();
|
||||
}
|
||||
} else if (display == DisplayOutput::ApproximateOnly || (!expanded && display == DisplayOutput::ExactAndApproximateToggle)) {
|
||||
Layout approximateLayout = createApproximateOutputLayout(context);
|
||||
KDCoordinate approximateOutputHeight = approximateLayout.layoutSize().height();
|
||||
}
|
||||
}
|
||||
|
||||
DisplayOutput display = displayOutput(context);
|
||||
if (display == DisplayOutput::ExactOnly) {
|
||||
KDCoordinate exactOutputHeight = exactLayout.layoutSize().height();
|
||||
if (allExpressionsInline) {
|
||||
KDCoordinate exactOutputBaseline = exactLayout.baseline();
|
||||
result = maxCoordinate(inputBaseline, exactOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, exactOutputHeight-exactOutputBaseline);
|
||||
} else {
|
||||
result = inputHeight+exactOutputHeight;
|
||||
}
|
||||
} else {
|
||||
Layout approximateLayout = createApproximateOutputLayout(context);
|
||||
KDCoordinate approximateOutputHeight = approximateLayout.layoutSize().height();
|
||||
if (display == DisplayOutput::ApproximateOnly || (!expanded && display == DisplayOutput::ExactAndApproximateToggle)) {
|
||||
if (allExpressionsInline) {
|
||||
KDCoordinate approximateOutputBaseline = approximateLayout.baseline();
|
||||
result = maxCoordinate(inputBaseline, approximateOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline);
|
||||
@@ -107,31 +141,29 @@ KDCoordinate Calculation::height(Context * context, bool expanded, bool allExpre
|
||||
}
|
||||
} else {
|
||||
assert(display == DisplayOutput::ExactAndApproximate || (display == DisplayOutput::ExactAndApproximateToggle && expanded));
|
||||
Layout approximateLayout = createApproximateOutputLayout(context);
|
||||
Layout exactLayout = createExactOutputLayout();
|
||||
KDCoordinate approximateOutputHeight = approximateLayout.layoutSize().height();
|
||||
KDCoordinate exactOutputHeight = exactLayout.layoutSize().height();
|
||||
KDCoordinate exactOutputBaseline = exactLayout.baseline();
|
||||
KDCoordinate approximateOutputBaseline = approximateLayout.baseline();
|
||||
if (allExpressionsInline) {
|
||||
result = maxCoordinate(inputBaseline, maxCoordinate(exactOutputBaseline, approximateOutputBaseline)) + maxCoordinate(inputHeight - inputBaseline, maxCoordinate(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline));
|
||||
} else {
|
||||
KDCoordinate outputHeight = maxCoordinate(exactOutputBaseline, approximateOutputBaseline) + maxCoordinate(exactOutputHeight-exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline);
|
||||
result = inputHeight + outputHeight;
|
||||
KDCoordinate outputHeight = maxCoordinate(exactOutputBaseline, approximateOutputBaseline) + maxCoordinate(exactOutputHeight-exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline);
|
||||
result = inputHeight + outputHeight;
|
||||
}
|
||||
}
|
||||
/* For all display output except ExactAndApproximateToggle, the selected
|
||||
* height and the usual height are identical. We update both heights in
|
||||
* theses cases. */
|
||||
if (display != DisplayOutput::ExactAndApproximateToggle) {
|
||||
m_height = result;
|
||||
}
|
||||
|
||||
/* For all display outputs except ExactAndApproximateToggle, the selected
|
||||
* height and the usual height are identical. We update both heights in
|
||||
* theses cases. */
|
||||
if (display != DisplayOutput::ExactAndApproximateToggle) {
|
||||
m_height = result;
|
||||
m_expandedHeight = result;
|
||||
} else {
|
||||
if (expanded) {
|
||||
m_expandedHeight = result;
|
||||
} else {
|
||||
if (expanded) {
|
||||
m_expandedHeight = result;
|
||||
} else {
|
||||
m_height = result;
|
||||
}
|
||||
m_height = result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
ExactAndApproximate,
|
||||
ExactAndApproximateToggle
|
||||
};
|
||||
static bool DisplaysExact(DisplayOutput d) { return d != DisplayOutput::ApproximateOnly; }
|
||||
|
||||
/* It is not really the minimal size, but it clears enough space for most
|
||||
* calculations instead of clearing less space, then fail to serialize, clear
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
|
||||
// Layouts
|
||||
Poincare::Layout createInputLayout();
|
||||
Poincare::Layout createExactOutputLayout();
|
||||
Poincare::Layout createExactOutputLayout(bool * couldNotCreateExactLayout);
|
||||
Poincare::Layout createApproximateOutputLayout(Poincare::Context * context);
|
||||
|
||||
// Memoization of height
|
||||
@@ -73,6 +74,7 @@ public:
|
||||
|
||||
// Displayed output
|
||||
DisplayOutput displayOutput(Poincare::Context * context);
|
||||
void forceDisplayOutput(DisplayOutput d) { m_displayOutput = d; }
|
||||
bool shouldOnlyDisplayExactOutput();
|
||||
EqualSign exactAndApproximateDisplayedOutputsAreEqual(Poincare::Context * context);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "app.h"
|
||||
#include "../constant.h"
|
||||
#include "selectable_table_view.h"
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -177,15 +178,27 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
|
||||
// Memoization
|
||||
m_calculationCRC32 = newCalculationCRC;
|
||||
m_calculationExpanded = expanded;
|
||||
m_calculationDisplayOutput = calculation->displayOutput(context);
|
||||
m_calculationAdditionInformation = calculation->additionalInformationType(context);
|
||||
m_inputView.setLayout(calculation->createInputLayout());
|
||||
/* Both output expressions have to be updated at the same time. Otherwise,
|
||||
* when updating one layout, if the second one still points to a deleted
|
||||
* layout, calling to layoutSubviews() would fail. */
|
||||
Poincare::Layout leftOutputLayout = calculation->createExactOutputLayout();
|
||||
Poincare::Layout rightOutputLayout = (m_calculationDisplayOutput == Calculation::DisplayOutput::ExactOnly) ? leftOutputLayout :
|
||||
calculation->createApproximateOutputLayout(context);
|
||||
Poincare::Layout leftOutputLayout = Poincare::Layout();
|
||||
if (Calculation::DisplaysExact(calculation->displayOutput(context))) {
|
||||
bool couldNotCreateExactLayout = false;
|
||||
leftOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout);
|
||||
if (couldNotCreateExactLayout) {
|
||||
if (calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
|
||||
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
|
||||
} else {
|
||||
/* We should only display the exact result, but we cannot create it
|
||||
* -> raise an exception. */
|
||||
Poincare::ExceptionCheckpoint::Raise();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_calculationDisplayOutput = calculation->displayOutput(context);
|
||||
Poincare::Layout rightOutputLayout = (m_calculationDisplayOutput == Calculation::DisplayOutput::ExactOnly) ? leftOutputLayout : calculation->createApproximateOutputLayout(context);
|
||||
// We must set which subviews are displayed before setLayouts to mark the right rectangle as dirty
|
||||
m_scrollableOutputView.setDisplayLeft(m_calculationExpanded && m_calculationAdditionInformation != Poincare::Expression::AdditionalInformationType::None);
|
||||
m_scrollableOutputView.setDisplayCenter(m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximate || (m_calculationExpanded && m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximateToggle));
|
||||
|
||||
Reference in New Issue
Block a user