[omega] 1.20.3

This commit is contained in:
Quentin Guidée
2020-08-26 14:17:23 +02:00
78 changed files with 389 additions and 572 deletions

View File

@@ -40,7 +40,6 @@ info:
@echo "BUILD_DIR = $(BUILD_DIR)"
@echo "PLATFORM" = $(PLATFORM)
@echo "DEBUG" = $(DEBUG)
@echo "LEDS_CHOICE" = $(LEDS_CHOICE)
@echo "EPSILON_GETOPT" = $(EPSILON_GETOPT)
@echo "ESCHER_LOG_EVENTS_BINARY" = $(ESCHER_LOG_EVENTS_BINARY)
@echo "QUIZ_USE_CONSOLE" = $(QUIZ_USE_CONSOLE)

View File

@@ -41,7 +41,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make MODEL=n0100 clean
make MODEL=n0100 USERNAME="{Your name, max 15 characters}" -j4
make MODEL=n0100 OMEGA_USERNAME="{Your name, max 15 characters}" -j4
make MODEL=n0100 epsilon_flash
```
@@ -58,7 +58,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make USERNAME="{Your name, max 15 characters}" -j4
make OMEGA_USERNAME="{Your name, max 15 characters}" -j4
make epsilon_flash
```
@@ -77,10 +77,10 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make MODEL=n0100 USERNAME="" -j8
make MODEL=n0100 USERNAME="" binpack -j8
make USERNAME="" -j8
make USERNAME="" binpack -j8
make MODEL=n0100 OMEGA_USERNAME="" -j8
make MODEL=n0100 OMEGA_USERNAME="" binpack -j8
make OMEGA_USERNAME="" -j8
make OMEGA_USERNAME="" binpack -j8
```
Important: Don't forget the `--recursive` tag, because Omega relies on submodules.
@@ -108,7 +108,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make PLATFORM=simulator TARGET=web USERNAME="{Your name, max 15 characters}" -j4
make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Your name, max 15 characters}" -j4
```
The simulator is now in `output/release/simulator/web/simulator.zip`

View File

@@ -51,7 +51,7 @@ snapshots_count = $(words $(apps))
snapshot_includes = $(foreach i,$(app_headers),-include $(i) )
epsilon_app_names = '$(foreach i,${apps_list},"$(i)", )'
$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DUSERNAME="$(USERNAME)"
$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DOMEGA_USERNAME="$(OMEGA_USERNAME)"
# I18n file generation

View File

@@ -374,30 +374,7 @@ void AppsContainer::redrawWindow(bool force) {
void AppsContainer::activateExamMode(GlobalPreferences::ExamMode examMode) {
assert(examMode != GlobalPreferences::ExamMode::Off && examMode != GlobalPreferences::ExamMode::Unknown);
reset();
Preferences * preferences = Preferences::sharedPreferences();
switch ((int)preferences->colorOfLED()) {
case 0:
Ion::LED::setColor(KDColorRed);
break;
case 1:
Ion::LED::setColor(KDColorWhite);
break;
case 2:
Ion::LED::setColor(KDColorGreen);
break;
case 3:
Ion::LED::setColor(KDColorBlue);
break;
case 4:
Ion::LED::setColor(KDColorYellow);
break;
case 5:
Ion::LED::setColor(KDColorPurple);
break;
case 6:
Ion::LED::setColor(KDColorOrange);
break;
}
Ion::LED::setColor(KDColorRed);
/* The Dutch exam mode LED is supposed to be orange but we can only make
* blink "pure" colors: with RGB leds on or off (as the PWM is used for
* blinking). The closest "pure" color is Yellow. Moreover, Orange LED is

View File

@@ -26,10 +26,10 @@ void ComplexListController::setExpression(Poincare::Expression e) {
}
Poincare::Context * context = App::app()->localContext();
// Fill Calculation Store
m_calculationStore.push("im(z)", context);
m_calculationStore.push("re(z)", context);
m_calculationStore.push("arg(z)", context);
m_calculationStore.push("abs(z)", context);
m_calculationStore.push("im(z)", context, CalculationHeight);
m_calculationStore.push("re(z)", context, CalculationHeight);
m_calculationStore.push("arg(z)", context, CalculationHeight);
m_calculationStore.push("abs(z)", context, CalculationHeight);
// Set Complex illustration
// Compute a and b as in Expression::hasDefinedComplexApproximation to ensure the same defined result

View File

@@ -80,16 +80,7 @@ KDCoordinate IllustratedListController::rowHeight(int j) {
}
Shared::ExpiringPointer<Calculation> calculation = m_calculationStore.calculationAtIndex(calculationIndex);
constexpr bool expanded = true;
KDCoordinate result = calculation->memoizedHeight(expanded);
if (result < 0) {
result = ScrollableThreeExpressionsCell::Height(calculation.pointer());
if (result < 0) {
// Raise, because Height modified the calculation and failed.
Poincare::ExceptionCheckpoint::Raise();
}
calculation->setMemoizedHeight(expanded, result);
}
return result + Metric::CellSeparatorThickness;
return calculation->height(expanded) + Metric::CellSeparatorThickness;
}
int IllustratedListController::typeAtLocation(int i, int j) {
@@ -98,7 +89,6 @@ int IllustratedListController::typeAtLocation(int i, int j) {
void IllustratedListController::willDisplayCellForIndex(HighlightCell * cell, int index) {
if (index == 0) {
// TODO ?
return;
}
Poincare::Context * context = App::app()->localContext();
@@ -106,7 +96,6 @@ void IllustratedListController::willDisplayCellForIndex(HighlightCell * cell, in
Calculation * c = m_calculationStore.calculationAtIndex(index-1).pointer();
myCell->setCalculation(c);
myCell->setDisplayCenter(c->displayOutput(context) != Calculation::DisplayOutput::ApproximateOnly);
//myCell->setHighlighted(myCell->isHighlighted()); //TODO??
}
void IllustratedListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {

View File

@@ -10,8 +10,6 @@
namespace Calculation {
class IllustratedListController : public ListController, public SelectableTableViewDelegate {
/* TODO There is factorizable code between this and
* Calculation::HistoryController (at least rowHeight). */
public:
IllustratedListController(EditExpressionController * editExpressionController);
@@ -35,6 +33,7 @@ public:
constexpr static KDCoordinate k_illustrationHeight = 120;
protected:
static KDCoordinate CalculationHeight(Calculation * c, bool expanded) { return ScrollableThreeExpressionsCell::Height(c); }
Poincare::Expression m_savedExpression;
CalculationStore m_calculationStore;
private:

View File

@@ -8,8 +8,8 @@ void ScrollableThreeExpressionsView::resetMemoization() {
setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout());
}
void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, bool * didForceOutput) {
assert(!didForceOutput || *didForceOutput == false);
// TODO: factorize with HistoryViewCell!
void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, bool canChangeDisplayOutput) {
Poincare::Context * context = App::app()->localContext();
// Clean the layouts to make room in the pool
@@ -24,13 +24,10 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, b
bool couldNotCreateExactLayout = false;
exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout);
if (couldNotCreateExactLayout) {
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ExactOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
if (didForceOutput) {
*didForceOutput = true;
}
} else {
Poincare::ExceptionCheckpoint::Raise();
}
}
}
@@ -44,21 +41,18 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, b
bool couldNotCreateApproximateLayout = false;
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
/* Set the display output to ApproximateOnly, make room in the pool by
* erasing the exact layout, and retry to create the approximate layout */
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
if (didForceOutput) {
*didForceOutput = true;
}
exactOutputLayout = Poincare::Layout();
couldNotCreateApproximateLayout = false;
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
Poincare::ExceptionCheckpoint::Raise();
}
} else {
Poincare::ExceptionCheckpoint::Raise();
}
}
@@ -74,16 +68,7 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, b
KDCoordinate ScrollableThreeExpressionsCell::Height(Calculation * calculation) {
ScrollableThreeExpressionsCell cell;
bool didForceOutput = false;
cell.setCalculation(calculation, &didForceOutput);
if (didForceOutput) {
/* We could not compute the height of the calculation as it is (the display
* output was forced to another value during the height computation).
* Warning: the display output of calculation was actually changed, so it
* will cause problems if we already did some computations with another
* display value. */
return -1;
}
cell.setCalculation(calculation, true);
KDRect leftFrame = KDRectZero;
KDRect centerFrame = KDRectZero;
KDRect approximateSignFrame = KDRectZero;
@@ -103,8 +88,8 @@ void ScrollableThreeExpressionsCell::reinitSelection() {
m_view.reloadScroll();
}
void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation, bool * didForceOutput) {
m_view.setCalculation(calculation, didForceOutput);
void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation, bool canChangeDisplayOutput) {
m_view.setCalculation(calculation, canChangeDisplayOutput);
layoutSubviews();
}

View File

@@ -20,7 +20,7 @@ public:
setBackgroundColor(Palette::BackgroundApps);
}
void resetMemoization();
void setCalculation(Calculation * calculation, bool * didForceOutput = nullptr);
void setCalculation(Calculation * calculation, bool canChangeDisplayOutput);
void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) {
return m_contentCell.subviewFrames(leftFrame, centerFrame, approximateSignFrame, rightFrame);
}
@@ -61,7 +61,7 @@ public:
void setHighlighted(bool highlight) override { m_view.evenOddCell()->setHighlighted(highlight); }
void resetMemoization() { m_view.resetMemoization(); }
void setCalculation(Calculation * calculation, bool * didForceOutput = nullptr);
void setCalculation(Calculation * calculation, bool canChangeDisplayOutput = false);
void setDisplayCenter(bool display);
ScrollableThreeExpressionsView::SubviewPosition selectedSubviewPosition() { return m_view.selectedSubviewPosition(); }
void setSelectedSubviewPosition(ScrollableThreeExpressionsView::SubviewPosition subviewPosition) { m_view.setSelectedSubviewPosition(subviewPosition); }

View File

