mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[solver] Create a class SolutionsController
This commit is contained in:
@@ -7,6 +7,7 @@ app_objs += $(addprefix apps/solver/,\
|
||||
equation.o\
|
||||
equation_store.o\
|
||||
list_controller.o\
|
||||
solutions_controller.o\
|
||||
)
|
||||
|
||||
i18n_files += $(addprefix apps/solver/,\
|
||||
|
||||
213
apps/solver/solutions_controller.cpp
Normal file
213
apps/solver/solutions_controller.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "solutions_controller.h"
|
||||
#include "app.h"
|
||||
#include "../constant.h"
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
using namespace Poincare;
|
||||
using namespace Shared;
|
||||
|
||||
namespace Solver {
|
||||
|
||||
SolutionsController::SolutionsController(Responder * parentResponder, EquationStore * equationStore) :
|
||||
ViewController(parentResponder),
|
||||
m_equationStore(equationStore),
|
||||
m_selectableTableView(this)
|
||||
{
|
||||
m_selectableTableView.setBackgroundColor(Palette::WallScreenDark);
|
||||
m_selectableTableView.setVerticalCellOverlap(0);
|
||||
for (int i = 0; i < EquationStore::k_maxNumberOfExactSolutions; i++) {
|
||||
m_exactValueCells[i].setParentResponder(&m_selectableTableView);
|
||||
}
|
||||
for (int i = 0; i < EquationStore::k_maxNumberOfSolutions; i++) {
|
||||
m_symbolCells[i].setAlignment(0.5f, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
/* ViewController */
|
||||
const char * SolutionsController::title() {
|
||||
if (m_equationStore->type() == EquationStore::Type::Monovariable) {
|
||||
return I18n::translate(I18n::Message::ApproximateSolution);
|
||||
}
|
||||
return I18n::translate(I18n::Message::Solution);
|
||||
}
|
||||
|
||||
View * SolutionsController::view() {
|
||||
return &m_selectableTableView;
|
||||
}
|
||||
|
||||
void SolutionsController::viewWillAppear() {
|
||||
ViewController::viewWillAppear();
|
||||
m_selectableTableView.reloadData();
|
||||
if (selectedRow() < 0) {
|
||||
selectCellAtLocation(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* AlternateEmptyRowDelegate */
|
||||
|
||||
bool SolutionsController::isEmpty() const {
|
||||
if (m_equationStore->numberOfSolutions() == 0 || m_equationStore->numberOfSolutions() == INT_MAX) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
I18n::Message SolutionsController::emptyMessage() {
|
||||
if (m_equationStore->numberOfSolutions() == INT_MAX) {
|
||||
return I18n::Message::InfiniteNumberOfSolutions;
|
||||
}
|
||||
return I18n::Message::NoSolution;
|
||||
}
|
||||
|
||||
Responder * SolutionsController::defaultController() {
|
||||
return parentResponder();
|
||||
}
|
||||
|
||||
/* TableViewDataSource */
|
||||
|
||||
int SolutionsController::numberOfRows() {
|
||||
if (m_equationStore->type() == EquationStore::Type::PolynomialMonovariable) {
|
||||
return m_equationStore->numberOfSolutions() + 1; // add the delta row
|
||||
}
|
||||
return m_equationStore->numberOfSolutions();
|
||||
}
|
||||
|
||||
int SolutionsController::numberOfColumns() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void SolutionsController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
|
||||
EvenOddCell * evenOddCell = static_cast<EvenOddCell *>(cell);
|
||||
evenOddCell->setEven(j%2 == 0);
|
||||
if (i == 0) {
|
||||
EvenOddBufferTextCell * symbolCell = static_cast<EvenOddBufferTextCell *>(cell);
|
||||
symbolCell->setFontSize(KDText::FontSize::Large);
|
||||
char bufferSymbol[10]; // hold at maximum Delta = b^2-4ac
|
||||
switch (m_equationStore->type()) {
|
||||
case EquationStore::Type::LinearSystem:
|
||||
bufferSymbol[0] = m_equationStore->variableAtIndex(j);
|
||||
bufferSymbol[1] = 0;
|
||||
break;
|
||||
case EquationStore::Type::PolynomialMonovariable:
|
||||
if (j == m_equationStore->numberOfSolutions()) {
|
||||
symbolCell->setFontSize(KDText::FontSize::Small);
|
||||
strlcpy(bufferSymbol, I18n::translate(I18n::Message::DiscriminantFormulaDegree2), 10);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
bufferSymbol[0] = m_equationStore->variableAtIndex(0);
|
||||
bufferSymbol[1] = j+'0';
|
||||
bufferSymbol[2] = 0;
|
||||
break;
|
||||
}
|
||||
symbolCell->setText(bufferSymbol);
|
||||
return;
|
||||
}
|
||||
if (m_equationStore->type() == EquationStore::Type::Monovariable) {
|
||||
EvenOddBufferTextCell * valueCell = static_cast<EvenOddBufferTextCell *>(cell);
|
||||
char bufferValue[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
||||
PrintFloat::convertFloatToText<double>(m_equationStore->approximateSolutionAtIndex(j), bufferValue, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
valueCell->setText(bufferValue);
|
||||
} else {
|
||||
Shared::ScrollableExactApproximateExpressionsCell * valueCell = static_cast<ScrollableExactApproximateExpressionsCell *>(cell);
|
||||
Poincare::ExpressionLayout * exactSolutionLayouts[2] = {m_equationStore->exactSolutionLayoutAtIndex(j, false), m_equationStore->exactSolutionLayoutAtIndex(j, true)};
|
||||
valueCell->setExpressions(exactSolutionLayouts);
|
||||
valueCell->setEqualMessage(I18n::Message::AlmostEqual);// TODO: true equal when possible?
|
||||
}
|
||||
}
|
||||
|
||||
KDCoordinate SolutionsController::columnWidth(int i) {
|
||||
if (i == 0) {
|
||||
return k_symbolCellWidth;
|
||||
}
|
||||
return k_valueCellWidth;
|
||||
}
|
||||
|
||||
KDCoordinate SolutionsController::rowHeight(int j) {
|
||||
if (m_equationStore->type() == EquationStore::Type::Monovariable) {
|
||||
return k_defaultCellHeight;
|
||||
}
|
||||
Poincare::ExpressionLayout * exactLayout = m_equationStore->exactSolutionLayoutAtIndex(j, true);
|
||||
Poincare::ExpressionLayout * approximateLayout = m_equationStore->exactSolutionLayoutAtIndex(j, false);
|
||||
KDCoordinate exactLayoutHeight = exactLayout->size().height();
|
||||
KDCoordinate approximateLayoutHeight = approximateLayout->size().height();
|
||||
KDCoordinate layoutHeight = max(exactLayout->baseline(), approximateLayout->baseline()) + max(exactLayoutHeight-exactLayout->baseline(), approximateLayoutHeight-approximateLayout->baseline());
|
||||
return layoutHeight+k_defaultCellHeight;
|
||||
}
|
||||
|
||||
KDCoordinate SolutionsController::cumulatedHeightFromIndex(int j) {
|
||||
int result = 0;
|
||||
for (int k = 0; k < j; k++) {
|
||||
result += rowHeight(k);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int SolutionsController::indexFromCumulatedHeight(KDCoordinate offsetY) {
|
||||
int result = 0;
|
||||
int j = 0;
|
||||
while (result < offsetY && j < numberOfRows()) {
|
||||
result += rowHeight(j++);
|
||||
}
|
||||
return (result < offsetY || offsetY == 0) ? j : j - 1;
|
||||
}
|
||||
|
||||
KDCoordinate SolutionsController::cumulatedWidthFromIndex(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return k_symbolCellWidth;
|
||||
case 2:
|
||||
return k_symbolCellWidth+k_valueCellWidth;
|
||||
default:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int SolutionsController::indexFromCumulatedWidth(KDCoordinate offsetX) {
|
||||
if (offsetX <= k_symbolCellWidth) {
|
||||
return 0;
|
||||
} else {
|
||||
if (offsetX <= k_symbolCellWidth+k_valueCellWidth)
|
||||
return 1;
|
||||
else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HighlightCell * SolutionsController::reusableCell(int index, int type) {
|
||||
if (type == 0) {
|
||||
return &m_symbolCells[index];
|
||||
} else if (type == 1) {
|
||||
return &m_exactValueCells[index];
|
||||
}
|
||||
return &m_approximateValueCells[index];
|
||||
}
|
||||
|
||||
int SolutionsController::reusableCellCount(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return EquationStore::k_maxNumberOfSolutions;
|
||||
case 1:
|
||||
return EquationStore::k_maxNumberOfExactSolutions;
|
||||
default:
|
||||
return EquationStore::k_maxNumberOfApproximateSolutions;
|
||||
}
|
||||
}
|
||||
|
||||
int SolutionsController::typeAtLocation(int i, int j) {
|
||||
if (i == 0) {
|
||||
return 0;
|
||||
}
|
||||
return m_equationStore->type() == EquationStore::Type::Monovariable ? 2 : 1;
|
||||
}
|
||||
|
||||
void SolutionsController::didBecomeFirstResponder() {
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
}
|
||||
51
apps/solver/solutions_controller.h
Normal file
51
apps/solver/solutions_controller.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef SOLVER_SOLUTIONS_CONTROLLER_H
|
||||
#define SOLVER_SOLUTIONS_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "equation_store.h"
|
||||
#include "../shared/scrollable_exact_approximate_expressions_cell.h"
|
||||
#include "../i18n.h"
|
||||
|
||||
namespace Solver {
|
||||
|
||||
class SolutionsController : public ViewController, public AlternateEmptyViewDelegate, public SelectableTableViewDataSource, public TableViewDataSource {
|
||||
public:
|
||||
SolutionsController(Responder * parentResponder, EquationStore * equationStore);
|
||||
/* ViewController */
|
||||
const char * title() override;
|
||||
View * view() override;
|
||||
void viewWillAppear() override;
|
||||
/* AlternateEmptyViewDelegate */
|
||||
bool isEmpty() const override;
|
||||
virtual I18n::Message emptyMessage() override;
|
||||
virtual Responder * defaultController() override;
|
||||
/* TableViewDataSource */
|
||||
int numberOfRows() override;
|
||||
int numberOfColumns() override;
|
||||
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override;
|
||||
KDCoordinate columnWidth(int i) override;
|
||||
KDCoordinate rowHeight(int j) override;
|
||||
KDCoordinate cumulatedWidthFromIndex(int i) override;
|
||||
KDCoordinate cumulatedHeightFromIndex(int j) override;
|
||||
int indexFromCumulatedWidth(KDCoordinate offsetX) override;
|
||||
int indexFromCumulatedHeight(KDCoordinate offsetY) override;
|
||||
HighlightCell * reusableCell(int index, int type) override;
|
||||
int reusableCellCount(int type) override;
|
||||
int typeAtLocation(int i, int j) override;
|
||||
/* Responder */
|
||||
void didBecomeFirstResponder() override;
|
||||
private:
|
||||
constexpr static int k_symbolCellWidth = 100;
|
||||
constexpr static int k_valueCellWidth = 180;
|
||||
constexpr static KDCoordinate k_defaultCellHeight = 20;
|
||||
EquationStore * m_equationStore;
|
||||
EvenOddBufferTextCell m_symbolCells[EquationStore::k_maxNumberOfSolutions];
|
||||
Shared::ScrollableExactApproximateExpressionsCell m_exactValueCells[EquationStore::k_maxNumberOfExactSolutions];
|
||||
EvenOddBufferTextCell m_approximateValueCells[EquationStore::k_maxNumberOfApproximateSolutions];
|
||||
SelectableTableView m_selectableTableView;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user