mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps/graph] Copy/Cut events on the values controller turn the "(1;3)"
notation into "[[1][3]]" in order to create a matrix layout when paste into a layout field
This commit is contained in:
committed by
LeaNumworks
parent
c982b4c452
commit
ff6eb7525f
@@ -11,6 +11,7 @@ namespace Graph {
|
||||
|
||||
ValuesController::ValuesController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header) :
|
||||
Shared::ValuesController(parentResponder, header),
|
||||
m_selectableTableView(this),
|
||||
m_functionTitleCells{},
|
||||
m_floatCells{},
|
||||
m_abscissaTitleCells{},
|
||||
@@ -38,7 +39,7 @@ ValuesController::ValuesController(Responder * parentResponder, InputEventHandle
|
||||
m_functionTitleCells[i].setOrientation(FunctionTitleCell::Orientation::HorizontalIndicator);
|
||||
m_functionTitleCells[i].setFont(KDFont::SmallFont);
|
||||
}
|
||||
setupAbscissaCellsAndTitleCells(inputEventHandlerDelegate);
|
||||
setupSelectableTableViewAndCells(inputEventHandlerDelegate);
|
||||
m_selectableTableView.setDelegate(this);
|
||||
}
|
||||
|
||||
@@ -286,4 +287,42 @@ void ValuesController::updateNumberOfColumns() const {
|
||||
}
|
||||
}
|
||||
|
||||
int writeMatrixBrakets(char * buffer, const int bufferSize, int type) {
|
||||
/* Write the double brackets required in matrix notation.
|
||||
* - type == 1: "[["
|
||||
* - type == 0: "]["
|
||||
* - type == -1: "]]"
|
||||
*/
|
||||
int currentChar = 0;
|
||||
assert(currentChar < bufferSize-1);
|
||||
buffer[currentChar++] = type < 0 ? '[' : ']';
|
||||
assert(currentChar < bufferSize-1);
|
||||
buffer[currentChar++] = type <= 0 ? '[' : ']';
|
||||
return currentChar;
|
||||
}
|
||||
|
||||
bool ValuesController::ValuesSelectableTableView::handleEvent(Ion::Events::Event event) {
|
||||
bool handledEvent = SelectableTableView::handleEvent(event);
|
||||
if (handledEvent && (event == Ion::Events::Copy || event == Ion::Events::Cut)) {
|
||||
const char * text = Clipboard::sharedClipboard()->storedText();
|
||||
if (text[0] == '(') {
|
||||
constexpr int bufferSize = 2*PrintFloat::k_maxFloatCharSize + 6; // "[[a][b]]" gives 6 characters in addition to the 2 floats
|
||||
char buffer[bufferSize];
|
||||
int currentChar = 0;
|
||||
currentChar += writeMatrixBrakets(buffer + currentChar, bufferSize - currentChar, -1);
|
||||
assert(currentChar < bufferSize-1);
|
||||
size_t semiColonPosition = UTF8Helper::CopyUntilCodePoint(buffer+currentChar, TextField::maxBufferSize() - currentChar, text+1, ';');
|
||||
currentChar += semiColonPosition;
|
||||
currentChar += writeMatrixBrakets(buffer + currentChar, bufferSize - currentChar, 0);
|
||||
assert(currentChar < bufferSize-1);
|
||||
currentChar += UTF8Helper::CopyUntilCodePoint(buffer+currentChar, TextField::maxBufferSize() - currentChar, text+1+semiColonPosition+1, ')');
|
||||
currentChar += writeMatrixBrakets(buffer + currentChar, bufferSize - currentChar, 1);
|
||||
assert(currentChar < bufferSize-1);
|
||||
buffer[currentChar] = 0;
|
||||
Clipboard::sharedClipboard()->store(buffer);
|
||||
}
|
||||
}
|
||||
return handledEvent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,20 @@ private:
|
||||
int abscissaTitleCellsCount() const override { return Shared::ContinuousFunction::k_numberOfPlotTypes; }
|
||||
EvenOddMessageTextCell * abscissaTitleCells(int j) override { assert (j >= 0 && j < abscissaTitleCellsCount()); return &m_abscissaTitleCells[j]; }
|
||||
ViewController * functionParameterController() override;
|
||||
SelectableTableView * selectableTableView() override { return &m_selectableTableView; }
|
||||
|
||||
/* For parametric function, we display the evaluation with the form "(1;2)".
|
||||
* This form is not parsable so when we store it into the clipboard, we want
|
||||
* to turn it into a parsable matrix "[[1][2]]". To do so, we use a child
|
||||
* class of SelectableTableView to override the behaviour of the responder
|
||||
* when encountering a cut/copy events. */
|
||||
class ValuesSelectableTableView : public SelectableTableView {
|
||||
public:
|
||||
ValuesSelectableTableView(ValuesController * vc) : SelectableTableView(vc, vc, vc) {}
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
};
|
||||
|
||||
ValuesSelectableTableView m_selectableTableView;
|
||||
mutable int m_numberOfColumnsForType[Shared::ContinuousFunction::k_numberOfPlotTypes];
|
||||
Shared::BufferFunctionTitleCell m_functionTitleCells[k_maxNumberOfFunctions];
|
||||
Shared::HideableEvenOddBufferTextCell m_floatCells[k_maxNumberOfCells];
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Sequence {
|
||||
|
||||
ValuesController::ValuesController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header) :
|
||||
Shared::ValuesController(parentResponder, header),
|
||||
m_selectableTableView(this),
|
||||
m_sequenceTitleCells{},
|
||||
m_floatCells{},
|
||||
m_abscissaTitleCell(),
|
||||
@@ -30,7 +31,7 @@ ValuesController::ValuesController(Responder * parentResponder, InputEventHandle
|
||||
for (int i = 0; i < k_maxNumberOfSequences; i++) {
|
||||
m_sequenceTitleCells[i].setOrientation(Shared::FunctionTitleCell::Orientation::HorizontalIndicator);
|
||||
}
|
||||
setupAbscissaCellsAndTitleCells(inputEventHandlerDelegate);
|
||||
setupSelectableTableViewAndCells(inputEventHandlerDelegate);
|
||||
}
|
||||
|
||||
KDCoordinate ValuesController::columnWidth(int i) {
|
||||
|
||||
@@ -33,6 +33,7 @@ private:
|
||||
|
||||
SequenceStore * functionStore() const override { return static_cast<SequenceStore *>(Shared::ValuesController::functionStore()); }
|
||||
ViewController * functionParameterController() override;
|
||||
SelectableTableView * selectableTableView() override { return &m_selectableTableView; }
|
||||
int abscissaCellsCount() const override { return k_maxNumberOfRows; }
|
||||
EvenOddEditableTextCell * abscissaCells(int j) override {
|
||||
assert (j >= 0 && j < k_maxNumberOfRows);
|
||||
@@ -51,6 +52,7 @@ private:
|
||||
assert(j >= 0 && j < k_maxNumberOfCells);
|
||||
return &m_floatCells[j];
|
||||
}
|
||||
SelectableTableView m_selectableTableView;
|
||||
SequenceTitleCell m_sequenceTitleCells[k_maxNumberOfSequences];
|
||||
EvenOddBufferTextCell m_floatCells[k_maxNumberOfCells];
|
||||
EvenOddMessageTextCell m_abscissaTitleCell;
|
||||
|
||||
@@ -12,19 +12,19 @@ ValuesController::ValuesController(Responder * parentResponder, ButtonRowControl
|
||||
ButtonRowDelegate(header, nullptr),
|
||||
m_numberOfColumns(0),
|
||||
m_numberOfColumnsNeedUpdate(true),
|
||||
m_selectableTableView(this),
|
||||
m_abscissaParameterController(this)
|
||||
{
|
||||
m_selectableTableView.setVerticalCellOverlap(0);
|
||||
m_selectableTableView.setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin);
|
||||
m_selectableTableView.setBackgroundColor(Palette::WallScreenDark);
|
||||
}
|
||||
|
||||
void ValuesController::setupAbscissaCellsAndTitleCells(InputEventHandlerDelegate * inputEventHandlerDelegate) {
|
||||
void ValuesController::setupSelectableTableViewAndCells(InputEventHandlerDelegate * inputEventHandlerDelegate) {
|
||||
selectableTableView()->setVerticalCellOverlap(0);
|
||||
selectableTableView()->setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin);
|
||||
selectableTableView()->setBackgroundColor(Palette::WallScreenDark);
|
||||
|
||||
int numberOfAbscissaCells = abscissaCellsCount();
|
||||
for (int i = 0; i < numberOfAbscissaCells; i++) {
|
||||
EvenOddEditableTextCell * c = abscissaCells(i);
|
||||
c->setParentResponder(&m_selectableTableView);
|
||||
c->setParentResponder(selectableTableView());
|
||||
c->editableTextCell()->textField()->setDelegates(inputEventHandlerDelegate, this);
|
||||
c->editableTextCell()->textField()->setFont(k_font);
|
||||
}
|
||||
|
||||
@@ -41,17 +41,15 @@ protected:
|
||||
constexpr static int k_maxNumberOfRows = 10;
|
||||
|
||||
static constexpr const KDFont * k_font = KDFont::SmallFont;
|
||||
void setupAbscissaCellsAndTitleCells(InputEventHandlerDelegate * inputEventHandlerDelegate);
|
||||
void setupSelectableTableViewAndCells(InputEventHandlerDelegate * inputEventHandlerDelegate);
|
||||
StackViewController * stackController() const;
|
||||
bool setDataAtLocation(double floatBody, int columnIndex, int rowIndex) override;
|
||||
virtual void updateNumberOfColumns() const;
|
||||
virtual FunctionStore * functionStore() const;
|
||||
virtual Ion::Storage::Record recordAtColumn(int i);
|
||||
int numberOfElementsInColumn(int columnIndex) const override;
|
||||
SelectableTableView * selectableTableView() override { return &m_selectableTableView; }
|
||||
mutable int m_numberOfColumns;
|
||||
mutable bool m_numberOfColumnsNeedUpdate;
|
||||
SelectableTableView m_selectableTableView;
|
||||
private:
|
||||
virtual void setStartEndMessages(Shared::IntervalParameterController * controller, int column) = 0;
|
||||
Responder * tabController() const override;
|
||||
|
||||
Reference in New Issue
Block a user