@@ -11,9 +11,9 @@ void TrigonometryListController::setExpression(Poincare::Expression e) {
// Fill calculation store
Poincare::Context * context = App::app()->localContext();
m_calculationStore.push("sin(θ)", context);
m_calculationStore.push("cos(θ)", context);
m_calculationStore.push("θ", context);
m_calculationStore.push("sin(θ)", context, CalculationHeight);
m_calculationStore.push("cos(θ)", context, CalculationHeight);
m_calculationStore.push("θ", context, CalculationHeight);
// Set trigonometry illustration
float angle = Shared::PoincareHelpers::ApproximateToScalar<float>(m_calculationStore.calculationAtIndex(0)->approximateOutput(context, Calculation::NumberOfSignificantDigits::Maximal), context);

View File

@@ -38,12 +38,6 @@ Calculation * Calculation::next() const {
return reinterpret_cast<Calculation *>(const_cast<char *>(result));
}
void Calculation::tidy() {
/* Reset height memoization (the complex format could have changed when
* re-entering Calculation app which would impact the heights). */
resetHeightMemoization();
}
const char * Calculation::approximateOutputText(NumberOfSignificantDigits numberOfSignificantDigits) const {
const char * exactOutput = exactOutputText();
const char * approximateOutputTextWithMaxNumberOfDigits = exactOutput + strlen(exactOutput) + 1;
@@ -126,12 +120,15 @@ Layout Calculation::createApproximateOutputLayout(Context * context, bool * coul
}
}
void Calculation::setMemoizedHeight(bool expanded, KDCoordinate height) {
if (expanded) {
m_expandedHeight = height;
} else {
m_height = height;
}
KDCoordinate Calculation::height(bool expanded) {
KDCoordinate h = expanded ? m_expandedHeight : m_height;
assert(h >= 0);
return h;
}
void Calculation::setHeights(KDCoordinate height, KDCoordinate expandedHeight) {
m_height = height;
m_expandedHeight = expandedHeight;
}
Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
@@ -190,9 +187,9 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
}
void Calculation::forceDisplayOutput(DisplayOutput d) {
// Heights haven't been computed yet
assert(m_height == -1 && m_expandedHeight == -1);
m_displayOutput = d;
// Reset heights memoization as it might have changed when we modify the display output
resetHeightMemoization();
}
bool Calculation::shouldOnlyDisplayExactOutput() {
@@ -219,6 +216,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual(
Poincare::ExceptionCheckpoint ecp;
if (ExceptionRun(ecp)) {
Preferences * preferences = Preferences::sharedPreferences();
// TODO: complex format should not be needed here (as it is not used to create layouts)
Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText);
m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit()) ? EqualSign::Equal : EqualSign::Approximation;
return m_equalSign;
@@ -256,25 +254,32 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
}
if (o.hasUnit()) {
Expression unit;
PoincareHelpers::Reduce(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User,ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, ExpressionNode::UnitConversion::None);
PoincareHelpers::Reduce(&o,
App::app()->localContext(),
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined,
ExpressionNode::UnitConversion::None);
o = o.removeUnit(&unit);
if (Unit::IsSI(unit)) {
if (Unit::IsSISpeed(unit) || Unit::IsSIVolume(unit) || Unit::IsSIEnergy(unit)) {
/* All these units will provide misc. classic representatives in
* addition to the SI unit in additional information. */
return AdditionalInformationType::Unit;
}
if (Unit::IsSITime(unit)) {
/* If the number of seconds is above 60s, we can write it in the form
* of an addition: 23_min + 12_s for instance. */
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
if (value > Unit::SecondsPerMinute) {
// There might be no unit in the end, if the reduction was interrupted.
if (!unit.isUninitialized()) {
if (Unit::IsSI(unit)) {
if (Unit::IsSISpeed(unit) || Unit::IsSIVolume(unit) || Unit::IsSIEnergy(unit)) {
/* All these units will provide misc. classic representatives in
* addition to the SI unit in additional information. */
return AdditionalInformationType::Unit;
}
if (Unit::IsSITime(unit)) {
/* If the number of seconds is above 60s, we can write it in the form
* of an addition: 23_min + 12_s for instance. */
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
if (value > Unit::SecondsPerMinute) {
return AdditionalInformationType::Unit;
}
}
return AdditionalInformationType::None;
}
return AdditionalInformationType::None;
return AdditionalInformationType::Unit;
}
return AdditionalInformationType::Unit;
}
if (o.isBasedIntegerCappedBy(k_maximalIntegerWithAdditionalInformation)) {
return AdditionalInformationType::Integer;
@@ -289,9 +294,4 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
return AdditionalInformationType::None;
}
void Calculation::resetHeightMemoization() {
m_height = -1;
m_expandedHeight = -1;
}
}

View File

@@ -61,8 +61,6 @@ public:
bool operator==(const Calculation& c);
Calculation * next() const;
void tidy();
// Texts
enum class NumberOfSignificantDigits {
Maximal,
@@ -83,9 +81,8 @@ public:
Poincare::Layout createExactOutputLayout(bool * couldNotCreateExactLayout);
Poincare::Layout createApproximateOutputLayout(Poincare::Context * context, bool * couldNotCreateApproximateLayout);
// Memoization of height
KDCoordinate memoizedHeight(bool expanded) { return expanded ? m_expandedHeight : m_height; }
void setMemoizedHeight(bool expanded, KDCoordinate height);
// Heights
KDCoordinate height(bool expanded);
// Displayed output
DisplayOutput displayOutput(Poincare::Context * context);
@@ -100,7 +97,9 @@ private:
static constexpr int k_numberOfExpressions = 4;
static constexpr KDCoordinate k_heightComputationFailureHeight = 50;
static constexpr const char * k_maximalIntegerWithAdditionalInformation = "10000000000000000";
void resetHeightMemoization();
void setHeights(KDCoordinate height, KDCoordinate expandedHeight);
/* Buffers holding text expressions have to be longer than the text written
* by user (of maximum length TextField::maxBufferSize()) because when we
* print an expression we add omitted signs (multiplications, parenthesis...) */

View File

@@ -51,7 +51,7 @@ ExpiringPointer<Calculation> CalculationStore::calculationAtIndex(int i) {
return calculationAtIndex(i);
}
ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context) {
ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context, HeightComputer heightComputer) {
/* Compute ans now, before the buffer is slided and before the calculation
* might be deleted */
Expression ans = ansExpression(context);
@@ -85,7 +85,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
/* If the input does not fit in the store (event if the current
* calculation is the only calculation), just replace the calculation with
* undef. */
return emptyStoreAndPushUndef(context);
return emptyStoreAndPushUndef(context, heightComputer);
}
nextSerializationLocation += strlen(nextSerializationLocation) + 1;
}
@@ -116,7 +116,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
* undef if it fits, else replace the whole calcualtion with undef. */
Expression undef = Undefined::Builder();
if (!pushSerializeExpression(undef, nextSerializationLocation, &newCalculationsLocation)) {
return emptyStoreAndPushUndef(context);
return emptyStoreAndPushUndef(context, heightComputer);
}
}
nextSerializationLocation += strlen(nextSerializationLocation) + 1;
@@ -133,7 +133,15 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
// Clean the memoization
resetMemoizedModelsAfterCalculationIndex(-1);
return ExpiringPointer<Calculation>(reinterpret_cast<Calculation *>(m_buffer));
ExpiringPointer<Calculation> calculation = ExpiringPointer<Calculation>(reinterpret_cast<Calculation *>(m_buffer));
/* Heights are computed now to make sure that the display output is decided
* accordingly to the remaining size in the Poincare pool. Once it is, it
* can't change anymore: the calculation heights are fixed which ensures that
* scrolling computation is right. */
calculation->setHeights(
heightComputer(calculation.pointer(), false),
heightComputer(calculation.pointer(), true));
return calculation;
}
void CalculationStore::deleteCalculationAtIndex(int i) {
@@ -164,9 +172,6 @@ void CalculationStore::tidy() {
return;
}
resetMemoizedModelsAfterCalculationIndex(-1);
for (Calculation * c : *this) {
c->tidy();
}
}
Expression CalculationStore::ansExpression(Context * context) {
@@ -255,12 +260,12 @@ const char * CalculationStore::lastCalculationPosition(const char * calculations
return reinterpret_cast<const char *>(c);
}
Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context) {
Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context, HeightComputer heightComputer) {
/* We end up here as a result of a failed calculation push. The store
* attributes are not necessarily clean, so we need to reset them. */
m_slidedBuffer = false;
deleteAll();
return push(Undefined::Name(), context);
return push(Undefined::Name(), context, heightComputer);
}
void CalculationStore::resetMemoizedModelsAfterCalculationIndex(int index) {

View File

@@ -28,7 +28,8 @@ class CalculationStore {
public:
CalculationStore();
Shared::ExpiringPointer<Calculation> calculationAtIndex(int i);
Shared::ExpiringPointer<Calculation> push(const char * text, Poincare::Context * context);
typedef KDCoordinate (*HeightComputer)(Calculation * c, bool expanded);
Shared::ExpiringPointer<Calculation> push(const char * text, Poincare::Context * context, HeightComputer heightComputer);
void deleteCalculationAtIndex(int i);
void deleteAll();
int numberOfCalculations() const { return m_numberOfCalculations; }
@@ -60,7 +61,7 @@ private:
char * slideCalculationsToEndOfBuffer(); // returns the new position of the calculations
size_t deleteLastCalculation(const char * calculationsStart = nullptr);
const char * lastCalculationPosition(const char * calculationsStart) const;
Shared::ExpiringPointer<Calculation> emptyStoreAndPushUndef(Poincare::Context * context);
Shared::ExpiringPointer<Calculation> emptyStoreAndPushUndef(Poincare::Context * context, HeightComputer heightComputer);
char m_buffer[k_bufferSize];
const char * m_bufferEnd;

View File

@@ -122,7 +122,7 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event
if (!myApp->isAcceptableText(m_cacheBuffer)) {
return true;
}
m_calculationStore->push(m_cacheBuffer, myApp->localContext());
m_calculationStore->push(m_cacheBuffer, myApp->localContext(), HistoryViewCell::Height);
m_historyController->reload();
return true;
}
@@ -145,7 +145,7 @@ bool EditExpressionController::inputViewDidFinishEditing(const char * text, Layo
} else {
layoutR.serializeParsedExpression(m_cacheBuffer, k_cacheBufferSize, context);
}
m_calculationStore->push(m_cacheBuffer, context);
m_calculationStore->push(m_cacheBuffer, context, HistoryViewCell::Height);
m_historyController->reload();
m_contentView.expressionField()->setEditing(true, true);
telemetryReportEvent("Input", m_cacheBuffer);

View File

@@ -129,7 +129,9 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
return true;
}
m_selectableTableView.selectCellAtLocation(0, focusRow > 0 ? focusRow - 1 : 0);
setSelectedSubviewType(subviewType, true, 0, selectedRow());
/* The parameters 'sameCell' and 'previousSelectedY' are chosen to enforce
* toggling of the output when necessary. */
setSelectedSubviewType(subviewType, false, 0, (subviewType == SubviewType::Input) ? selectedRow() : -1);
return true;
}
if (event == Ion::Events::Clear) {
@@ -204,20 +206,7 @@ KDCoordinate HistoryController::rowHeight(int j) {
}
Shared::ExpiringPointer<Calculation> calculation = calculationAtIndex(j);
bool expanded = j == selectedRow() && selectedSubviewType() == SubviewType::Output;
KDCoordinate result = calculation->memoizedHeight(expanded);
if (result < 0) {
result = HistoryViewCell::Height(calculation.pointer(), expanded);
if (result < 0) {
// Raise, because Height modified the calculation and failed.
Poincare::ExceptionCheckpoint::Raise();
}
calculation->setMemoizedHeight(expanded, result);
}
/* We might want to put an assertion here to check the memoization:
* assert(result == HistoryViewCell::Height(calculation.pointer(), expanded));
* However, Height might fail due to pool memory exhaustion, in which case the
* assertion fails even if "result" had the right value. */
return result;
return calculation->height(expanded);
}
int HistoryController::typeAtLocation(int i, int j) {

View File

@@ -36,16 +36,7 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType,
KDCoordinate HistoryViewCell::Height(Calculation * calculation, bool expanded) {
HistoryViewCell cell(nullptr);
bool didForceOutput = false;
cell.setCalculation(calculation, expanded, &didForceOutput);
if (didForceOutput) {
/* We could not compute the height of the calculation as it is (the display
* output was forced to another value during the height computation).
* Warning: the display output of calculation was actually changed, so it
* will cause problems if we already did some computations with another
* display value. */
return -1;
}
cell.setCalculation(calculation, expanded, true);
KDRect ellipsisFrame = KDRectZero;
KDRect inputFrame = KDRectZero;
KDRect outputFrame = KDRectZero;
@@ -246,8 +237,7 @@ void HistoryViewCell::resetMemoization() {
m_calculationCRC32 = 0;
}
void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, bool * didForceOutput) {
assert(!didForceOutput || *didForceOutput == false);
void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput) {
uint32_t newCalculationCRC = Ion::crc32Byte((const uint8_t *)calculation, ((char *)calculation->next()) - ((char *) calculation));
if (newCalculationCRC == m_calculationCRC32 && m_calculationExpanded == expanded) {
return;
@@ -273,11 +263,8 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, b
bool couldNotCreateExactLayout = false;
exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout);
if (couldNotCreateExactLayout) {
if (calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
if (didForceOutput) {
*didForceOutput = true;
}
} else {
/* We should only display the exact result, but we cannot create it
* -> raise an exception. */
@@ -294,21 +281,18 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, b
bool couldNotCreateApproximateLayout = false;
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
/* Set the display output to ApproximateOnly, make room in the pool by
* erasing the exact layout, and retry to create the approximate layout */
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
if (didForceOutput) {
*didForceOutput = true;
}
exactOutputLayout = Poincare::Layout();
couldNotCreateApproximateLayout = false;
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
Poincare::ExceptionCheckpoint::Raise();
}
} else {
Poincare::ExceptionCheckpoint::Raise();
}
}
}

View File

@@ -51,7 +51,7 @@ public:
Poincare::Layout layout() const override;
KDColor backgroundColor() const override { return m_even ? Palette::CalculationBackgroundEven : Palette::CalculationBackgroundOdd; }
void resetMemoization();
void setCalculation(Calculation * calculation, bool expanded, bool * didForceOutput = nullptr);
void setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput = false);
int numberOfSubviews() const override { return 2 + displayedEllipsis(); }
View * subviewAtIndex(int index) override;
void layoutSubviews(bool force = false) override;

View File

