mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-21 14:50:44 +01:00
Merge branch 'omega-hotfix' into omega-dev
This commit is contained in:
@@ -24,6 +24,13 @@ int ExpressionsListController::reusableCellCount(int type) {
|
||||
return k_maxNumberOfCells;
|
||||
}
|
||||
|
||||
void ExpressionsListController::viewDidDisappear() {
|
||||
// Reset cell memoization to avoid taking extra space in the pool
|
||||
for (int i = 0; i < k_maxNumberOfCells; i++) {
|
||||
m_cells[i].setLayout(Layout());
|
||||
}
|
||||
}
|
||||
|
||||
HighlightCell * ExpressionsListController::reusableCell(int index, int type) {
|
||||
return &m_cells[index];
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
ExpressionsListController(Responder * parentResponder, EditExpressionController * editExpressionController);
|
||||
|
||||
// Responder
|
||||
void viewDidDisappear() override;
|
||||
void didEnterResponderChain(Responder * previousFirstResponder) override;
|
||||
|
||||
//ListViewDataSource
|
||||
|
||||
@@ -42,6 +42,10 @@ void IllustratedListController::viewDidDisappear() {
|
||||
Poincare::Symbol s = Poincare::Symbol::Builder(expressionSymbol());
|
||||
context->setExpressionForSymbolAbstract(m_savedExpression, s);
|
||||
}
|
||||
// Reset cell memoization to avoid taking extra space in the pool
|
||||
for (int i = 0; i < k_maxNumberOfAdditionalCalculations; i++) {
|
||||
m_additionalCalculationCells[i].resetMemoization();
|
||||
}
|
||||
}
|
||||
|
||||
int IllustratedListController::numberOfRows() const {
|
||||
|
||||
@@ -32,8 +32,12 @@ bool ListController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
|
||||
char buffer[Constant::MaxSerializedExpressionSize];
|
||||
textAtIndex(buffer, Constant::MaxSerializedExpressionSize, selectedRow());
|
||||
m_editExpressionController->insertTextBody(buffer);
|
||||
/* The order is important here: we dismiss the pop-up first because it
|
||||
* clears the Poincare pool from the layouts used to display the pop-up.
|
||||
* Thereby it frees memory to do Poincare computations required by
|
||||
* insertTextBody. */
|
||||
Container::activeApp()->dismissModalViewController();
|
||||
m_editExpressionController->insertTextBody(buffer);
|
||||
Container::activeApp()->setFirstResponder(m_editExpressionController);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,15 @@
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
void ScrollableThreeExpressionsView::resetMemoization() {
|
||||
setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout());
|
||||
}
|
||||
|
||||
void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) {
|
||||
Poincare::Context * context = App::app()->localContext();
|
||||
|
||||
// Clean the layouts to make room in the pool
|
||||
setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout());
|
||||
resetMemoization();
|
||||
|
||||
// Create the input layout
|
||||
Poincare::Layout inputLayout = calculation->createInputLayout();
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
setMargins(Metric::CommonSmallMargin, Metric::CommonSmallMargin, Metric::CommonSmallMargin, Metric::CommonSmallMargin); // Left Right margins are already added by TableCell
|
||||
setBackgroundColor(KDColorWhite);
|
||||
}
|
||||
void resetMemoization();
|
||||
void setCalculation(Calculation * calculation);
|
||||
private:
|
||||
class ContentCell : public Shared::AbstractScrollableMultipleExpressionsView::ContentCell {
|
||||
@@ -50,6 +51,7 @@ public:
|
||||
View * labelView() const override { return (View *)&m_view; }
|
||||
|
||||
void setHighlighted(bool highlight) override { m_view.evenOddCell()->setHighlighted(highlight); }
|
||||
void resetMemoization() { m_view.resetMemoization(); }
|
||||
void setCalculation(Calculation * calculation);
|
||||
void setDisplayCenter(bool display);
|
||||
ScrollableThreeExpressionsView::SubviewPosition selectedSubviewPosition() { return m_view.selectedSubviewPosition(); }
|
||||
|
||||
@@ -313,6 +313,12 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
|
||||
return m_displayOutput;
|
||||
}
|
||||
|
||||
void Calculation::forceDisplayOutput(DisplayOutput d) {
|
||||
m_displayOutput = d;
|
||||
// Reset heights memoization as it might have changed when we modify the display output
|
||||
m_height = -1;
|
||||
m_expandedHeight = -1;
|
||||
}
|
||||
bool Calculation::shouldOnlyDisplayExactOutput() {
|
||||
/* If the input is a "store in a function", do not display the approximate
|
||||
* result. This prevents x->f(x) from displaying x = undef. */
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
|
||||
// Displayed output
|
||||
DisplayOutput displayOutput(Poincare::Context * context);
|
||||
void forceDisplayOutput(DisplayOutput d) { m_displayOutput = d; }
|
||||
void forceDisplayOutput(DisplayOutput d);
|
||||
bool shouldOnlyDisplayExactOutput();
|
||||
EqualSign exactAndApproximateDisplayedOutputsAreEqual(Poincare::Context * context);
|
||||
|
||||
|
||||
@@ -231,6 +231,10 @@ void HistoryController::historyViewCellDidChangeSelection(HistoryViewCell ** cel
|
||||
m_selectableTableView.reloadData();
|
||||
}
|
||||
|
||||
// It might be necessary to scroll to the sub type if the cell overflows the screen
|
||||
if (selectedRow() >= 0) {
|
||||
m_selectableTableView.scrollToSubviewOfTypeOfCellAtLocation(type, m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow());
|
||||
}
|
||||
// Fill the selected cell and the previous selected cell because cells repartition might have changed
|
||||
*cell = static_cast<HistoryViewCell *>(m_selectableTableView.selectedCell());
|
||||
*previousCell = static_cast<HistoryViewCell *>(m_selectableTableView.cellAtLocation(previousSelectedCellX, previousSelectedCellY));
|
||||
|
||||
@@ -309,9 +309,6 @@ bool HistoryViewCell::handleEvent(Ion::Events::Event event) {
|
||||
otherSubviewType = HistoryViewCellDataSource::SubviewType::Output;
|
||||
}
|
||||
m_dataSource->setSelectedSubviewType(otherSubviewType, true);
|
||||
CalculationSelectableTableView * tableView = (CalculationSelectableTableView *)parentResponder();
|
||||
tableView->scrollToSubviewOfTypeOfCellAtLocation(otherSubviewType, tableView->selectedColumn(), tableView->selectedRow());
|
||||
Container::activeApp()->setFirstResponder(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -24,18 +24,6 @@ void CalculationSelectableTableView::scrollToCell(int i, int j) {
|
||||
KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(dataSource()->numberOfRows()) - maxContentHeightDisplayableWithoutScrolling();
|
||||
setContentOffset(KDPoint(contentOffsetX, contentOffsetY));
|
||||
}
|
||||
if (dataSource()->numberOfRows() > j && dataSource()->numberOfColumns() > i && dataSource()->rowHeight(j) > bounds().height()) {
|
||||
KDCoordinate contentOffsetX = contentOffset().x();
|
||||
KDCoordinate contentOffsetY = contentOffset().y();
|
||||
if (contentOffsetY > dataSource()->cumulatedHeightFromIndex(j) && contentOffsetY > dataSource()->cumulatedHeightFromIndex(j+1)) {
|
||||
// Let's scroll the tableView to align the top of the cell to the top
|
||||
contentOffsetY = dataSource()->cumulatedHeightFromIndex(j);
|
||||
} else {
|
||||
// Let's scroll the tableView to align the bottom of the cell to the bottom
|
||||
contentOffsetY = dataSource()->cumulatedHeightFromIndex(j+1) - maxContentHeightDisplayableWithoutScrolling();
|
||||
}
|
||||
setContentOffset(KDPoint(contentOffsetX, contentOffsetY));
|
||||
}
|
||||
}
|
||||
|
||||
void CalculationSelectableTableView::scrollToSubviewOfTypeOfCellAtLocation(HistoryViewCellDataSource::SubviewType subviewType, int i, int j) {
|
||||
@@ -44,10 +32,8 @@ void CalculationSelectableTableView::scrollToSubviewOfTypeOfCellAtLocation(Histo
|
||||
}
|
||||
/* As we scroll, the selected calculation does not use the same history view
|
||||
* cell, thus, we want to deselect the previous used history view cell. */
|
||||
if (selectedRow() >= 0) {
|
||||
HighlightCell * previousCell = selectedCell();
|
||||
previousCell->setHighlighted(false);
|
||||
}
|
||||
unhighlightSelectedCell();
|
||||
|
||||
/* Main part of the scroll */
|
||||
KDCoordinate contentOffsetX = contentOffset().x();
|
||||
KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(j+1) - maxContentHeightDisplayableWithoutScrolling();
|
||||
@@ -58,16 +44,13 @@ void CalculationSelectableTableView::scrollToSubviewOfTypeOfCellAtLocation(Histo
|
||||
contentOffsetY = dataSource()->cumulatedHeightFromIndex(j);
|
||||
}
|
||||
}
|
||||
/* For the same reason, we have to rehighlight the new history view cell and
|
||||
* inform the delegate which history view cell is highlighted even if the
|
||||
* selected calculation has not changed. */
|
||||
setContentOffset(KDPoint(contentOffsetX, contentOffsetY));
|
||||
HighlightCell * cell = cellAtLocation(i, j);
|
||||
/* For the same reason, we have to rehighlight the new history view cell and
|
||||
* reselect the first responder. */
|
||||
HistoryViewCell * cell = (HistoryViewCell *)(selectedCell());
|
||||
assert(cell);
|
||||
cell->setHighlighted(true);
|
||||
if (m_delegate) {
|
||||
m_delegate->tableViewDidChangeSelection(this, selectedColumn(), selectedRow());
|
||||
}
|
||||
Container::activeApp()->setFirstResponder(cell);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ void FunctionApp::Snapshot::storageDidChangeForRecord(const Ion::Storage::Record
|
||||
|
||||
void FunctionApp::willBecomeInactive() {
|
||||
if (m_modalViewController.isDisplayingModal()) {
|
||||
m_modalViewController.dismissModalViewController();
|
||||
m_modalViewController.dismissModalViewController(true);
|
||||
}
|
||||
if (inputViewController()->isDisplayingModal()) {
|
||||
inputViewController()->abortEditionAndDismiss();
|
||||
|
||||
@@ -60,7 +60,7 @@ App::App(Snapshot * snapshot) :
|
||||
|
||||
void App::willBecomeInactive() {
|
||||
if (m_modalViewController.isDisplayingModal()) {
|
||||
m_modalViewController.dismissModalViewController();
|
||||
m_modalViewController.dismissModalViewController(true);
|
||||
}
|
||||
if (inputViewController()->isDisplayingModal()) {
|
||||
inputViewController()->abortEditionAndDismiss();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "shared/continuous_function.h"
|
||||
#include <escher/metric.h>
|
||||
#include <ion/unicode/utf8_decoder.h>
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/matrix_layout.h>
|
||||
#include <poincare/preferences.h>
|
||||
@@ -235,10 +236,20 @@ Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record,
|
||||
assert(m_firstMemoizedLayoutIndex >= 0);
|
||||
}
|
||||
assert(index >= m_firstMemoizedLayoutIndex && index < m_firstMemoizedLayoutIndex + k_maxNumberOfDisplayedRows);
|
||||
Layout result;
|
||||
if (m_layouts[index-m_firstMemoizedLayoutIndex].isUninitialized()) {
|
||||
m_layouts[index-m_firstMemoizedLayoutIndex] = GlobalContext::LayoutForRecord(record);
|
||||
/* Creating the layout of a very long variable might throw a pool exception.
|
||||
* We want to catch it and return a dummy layout instead, otherwise the user
|
||||
* won't be able to open the variable box again, until she deletes the
|
||||
* problematic variable -> and she has no help to remember its name, as she
|
||||
* can't open the variable box. */
|
||||
Poincare::ExceptionCheckpoint ecp;
|
||||
if (ExceptionRun(ecp)) {
|
||||
result = GlobalContext::LayoutForRecord(record);
|
||||
}
|
||||
}
|
||||
return m_layouts[index-m_firstMemoizedLayoutIndex];
|
||||
m_layouts[index-m_firstMemoizedLayoutIndex] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
const char * VariableBoxController::extension() const {
|
||||
|
||||
Reference in New Issue
Block a user