mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
Merge changes I02e841da,Id36bf568,I51388c74
* changes: [apps] Add a tool box as instance variable of the app container [apps] Handle enter in tool box controller [escher] add methods to add text to buffer in textfield
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "graph/app.h"
|
||||
#include "probability/app.h"
|
||||
#include "calculation/app.h"
|
||||
#include "tool_box_controller.h"
|
||||
|
||||
#define USE_PIC_VIEW_APP 0
|
||||
#if USE_PIC_VIEW_APP
|
||||
@@ -29,6 +30,7 @@ private:
|
||||
PicViewApp m_picViewApp;
|
||||
#endif
|
||||
Context m_context;
|
||||
ToolBoxController m_toolBoxController;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,11 +61,11 @@ const char * EditExpressionController::title() const {
|
||||
}
|
||||
|
||||
const char * EditExpressionController::textBody() {
|
||||
return m_contentView.textField()->textBuffer();
|
||||
return m_contentView.textField()->text();
|
||||
}
|
||||
|
||||
void EditExpressionController::setTextBody(const char * text) {
|
||||
m_contentView.textField()->setTextBuffer(text);
|
||||
m_contentView.textField()->setText(text);
|
||||
}
|
||||
|
||||
bool EditExpressionController::handleEvent(Ion::Events::Event event) {
|
||||
@@ -78,7 +78,7 @@ bool EditExpressionController::handleEvent(Ion::Events::Event event) {
|
||||
m_calculationStore->push(&calculation);
|
||||
m_historyController->reload();
|
||||
m_contentView.mainView()->scrollToCell(0, m_historyController->numberOfRows()-1);
|
||||
m_contentView.textField()->setTextBuffer("");
|
||||
m_contentView.textField()->setText("");
|
||||
return true;
|
||||
}
|
||||
case Ion::Events::Event::ESC:
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
#include <math.h>
|
||||
|
||||
bool ExpressionTextFieldDelegate::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Event::ENTER && Expression::parse(textField->textBuffer()) == nullptr) {
|
||||
if (textField->bufferLength() == 0) {
|
||||
if (event == Ion::Events::Event::ENTER && Expression::parse(textField->text()) == nullptr) {
|
||||
if (textField->textLength() == 0) {
|
||||
return true;
|
||||
}
|
||||
textField->app()->displayWarning("Attention a la syntaxe jeune padawan");
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Event::ENTER &&
|
||||
isnan(Expression::parse(textField->textBuffer())->approximate(*evaluateContext()))) {
|
||||
isnan(Expression::parse(textField->text())->approximate(*evaluateContext()))) {
|
||||
textField->app()->displayWarning("Relis ton cours de maths, veux tu?");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@ static const char * labels[] = {
|
||||
"Trigonometrie hyperbolique"
|
||||
};
|
||||
|
||||
static const char * mathCommands[] = {
|
||||
"abs()",
|
||||
"root(,)",
|
||||
"log()"
|
||||
};
|
||||
|
||||
ToolBoxController::ToolBoxController() :
|
||||
StackViewController(nullptr, this, true),
|
||||
m_selectableTableView(SelectableTableView(this, this))
|
||||
@@ -26,6 +32,22 @@ const char * ToolBoxController::title() const {
|
||||
}
|
||||
|
||||
bool ToolBoxController::handleEvent(Ion::Events::Event event) {
|
||||
switch (event) {
|
||||
case Ion::Events::Event::ENTER:
|
||||
return handleEnter();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ToolBoxController::handleEnter() {
|
||||
if (m_selectableTableView.selectedRow() < 3) {
|
||||
m_textFieldCaller->appendText(mathCommands[m_selectableTableView.selectedRow()]);
|
||||
int cursorPosition = m_selectableTableView.selectedRow() == 1 ? -2 : -1;
|
||||
m_textFieldCaller->moveCursor(cursorPosition);
|
||||
app()->dismissModalViewController();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
int typeAtLocation(int i, int j) override;
|
||||
void setTextFieldCaller(TextField * textField);
|
||||
private:
|
||||
bool handleEnter();
|
||||
constexpr static int k_numberOfCommandRows = 3;
|
||||
constexpr static int k_numberOfMenuRows = 8;
|
||||
constexpr static int k_maxNumberOfDisplayedRows = 6;
|
||||
|
||||
@@ -13,11 +13,17 @@ public:
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
// Responder
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
const char * textBuffer() const;
|
||||
int bufferLength() const;
|
||||
void setTextBuffer(const char * text);
|
||||
KDSize minimalSizeForOptimalDisplay() override;
|
||||
const char * text() const;
|
||||
int textLength() const;
|
||||
void setText(const char * text);
|
||||
/* If the text to be appended is too long to be added without overflowing the
|
||||
* buffer, nothing is done (not even adding few letters from the text to reach
|
||||
* the maximum buffer capacity. */
|
||||
void appendText(const char * text);
|
||||
void moveCursor(int delta);
|
||||
KDSize minimalSizeForOptimalDisplay() override;
|
||||
protected:
|
||||
void reload();
|
||||
#if ESCHER_VIEW_LOGGING
|
||||
const char * className() const override;
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@ const char * InputViewController::title() const {
|
||||
}
|
||||
|
||||
const char * InputViewController::textBody() {
|
||||
return m_textFieldController.textField()->textBuffer();
|
||||
return m_textFieldController.textField()->text();
|
||||
}
|
||||
|
||||
void InputViewController::showInput() {
|
||||
@@ -42,7 +42,7 @@ void InputViewController::showInput() {
|
||||
}
|
||||
|
||||
void InputViewController::setTextBody(const char * text) {
|
||||
m_textFieldController.textField()->setTextBuffer(text);
|
||||
m_textFieldController.textField()->setText(text);
|
||||
}
|
||||
|
||||
bool InputViewController::handleEvent(Ion::Events::Event event) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <escher/text_field.h>
|
||||
#include <assert.h>
|
||||
|
||||
TextField::TextField(Responder * parentResponder, char * textBuffer, size_t textBufferSize, TextFieldDelegate * delegate) :
|
||||
View(),
|
||||
@@ -24,6 +25,12 @@ const char * TextField::className() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
void TextField::reload() {
|
||||
KDSize sizeText = KDText::stringSize(m_textBuffer);
|
||||
KDRect dirtyZone(0, 0, sizeText.width(), sizeText.height());
|
||||
markRectAsDirty(dirtyZone);
|
||||
}
|
||||
|
||||
/* Responder */
|
||||
|
||||
bool TextField::handleEvent(Ion::Events::Event event) {
|
||||
@@ -45,15 +52,13 @@ bool TextField::handleEvent(Ion::Events::Event event) {
|
||||
return true;
|
||||
case Ion::Events::Event::DELETE:
|
||||
if (m_currentCursorPosition > 0) {
|
||||
KDSize sizePreviousText = KDText::stringSize(m_textBuffer);
|
||||
reload();
|
||||
m_currentTextLength--;
|
||||
m_currentCursorPosition--;
|
||||
for (int k = m_currentCursorPosition; k < m_currentTextLength; k ++) {
|
||||
m_textBuffer[k] = m_textBuffer[k+1];
|
||||
}
|
||||
m_textBuffer[m_currentTextLength] = 0;
|
||||
KDRect dirtyZone(0, 0, sizePreviousText.width(), sizePreviousText.height());
|
||||
markRectAsDirty(dirtyZone);
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
@@ -66,28 +71,47 @@ bool TextField::handleEvent(Ion::Events::Event event) {
|
||||
}
|
||||
m_textBuffer[++m_currentTextLength] = 0;
|
||||
m_textBuffer[m_currentCursorPosition++] = (int)event;
|
||||
KDSize sizeText = KDText::stringSize(m_textBuffer);
|
||||
KDRect dirtyZone(0, 0, sizeText.width(), sizeText.height());
|
||||
markRectAsDirty(dirtyZone);
|
||||
reload();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const char * TextField::textBuffer () const {
|
||||
const char * textBuffer = (const char *)m_textBuffer;
|
||||
return textBuffer;
|
||||
const char * TextField::text() const {
|
||||
return (const char *)m_textBuffer;
|
||||
}
|
||||
|
||||
int TextField::bufferLength () const {
|
||||
int TextField::textLength() const {
|
||||
assert(strlen(text()) == m_currentTextLength);
|
||||
return m_currentTextLength;
|
||||
}
|
||||
|
||||
void TextField::setTextBuffer(const char * text) {
|
||||
void TextField::setText(const char * text) {
|
||||
strlcpy(m_textBuffer, text, m_textBufferSize);
|
||||
m_currentCursorPosition = strlen(text);
|
||||
m_currentTextLength = m_currentCursorPosition;
|
||||
markRectAsDirty(bounds());
|
||||
reload();
|
||||
}
|
||||
|
||||
void TextField::appendText(const char * text) {
|
||||
int textSize = strlen(text);
|
||||
if (m_currentTextLength + textSize > m_textBufferSize) {
|
||||
return;
|
||||
}
|
||||
for (int k = m_currentTextLength; k > m_currentCursorPosition - 1; k--) {
|
||||
m_textBuffer[k+textSize] = m_textBuffer[k];
|
||||
}
|
||||
strlcpy(&m_textBuffer[m_currentCursorPosition], text, textSize);
|
||||
m_currentCursorPosition += textSize;
|
||||
m_textBuffer[m_currentCursorPosition-1] = text[textSize-1];
|
||||
m_currentTextLength += textSize;
|
||||
reload();
|
||||
}
|
||||
|
||||
void TextField::moveCursor(int position) {
|
||||
assert(m_currentCursorPosition + position <= m_currentTextLength);
|
||||
assert(m_currentCursorPosition + position >= 0);
|
||||
m_currentCursorPosition += position;
|
||||
}
|
||||
|
||||
KDSize TextField::minimalSizeForOptimalDisplay() {
|
||||
|
||||
Reference in New Issue
Block a user