@@ -14,6 +14,7 @@ void assert_store_is(CalculationStore * store, const char * * result) {
}
}
KDCoordinate dummyHeight(::Calculation::Calculation * c, bool expanded) { return 0; }
QUIZ_CASE(calculation_store) {
Shared::GlobalContext globalContext;
@@ -22,7 +23,7 @@ QUIZ_CASE(calculation_store) {
const char * result[] = {"9", "8", "7", "6", "5", "4", "3", "2", "1", "0"};
for (int i = 0; i < 10; i++) {
char text[2] = {(char)(i+'0'), 0};
store.push(text, &globalContext);
store.push(text, &globalContext, dummyHeight);
quiz_assert(store.numberOfCalculations() == i+1);
}
assert_store_is(&store, result);
@@ -41,13 +42,13 @@ QUIZ_CASE(calculation_ans) {
Shared::GlobalContext globalContext;
CalculationStore store;
store.push("1+3/4", &globalContext);
store.push("ans+2/3", &globalContext);
store.push("1+3/4", &globalContext, dummyHeight);
store.push("ans+2/3", &globalContext, dummyHeight);
Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store.calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximate);
quiz_assert(strcmp(lastCalculation->exactOutputText(),"29/12") == 0);
store.push("ans+0.22", &globalContext);
store.push("ans+0.22", &globalContext, dummyHeight);
lastCalculation = store.calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximateToggle);
quiz_assert(strcmp(lastCalculation->approximateOutputText(::Calculation::Calculation::NumberOfSignificantDigits::Maximal),"2.6366666666667") == 0);
@@ -56,7 +57,7 @@ QUIZ_CASE(calculation_ans) {
}
void assertCalculationIs(const char * input, ::Calculation::Calculation::DisplayOutput display, ::Calculation::Calculation::EqualSign sign, const char * exactOutput, const char * displayedApproximateOutput, const char * storedApproximateOutput, Context * context, CalculationStore * store) {
store->push(input, context);
store->push(input, context, dummyHeight);
Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store->calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(context) == display);
if (sign != ::Calculation::Calculation::EqualSign::Unknown) {

View File

@@ -1,7 +1,7 @@
AddScript = "Aggiungere script"
AllowedCharactersaz09 = "Caratteri consentiti : a-z, 0-9, _"
Autocomplete = "Autocompletamento"
AutoImportScript = "Importazione automatica dello script"
AutoImportScript = "Auto importazione nella console"
BuiltinsAndKeywords = "Funzioni native e parole chiave"
Console = "Console d'esecuzione"
DeleteScript = "Eliminare lo script"

View File

@@ -8,11 +8,7 @@
namespace ExamModeConfiguration {
// Settings menu
#if LEDS_CHOICE
extern const Shared::SettingsMessageTree s_modelExamChildren[3];
#else
extern const Shared::SettingsMessageTree s_modelExamChildren[2];
#endif
int numberOfAvailableExamMode();
GlobalPreferences::ExamMode examModeAtIndex(int index);
I18n::Message examModeActivationMessage(int index);

View File

@@ -3,19 +3,10 @@
using namespace Poincare;
constexpr Shared::SettingsMessageTree s_examModeMode[] = {Shared::SettingsMessageTree(I18n::Message::ExamModeModeStandard), Shared::SettingsMessageTree(I18n::Message::ExamModeModeNoSym), Shared::SettingsMessageTree(I18n::Message::ExamModeModeNoSymNoText)};
#if LEDS_CHOICE
constexpr Shared::SettingsMessageTree s_ledColorChildren[] = {Shared::SettingsMessageTree(I18n::Message::ColorRed), Shared::SettingsMessageTree(I18n::Message::ColorWhite), Shared::SettingsMessageTree(I18n::Message::ColorGreen), Shared::SettingsMessageTree(I18n::Message::ColorBlue), Shared::SettingsMessageTree(I18n::Message::ColorYellow), Shared::SettingsMessageTree(I18n::Message::ColorPurple), Shared::SettingsMessageTree(I18n::Message::ColorOrange)};
constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[] = {Shared::SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren), Shared::SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode), Shared::SettingsMessageTree(I18n::Message::ActivateExamMode)};
#else
constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[] = {Shared::SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode), Shared::SettingsMessageTree(I18n::Message::ActivateExamMode)};
#endif
int ExamModeConfiguration::numberOfAvailableExamMode() {
#if LEDS_CHOICE
return 3;
#else
return 2;
#endif
}
GlobalPreferences::ExamMode ExamModeConfiguration::examModeAtIndex(int index) {
@@ -38,24 +29,7 @@ I18n::Message ExamModeConfiguration::examModeActivationWarningMessage(GlobalPref
KDColor ExamModeConfiguration::examModeColor(GlobalPreferences::ExamMode mode) {
assert(mode == GlobalPreferences::ExamMode::Standard || mode == GlobalPreferences::ExamMode::NoSym || mode == GlobalPreferences::ExamMode::NoSymNoText);
Preferences * preferences = Preferences::sharedPreferences();
switch((int) preferences->colorOfLED()) {
case 1:
return KDColorWhite;
case 2:
return KDColorGreen;
case 3:
return KDColorBlue;
case 4:
return KDColorYellow;
case 5:
return KDColorPurple;
case 6:
return KDColorOrange;
default:
return KDColorRed;
}
return KDColorRed;
}
bool ExamModeConfiguration::appIsForbiddenInExamMode(App::Descriptor::ExaminationLevel appExaminationLevel, GlobalPreferences::ExamMode mode) {

View File

@@ -21,10 +21,6 @@ PreimageParameterController::PreimageParameterController(
{
}
const char * PreimageParameterController::title() {
return I18n::translate(I18n::Message::Preimage);
}
void PreimageParameterController::viewWillAppear() {
setParameterName(I18n::Message::Y);
m_preimageGraphController->setImage(m_cursor->y());
@@ -32,19 +28,17 @@ void PreimageParameterController::viewWillAppear() {
}
void PreimageParameterController::buttonAction() {
m_preimageGraphController->setRecord(m_record);
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
stack->pop();
stack->pop();
stack->pop();
stack->push(m_preimageGraphController);
if (confirmParameterAtIndex(0, m_tempParameter)) {
m_preimageGraphController->setRecord(m_record);
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
stack->pop();
stack->pop();
stack->pop();
stack->push(m_preimageGraphController);
}
}
double PreimageParameterController::parameterAtIndex(int index) {
assert(index == 0);
return m_preimageGraphController->image();
}
bool PreimageParameterController::setParameterAtIndex(int parameterIndex, double f) {
bool PreimageParameterController::confirmParameterAtIndex(int parameterIndex, double f) {
assert(parameterIndex == 0);
m_preimageGraphController->setImage(f);
return true;

View File

@@ -15,13 +15,16 @@ public:
Shared::CurveViewCursor * cursor,
PreimageGraphController * preimageGraphController
);
const char * title() override;
const char * title() override { return I18n::translate(I18n::Message::Preimage); }
void setRecord(Ion::Storage::Record record) { m_record = record; }
void viewWillAppear() override;
private:
void buttonAction() override;
double parameterAtIndex(int index) override;
bool setParameterAtIndex(int parameterIndex, double f) override;
double extractParameterAtIndex(int index) override {
assert(index == 0);
return m_preimageGraphController->image();
}
bool confirmParameterAtIndex(int parameterIndex, double f) override;
Ion::Storage::Record m_record;
PreimageGraphController * m_preimageGraphController;
};

View File

@@ -30,7 +30,7 @@ const char * GoToParameterController::title() {
return I18n::translate(I18n::Message::YPrediction);
}
double GoToParameterController::parameterAtIndex(int index) {
double GoToParameterController::extractParameterAtIndex(int index) {
assert(index == 0);
if (m_xPrediction) {
return m_cursor->x();
@@ -38,7 +38,7 @@ double GoToParameterController::parameterAtIndex(int index) {
return m_cursor->y();
}
bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) {
bool GoToParameterController::confirmParameterAtIndex(int parameterIndex, double f) {
assert(parameterIndex == 0);
int series = m_graphController->selectedSeriesIndex();
Poincare::Context * globContext = AppsContainer::sharedAppsContainer()->globalContext();

View File

@@ -15,8 +15,8 @@ public:
void setXPrediction(bool xPrediction);
const char * title() override;
private:
double parameterAtIndex(int index) override;
bool setParameterAtIndex(int parameterIndex, double f) override;
double extractParameterAtIndex(int index) override;
bool confirmParameterAtIndex(int parameterIndex, double f) override;
Store * m_store;
bool m_xPrediction;
GraphController * m_graphController;

View File

@@ -19,7 +19,7 @@ constexpr SettingsMessageTree s_modelMathOptionsChildren[6] = {SettingsMessageTr
constexpr SettingsMessageTree s_modelFontChildren[2] = {SettingsMessageTree(I18n::Message::LargeFont), SettingsMessageTree(I18n::Message::SmallFont)};
constexpr SettingsMessageTree s_accessibilityChildren[6] = {SettingsMessageTree(I18n::Message::AccessibilityInvertColors), SettingsMessageTree(I18n::Message::AccessibilityMagnify),SettingsMessageTree(I18n::Message::AccessibilityGamma),SettingsMessageTree(I18n::Message::AccessibilityGammaRed),SettingsMessageTree(I18n::Message::AccessibilityGammaGreen),SettingsMessageTree(I18n::Message::AccessibilityGammaBlue)};
constexpr SettingsMessageTree s_contributorsChildren[20] = {SettingsMessageTree(I18n::Message::Developers), SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::SandraSimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::David), SettingsMessageTree(I18n::Message::DamienNicolet), SettingsMessageTree(I18n::Message::EvannDreumont), SettingsMessageTree(I18n::Message::SzaboLevente), SettingsMessageTree(I18n::Message::VenceslasDuet), SettingsMessageTree(I18n::Message::CharlotteThomas), SettingsMessageTree(I18n::Message::AntoninLoubiere), SettingsMessageTree(I18n::Message::BetaTesters), SettingsMessageTree(I18n::Message::CyprienMejat), SettingsMessageTree(I18n::Message::TimeoArnouts), SettingsMessageTree(I18n::Message::JulieC), SettingsMessageTree(I18n::Message::LelahelHideux), SettingsMessageTree(I18n::Message::Madil), SettingsMessageTree(I18n::Message::HilaireLeRoux)};
#ifdef USERNAME
#ifdef OMEGA_USERNAME
constexpr SettingsMessageTree s_modelAboutChildren[8] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)};
#else
constexpr SettingsMessageTree s_modelAboutChildren[7] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)};

View File

@@ -23,7 +23,7 @@ extern const Shared::SettingsMessageTree s_modelMathOptionsChildren[6];
extern const Shared::SettingsMessageTree s_modelFontChildren[2];
extern const Shared::SettingsMessageTree s_accessibilityChildren[6];
extern const Shared::SettingsMessageTree s_contributorsChildren[20];
#ifdef USERNAME
#ifdef OMEGA_USERNAME
extern const Shared::SettingsMessageTree s_modelAboutChildren[8];
#else
extern const Shared::SettingsMessageTree s_modelAboutChildren[7];

View File

@@ -142,7 +142,7 @@ void AboutController::willDisplayCellForIndex(HighlightCell * cell, int index) {
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell;
static const char * mpVersion = MICROPY_VERSION_STRING;
static const char * messages[] = {
#ifdef USERNAME
#ifdef OMEGA_USERNAME
Ion::username(),
#endif
Ion::softwareVersion(),

View File

@@ -21,7 +21,7 @@ public:
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
int typeAtLocation(int i, int j) override;
private:
#ifdef USERNAME
#ifdef OMEGA_USERNAME
constexpr static int k_totalNumberOfCell = 8;
#else
constexpr static int k_totalNumberOfCell = 7;

View File

@@ -19,9 +19,6 @@ ExamModeController::ExamModeController(Responder * parentResponder) :
m_cell{},
m_ledController(this),
m_examModeModeController(this),
#if LEDS_CHOICE
m_ledColorCell(KDFont::LargeFont, KDFont::SmallFont),
#endif
m_examModeCell(KDFont::LargeFont, KDFont::SmallFont)
{
for (int i = 0; i < k_maxNumberOfCells; i++) {
@@ -38,14 +35,6 @@ bool ExamModeController::handleEvent(Ion::Events::Event event) {
stack->push(&m_examModeModeController);
return true;
}
#if LEDS_CHOICE
else if (m_messageTreeModel->childAtIndex(selectedRow())->label() == I18n::Message::LEDColor) {
(&m_ledController)->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow()));
StackViewController * stack = stackController();
stack->push(&m_ledController);
return true;
}
#endif
else {
AppsContainer::sharedAppsContainer()->displayExamModePopUp(examMode());
return true;
@@ -79,11 +68,6 @@ int ExamModeController::numberOfRows() const {
HighlightCell * ExamModeController::reusableCell(int index, int type) {
assert(type == 0);
assert(index >= 0 && index < 3);
#if LEDS_CHOICE
if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::LEDColor) {
return &m_ledColorCell;
}
#endif
if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::ExamModeMode) {
return &m_examModeCell;
}
@@ -107,13 +91,6 @@ void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index
MessageTableCell * myCell = (MessageTableCell *)cell;
myCell->setMessage(I18n::Message::ExamModeActive);
}
#if LEDS_CHOICE
if (thisLabel == I18n::Message::LEDColor) {
MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell;
I18n::Message message = (I18n::Message) m_messageTreeModel->childAtIndex(index)->childAtIndex((int)preferences->colorOfLED())->label();
myTextCell->setSubtitle(message);
}
#endif
if (thisLabel == I18n::Message::ExamModeMode) {
MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell;
I18n::Message message = (I18n::Message) m_messageTreeModel->childAtIndex(index)->childAtIndex((uint8_t)GlobalPreferences::sharedGlobalPreferences()->tempExamMode() - 1)->label();

View File

@@ -30,9 +30,6 @@ private:
MessageTableCell m_cell[k_maxNumberOfCells];
PreferencesController m_ledController;
PreferencesController m_examModeModeController;
#if LEDS_CHOICE
MessageTableCellWithChevronAndMessage m_ledColorCell;
#endif
MessageTableCellWithChevronAndMessage m_examModeCell;
};

View File

@@ -107,43 +107,6 @@ Layout PreferencesController::layoutForPreferences(I18n::Message message) {
);
}
// LED placeholders
case I18n::Message::ColorRed:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
case I18n::Message::ColorWhite:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
case I18n::Message::ColorBlue:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
case I18n::Message::ColorGreen:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
case I18n::Message::ColorYellow:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
case I18n::Message::ColorPurple:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
case I18n::Message::ColorOrange:
{
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
// Exam mode modes
case I18n::Message::ExamModeModeStandard:
{
@@ -242,8 +205,6 @@ void PreferencesController::setPreferenceWithValueIndex(I18n::Message message, i
preferences->setEditionMode((Preferences::EditionMode)valueIndex);
} else if (message == I18n::Message::ComplexFormat) {
preferences->setComplexFormat((Preferences::ComplexFormat)valueIndex);
} else if (message == I18n::Message::LEDColor) {
preferences->setColorOfLED((Preferences::LEDColor)valueIndex);
} else if (message == I18n::Message::ExamModeMode) {
GlobalPreferences::sharedGlobalPreferences()->setTempExamMode((GlobalPreferences::ExamMode)((uint8_t)valueIndex + 1));
} else if (message == I18n::Message::SymbolMultiplication) {
@@ -269,11 +230,6 @@ int PreferencesController::valueIndexForPreference(I18n::Message message) const
if (message == I18n::Message::ComplexFormat) {
return (int)preferences->complexFormat();
}
#if LEDS_CHOICE
if (message == I18n::Message::LEDColor) {
return (int)preferences->colorOfLED();
}
#endif
if (message == I18n::Message::SymbolMultiplication) {
return (int)preferences->symbolOfMultiplication();
}

View File

@@ -81,16 +81,8 @@ XStart = "X Startwert"
Zoom = "Zoom"
Developers = "Entwickler"
BetaTesters = "Beta-Tester"
LEDColor = "LED Farbe"
ExamModeMode = "Modus"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "Ohne Symbole "
ExamModeModeNoSymNoText = "Ohne Symbole & Text "
ExamModeModeDutch = "Niederländisch "
ColorRed = "Rot "
ColorWhite = "Weiss "
ColorBlue = "Blau "
ColorGreen = "Grün "
ColorYellow = "Gelb "
ColorPurple = "Lila "
ColorOrange = "Orange "

View File

@@ -81,16 +81,8 @@ XStart = "X start"
Zoom = "Zoom"
Developers = "Developers"
BetaTesters = "Beta testers"
LEDColor = "LED color"
ExamModeMode = "Mode"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "No sym "
ExamModeModeNoSymNoText = "No sym no text "
ExamModeModeDutch = "Dutch "
ColorRed = "Red "
ColorWhite = "White "
ColorBlue = "Blue "
ColorGreen = "Green "
ColorYellow = "Yellow "
ColorPurple = "Purple "
ColorOrange = "Orange "

View File

@@ -81,16 +81,8 @@ XStart = "X inicio"
Zoom = "Zoom"
Developers = "Desarrolladores"
BetaTesters = "Probadores beta"
LEDColor = "Color del LED"
ExamModeMode = "Modo"
ExamModeModeStandard = "Estándar "
ExamModeModeNoSym = "Sin simbólico "
ExamModeModeNoSymNoText = "sin simbolismo sin texto "
ExamModeModeDutch = "Holandés "
ColorRed = "Rojo "
ColorWhite = "Blanco "
ColorBlue = "Azul "
ColorGreen = "Verde "
ColorYellow = "Amarillo "
ColorPurple = "Púrpura "
ColorOrange = "Naranja "

View File

@@ -81,16 +81,8 @@ XStart = "X début"
Zoom = "Zoom"
Developers = "Développeurs"
BetaTesters = "Beta testeurs"
LEDColor = "Couleur LED"
ExamModeMode = "Mode"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "Sans symbolique "
ExamModeModeNoSymNoText = "Sans symbolique ni texte "
ExamModeModeDutch = "Néerlandais "
ColorRed = "Rouge "
ColorWhite = "Blanc "
ColorBlue = "Bleu "
ColorGreen = "Vert "
ColorYellow = "Jaune "
ColorPurple = "Mauve "
ColorOrange = "Orange "

View File

@@ -81,16 +81,8 @@ XStart = "X kezdete"
Zoom = "Zoom"
Developers = "Fejlesztök"
BetaTesters = "Béta tesztelök"
LEDColor = "LED szín"
ExamModeMode = "Üzemmód"
ExamModeModeStandard = "Normál"
ExamModeModeNoSym = "Nincs sym"
ExamModeModeNoSymNoText = "Nincs szimbolikus, nincs szöveg "
ExamModeModeDutch = "Holland "
ColorRed = "Piros "
ColorWhite = "Fehér "
ColorBlue = "Kék "
ColorGreen = "Zöld "
ColorYellow = "Sárga "
ColorPurple = "Lila "
ColorOrange = "Narancssárga "

View File

@@ -81,16 +81,8 @@ XStart = "X iniziale"
Zoom = "Zoom"
Developers = "Developers"
BetaTesters = "Beta testers"
LEDColor = "LED color"
ExamModeMode = "Mode"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "No sym "
ExamModeModeNoSymNoText = "No sym no text "
ExamModeModeDutch = "Dutch "
ColorRed = "Red "
ColorWhite = "White "
ColorBlue = "Blue "
ColorGreen = "Green "
ColorYellow = "Yellow "
ColorPurple = "Purple "
ColorOrange = "Orange "

View File

@@ -81,16 +81,8 @@ XStart = "X begin"
Zoom = "Zoom"
Developers = "Developers"
BetaTesters = "Beta testers"
LEDColor = "LED color"
ExamModeMode = "Mode"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "No sym "
ExamModeModeNoSymNoText = "No sym no text "
ExamModeModeDutch = "Dutch "
ColorRed = "Red "
ColorWhite = "White "
ColorBlue = "Blue "
ColorGreen = "Green "
ColorYellow = "Yellow "
ColorPurple = "Purple "
ColorOrange = "Orange "

View File

@@ -81,16 +81,8 @@ XStart = "X início"
Zoom = "Zoom"
Developers = "Desenvolvedores"
BetaTesters = "Testadores beta"
LEDColor = "Cor LED"
ExamModeMode = "Modo"
ExamModeModeStandard = "Padrão "
ExamModeModeNoSym = "Sem simbólico "
ExamModeModeNoSymNoText = "Sem simbólico sem texto "
ExamModeModeDutch = "Holandês "
ColorRed = "Vermelho "
ColorWhite = "Branco "
ColorBlue = "Azul "
ColorGreen = "Verde "
ColorYellow = "Amarelo "
ColorPurple = "Roxo "
ColorOrange = "Caranja "

View File

@@ -336,28 +336,28 @@ PHilaireLeRoux = "@0Babass2"
SpeedOfLight = "2.99792458·10^8_m_s^-1"
YearLight = "9.461·10^15_m"
Boltzmann = "1.380649·10^-23_J_K^-1"
StefanBoltzmann = "5.670374·10^-8_W_m^-2_K^-4"
VacuumImpedance = "376.730313461_Ω"
StefanBoltzmann = "5.670374419·10^-8_W_m^-2_K^-4"
VacuumImpedance = "376.730313668_Ω"
WaterTriplePoint = "273.16_K"
AtmosphericPressure = "101325_Pa"
AtomicMassUnit = "1.660539040·10^-27_kg"
Wien = "2.8977729·10^-3_K_m"
BohrRadius = "5.2917721067·10^-11_m"
BohrMagneton = "9.274009994·10^-24_A_m^2"
NuclearMagneton = "5.050783699·10^-27_A_m^2"
MuonMass = "1.883531594·10^-28_kg"
AtomicMassUnit = "1.66053906660·10^-27_kg"
Wien = "2.897771955·10^-3_K_m"
BohrRadius = "5.29177210903·10^-11_m"
BohrMagneton = "9.2740100783·10^-24_A_m^2"
NuclearMagneton = "5.0507837461·10^-27_A_m^2"
MuonMass = "1.883531627·10^-28_kg"
Avogadro = "6.02214076·10^23_mol^-1"
Gas = "8.31446261815324_J_mol^-1_K^-1"
Coulomb = "8.9875517887·10^9_N_m^2_C^-2"
Gas = "8.314462618_J_mol^-1_K^-1"
Coulomb = "8.9875517923·10^9_N_m^2_C^-2"
Vacuum_permittivity = "8.8541878128·10^-12_F_m^-1"
Vacuum_permeability = "·10^-7_H_m^-1"
Vacuum_permeability = "1.25663706212·10^-6_H_m^-1"
Planck = "6.62607015·10^-34_J_s"
ElectronMass = "9.109383·10^-31_kg"
ProtonMass = "1.672649·10^-27_kg"
NeutronMass = "1.67493·10^-27_kg"
ElementalCharge = "1.60217662·10^-19_C"
ElectronMass = "9.1093837015·10^-31_kg"
ProtonMass = "1.67262192369·10^-27_kg"
NeutronMass = "1.67492749804·10^-27_kg"
ElementalCharge = "1.602176634·10^-19_C"
GAcceleration = "9.80665_m_s^-2"
GConstant = "6.674·10^-11_m^3_kg^-1_s^-2"
GConstant = "6.67430·10^-11_m^3_kg^-1_s^-2"
SpeedOfSound0 = "343.4_m_s^-1"
SpeedOfSoundWater = "1480_m_s^-1"
SpeedOfSoundSteel = "5600_m_s^-1"
@@ -370,7 +370,7 @@ EarthRadius = "6378140_m"
MoonRadius = "3474600_m"
EarthMoonDistance = "384400000_m"
EarthSunDistance = "149597870000_m"
FaradayConstant = "96484_C_mol^-1"
FaradayConstant = "96485.33212_C_mol^-1"
EscapeVelocityOfEarth = "11186_m_s^-1"
EscapeVelocityOfMoon = "2380_m_s^-1"
EscapeVelocityOfSun = "42100_m_s^-1"
@@ -409,11 +409,11 @@ Pka14Value = "2.1"
Pka15Value = "1.9"
Pka16Value = "0"
Pka = "pKa"
PlanckReduce = "1.504571800·10^-34_J_s"
PlanckMass = "2.176470·10^-8_kg"
PlanckLength = "1.616229·10^-35_m"
PlanckTime = "5.39116·10^-44_s"
PlanckTemperature = "1.416808·10^32_K"
PlanckReduce = "1.054571817·10^-34_J_s"
PlanckMass = "2.176434·10^-8_kg"
PlanckLength = "1.616255·10^-35_m"
PlanckTime = "5.391247·10^-44_s"
PlanckTemperature = "1.416784·10^32_K"
PlanckCharge = "1.875·10^-18_C"
PlanckForce = "1.210·10^44_N"
PlanckEnergy = "1.956·10^9_J"
@@ -425,12 +425,12 @@ PlanckTension = "1.0432·10^27_V"
PlanckCurrent = "3.479·10^25_A"
PlanckPressure = "4.635·10^113_Pa"
PlanckImpedance = "29.986_Ω"
TauonMass = "3.16747·10^-27_kg"
TauonMass = "3.16754·10^-27_kg"
WBosonMass = "1.4334·10^-25_kg"
ZBosonMass = "1.62556·10^-25_kg"
FineStructure = "7.2973525664·10^-3"
RydbergConstant = "1.0973731568508·10^7_m^-1"
HartreeConstant = "4.359744650·10^-18_J"
MagneticFluxQuantum = "2.067833831·10^-15_Wb"
ConductanceQuantum = "7.7480917310·10^-5_S"
CirculationQuantum = "3.6369475486·10^-4_m^2_s^-1"
FineStructure = "7.2973525693·10^-3"
RydbergConstant = "10973731.568160_m^-1"
HartreeConstant = "4.3597447222071·10^-18_J"
MagneticFluxQuantum = "2.067833848·10^-15_Wb"
ConductanceQuantum = "7.748091729·10^-5_S"
CirculationQuantum = "3.6369475516·10^-4_m^2_s^-1"

View File

@@ -11,16 +11,7 @@ FunctionGoToParameterController::FunctionGoToParameterController(Responder * par
{
}
const char * FunctionGoToParameterController::title() {
return I18n::translate(I18n::Message::Goto);
}
double FunctionGoToParameterController::parameterAtIndex(int index) {
assert(index == 0);
return m_cursor->t();
}
bool FunctionGoToParameterController::setParameterAtIndex(int parameterIndex, double f) {
bool FunctionGoToParameterController::confirmParameterAtIndex(int parameterIndex, double f) {
assert(parameterIndex == 0);
FunctionApp * myApp = FunctionApp::app();
ExpiringPointer<Function> function = myApp->functionStore()->modelForRecord(m_record);

View File

@@ -9,13 +9,16 @@ namespace Shared {
class FunctionGoToParameterController : public GoToParameterController {
public:
FunctionGoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor);
const char * title() override;
const char * title() override { return I18n::translate(I18n::Message::Goto); }
void setRecord(Ion::Storage::Record record);
protected:
bool setParameterAtIndex(int parameterIndex, double f) override;
bool confirmParameterAtIndex(int parameterIndex, double f) override;
Ion::Storage::Record m_record;
private:
double parameterAtIndex(int index) override;
double extractParameterAtIndex(int index) override {
assert(index == 0);
return m_cursor->t();
}
};
}

View File

@@ -11,19 +11,11 @@ GoToParameterController::GoToParameterController(Responder * parentResponder, In
{
}
int GoToParameterController::numberOfRows() const {
return 2;
}
HighlightCell * GoToParameterController::reusableParameterCell(int index, int type) {
assert(index == 0);
return &m_parameterCell;
}
int GoToParameterController::reusableParameterCellCount(int type) {
return 1;
}
bool GoToParameterController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::Left) {
stackController()->pop();
@@ -32,10 +24,25 @@ bool GoToParameterController::handleEvent(Ion::Events::Event event) {
return false;
}
void GoToParameterController::viewWillAppear() {
// Initialize m_tempParameter to the extracted value.
setParameterAtIndex(0, extractParameterAtIndex(0));
FloatParameterController::viewWillAppear();
}
bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) {
assert(parameterIndex == 0);
m_tempParameter = f;
return true;
}
void GoToParameterController::buttonAction() {
StackViewController * stack = (StackViewController *)parentResponder();
stack->pop();
stack->pop();
// Update parameter value to m_tempParameter, and proceed if value is valid
if (confirmParameterAtIndex(0, m_tempParameter)) {
StackViewController * stack = (StackViewController *)parentResponder();
stack->pop();
stack->pop();
}
}
}

View File

@@ -11,16 +11,28 @@ namespace Shared {
class GoToParameterController : public FloatParameterController<double> {
public:
GoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor);
int numberOfRows() const override;
int numberOfRows() const override { return 2; }
bool handleEvent(Ion::Events::Event event) override;
protected:
void setParameterName(I18n::Message message) { m_parameterCell.setMessage(message); }
void viewWillAppear() override;
// extractParameterAtIndex extracts the current value of the parameter
virtual double extractParameterAtIndex(int index) = 0;
// confirmParameterAtIndex updates the current value of the parameter
virtual bool confirmParameterAtIndex(int parameterIndex, double f) = 0;
// parameterAtIndex and setParameterAtIndex manipulate m_tempParameter only
double parameterAtIndex(int index) override {
assert(index == 0);
return m_tempParameter;
}
bool setParameterAtIndex(int parameterIndex, double f) override;
CurveViewCursor * m_cursor;
InteractiveCurveViewRange * m_graphRange;
double m_tempParameter;
private:
void buttonAction() override;
HighlightCell * reusableParameterCell(int index, int type) override;
int reusableParameterCellCount(int type) override;
int reusableParameterCellCount(int type) override { return 1; }
MessageTableCellWithEditableText m_parameterCell;
};

View File

@@ -15,8 +15,10 @@ InteractiveCurveViewController::InteractiveCurveViewController(Responder * paren
m_rangeVersion(rangeVersion),
m_rangeParameterController(this, inputEventHandlerDelegate, interactiveRange),
m_zoomParameterController(this, interactiveRange, curveView),
m_interactiveRange(interactiveRange),
m_rangeButton(this, I18n::Message::Axis, Invocation([](void * context, void * sender) {
InteractiveCurveViewController * graphController = (InteractiveCurveViewController *) context;
graphController->rangeParameterController()->setRange(graphController->interactiveRange());
StackViewController * stack = graphController->stackController();
stack->push(graphController->rangeParameterController());
return true;
@@ -113,7 +115,7 @@ void InteractiveCurveViewController::didBecomeFirstResponder() {
}
}
ViewController * InteractiveCurveViewController::rangeParameterController() {
RangeParameterController * InteractiveCurveViewController::rangeParameterController() {
return &m_rangeParameterController;
}

View File

@@ -19,7 +19,7 @@ public:
void didBecomeFirstResponder() override;
TELEMETRY_ID("Graph");
ViewController * rangeParameterController();
RangeParameterController * rangeParameterController();
ViewController * zoomParameterController();
virtual ViewController * initialisationParameterController() = 0;
@@ -35,6 +35,7 @@ public:
void willExitResponderChain(Responder * nextFirstResponder) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
protected:
Responder * tabController() const;
virtual StackViewController * stackController() const;
@@ -56,6 +57,8 @@ protected:
// SimpleInteractiveCurveViewController
float cursorBottomMarginRatio() override;
InteractiveCurveViewRange * interactiveRange() { return m_interactiveRange; }
OkView m_okView;
private:
/* The value 21 is the actual height of the ButtonRow, that is
@@ -75,6 +78,7 @@ private:
uint32_t * m_rangeVersion;
RangeParameterController m_rangeParameterController;
ZoomParameterController m_zoomParameterController;
InteractiveCurveViewRange * m_interactiveRange;
Button m_rangeButton;
Button m_zoomButton;
Button m_defaultInitialisationButton;

View File

@@ -29,21 +29,6 @@ double Interval::element(int i) {
return m_intervalBuffer[i];
}
void Interval::setStart(double f) {
m_start = f;
m_needCompute = true;
}
void Interval::setEnd(double f) {
m_end = f;
m_needCompute = true;
}
void Interval::setStep(double f) {
m_step = f;
m_needCompute = true;
}
void Interval::setElement(int i, double f) {
assert(i <= numberOfElements() && i < k_maxNumberOfElements);
computeElements();
@@ -54,16 +39,16 @@ void Interval::setElement(int i, double f) {
}
void Interval::reset() {
m_start = 0.0;
m_end = 10.0;
m_step = 1.0;
m_parameters.setStart(0.0);
m_parameters.setEnd(10.0);
m_parameters.setStep(1.0);
m_needCompute = true;
}
void Interval::clear() {
m_start = 1.0;
m_end = 0.0;
m_step = 1.0;
m_parameters.setStart(1.0);
m_parameters.setEnd(0.0);
m_parameters.setStep(1.0);
m_needCompute = true;
}
@@ -71,14 +56,14 @@ void Interval::computeElements() {
if (!m_needCompute) {
return;
}
if (m_start > m_end) {
if (m_parameters.start() > m_parameters.end()) {
m_numberOfElements = 0;
} else {
m_numberOfElements = m_step > 0 ? 1 + (m_end - m_start)/m_step : k_maxNumberOfElements;
m_numberOfElements = m_parameters.step() > 0 ? 1 + (m_parameters.end() - m_parameters.start())/m_parameters.step() : k_maxNumberOfElements;
m_numberOfElements = m_numberOfElements > k_maxNumberOfElements || m_numberOfElements < 0 ? k_maxNumberOfElements : m_numberOfElements;
}
for (int i = 0; i < m_numberOfElements; i += 1) {
m_intervalBuffer[i] = m_start + i * m_step;
m_intervalBuffer[i] = m_parameters.start() + i * m_parameters.step();
}
m_needCompute = false;
}

View File

@@ -10,13 +10,22 @@ public:
Interval(const Interval&) = delete;
int numberOfElements();
void deleteElementAtIndex(int index);
class IntervalParameters {
public:
void setStart(double f) { m_start = f; }
void setEnd(double f) { m_end = f; }
void setStep(double f) { m_step = f; }
double start() const { return m_start; }
double end() const { return m_end; }
double step() const { return m_step; }
private:
double m_start;
double m_end;
double m_step;
};
double element(int i);
double start() const { return m_start; }
double end() const { return m_end; }
double step() const { return m_step; }
void setStart(double f);
void setEnd(double f);
void setStep(double f);
IntervalParameters * parameters() { return &m_parameters; }
void setParameters(IntervalParameters parameters) { m_parameters = parameters; }
void setElement(int i, double f);
void forceRecompute(){ m_needCompute = true;}
void reset();
@@ -27,14 +36,12 @@ private:
void computeElements();
int m_numberOfElements;
double m_intervalBuffer[k_maxNumberOfElements];
double m_start;
double m_end;
double m_step;
bool m_needCompute;
IntervalParameters m_parameters;
};
typedef void (Interval::*SetterPointer)(double);
typedef double (Interval::*GetterPointer)() const;
typedef void (Interval::IntervalParameters::*SetterPointer)(double);
typedef double (Interval::IntervalParameters::*GetterPointer)() const;
}

View File

@@ -2,6 +2,11 @@
namespace Shared {
Interval::IntervalParameters * IntervalParameterController::SharedTempIntervalParameters() {
static Interval::IntervalParameters sTempIntervalParameters;
return &sTempIntervalParameters;
}
IntervalParameterController::IntervalParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) :
FloatParameterController<double>(parentResponder),
m_interval(nullptr),
@@ -16,6 +21,11 @@ IntervalParameterController::IntervalParameterController(Responder * parentRespo
}
}
void IntervalParameterController::setInterval(Interval * interval) {
m_interval = interval;
*SharedTempIntervalParameters() = *(interval->parameters());
}
const char * IntervalParameterController::title() {
return I18n::translate(m_title);
}
@@ -42,8 +52,8 @@ void IntervalParameterController::willDisplayCellForIndex(HighlightCell * cell,
}
double IntervalParameterController::parameterAtIndex(int index) {
GetterPointer getters[k_totalNumberOfCell] = {&Interval::start, &Interval::end, &Interval::step};
return (m_interval->*getters[index])();
GetterPointer getters[k_totalNumberOfCell] = {&Shared::Interval::IntervalParameters::start, &Shared::Interval::IntervalParameters::end, &Shared::Interval::IntervalParameters::step};
return (SharedTempIntervalParameters()->*getters[index])();
}
bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double f) {
@@ -51,18 +61,18 @@ bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double
Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue);
return false;
}
double start = parameterIndex == 0 ? f : m_interval->start();
double end = parameterIndex == 1 ? f : m_interval->end();
double start = parameterIndex == 0 ? f : SharedTempIntervalParameters()->start();
double end = parameterIndex == 1 ? f : SharedTempIntervalParameters()->end();
if (start > end) {
if (parameterIndex == 1) {
Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue);
return false;
}
double g = f+1.0;
m_interval->setEnd(g);
SharedTempIntervalParameters()->setEnd(g);
}
SetterPointer setters[k_totalNumberOfCell] = {&Interval::setStart, &Interval::setEnd, &Interval::setStep};
(m_interval->*setters[parameterIndex])(f);
SetterPointer setters[k_totalNumberOfCell] = {&Shared::Interval::IntervalParameters::setStart, &Shared::Interval::IntervalParameters::setEnd, &Shared::Interval::IntervalParameters::setStep};
(SharedTempIntervalParameters()->*setters[parameterIndex])(f);
return true;
}
@@ -85,6 +95,7 @@ int IntervalParameterController::reusableParameterCellCount(int type) {
}
void IntervalParameterController::buttonAction() {
m_interval->setParameters(*SharedTempIntervalParameters());
m_interval->forceRecompute();
StackViewController * stack = stackController();
stack->pop();

View File

@@ -12,7 +12,7 @@ class IntervalParameterController : public Shared::FloatParameterController<doub
public:
IntervalParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate);
Interval * interval() { assert(m_interval); return m_interval; }
void setInterval(Interval * interval) { m_interval = interval; }
void setInterval(Interval * interval);
const char * title() override;
void setTitle(I18n::Message title) { m_title = title; }
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
@@ -24,6 +24,7 @@ protected:
Interval * m_interval;
bool handleEvent(Ion::Events::Event event) override;
private:
static Interval::IntervalParameters * SharedTempIntervalParameters();
HighlightCell * reusableParameterCell(int index, int type) override;
int reusableParameterCellCount(int type) override;
double parameterAtIndex(int index) override;

View File

@@ -8,6 +8,7 @@ namespace Shared {
RangeParameterController::RangeParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * interactiveRange) :
FloatParameterController<float>(parentResponder),
m_interactiveRange(interactiveRange),
m_tempInteractiveRange(*interactiveRange),
m_xRangeCells{},
m_yRangeCells{},
m_yAutoCell(I18n::Message::YAuto)
@@ -18,7 +19,7 @@ RangeParameterController::RangeParameterController(Responder * parentResponder,
}
for (int i = 0; i < k_numberOfConvertibleTextCell; i++) {
m_yRangeCells[i].setParentResponder(&m_selectableTableView);
m_yRangeCells[i].setInteractiveCurveViewRange(m_interactiveRange);
m_yRangeCells[i].setInteractiveCurveViewRange(&m_tempInteractiveRange);
m_yRangeCells[i].textField()->setDelegates(inputEventHandlerDelegate, this);
}
}
@@ -50,13 +51,13 @@ void RangeParameterController::willDisplayCellForIndex(HighlightCell * cell, int
}
if (index == 2) {
SwitchView * switchView = (SwitchView *)m_yAutoCell.accessoryView();
switchView->setState(m_interactiveRange->yAuto());
switchView->setState(m_tempInteractiveRange.yAuto());
return;
}
MessageTableCellWithEditableText * myCell = (MessageTableCellWithEditableText *)cell;
I18n::Message labels[k_numberOfTextCell+1] = {I18n::Message::XMin, I18n::Message::XMax, I18n::Message::Default, I18n::Message::YMin, I18n::Message::YMax};
myCell->setMessage(labels[index]);
KDColor yColor = m_interactiveRange->yAuto() ? Palette::SecondaryText : Palette::PrimaryText;
KDColor yColor = m_tempInteractiveRange.yAuto() ? Palette::SecondaryText : Palette::PrimaryText;
KDColor colors[k_numberOfTextCell+1] = {Palette::PrimaryText, Palette::PrimaryText, Palette::PrimaryText, yColor, yColor};
myCell->setTextColor(colors[index]);
FloatParameterController::willDisplayCellForIndex(cell, index);
@@ -70,9 +71,14 @@ bool RangeParameterController::textFieldDidFinishEditing(TextField * textField,
return false;
}
void RangeParameterController::setRange(InteractiveCurveViewRange * range){
m_interactiveRange = range;
m_tempInteractiveRange = *range;
}
bool RangeParameterController::handleEvent(Ion::Events::Event event) {
if (activeCell() == 2 && (event == Ion::Events::OK || event == Ion::Events::EXE)) {
m_interactiveRange->setYAuto(!m_interactiveRange->yAuto());
m_tempInteractiveRange.setYAuto(!m_tempInteractiveRange.yAuto());
m_selectableTableView.reloadData();
return true;
}
@@ -83,14 +89,14 @@ float RangeParameterController::parameterAtIndex(int parameterIndex) {
ParameterGetterPointer getters[k_numberOfTextCell] = {&InteractiveCurveViewRange::xMin,
&InteractiveCurveViewRange::xMax, &InteractiveCurveViewRange::yMin, &InteractiveCurveViewRange::yMax};
int index = parameterIndex > 2 ? parameterIndex - 1 : parameterIndex;
return (m_interactiveRange->*getters[index])();
return (m_tempInteractiveRange.*getters[index])();
}
bool RangeParameterController::setParameterAtIndex(int parameterIndex, float f) {
ParameterSetterPointer setters[k_numberOfTextCell] = {&InteractiveCurveViewRange::setXMin,
&InteractiveCurveViewRange::setXMax, &InteractiveCurveViewRange::setYMin, &InteractiveCurveViewRange::setYMax};
int index = parameterIndex > 2 ? parameterIndex - 1 : parameterIndex;
(m_interactiveRange->*setters[index])(f);
(m_tempInteractiveRange.*setters[index])(f);
return true;
}
@@ -119,4 +125,10 @@ int RangeParameterController::reusableParameterCellCount(int type) {
return k_numberOfConvertibleTextCell;
}
void RangeParameterController::buttonAction() {
*m_interactiveRange = m_tempInteractiveRange;
StackViewController * stack = stackController();
stack->pop();
}
}

View File

@@ -16,6 +16,7 @@ public:
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool handleEvent(Ion::Events::Event event) override;
void setRange(InteractiveCurveViewRange * range);
TELEMETRY_ID("Range");
private:
class MessageTableCellWithConvertibleEditableText : public MessageTableCellWithEditableText {
@@ -35,10 +36,12 @@ private:
int reusableParameterCellCount(int type) override;
float parameterAtIndex(int index) override;
bool setParameterAtIndex(int parameterIndex, float f) override;
void buttonAction() override;
constexpr static int k_numberOfEditableTextCell = 2;
constexpr static int k_numberOfConvertibleTextCell = 2;
constexpr static int k_numberOfTextCell = k_numberOfEditableTextCell+k_numberOfConvertibleTextCell;
InteractiveCurveViewRange * m_interactiveRange;
InteractiveCurveViewRange m_tempInteractiveRange;
MessageTableCellWithEditableText m_xRangeCells[k_numberOfEditableTextCell];
MessageTableCellWithConvertibleEditableText m_yRangeCells[k_numberOfConvertibleTextCell];
MessageTableCellWithSwitch m_yAutoCell;

View File

@@ -41,7 +41,7 @@ void TextToInsertForCommandText(const char * command, int commandLength, char *
UTF8Decoder decoder(command);
CodePoint codePoint = decoder.nextCodePoint();
while (codePoint != UCodePointNull && (commandLength < 0 || (decoder.stringPosition() - command <= commandLength))) {
while (codePoint != UCodePointNull && index < bufferSize - 1 && (commandLength < 0 || (decoder.stringPosition() - command <= commandLength))) {
if (codePoint == ')') {
numberOfOpenParentheses--;
} else if (codePoint == ']') {

View File

@@ -116,7 +116,7 @@ BasedLogarithm = "Logaritme met grondtal a"
Calculation = "Calculatie"
ComplexNumber = "Complexe getallen"
Combinatorics = "Combinatoriek"
Arithmetic = "rekenkunde"
Arithmetic = "Rekenkunde"
Matrices = "Matrix"
NewMatrix = "Nieuwe matrix"
Identity = "Eenheidsmatrix van formaat n"

View File

@@ -5,8 +5,8 @@ DEBUG ?= 0
HOME_DISPLAY_EXTERNALS ?= 1
EPSILON_VERSION ?= 14.4.1
OMEGA_VERSION ?= 1.20.2
# USERNAME ?= N/A
OMEGA_VERSION ?= 1.20.3
# OMEGA_USERNAME ?= N/A
EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings external
EPSILON_I18N ?= en fr nl pt it de es hu
EPSILON_GETOPT ?= 0
@@ -14,4 +14,3 @@ EPSILON_TELEMETRY ?= 0
ESCHER_LOG_EVENTS_BINARY ?= 0
THEME_NAME ?= omega_light
THEME_REPO ?= local
LEDS_CHOICE ?= 0

View File

@@ -2,9 +2,8 @@ HOSTCC = gcc
HOSTCXX = g++
PYTHON = python3
SFLAGS += -DLEDS_CHOICE=$(LEDS_CHOICE)
ifdef USERNAME
SFLAGS += -DUSERNAME="$(USERNAME)"
ifdef OMEGA_USERNAME
SFLAGS += -DOMEGA_USERNAME="$(OMEGA_USERNAME)"
endif
SFLAGS += -DEPSILON_GETOPT=$(EPSILON_GETOPT)
SFLAGS += -DEPSILON_TELEMETRY=$(EPSILON_TELEMETRY)

View File

@@ -4,10 +4,10 @@ set -e
REPO="${1:-https://github.com/Omega-Numworks/Omega.git}"
BRANCH="${2:-master}"
MODEL="${3:-MODEL=n0110}"
USERNAME="${4:- }"
OMEGA_USERNAME="${4:- }"
OPTIONS="${5:-epsilon_flash}"
echo Building ${REPO} branch ${BRANCH} for ${MODEL} with options ${OPTIONS} !
git clone --recurse-submodules -j $(nproc) --depth 1 --branch ${BRANCH} ${REPO} omega
time make cleanall && time make -j $(nproc) -C omega ${MODEL} ${USERNAME} ${OPTIONS}
time make cleanall && time make -j $(nproc) -C omega ${MODEL} ${OMEGA_USERNAME} ${OPTIONS}

View File

@@ -20,7 +20,7 @@ include ion/src/shared/tools/Makefile
# char test[4]= "ab"; is valid and should initialize test to 'a','b',0,0).
# Older versions of GCC are not conformant so we resort to an initializer list.
initializer_list = $(shell echo $(1) | sed "s/\(.\)/'\1',/g")0
$(call object_for,ion/src/shared/platform_info.cpp): SFLAGS += -DPATCH_LEVEL="$(call initializer_list,$(PATCH_LEVEL))" -DEPSILON_VERSION="$(call initializer_list,$(EPSILON_VERSION))" -DOMEGA_VERSION="$(call initializer_list,$(OMEGA_VERSION))" -DUSERNAME="$(call initializer_list,$(USERNAME))"
$(call object_for,ion/src/shared/platform_info.cpp): SFLAGS += -DPATCH_LEVEL="$(call initializer_list,$(PATCH_LEVEL))" -DEPSILON_VERSION="$(call initializer_list,$(EPSILON_VERSION))" -DOMEGA_VERSION="$(call initializer_list,$(OMEGA_VERSION))" -DOMEGA_USERNAME="$(call initializer_list,$(OMEGA_USERNAME))"
ion_src += $(addprefix ion/src/shared/, \
console_display.cpp:+consoledisplay \

View File

@@ -30,7 +30,7 @@ void ion_main(int argc, const char * const argv[]);
namespace Ion {
const char * serialNumber();
#ifdef USERNAME
#ifdef OMEGA_USERNAME
const char * username();
#endif
const char * softwareVersion();

View File

@@ -434,8 +434,9 @@ void initPanel() {
// Calibration
const uint8_t * gammaCalibration = nullptr;
uint32_t panelId = panelIdentifier();
if (panelId == 0x4E4101) {
// Don't forget the "static" qualifier, otherwise this array can be deleted before reaching send_long_command
if (panelId == 0x4E4101 || panelId == 0x4E4801) {
/* Don't forget the "static" qualifier, otherwise this array can be deleted
* before reaching send_long_command. */
static const uint8_t calibration[] = {0xA2, 0xA, 0x11, 0xA, 0xC, 0x1A, 0x34, 0x22, 0x4D, 0x28, 0x15, 0x13, 0x29, 0x2D};
gammaCalibration = calibration;
}

View File

@@ -33,8 +33,8 @@ public:
m_footer(Magic),
m_ohm_header(OmegaMagic),
m_omegaVersion{OMEGA_VERSION},
#ifdef USERNAME
m_username{USERNAME},
#ifdef OMEGA_USERNAME
m_username{OMEGA_USERNAME},
#else
m_username{"\0"},
#endif
@@ -57,7 +57,7 @@ public:
assert(m_ohm_footer == OmegaMagic);
return m_omegaVersion;
}
#ifdef USERNAME
#ifdef OMEGA_USERNAME
const char * username() const {
assert(m_storageAddress != nullptr);
assert(m_storageSize != 0);
@@ -102,7 +102,7 @@ const char * Ion::omegaVersion() {
return platform_infos.omegaVersion();
}
#ifdef USERNAME
#ifdef OMEGA_USERNAME
const char * Ion::username() {
return platform_infos.username();
}

View File

@@ -36,7 +36,7 @@ android {
defaultConfig {
applicationId "io.github.omega.simulator"
minSdkVersion 16
targetSdkVersion 28
targetSdkVersion 29
def (major, minor, patch) = System.getenv('OMEGA_VERSION').toLowerCase().tokenize('.').collect{it.toInteger()}
versionCode major*1000000 + minor*10000 + patch * 100
versionName System.getenv('OMEGA_VERSION')

View File

@@ -50,6 +50,8 @@ constexpr static KeySDLKeyPair sKeyPairs[] = {
constexpr int sNumberOfKeyPairs = sizeof(sKeyPairs)/sizeof(KeySDLKeyPair);
static bool previousState = false;
State scan() {
// We need to tell SDL to get new state from the host OS
SDL_PumpEvents();
@@ -69,9 +71,13 @@ State scan() {
// Register a key for the mouse, if any
SDL_Point p;
Uint32 mouseState = SDL_GetMouseState(&p.x, &p.y);
if (mouseState & SDL_BUTTON(SDL_BUTTON_LEFT)) {
if (!(previousState) && mouseState & SDL_BUTTON(SDL_BUTTON_LEFT)){
Key k = Simulator::Layout::keyAt(&p);
state.setKey(k);
previousState = true;
}
if (!(mouseState & SDL_BUTTON(SDL_BUTTON_LEFT))) {
previousState = false;
}
#endif

View File

@@ -37,15 +37,6 @@ public:
Radian = 1,
Gradian = 2
};
enum class LEDColor : uint8_t {
Red = 0,
White = 1,
Green = 2,
Blue = 3,
Yellow = 4,
Purple = 5,
Orange = 6,
};
enum class SymbolMultiplication : uint8_t {
Cross = 0,
MiddleDot = 1,
@@ -73,8 +64,6 @@ public:
void setComplexFormat(Preferences::ComplexFormat complexFormat) { m_complexFormat = complexFormat; }
uint8_t numberOfSignificantDigits() const { return m_numberOfSignificantDigits; }
void setNumberOfSignificantDigits(uint8_t numberOfSignificantDigits) { m_numberOfSignificantDigits = numberOfSignificantDigits; }
LEDColor colorOfLED() const { return m_colorOfLED; }
void setColorOfLED(LEDColor color) { m_colorOfLED = color; }
SymbolMultiplication symbolOfMultiplication() const { return m_symbolMultiplication; }
void setSymbolMultiplication(SymbolMultiplication symbolOfMultiplication) { m_symbolMultiplication = symbolOfMultiplication; }
SymbolFunction symbolOfFunction() const { return m_symbolFunction; }
@@ -88,7 +77,6 @@ private:
EditionMode m_editionMode;
ComplexFormat m_complexFormat;
uint8_t m_numberOfSignificantDigits;
LEDColor m_colorOfLED;
SymbolMultiplication m_symbolMultiplication;
SymbolFunction m_symbolFunction;
PythonFont m_pythonFont;

View File

@@ -156,13 +156,16 @@ Expression Addition::shallowReduce(ExpressionNode::ReductionContext reductionCon
* the result is not homogeneous. */
{
Expression unit;
childAtIndex(0).removeUnit(&unit);
if (childAtIndex(0).removeUnit(&unit).isUndefined()) {
return replaceWithUndefinedInPlace();
}
const bool hasUnit = !unit.isUninitialized();
for (int i = 1; i < childrenCount; i++) {
Expression otherUnit;
childAtIndex(i).removeUnit(&otherUnit);
if (hasUnit == otherUnit.isUninitialized() ||
(hasUnit && !unit.isIdenticalTo(otherUnit)))
Expression childI = childAtIndex(i).removeUnit(&otherUnit);
if (childI.isUndefined()
|| hasUnit == otherUnit.isUninitialized()
|| (hasUnit && !unit.isIdenticalTo(otherUnit)))
{
return replaceWithUndefinedInPlace();
}

View File

@@ -366,8 +366,8 @@ Expression Expression::defaultHandleUnitsInChildren() {
const int childrenCount = numberOfChildren();
for (int i = 0; i < childrenCount; i++) {
Expression unit;
childAtIndex(i).removeUnit(&unit);
if (!unit.isUninitialized()) {
Expression childI = childAtIndex(i).removeUnit(&unit);
if (childI.isUndefined() || !unit.isUninitialized()) {
return replaceWithUndefinedInPlace();
}
}
@@ -817,7 +817,11 @@ Expression Expression::angleUnitToRadian(Preferences::AngleUnit angleUnit) {
Expression Expression::reduce(ExpressionNode::ReductionContext reductionContext) {
sSimplificationHasBeenInterrupted = false;
return deepReduce(reductionContext);
Expression result = deepReduce(reductionContext);
if (sSimplificationHasBeenInterrupted) {
return replaceWithUndefinedInPlace();
}
return result;
}
Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionContext) {

View File

@@ -279,8 +279,16 @@ Expression Multiplication::removeUnit(Expression * unit) {
Multiplication unitMult = Multiplication::Builder();
int resultChildrenCount = 0;
for (int i = 0; i < numberOfChildren(); i++) {
Expression childI = childAtIndex(i);
assert(!childI.isUndefined());
Expression currentUnit;
childAtIndex(i).removeUnit(&currentUnit);
childI = childI.removeUnit(&currentUnit);
if (childI.isUndefined()) {
/* If the child was a unit convert, it replaced itself with an undefined
* during the removeUnit. */
*unit = Expression();
return replaceWithUndefinedInPlace();
}
if (!currentUnit.isUninitialized()) {
unitMult.addChildAtIndexInPlace(currentUnit, resultChildrenCount, resultChildrenCount);
resultChildrenCount++;
@@ -384,7 +392,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
self = deepReduce(reductionContext); // removeUnit has to be called on reduced expression
self = removeUnit(&units);
if (units.isUninitialized()) {
if (self.isUndefined() || units.isUninitialized()) {
// TODO: handle error "Invalid unit"
result = Undefined::Builder();
goto replace_by_result;

View File

@@ -407,8 +407,8 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex
{
Expression indexUnit;
index = index.removeUnit(&indexUnit);
if (!indexUnit.isUninitialized()) {
// There must be no unit in the exponent
if (!indexUnit.isUninitialized() || index.isUndefined()) {
// There must be no unit nor undefined in the exponent
return replaceWithUndefinedInPlace();
}
assert(index == childAtIndex(1));

View File

@@ -13,7 +13,6 @@ Preferences::Preferences() :
m_editionMode(EditionMode::Edition2D),
m_complexFormat(Preferences::ComplexFormat::Real),
m_numberOfSignificantDigits(PrintFloat::k_numberOfPrintedSignificantDigits),
m_colorOfLED(Preferences::LEDColor::Red),
m_symbolMultiplication(Preferences::SymbolMultiplication::Auto),
m_symbolFunction(Preferences::SymbolFunction::Default),
m_pythonFont(Preferences::PythonFont::Large)

View File

@@ -59,8 +59,8 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
reductionContext.target(),
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined);
Expression unit;
childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit);
if (unit.isUninitialized()) {
Expression childWithoutUnit = childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit);
if (childWithoutUnit.isUndefined() || unit.isUninitialized()) {
// There is no unit on the right
return replaceWithUndefinedInPlace();
}

View File

@@ -70,8 +70,8 @@ QUIZ_CASE(poincare_context_user_variable_simple) {
}
QUIZ_CASE(poincare_context_user_variable_2_circular_variables) {
assert_simplify("a→b");
assert_simplify("b→a");
assert_reduce("a→b");
assert_reduce("b→a");
assert_expression_approximates_to<double>("a", Undefined::Name());
assert_expression_approximates_to<double>("b", Undefined::Name());
@@ -81,9 +81,9 @@ QUIZ_CASE(poincare_context_user_variable_2_circular_variables) {
}
QUIZ_CASE(poincare_context_user_variable_3_circular_variables) {
assert_simplify("a→b");
assert_simplify("b→c");
assert_simplify("c→a");
assert_reduce("a→b");
assert_reduce("b→c");
assert_reduce("c→a");
assert_expression_approximates_to<double>("a", Undefined::Name());
assert_expression_approximates_to<double>("b", Undefined::Name());
assert_expression_approximates_to<double>("c", Undefined::Name());
@@ -96,7 +96,7 @@ QUIZ_CASE(poincare_context_user_variable_3_circular_variables) {
QUIZ_CASE(poincare_context_user_variable_1_circular_function) {
// h: x → h(x)
assert_simplify("h(x)→h(x)");
assert_reduce("h(x)→h(x)");
assert_expression_approximates_to<double>("h(1)", Undefined::Name());
// Clean the storage for other tests
@@ -104,9 +104,9 @@ QUIZ_CASE(poincare_context_user_variable_1_circular_function) {
}
QUIZ_CASE(poincare_context_user_variable_2_circular_functions) {
assert_simplify("1→f(x)");
assert_simplify("f(x)→g(x)");
assert_simplify("g(x)→f(x)");
assert_reduce("1→f(x)");
assert_reduce("f(x)→g(x)");
assert_reduce("g(x)→f(x)");
assert_expression_approximates_to<double>("f(1)", Undefined::Name());
assert_expression_approximates_to<double>("g(1)", Undefined::Name());
@@ -116,10 +116,10 @@ QUIZ_CASE(poincare_context_user_variable_2_circular_functions) {
}
QUIZ_CASE(poincare_context_user_variable_3_circular_functions) {
assert_simplify("1→f(x)");
assert_simplify("f(x)→g(x)");
assert_simplify("g(x)→h(x)");
assert_simplify("h(x)→f(x)");
assert_reduce("1→f(x)");
assert_reduce("f(x)→g(x)");
assert_reduce("g(x)→h(x)");
assert_reduce("h(x)→f(x)");
assert_expression_approximates_to<double>("f(1)", Undefined::Name());
assert_expression_approximates_to<double>("g(1)", Undefined::Name());
assert_expression_approximates_to<double>("h(1)", Undefined::Name());
@@ -131,9 +131,9 @@ QUIZ_CASE(poincare_context_user_variable_3_circular_functions) {
}
QUIZ_CASE(poincare_context_user_variable_circular_variables_and_functions) {
assert_simplify("a→b");
assert_simplify("b→a");
assert_simplify("a→f(x)");
assert_reduce("a→b");
assert_reduce("b→a");
assert_reduce("a→f(x)");
assert_expression_approximates_to<double>("f(1)", Undefined::Name());
assert_expression_approximates_to<double>("a", Undefined::Name());
assert_expression_approximates_to<double>("b", Undefined::Name());
@@ -146,21 +146,21 @@ QUIZ_CASE(poincare_context_user_variable_circular_variables_and_functions) {
QUIZ_CASE(poincare_context_user_variable_composed_functions) {
// f: x→x^2
assert_simplify("x^2→f(x)");
assert_reduce("x^2→f(x)");
// g: x→f(x-2)
assert_simplify("f(x-2)→g(x)");
assert_reduce("f(x-2)→g(x)");
assert_expression_approximates_to<double>("f(2)", "4");
assert_expression_approximates_to<double>("g(3)", "1");
assert_expression_approximates_to<double>("g(5)", "9");
// g: x→f(x-2)+f(x+1)
assert_simplify("f(x-2)+f(x+1)→g(x)");
assert_reduce("f(x-2)+f(x+1)→g(x)");
// Add a sum to bypass simplification
assert_expression_approximates_to<double>("g(3)+sum(1, n, 2, 4)", "20");
assert_expression_approximates_to<double>("g(5)", "45");
// g: x→x+1
assert_simplify("x+1→g(x)");
assert_reduce("x+1→g(x)");
assert_expression_approximates_to<double>("f(g(4))", "25");
// Add a sum to bypass simplification
assert_expression_approximates_to<double>("f(g(4))+sum(1, n, 2, 4)", "28");
@@ -172,7 +172,7 @@ QUIZ_CASE(poincare_context_user_variable_composed_functions) {
QUIZ_CASE(poincare_context_user_variable_functions_approximation_with_value_for_symbol) {
// f : x→ x^2
assert_simplify("x^2→f(x)");
assert_reduce("x^2→f(x)");
// Approximate f(?-2) with ? = 5
constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1;
@@ -187,7 +187,7 @@ QUIZ_CASE(poincare_context_user_variable_functions_approximation_with_value_for_
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
// f : x → √(-1)
assert_simplify("√(-1)×√(-1)→f(x)");
assert_reduce("√(-1)×√(-1)→f(x)");
// Approximate f(?) with ? = 5
// Cartesian
assert_parsed_expression_approximates_with_value_for_symbol(Function::Builder("f", 1, Symbol::Builder(UCodePointUnknown)), x, 1.0, -1.0);

View File

@@ -48,7 +48,7 @@ QUIZ_CASE(poincare_properties_is_approximate) {
assert_expression_has_property("3.4", &context, Expression::IsApproximate);
assert_expression_has_property("2.3+1", &context, Expression::IsApproximate);
assert_expression_has_not_property("a", &context, Expression::IsApproximate);
assert_simplify("42.3→a");
assert_reduce("42.3→a");
assert_expression_has_property("a", &context, Expression::IsApproximate);
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
}
@@ -93,7 +93,7 @@ QUIZ_CASE(poincare_properties_is_infinity) {
assert_expression_has_property("3.4+inf", &context, Expression::IsInfinity);
assert_expression_has_not_property("2.3+1", &context, Expression::IsInfinity);
assert_expression_has_not_property("a", &context, Expression::IsInfinity);
assert_simplify("42.3+inf→a");
assert_reduce("42.3+inf→a");
assert_expression_has_property("a", &context, Expression::IsInfinity);
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
}
@@ -155,7 +155,7 @@ QUIZ_CASE(poincare_properties_sign) {
assert_reduced_expression_sign("sign(π)", Positive);
assert_reduced_expression_sign("sign(-π)", Negative);
assert_reduced_expression_sign("a", Unknown);
assert_simplify("42→a");
assert_reduce("42→a");
assert_reduced_expression_sign("a", Positive);
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
}
@@ -232,7 +232,7 @@ QUIZ_CASE(poincare_properties_polynomial_degree) {
assert_reduced_expression_polynomial_degree("π×x", 1);
assert_reduced_expression_polynomial_degree("√(-1)×x", -1, "x", Real);
// f: x→x^2+πx+1
assert_simplify("1+π×x+x^2→f(x)");
assert_reduce("1+π×x+x^2→f(x)");
assert_reduced_expression_polynomial_degree("f(x)", 2);
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
}
@@ -271,7 +271,7 @@ QUIZ_CASE(poincare_properties_characteristic_range) {
// cos(cos(x)), degree
assert_reduced_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol::Builder(UCodePointUnknown))), 360.0f);
// f(x) with f : x --> cos(x), degree
assert_simplify("cos(x)→f(x)");
assert_reduce("cos(x)→f(x)");
assert_reduced_expression_has_characteristic_range(Function::Builder("f",1,Symbol::Builder(UCodePointUnknown)), 360.0f);
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
}
@@ -309,7 +309,7 @@ QUIZ_CASE(poincare_properties_get_variables) {
assert_expression_has_variables("a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+aa+bb+cc+dd+ee+ff+gg+hh+ii+jj+kk+ll+mm+nn+oo", variableBuffer6, -1);
assert_expression_has_variables("a+b+c+d+e+f+g", variableBuffer6, -1);
// f: x→1+πx+x^2+toto
assert_simplify("1+π×x+x^2+toto→f(x)");
assert_reduce("1+π×x+x^2+toto→f(x)");
const char * variableBuffer7[] = {"tata","toto", ""};
assert_expression_has_variables("f(tata)", variableBuffer7, 2);
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
@@ -347,7 +347,7 @@ QUIZ_CASE(poincare_properties_get_polynomial_coefficients) {
assert_reduced_expression_has_polynomial_coefficient("x^2-π×x+1", "x", coefficient3);
// f: x→x^2+Px+1
assert_simplify("1+π×x+x^2→f(x)");
assert_reduce("1+π×x+x^2→f(x)");
const char * coefficient4[] = {"1", "π", "1", 0}; //x^2+π×x+1
assert_reduced_expression_has_polynomial_coefficient("f(x)", "x", coefficient4);
const char * coefficient5[] = {"0", "𝐢", 0}; //√(-1)x
@@ -356,7 +356,7 @@ QUIZ_CASE(poincare_properties_get_polynomial_coefficients) {
assert_reduced_expression_has_polynomial_coefficient("√(-1)x", "x", coefficient6, Real);
// 3 -> x
assert_simplify("3→x");
assert_reduce("3→x");
const char * coefficient7[] = {"4", 0};
assert_reduced_expression_has_polynomial_coefficient("x+1", "x", coefficient7 );
const char * coefficient8[] = {"2", "1", 0};

View File

@@ -76,13 +76,13 @@ Poincare::Expression parse_expression(const char * expression, Context * context
return result;
}
void assert_simplify(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) {
void assert_reduce(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) {
Shared::GlobalContext globalContext;
Expression e = parse_expression(expression, &globalContext, false);
assert_expression_simplify(e, angleUnit, complexFormat, target, expression);
assert_expression_reduce(e, angleUnit, complexFormat, target, expression);
}
void assert_expression_simplify(Expression e, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target, const char * printIfFailure) {
void assert_expression_reduce(Expression e, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target, const char * printIfFailure) {
Shared::GlobalContext globalContext;
e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, target));
quiz_assert_print_if_failure(!(e.isUninitialized()), printIfFailure);

View File

@@ -39,9 +39,9 @@ Poincare::Expression parse_expression(const char * expression, Poincare::Context
// Simplification
void assert_simplify(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User);
void assert_reduce(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User);
void assert_expression_simplify(Poincare::Expression expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User, const char * printIfFailure = "Error");
void assert_expression_reduce(Poincare::Expression expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User, const char * printIfFailure = "Error");
void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = User, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = DefaultUnitConversion);

View File

@@ -898,7 +898,7 @@ QUIZ_CASE(poincare_simplification_matrix) {
assert_parsed_expression_simplify_to("transpose(√(4))", "2");
// Expressions with unreduced matrix
assert_simplify("confidence(cos(2)/25,3)→a");
assert_reduce("confidence(cos(2)/25,3)→a");
// Check that matrices are not permuted in multiplication
assert_parsed_expression_simplify_to("cos(3a)*abs(transpose(a))", "cos(3×confidence(cos(2)/25,3))×abs(transpose(confidence(cos(2)/25,3)))");
assert_parsed_expression_simplify_to("abs(transpose(a))*cos(3a)", "abs(transpose(confidence(cos(2)/25,3)))×cos(3×confidence(cos(2)/25,3))");
@@ -1054,13 +1054,13 @@ QUIZ_CASE(poincare_simplification_unit_convert) {
assert_parsed_expression_simplify_to("4→_km/_m", Undefined::Name());
assert_parsed_expression_simplify_to("3×_min→_s+1-1", Undefined::Name());
assert_simplify("_m→a", Radian, Real);
assert_simplify("_m→b", Radian, Real);
assert_reduce("_m→a", Radian, Real);
assert_reduce("_m→b", Radian, Real);
assert_parsed_expression_simplify_to("1_km→a×b", Undefined::Name());
assert_simplify("2→a");
assert_reduce("2→a");
assert_parsed_expression_simplify_to("3_m→a×_km", Undefined::Name());
assert_simplify("2→f(x)");
assert_reduce("2→f(x)");
assert_parsed_expression_simplify_to("3_m→f(2)×_km", Undefined::Name());
// Clean the storage for other tests
@@ -1087,13 +1087,13 @@ QUIZ_CASE(poincare_simplification_complex_format) {
// User defined variable
assert_parsed_expression_simplify_to("a", "a", User, Radian, Real);
// a = 2+i
assert_simplify("2+𝐢→a", Radian, Real);
assert_reduce("2+𝐢→a", Radian, Real);
assert_parsed_expression_simplify_to("a", "unreal", User, Radian, Real);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
// User defined function
// f : x → x+1
assert_simplify("x+1+𝐢→f(x)", Radian, Real);
assert_reduce("x+1+𝐢→f(x)", Radian, Real);
assert_parsed_expression_simplify_to("f(3)", "unreal", User, Radian, Real);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
@@ -1173,13 +1173,13 @@ QUIZ_CASE(poincare_simplification_complex_format) {
// User defined variable
assert_parsed_expression_simplify_to("a", "a", User, Radian, Cartesian);
// a = 2+i
assert_simplify("2+𝐢→a", Radian, Cartesian);
assert_reduce("2+𝐢→a", Radian, Cartesian);
assert_parsed_expression_simplify_to("a", "2+𝐢", User, Radian, Cartesian);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
// User defined function
// f : x → x+1
assert_simplify("x+1+𝐢→f(x)", Radian, Cartesian);
assert_reduce("x+1+𝐢→f(x)", Radian, Cartesian);
assert_parsed_expression_simplify_to("f(3)", "4+𝐢", User, Radian, Cartesian);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
@@ -1223,13 +1223,13 @@ QUIZ_CASE(poincare_simplification_complex_format) {
// User defined variable
assert_parsed_expression_simplify_to("a", "a", User, Radian, Polar);
// a = 2 + 𝐢
assert_simplify("2+𝐢→a", Radian, Polar);
assert_reduce("2+𝐢→a", Radian, Polar);
assert_parsed_expression_simplify_to("a", "√(5)×^\u0012\u0012-2×atan(2)+π\u0013/2×𝐢\u0013", User, Radian, Polar);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
// User defined function
// f: x → x+1
assert_simplify("x+1+𝐢→f(x)", Radian, Polar);
assert_reduce("x+1+𝐢→f(x)", Radian, Polar);
assert_parsed_expression_simplify_to("f(3)", "√(17)×^\u0012\u0012-2×atan(4)+π\u0013/2×𝐢\u0013", User, Radian, Polar);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
@@ -1295,10 +1295,10 @@ QUIZ_CASE(poincare_simplification_unit_conversion) {
QUIZ_CASE(poincare_simplification_user_function) {
// User defined function
// f: x → x*1
assert_simplify("x*3→f(x)", Radian, Polar);
assert_reduce("x*3→f(x)", Radian, Polar);
assert_parsed_expression_simplify_to("f(1+1)", "6", User, Radian, Polar);
// f: x → 3
assert_simplify("3→f(x)", Radian, Polar);
assert_reduce("3→f(x)", Radian, Polar);
assert_parsed_expression_simplify_to("f(1/0)", Undefined::Name(), User, Radian, Polar);
// Clean the storage for other tests
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
@@ -1315,8 +1315,19 @@ QUIZ_CASE(poincare_simplification_user_function_with_convert) {
Function::Builder(
"f", 1,
Symbol::Builder('x')));
assert_expression_simplify(e);
assert_simplify("e^(f(0))", Radian, Polar);
assert_expression_reduce(e);
assert_parsed_expression_simplify_to("e^(f(0))", "undef");
e = Store::Builder(
UnitConvert::Builder(
Rational::Builder(0),
Unit::Second()),
Function::Builder(
"f", 1,
Symbol::Builder('x')));
assert_expression_reduce(e);
assert_parsed_expression_simplify_to("0f(0)", "undef");
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
}

2
themes

Submodule themes updated: d9bc63ee68...48fc1cc727