mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 08:47:28 +01:00
280 lines
9.9 KiB
C++
280 lines
9.9 KiB
C++
#include "calculation_controller.h"
|
|
#include "../constant.h"
|
|
#include "../apps_container.h"
|
|
#include "../../poincare/src/layout/baseline_relative_layout.h"
|
|
#include "../../poincare/src/layout/string_layout.h"
|
|
#include <poincare.h>
|
|
#include <assert.h>
|
|
|
|
using namespace Poincare;
|
|
using namespace Shared;
|
|
|
|
namespace Regression {
|
|
|
|
CalculationController::CalculationController(Responder * parentResponder, ButtonRowController * header, Store * store) :
|
|
TabTableController(parentResponder, this),
|
|
ButtonRowDelegate(header, nullptr),
|
|
m_titleCells{},
|
|
m_r2TitleCell(nullptr),
|
|
m_columnTitleCell(nullptr),
|
|
m_doubleCalculationCells{},
|
|
m_calculationCells{},
|
|
m_store(store)
|
|
{
|
|
m_r2Layout = new BaselineRelativeLayout(new StringLayout("r", 1, KDText::FontSize::Small), new StringLayout("2", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Superscript);
|
|
}
|
|
|
|
CalculationController::~CalculationController() {
|
|
if (m_r2Layout) {
|
|
delete m_r2Layout;
|
|
m_r2Layout = nullptr;
|
|
}
|
|
}
|
|
|
|
const char * CalculationController::title() {
|
|
return I18n::translate(I18n::Message::StatTab);
|
|
}
|
|
|
|
bool CalculationController::handleEvent(Ion::Events::Event event) {
|
|
if (event == Ion::Events::Up) {
|
|
selectableTableView()->deselectTable();
|
|
app()->setFirstResponder(tabController());
|
|
return true;
|
|
}
|
|
if (event == Ion::Events::Copy && selectedColumn() == 1 && selectedRow() > 0) {
|
|
if (selectedRow() < 6) {
|
|
EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)selectableTableView()->selectedCell();
|
|
if (myCell->firstTextSelected()) {
|
|
Clipboard::sharedClipboard()->store(myCell->firstText());
|
|
} else {
|
|
Clipboard::sharedClipboard()->store(myCell->secondText());
|
|
}
|
|
} else {
|
|
EvenOddBufferTextCell * myCell = (EvenOddBufferTextCell *)selectableTableView()->selectedCell();
|
|
Clipboard::sharedClipboard()->store(myCell->text());
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CalculationController::didBecomeFirstResponder() {
|
|
if (selectedRow() == -1) {
|
|
selectCellAtLocation(1, 0);
|
|
} else {
|
|
selectCellAtLocation(selectedColumn(), selectedRow());
|
|
}
|
|
TabTableController::didBecomeFirstResponder();
|
|
}
|
|
|
|
void CalculationController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
|
|
/* To prevent selecting cell with no content (top left corner of the table),
|
|
* as soon as the selected cell is the top left corner, we either reselect
|
|
* the previous cell or select the tab controller depending on from which cell
|
|
* the selection comes. This trick does not create an endless loop as the
|
|
* previous cell cannot be the top left corner cell if it also is the
|
|
* selected one. */
|
|
if (t->selectedRow() == 0 && t->selectedColumn() == 0) {
|
|
if (previousSelectedCellX == 0 && previousSelectedCellY == 1) {
|
|
selectableTableView()->deselectTable();
|
|
app()->setFirstResponder(tabController());
|
|
} else {
|
|
t->selectCellAtLocation(previousSelectedCellX, previousSelectedCellY);
|
|
}
|
|
}
|
|
if (t->selectedColumn() == 1 && t->selectedRow() >= 0 && t->selectedRow() < 6) {
|
|
EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)t->selectedCell();
|
|
bool firstSubCellSelected = true;
|
|
if (previousSelectedCellX == 1 && previousSelectedCellY >= 0 && previousSelectedCellY < 6) {
|
|
EvenOddDoubleBufferTextCell * myPreviousCell = (EvenOddDoubleBufferTextCell *)t->cellAtLocation(previousSelectedCellX, previousSelectedCellY);
|
|
firstSubCellSelected = myPreviousCell->firstTextSelected();
|
|
}
|
|
myCell->selectFirstText(firstSubCellSelected);
|
|
app()->setFirstResponder(myCell);
|
|
} else {
|
|
if (previousSelectedCellX == 1 && previousSelectedCellY >= 0 && previousSelectedCellY < 6) {
|
|
EvenOddDoubleBufferTextCell * myPreviousCell = (EvenOddDoubleBufferTextCell *)t->cellAtLocation(previousSelectedCellX, previousSelectedCellY);
|
|
if (app()->firstResponder()->commonAncestorWith(myPreviousCell) == myPreviousCell) {
|
|
app()->setFirstResponder(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CalculationController::isEmpty() const {
|
|
if (m_store->numberOfPairs() == 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
I18n::Message CalculationController::emptyMessage() {
|
|
return I18n::Message::NoValueToCompute;
|
|
}
|
|
|
|
Responder * CalculationController::defaultController() {
|
|
return tabController();
|
|
}
|
|
|
|
int CalculationController::numberOfRows() {
|
|
return k_totalNumberOfRows;
|
|
}
|
|
|
|
int CalculationController::numberOfColumns() {
|
|
return k_totalNumberOfColumns;
|
|
}
|
|
|
|
void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
|
|
EvenOddCell * myCell = (EvenOddCell *)cell;
|
|
myCell->setEven(j%2 == 0);
|
|
myCell->setHighlighted(i == selectedColumn() && j == selectedRow());
|
|
if (j == 0 && i > 0) {
|
|
EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)cell;
|
|
myCell->setFirstText("x");
|
|
myCell->setSecondText("y");
|
|
return;
|
|
}
|
|
if (i == 0) {
|
|
if (j == 10) {
|
|
EvenOddExpressionCell * myCell = (EvenOddExpressionCell *)cell;
|
|
myCell->setExpression(m_r2Layout);
|
|
return;
|
|
}
|
|
EvenOddMessageTextCell * myCell = (EvenOddMessageTextCell *)cell;
|
|
if (j == 0) {
|
|
myCell->setMessage(I18n::Message::Default);
|
|
return;
|
|
}
|
|
myCell->setAlignment(1.0f, 0.5f);
|
|
I18n::Message titles[k_totalNumberOfRows-1] = {I18n::Message::Mean, I18n::Message::Sum, I18n::Message::SquareSum, I18n::Message::StandardDeviation, I18n::Message::Deviation, I18n::Message::NumberOfDots, I18n::Message::Covariance, I18n::Message::Sxy, I18n::Message::R, I18n::Message::Default};
|
|
myCell->setMessage(titles[j-1]);
|
|
return;
|
|
}
|
|
if (i == 1 && j > 0 && j < 6) {
|
|
ArgCalculPointer calculationMethods[(k_totalNumberOfRows-1)/2] = {&Store::meanOfColumn, &Store::sumOfColumn,
|
|
&Store::squaredValueSumOfColumn, &Store::standardDeviationOfColumn, &Store::varianceOfColumn};
|
|
float calculation1 = (m_store->*calculationMethods[j-1])(0);
|
|
float calculation2 = (m_store->*calculationMethods[j-1])(1);
|
|
EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)cell;
|
|
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
|
Complex::convertFloatToText(calculation1, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
|
myCell->setFirstText(buffer);
|
|
Complex::convertFloatToText(calculation2, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
|
myCell->setSecondText(buffer);
|
|
return;
|
|
}
|
|
if (i == 1 && j > 5) {
|
|
CalculPointer calculationMethods[(k_totalNumberOfRows-1)/2] = {&Store::numberOfPairs, &Store::covariance,
|
|
&Store::columnProductSum, &Store::correlationCoefficient, &Store::squaredCorrelationCoefficient};
|
|
float calculation = (m_store->*calculationMethods[j-6])();
|
|
EvenOddBufferTextCell * myCell = (EvenOddBufferTextCell *)cell;
|
|
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
|
Complex::convertFloatToText(calculation, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
|
myCell->setText(buffer);
|
|
return;
|
|
}
|
|
}
|
|
|
|
KDCoordinate CalculationController::columnWidth(int i) {
|
|
return k_cellWidth;
|
|
}
|
|
|
|
KDCoordinate CalculationController::rowHeight(int j) {
|
|
return k_cellHeight;
|
|
}
|
|
|
|
HighlightCell * CalculationController::reusableCell(int index, int type) {
|
|
if (type == 0) {
|
|
assert(index < k_maxNumberOfDisplayableRows);
|
|
return m_titleCells[index];
|
|
}
|
|
if (type == 1) {
|
|
assert(index == 0);
|
|
return m_r2TitleCell;
|
|
}
|
|
if (type == 2) {
|
|
assert(index == 0);
|
|
return m_columnTitleCell;
|
|
}
|
|
if (type == 3) {
|
|
assert(index < k_totalNumberOfRows/2);
|
|
return m_doubleCalculationCells[index];
|
|
}
|
|
assert(index < k_totalNumberOfRows/2);
|
|
return m_calculationCells[index];
|
|
}
|
|
|
|
int CalculationController::reusableCellCount(int type) {
|
|
if (type == 0) {
|
|
return k_maxNumberOfDisplayableRows;
|
|
}
|
|
if (type == 1) {
|
|
return 1;
|
|
}
|
|
if (type == 2) {
|
|
return 1;
|
|
}
|
|
if (type == 3) {
|
|
return k_maxNumberOfDisplayableRows/2;
|
|
}
|
|
return k_maxNumberOfDisplayableRows/2;
|
|
}
|
|
|
|
int CalculationController::typeAtLocation(int i, int j) {
|
|
if (i == 0 && j == 10) {
|
|
return 1;
|
|
}
|
|
if (i == 0) {
|
|
return 0;
|
|
}
|
|
if (j == 0) {
|
|
return 2;
|
|
}
|
|
if (j > 0 && j < 6) {
|
|
return 3;
|
|
}
|
|
return 4;
|
|
}
|
|
|
|
Responder * CalculationController::tabController() const {
|
|
return (parentResponder()->parentResponder()->parentResponder());
|
|
}
|
|
|
|
View * CalculationController::loadView() {
|
|
SelectableTableView * tableView = (SelectableTableView *)TabTableController::loadView();
|
|
m_r2TitleCell = new EvenOddExpressionCell(1.0f, 0.5f);
|
|
m_columnTitleCell = new EvenOddDoubleBufferTextCell(tableView);
|
|
for (int i = 0; i < k_maxNumberOfDisplayableRows; i++) {
|
|
m_titleCells[i] = new EvenOddMessageTextCell(KDText::FontSize::Small);
|
|
}
|
|
for (int i = 0; i < k_maxNumberOfDisplayableRows/2; i++) {
|
|
m_doubleCalculationCells[i] = new EvenOddDoubleBufferTextCell();
|
|
m_doubleCalculationCells[i]->setTextColor(Palette::GreyDark);
|
|
m_doubleCalculationCells[i]->setParentResponder(tableView);
|
|
m_calculationCells[i] = new EvenOddBufferTextCell(KDText::FontSize::Small);
|
|
m_calculationCells[i]->setTextColor(Palette::GreyDark);
|
|
}
|
|
return tableView;
|
|
}
|
|
|
|
void CalculationController::unloadView(View * view) {
|
|
delete m_r2TitleCell;
|
|
m_r2TitleCell = nullptr;
|
|
delete m_columnTitleCell;
|
|
m_columnTitleCell = nullptr;
|
|
for (int i = 0; i < k_maxNumberOfDisplayableRows/2; i++) {
|
|
delete m_doubleCalculationCells[i];
|
|
m_doubleCalculationCells[i] = nullptr;
|
|
delete m_calculationCells[i];
|
|
m_calculationCells[i] = nullptr;
|
|
}
|
|
for (int i = 0; i < k_maxNumberOfDisplayableRows; i++) {
|
|
delete m_titleCells[i];
|
|
m_titleCells[i] = nullptr;
|
|
}
|
|
TabTableController::unloadView(view);
|
|
}
|
|
|
|
}
|
|
|