mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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\
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
15
escher/include/escher/input_event_handler.h
Normal file
15
escher/include/escher/input_event_handler.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
13
escher/src/input_event_handler.cpp
Normal file
13
escher/src/input_event_handler.cpp
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user