[escher] Clean Field and Input class hierarchy:

Class hierarchy:
- InputEventHandler
- TextInput
- EditableField derives from InputEventHandler
- LayoutField, TextField and ExpressioField derives from EditableField
- TextArea and TextField derives from TextInput
This commit is contained in:
Émilie Feral
2018-10-19 14:31:50 +02:00
parent c2adbe28c5
commit 01e433a9f2
36 changed files with 123 additions and 85 deletions

View File

@@ -109,14 +109,14 @@ bool App::handleEvent(Ion::Events::Event event) {
return false;
}
bool App::textInputDidReceiveEvent(TextInput * textInput, Ion::Events::Event event) {
bool App::textInputDidReceiveEvent(InputEventHandler * textInput, Ion::Events::Event event) {
const char * pythonText = Helpers::PythonTextForEvent(event);
if (pythonText != nullptr) {
textInput->handleEventWithText(pythonText);
return true;
}
if (event == Ion::Events::Var) {
m_variableBoxController.setTextInputCaller(textInput);
m_variableBoxController.setSender(textInput);
displayModalViewController(&m_variableBoxController, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
}

View File

@@ -41,7 +41,7 @@ public:
ConsoleController * consoleController() { return &m_consoleController; }
PythonToolbox * pythonToolbox() { return &m_toolbox; }
bool handleEvent(Ion::Events::Event event) override;
bool textInputDidReceiveEvent(TextInput * textInput, Ion::Events::Event event);
bool textInputDidReceiveEvent(InputEventHandler * textInput, Ion::Events::Event event);
// Python delegate
bool pythonIsInited() { return m_pythonUser != nullptr; }
bool isPythonUser(const void * pythonUser) { return m_pythonUser == pythonUser; }

View File

@@ -291,7 +291,7 @@ bool ConsoleController::textFieldDidAbortEditing(TextField * textField) {
return true;
}
Toolbox * ConsoleController::toolboxForTextInput(TextInput * textInput) {
Toolbox * ConsoleController::toolboxForTextInput(InputEventHandler * textInput) {
Code::App * codeApp = static_cast<Code::App *>(app());
return codeApp->pythonToolbox();
}

View File

@@ -60,7 +60,7 @@ public:
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool textFieldDidAbortEditing(TextField * textField) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override;
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override;
// MicroPython::ExecutionEnvironment
void displaySandbox() override;

View File

@@ -127,7 +127,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events:
return false;
}
Toolbox * EditorController::toolboxForTextInput(TextInput * textInput) {
Toolbox * EditorController::toolboxForTextInput(InputEventHandler * textInput) {
Code::App * codeApp = static_cast<Code::App *>(app());
return codeApp->pythonToolbox();
}

View File

@@ -25,7 +25,7 @@ public:
/* TextAreaDelegate */
bool textAreaDidReceiveEvent(TextArea * textArea, Ion::Events::Event event) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override;
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override;
private:
static constexpr int k_indentationSpacesNumber = 2;

View File

@@ -54,7 +54,7 @@ public:
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool textFieldDidAbortEditing(TextField * textField) override;
bool textFieldDidHandleEvent(TextField * textField, bool returnValue, bool textHasChanged) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override { return nullptr; }
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override { return nullptr; }
/* ButtonRowDelegate */
int numberOfButtons(ButtonRowController::Position position) const override { return 1; }

View File

@@ -26,8 +26,8 @@ VariableBoxController::ContentViewController::ContentViewController(Responder *
}
}
void VariableBoxController::ContentViewController::setTextInputCaller(TextInput * textInput) {
m_textInputCaller = textInput;
void VariableBoxController::ContentViewController::setSender(InputEventHandler * textInput) {
m_sender = textInput;
}
void VariableBoxController::ContentViewController::reloadData() {
@@ -147,7 +147,7 @@ void VariableBoxController::ContentViewController::insertTextInCaller(const char
char commandBuffer[k_maxScriptObjectNameSize];
assert(commandBufferMaxSize <= k_maxScriptObjectNameSize);
Shared::ToolboxHelpers::TextToInsertForCommandText(text, commandBuffer, commandBufferMaxSize, true);
m_textInputCaller->handleEventWithText(commandBuffer);
m_sender->handleEventWithText(commandBuffer);
}
VariableBoxController::VariableBoxController(App * pythonDelegate, ScriptStore * scriptStore) :
@@ -160,8 +160,8 @@ void VariableBoxController::didBecomeFirstResponder() {
app()->setFirstResponder(&m_contentViewController);
}
void VariableBoxController::setTextInputCaller(TextInput * textInput) {
m_contentViewController.setTextInputCaller(textInput);
void VariableBoxController::setSender(InputEventHandler * sender) {
m_contentViewController.setSender(sender);
}
void VariableBoxController::viewWillAppear() {

View File

@@ -13,14 +13,14 @@ class VariableBoxController : public StackViewController {
public:
VariableBoxController(App * pythonDelegate, ScriptStore * scriptStore);
void didBecomeFirstResponder() override;
void setTextInputCaller(TextInput * textInput);
void setSender(InputEventHandler * sender);
void viewWillAppear() override;
void viewDidDisappear() override;
private:
class ContentViewController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
public:
ContentViewController(Responder * parentResponder, App * pythonDelegate, ScriptStore * scriptStore);
void setTextInputCaller(TextInput * textInput);
void setSender(InputEventHandler * sender);
void reloadData();
void addFunctionAtIndex(const char * functionName, int scriptIndex);
@@ -52,7 +52,7 @@ private:
ScriptNode m_scriptNodes[k_maxScriptNodesCount];
App * m_pythonDelegate;
ScriptStore * m_scriptStore;
TextInput * m_textInputCaller;
InputEventHandler * m_sender;
ScriptNodeCell m_leafCells[k_maxNumberOfDisplayedRows];
SelectableTableView m_selectableTableView;
};

View File

@@ -28,7 +28,7 @@ const char * ListController::title() {
return I18n::translate(I18n::Message::SequenceTab);
}
Toolbox * ListController::toolboxForTextInput(TextInput * textInput) {
Toolbox * ListController::toolboxForTextInput(InputEventHandler * textInput) {
return toolboxForSender(textInput);
}
@@ -88,7 +88,7 @@ void ListController::selectPreviousNewSequenceCell() {
}
}
Toolbox * ListController::toolboxForSender(Responder * sender) {
Toolbox * ListController::toolboxForSender(InputEventHandler * sender) {
// Set extra cells
int recurrenceDepth = -1;
int sequenceDefinition = sequenceDefinitionForRow(selectedRow());

View File

@@ -21,13 +21,13 @@ public:
int numberOfExpressionRows() override;
KDCoordinate expressionRowHeight(int j) override;
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override;
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override;
Toolbox * toolboxForLayoutField(LayoutField * layoutField) override;
void selectPreviousNewSequenceCell();
void editExpression(Sequence * sequence, int sequenceDefinitionIndex, Ion::Events::Event event);
private:
static constexpr KDCoordinate k_expressionCellVerticalMargin = 3;
Toolbox * toolboxForSender(Responder * sender);
Toolbox * toolboxForSender(InputEventHandler * sender);
Shared::TextFieldDelegateApp * textFieldDelegateApp() override;
Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override;
ListParameterController * parameterController() override;

View File

@@ -12,7 +12,7 @@ bool TextFieldDelegate::textFieldDidReceiveEvent(::TextField * textField, Ion::E
return textFieldDelegateApp()->textFieldDidReceiveEvent(textField, event);
}
Toolbox * TextFieldDelegate::toolboxForTextInput(TextInput * textInput) {
Toolbox * TextFieldDelegate::toolboxForTextInput(InputEventHandler * textInput) {
return textFieldDelegateApp()->toolboxForTextInput(textInput);
}

View File

@@ -10,7 +10,7 @@ class TextFieldDelegate : public ::TextFieldDelegate {
public:
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override;
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override;
private:
virtual TextFieldDelegateApp * textFieldDelegateApp() = 0;
};

View File

@@ -41,7 +41,7 @@ bool TextFieldDelegateApp::textFieldDidReceiveEvent(TextField * textField, Ion::
return false;
}
Toolbox * TextFieldDelegateApp::toolboxForTextInput(TextInput * textInput) {
Toolbox * TextFieldDelegateApp::toolboxForTextInput(InputEventHandler * textInput) {
Toolbox * toolbox = container()->mathToolbox();
toolbox->setSender(textInput);
return toolbox;
@@ -49,12 +49,12 @@ Toolbox * TextFieldDelegateApp::toolboxForTextInput(TextInput * textInput) {
/* Protected */
bool TextFieldDelegateApp::fieldDidReceiveEvent(Field * field, Responder * responder, Ion::Events::Event event) {
bool TextFieldDelegateApp::fieldDidReceiveEvent(EditableField * field, Responder * responder, Ion::Events::Event event) {
if (event == Ion::Events::Var) {
forceEdition(field);
AppsContainer * appsContainer = (AppsContainer *)responder->app()->container();
VariableBoxController * variableBoxController = appsContainer->variableBoxController();
variableBoxController->setSender(responder);
variableBoxController->setSender(field);
responder->app()->displayModalViewController(variableBoxController, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
@@ -62,12 +62,12 @@ bool TextFieldDelegateApp::fieldDidReceiveEvent(Field * field, Responder * respo
if (event == Ion::Events::XNT) {
forceEdition(field);
const char xnt[2] = {field->XNTChar(XNT()), 0};
return responder->handleEventWithText(xnt);
return field->handleEventWithText(xnt);
}
return false;
}
void TextFieldDelegateApp::forceEdition(Field * field) {
void TextFieldDelegateApp::forceEdition(EditableField * field) {
if (!field->isEditing()) {
field->setEditing(true);
}

View File

@@ -17,12 +17,12 @@ public:
virtual char XNT();
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
virtual bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override;
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override;
protected:
TextFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController);
protected:
bool fieldDidReceiveEvent(Field * field, Responder * responder, Ion::Events::Event event);
void forceEdition(Field * field);
bool fieldDidReceiveEvent(EditableField * field, Responder * responder, Ion::Events::Event event);
void forceEdition(EditableField * field);
bool isFinishingEvent(Ion::Events::Event event);
bool unparsableText(const char * text, Responder * responder);
};

View File

@@ -26,6 +26,7 @@ objs += $(addprefix escher/src/,\
highlight_cell.o\
gauge_view.o\
image_view.o\
input_event_handler.o\
invocation.o\
input_view_controller.o\
key_view.o\

View File

@@ -12,6 +12,7 @@
#include <escher/clipboard.h>
#include <escher/container.h>
#include <escher/expression_field.h>
#include <escher/editable_field.h>
#include <escher/editable_text_cell.h>
#include <escher/ellipsis_view.h>
#include <escher/even_odd_cell.h>
@@ -24,11 +25,11 @@
#include <escher/expression_table_cell_with_pointer.h>
#include <escher/expression_table_cell_with_expression.h>
#include <escher/expression_view.h>
#include <escher/field.h>
#include <escher/gauge_view.h>
#include <escher/highlight_cell.h>
#include <escher/image.h>
#include <escher/image_view.h>
#include <escher/input_event_handler.h>
#include <escher/input_view_controller.h>
#include <escher/invocation.h>
#include <escher/i18n.h>

View File

@@ -1,9 +1,10 @@
#ifndef ESCHER_FIELD_H
#define ESCHER_FIELD_H
#ifndef ESCHER_EDITABLE_FIELD_H
#define ESCHER_EDITABLE_FIELD_H
#include <ion.h>
#include <escher/input_event_handler.h>
class Field {
class EditableField : public InputEventHandler {
public:
virtual bool isEditing() const = 0;
virtual void setEditing(bool isEditing, bool reinitDraftBuffer = true) = 0;

View File

@@ -7,12 +7,14 @@
#include <escher/text_field_delegate.h>
#include <poincare/layout.h>
class ExpressionField : public Responder, public View {
class ExpressionField : public Responder, public View, public EditableField {
public:
ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
void setEditing(bool isEditing, bool reinitDraftBuffer = true);
bool isEditing() const;
void setEditing(bool isEditing, bool reinitDraftBuffer = true) override;
bool isEditing() const override;
char XNTChar(char defaultXNTChar) override;
bool shouldFinishEditing(Ion::Events::Event event) override;
/* Warning: this function is VERY dangerous! Indeed: sometimes the
* m_layoutField might overflow the m_textBuffer once serialized
* and still have been accepted before because the model can hold a longer

View File

@@ -0,0 +1,15 @@
#ifndef ESCHER_INPUT_EVENT_HANDLER_H
#define ESCHER_INPUT_EVENT_HANDLER_H
class Toolbox;
class App;
class InputEventHandler {
public:
virtual bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) { return false; }
virtual Toolbox * toolbox() { return nullptr; }
protected:
bool handleToolboxEvent(App * app);
};
#endif

View File

@@ -24,7 +24,7 @@ public:
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool textFieldDidAbortEditing(TextField * textField) override;
Toolbox * toolboxForTextInput(TextInput * textInput) override;
Toolbox * toolboxForTextInput(InputEventHandler * textInput) override;
/* LayoutFieldDelegate */
bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override;

View File

@@ -1,7 +1,7 @@
#ifndef ESCHER_LAYOUT_FIELD_H
#define ESCHER_LAYOUT_FIELD_H
#include <escher/field.h>
#include <escher/editable_field.h>
#include <escher/expression_view.h>
#include <escher/layout_field_delegate.h>
#include <escher/scrollable_view.h>
@@ -11,7 +11,7 @@
#include <poincare/layout.h>
#include <poincare/layout_cursor.h>
class LayoutField : public ScrollableView, public ScrollViewDataSource, public Field {
class LayoutField : public ScrollableView, public ScrollViewDataSource, public EditableField {
public:
LayoutField(Responder * parentResponder, LayoutFieldDelegate * delegate = nullptr) :
ScrollableView(parentResponder, &m_contentView, this),

View File

@@ -1,6 +1,7 @@
#ifndef ESCHER_NESTED_MENU_CONTROLLER_H
#define ESCHER_NESTED_MENU_CONTROLLER_H
#include <escher/input_event_handler.h>
#include <escher/highlight_cell.h>
#include <escher/list_view_data_source.h>
#include <escher/selectable_table_view.h>
@@ -9,7 +10,7 @@
class NestedMenuController : public StackViewController, public ListViewDataSource, public SelectableTableViewDataSource {
public:
NestedMenuController(Responder * parentResponder, I18n::Message title = (I18n::Message)0);
void setSender(Responder * sender) { m_sender = sender; }
void setSender(InputEventHandler * sender) { m_sender = sender; }
// StackViewController
bool handleEvent(Ion::Events::Event event) override;
@@ -63,14 +64,14 @@ protected:
virtual bool selectSubMenu(int selectedRow);
virtual bool returnToPreviousMenu();
virtual bool selectLeaf(int selectedRow) = 0;
Responder * sender() { return m_sender; }
InputEventHandler * sender() { return m_sender; }
virtual HighlightCell * leafCellAtIndex(int index) = 0;
virtual HighlightCell * nodeCellAtIndex(int index) = 0;
SelectableTableView m_selectableTableView;
Stack m_stack;
ListController m_listController;
private:
Responder * m_sender;
InputEventHandler * m_sender;
};
#endif

View File

@@ -4,13 +4,11 @@
#include <ion.h>
class App;
class Toolbox;
class Responder {
public:
Responder(Responder * parentResponder);
virtual bool handleEvent(Ion::Events::Event event); // Default implementation does nothing
virtual bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) { return false; }
virtual bool handleEvent(Ion::Events::Event event) { return false; }; // Default implementation does nothing
virtual void didBecomeFirstResponder();
virtual void willResignFirstResponder();
virtual void didEnterResponderChain(Responder * previousFirstResponder);
@@ -19,7 +17,6 @@ public:
Responder * commonAncestorWith(Responder * responder);
void setParentResponder(Responder * responder);
App * app() const;
virtual Toolbox * toolbox() { return nullptr; }
private:
Responder * m_parentResponder;
};

View File

@@ -2,16 +2,18 @@
#define ESCHER_TEXT_AREA_H
#include <escher/text_input.h>
#include <escher/input_event_handler.h>
#include <escher/text_area_delegate.h>
#include <assert.h>
#include <string.h>
class TextArea : public TextInput {
class TextArea : public TextInput, public InputEventHandler {
public:
TextArea(Responder * parentResponder, View * contentView, const KDFont * font = KDFont::LargeFont);
void setDelegate(TextAreaDelegate * delegate) { m_delegate = delegate; }
bool handleEvent(Ion::Events::Event event) override;
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) override;
Toolbox * toolbox() override;
void setText(char * textBuffer, size_t textBufferSize);
protected:

View File

@@ -1,12 +1,12 @@
#ifndef ESCHER_TEXT_FIELD_H
#define ESCHER_TEXT_FIELD_H
#include <escher/field.h>
#include <escher/editable_field.h>
#include <escher/text_input.h>
#include <escher/text_field_delegate.h>
#include <string.h>
class TextField : public TextInput, public Field {
class TextField : public TextInput, public EditableField {
public:
TextField(Responder * parentResponder, char * textBuffer, char * draftTextBuffer, size_t textBufferSize,
TextFieldDelegate * delegate = nullptr, bool hasTwoBuffers = true, const KDFont * font = KDFont::LargeFont,
@@ -24,6 +24,7 @@ public:
char XNTChar(char defaultXNTChar) override;
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) override;
bool handleEvent(Ion::Events::Event event) override;
Toolbox * toolbox() override;
constexpr static int maxBufferSize() {
return ContentView::k_maxBufferSize;
}

View File

@@ -11,7 +11,6 @@ class TextInput : public ScrollableView, public ScrollViewDataSource {
public:
TextInput(Responder * parentResponder, View * contentView);
void setFont(const KDFont * font) { contentView()->setFont(font); }
Toolbox * toolbox() override;
const char * text() const { return nonEditableContentView()->text(); }
bool removeChar();
size_t cursorLocation() const { return nonEditableContentView()->cursorLocation(); }

View File

@@ -1,11 +1,12 @@
#ifndef ESCHER_TEXT_INPUT_DELEGATE_H
#define ESCHER_TEXT_INPUT_DELEGATE_H
#include <escher/input_event_handler.h>
class TextInput;
class TextInputDelegate {
public:
virtual Toolbox * toolboxForTextInput(TextInput * textInput) = 0;
virtual Toolbox * toolboxForTextInput(InputEventHandler * textInput) = 0;
};
#endif

View File

@@ -35,6 +35,14 @@ bool ExpressionField::isEditing() const {
return editionIsInTextField() ? m_textField.isEditing() : m_layoutField.isEditing();
}
char ExpressionField::XNTChar(char defaultXNTChar) {
return editionIsInTextField() ? m_textField.XNTChar(defaultXNTChar) : m_layoutField.XNTChar(defaultXNTChar);
}
bool ExpressionField::shouldFinishEditing(Ion::Events::Event event) {
return editionIsInTextField() ? m_textField.shouldFinishEditing(event) : m_layoutField.shouldFinishEditing(event);
}
const char * ExpressionField::text() {
if (!editionIsInTextField()) {
m_layoutField.serialize(m_textBuffer, m_textBufferLength);

View File

@@ -0,0 +1,13 @@
#include <escher/input_event_handler.h>
#include <escher/app.h>
#include <escher/toolbox.h>
#include <escher/metric.h>
bool InputEventHandler::handleToolboxEvent(App * app) {
if (toolbox() != nullptr) {
toolbox()->setSender(this);
app->displayModalViewController(toolbox(), 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
}
return false;
}

View File

@@ -64,7 +64,7 @@ bool InputViewController::textFieldDidReceiveEvent(TextField * textField, Ion::E
return m_textFieldDelegate->textFieldDidReceiveEvent(textField, event);
}
Toolbox * InputViewController::toolboxForTextInput(TextInput * input) {
Toolbox * InputViewController::toolboxForTextInput(InputEventHandler * input) {
return m_textFieldDelegate->toolboxForTextInput(input);
}

View File

@@ -185,13 +185,13 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) {
if (m_delegate && m_delegate->layoutFieldDidReceiveEvent(this, event)) {
return true;
}
if (Responder::handleEvent(event)) {
/* The only event Responder handles is 'Toolbox' displaying. In that case,
* the LayoutField is forced into editing mode. */
if (!isEditing()) {
setEditing(true);
if (event == Ion::Events::Toolbox) {
if (handleToolboxEvent(app())) {
if (!isEditing()) {
setEditing(true);
}
return true;
}
return true;
}
if (isEditing() && m_delegate->layoutFieldShouldFinishEditing(this, event)) { //TODO use class method?
setEditing(false);

View File

@@ -1,6 +1,5 @@
#include <escher/responder.h>
#include <escher/app.h>
#include <escher/toolbox.h>
#include <escher/metric.h>
#include <assert.h>
@@ -17,15 +16,6 @@ void Responder::setParentResponder(Responder * responder) {
m_parentResponder = responder;
}
bool Responder::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::Toolbox && toolbox() != nullptr) {
toolbox()->setSender(this);
app()->displayModalViewController(toolbox(), 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
}
return false;
}
void Responder::didBecomeFirstResponder() {
}

View File

@@ -18,6 +18,13 @@ TextArea::TextArea(Responder * parentResponder, View * contentView, const KDFont
{
}
Toolbox * TextArea::toolbox() {
if (delegate()) {
return delegate()->toolboxForTextInput(this);
}
return nullptr;
}
bool TextArea::handleEventWithText(const char * text, bool indentation, bool forceCursorRightOfText) {
int nextCursorLocation = cursorLocation();
@@ -50,9 +57,8 @@ bool TextArea::handleEventWithText(const char * text, bool indentation, bool for
bool TextArea::handleEvent(Ion::Events::Event event) {
if (m_delegate != nullptr && m_delegate->textAreaDidReceiveEvent(this, event)) {
return true;
} else if (Responder::handleEvent(event)) {
// The only event Responder handles is 'Toolbox' displaying.
return true;
} else if (event == Ion::Events::Toolbox) {
return handleToolboxEvent(app());
} else if (event == Ion::Events::Left) {
return setCursorLocation(cursorLocation()-1);
} else if (event == Ion::Events::Right) {

View File

@@ -228,13 +228,13 @@ void TextField::setEditing(bool isEditing, bool reinitDrafBuffer) {
}
bool TextField::privateHandleEvent(Ion::Events::Event event) {
if (Responder::handleEvent(event)) {
/* The only event Responder handles is 'Toolbox' displaying. In that case,
* the text field is forced into editing mode. */
if (!isEditing()) {
setEditing(true);
if (event == Ion::Events::Toolbox) {
if (handleToolboxEvent(app())) {
if (!isEditing()) {
setEditing(true);
}
return true;
}
return true;
}
if (event == Ion::Events::Left && isEditing() && cursorLocation() > 0) {
return setCursorLocation(cursorLocation()-1);
@@ -358,6 +358,13 @@ char TextField::XNTChar(char defaultXNTChar) {
return defaultXNTChar;
}
Toolbox * TextField::toolbox() {
if (delegate()) {
return delegate()->toolboxForTextInput(this);
}
return nullptr;
}
bool TextField::handleEvent(Ion::Events::Event event) {
assert(m_delegate != nullptr);
if (m_delegate->textFieldDidReceiveEvent(this, event)) {

View File

@@ -59,13 +59,6 @@ TextInput::TextInput(Responder * parentResponder, View * contentView) :
{
}
Toolbox * TextInput::toolbox() {
if (delegate()) {
return delegate()->toolboxForTextInput(this);
}
return nullptr;
}
bool TextInput::removeChar() {
contentView()->removeChar();
scrollToCursor();