mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] Continue removing layouts
This commit is contained in:
@@ -65,18 +65,18 @@ bool App::textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event e
|
||||
return false;
|
||||
}
|
||||
|
||||
bool App::expressionLayoutFieldDidReceiveEvent(::ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
if ((event == Ion::Events::Var || event == Ion::Events::XNT) && ExpressionFieldDelegateApp::expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event)) {
|
||||
bool App::layoutFieldDidReceiveEvent(::LayoutField * layoutField, Ion::Events::Event event) {
|
||||
if ((event == Ion::Events::Var || event == Ion::Events::XNT) && ExpressionFieldDelegateApp::layoutFieldDidReceiveEvent(layoutField, event)) {
|
||||
return true;
|
||||
}
|
||||
if (expressionLayoutField->isEditing() && expressionLayoutField->expressionLayoutFieldShouldFinishEditing(event)) {
|
||||
if (!expressionLayoutField->hasText()) {
|
||||
if (layoutField->isEditing() && layoutField->layoutFieldShouldFinishEditing(event)) {
|
||||
if (!layoutField->hasText()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int bufferLength = Calculation::k_printedExpressionSize;
|
||||
char bufferForParsing[bufferLength];
|
||||
expressionLayoutField->writeTextInBuffer(bufferForParsing, bufferLength);
|
||||
layoutField->writeTextInBuffer(bufferForParsing, bufferLength);
|
||||
|
||||
if (!textInputIsCorrect(bufferForParsing)) {
|
||||
displayWarning(I18n::Message::SyntaxError);
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
};
|
||||
bool textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) override;
|
||||
bool textInputIsCorrect(const char * text);
|
||||
bool expressionLayoutFieldDidReceiveEvent(::ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidReceiveEvent(::LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
const char * XNT() override;
|
||||
private:
|
||||
App(Container * container, Snapshot * snapshot);
|
||||
|
||||
@@ -10,19 +10,15 @@ using namespace Poincare;
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
EditExpressionController::ContentView::ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) :
|
||||
EditExpressionController::ContentView::ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
|
||||
View(),
|
||||
m_mainView(subview),
|
||||
m_layout(new Poincare::HorizontalLayout()),
|
||||
m_expressionField(parentResponder, m_textBody, k_bufferLength, m_layout, textFieldDelegate, expressionLayoutFieldDelegate)
|
||||
m_layoutR(Poincare::HorizontalLayoutRef()),
|
||||
m_expressionField(parentResponder, m_textBody, k_bufferLength, m_layoutR, textFieldDelegate, layoutFieldDelegate)
|
||||
{
|
||||
m_textBody[0] = 0;
|
||||
}
|
||||
|
||||
EditExpressionController::ContentView::~ContentView() {
|
||||
delete m_layout;
|
||||
}
|
||||
|
||||
View * EditExpressionController::ContentView::subviewAtIndex(int index) {
|
||||
assert(index >= 0 && index < numberOfSubviews());
|
||||
if (index == 0) {
|
||||
@@ -92,22 +88,22 @@ bool EditExpressionController::textFieldDidAbortEditing(::TextField * textField)
|
||||
return inputViewDidAbortEditing(textField->text());
|
||||
}
|
||||
|
||||
bool EditExpressionController::expressionLayoutFieldDidReceiveEvent(::ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
if (expressionLayoutField->isEditing() && expressionLayoutField->expressionLayoutFieldShouldFinishEditing(event) && !expressionLayoutField->hasText() && m_calculationStore->numberOfCalculations() > 0) {
|
||||
bool EditExpressionController::layoutFieldDidReceiveEvent(::LayoutField * layoutField, Ion::Events::Event event) {
|
||||
if (layoutField->isEditing() && layoutField->layoutFieldShouldFinishEditing(event) && !layoutField->hasText() && m_calculationStore->numberOfCalculations() > 0) {
|
||||
return inputViewDidReceiveEvent(event);
|
||||
}
|
||||
return expressionFieldDelegateApp()->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event);
|
||||
return expressionFieldDelegateApp()->layoutFieldDidReceiveEvent(layoutField, event);
|
||||
}
|
||||
|
||||
bool EditExpressionController::expressionLayoutFieldDidFinishEditing(::ExpressionLayoutField * expressionLayoutField, ExpressionLayout * layout, Ion::Events::Event event) {
|
||||
return inputViewDidFinishEditing(nullptr, layout);
|
||||
bool EditExpressionController::layoutFieldDidFinishEditing(::LayoutField * layoutField, LayoutRef layoutR, Ion::Events::Event event) {
|
||||
return inputViewDidFinishEditing(nullptr, layoutR);
|
||||
}
|
||||
|
||||
bool EditExpressionController::expressionLayoutFieldDidAbortEditing(::ExpressionLayoutField * expressionLayoutField) {
|
||||
bool EditExpressionController::layoutFieldDidAbortEditing(::LayoutField * layoutField) {
|
||||
return inputViewDidAbortEditing(nullptr);
|
||||
}
|
||||
|
||||
void EditExpressionController::expressionLayoutFieldDidChangeSize(::ExpressionLayoutField * expressionLayoutField) {
|
||||
void EditExpressionController::layoutFieldDidChangeSize(::LayoutField * layoutField) {
|
||||
/* Reload the view only if the ExpressionField height actually changes, i.e.
|
||||
* not if the height is already maximal and stays maximal. */
|
||||
if (view()) {
|
||||
@@ -157,14 +153,14 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event
|
||||
}
|
||||
|
||||
|
||||
bool EditExpressionController::inputViewDidFinishEditing(const char * text, ExpressionLayout * layout) {
|
||||
bool EditExpressionController::inputViewDidFinishEditing(const char * text, LayoutRef layoutR) {
|
||||
App * calculationApp = (App *)app();
|
||||
if (layout == nullptr) {
|
||||
if (!layoutR.isDefined()) {
|
||||
assert(text);
|
||||
strlcpy(m_cacheBuffer, text, Calculation::k_printedExpressionSize);
|
||||
} else {
|
||||
assert(layout);
|
||||
layout->writeTextInBuffer(m_cacheBuffer, Calculation::k_printedExpressionSize);
|
||||
assert(layoutR.isDefined());
|
||||
layoutR.writeTextInBuffer(m_cacheBuffer, Calculation::k_printedExpressionSize);
|
||||
}
|
||||
m_calculationStore->push(m_cacheBuffer, calculationApp->localContext());
|
||||
m_historyController->reload();
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#define CALCULATION_EDIT_EXPRESSION_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include <poincare/expression_layout.h>
|
||||
#include <poincare/layout_reference.h>
|
||||
#include "expression_field.h"
|
||||
#include "../shared/text_field_delegate.h"
|
||||
#include "../shared/expression_layout_field_delegate.h"
|
||||
#include "../shared/layout_field_delegate.h"
|
||||
#include "history_controller.h"
|
||||
#include "calculation_store.h"
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Calculation {
|
||||
class HistoryController;
|
||||
|
||||
/* TODO: implement a split view */
|
||||
class EditExpressionController : public DynamicViewController, public Shared::TextFieldDelegate, public Shared::ExpressionLayoutFieldDelegate {
|
||||
class EditExpressionController : public DynamicViewController, public Shared::TextFieldDelegate, public Shared::LayoutFieldDelegate {
|
||||
public:
|
||||
EditExpressionController(Responder * parentResponder, HistoryController * historyController, CalculationStore * calculationStore);
|
||||
void didBecomeFirstResponder() override;
|
||||
@@ -26,21 +26,16 @@ public:
|
||||
bool textFieldDidFinishEditing(::TextField * textField, const char * text, Ion::Events::Event event) override;
|
||||
bool textFieldDidAbortEditing(::TextField * textField) override;
|
||||
|
||||
/* ExpressionLayoutFieldDelegate */
|
||||
bool expressionLayoutFieldDidReceiveEvent(::ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidFinishEditing(::ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidAbortEditing(::ExpressionLayoutField * expressionLayoutField) override;
|
||||
void expressionLayoutFieldDidChangeSize(::ExpressionLayoutField * expressionLayoutField) override;
|
||||
/* LayoutFieldDelegate */
|
||||
bool layoutFieldDidReceiveEvent(::LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidFinishEditing(::LayoutField * layoutField, Poincare::LayoutRef layoutR, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidAbortEditing(::LayoutField * layoutField) override;
|
||||
void layoutFieldDidChangeSize(::LayoutField * layoutField) override;
|
||||
|
||||
private:
|
||||
class ContentView : public View {
|
||||
public:
|
||||
ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate);
|
||||
~ContentView();
|
||||
ContentView(const ContentView& other) = delete;
|
||||
ContentView(ContentView&& other) = delete;
|
||||
ContentView& operator=(const ContentView& other) = delete;
|
||||
ContentView& operator=(ContentView&& other) = delete;
|
||||
ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
|
||||
void reload();
|
||||
TableView * mainView() { return m_mainView; }
|
||||
ExpressionField * expressionField() { return &m_expressionField; }
|
||||
@@ -52,14 +47,14 @@ private:
|
||||
static constexpr int k_bufferLength = TextField::maxBufferSize();
|
||||
TableView * m_mainView;
|
||||
char m_textBody[k_bufferLength];
|
||||
Poincare::ExpressionLayout * m_layout;
|
||||
Poincare::LayoutRef m_layoutR;
|
||||
ExpressionField m_expressionField;
|
||||
};
|
||||
View * loadView() override;
|
||||
void unloadView(View * view) override;
|
||||
void reloadView();
|
||||
bool inputViewDidReceiveEvent(Ion::Events::Event event);
|
||||
bool inputViewDidFinishEditing(const char * text, Poincare::ExpressionLayout * layout);
|
||||
bool inputViewDidFinishEditing(const char * text, Poincare::LayoutRef layoutR);
|
||||
bool inputViewDidAbortEditing(const char * text);
|
||||
Shared::TextFieldDelegateApp * textFieldDelegateApp() override;
|
||||
Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override;
|
||||
|
||||
@@ -10,7 +10,6 @@ app_objs += $(addprefix apps/shared/,\
|
||||
double_pair_store.o\
|
||||
editable_cell_table_view_controller.o\
|
||||
expression_field_delegate_app.o\
|
||||
expression_layout_field_delegate.o\
|
||||
expression_model.o\
|
||||
expression_model_list_controller.o\
|
||||
expression_model_store.o\
|
||||
@@ -36,6 +35,7 @@ app_objs += $(addprefix apps/shared/,\
|
||||
interval.o\
|
||||
interval_parameter_controller.o\
|
||||
language_controller.o\
|
||||
layout_field_delegate.o\
|
||||
list_parameter_controller.o\
|
||||
margin_even_odd_message_text_cell.o\
|
||||
memoized_curve_view_range.o\
|
||||
|
||||
@@ -9,31 +9,31 @@ namespace Shared {
|
||||
|
||||
ExpressionFieldDelegateApp::ExpressionFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) :
|
||||
TextFieldDelegateApp(container, snapshot, rootViewController),
|
||||
ExpressionLayoutFieldDelegate()
|
||||
LayoutFieldDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
char ExpressionFieldDelegateApp::privateXNT(ExpressionLayoutField * expressionLayoutField) {
|
||||
char xntCharFromLayout = expressionLayoutField->XNTChar();
|
||||
char ExpressionFieldDelegateApp::privateXNT(LayoutField * layoutField) {
|
||||
char xntCharFromLayout = layoutField->XNTChar();
|
||||
if (xntCharFromLayout != Ion::Charset::Empty) {
|
||||
return xntCharFromLayout;
|
||||
}
|
||||
return XNT()[0];
|
||||
}
|
||||
|
||||
bool ExpressionFieldDelegateApp::expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
bool ExpressionFieldDelegateApp::layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) {
|
||||
return event == Ion::Events::OK || event == Ion::Events::EXE;
|
||||
}
|
||||
|
||||
bool ExpressionFieldDelegateApp::expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
if (expressionLayoutField->isEditing() && expressionLayoutField->expressionLayoutFieldShouldFinishEditing(event)) {
|
||||
if (!expressionLayoutField->hasText()) {
|
||||
expressionLayoutField->app()->displayWarning(I18n::Message::SyntaxError);
|
||||
bool ExpressionFieldDelegateApp::layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) {
|
||||
if (layoutField->isEditing() && layoutField->layoutFieldShouldFinishEditing(event)) {
|
||||
if (!layoutField->hasText()) {
|
||||
layoutField->app()->displayWarning(I18n::Message::SyntaxError);
|
||||
return true;
|
||||
}
|
||||
char buffer[TextField::maxBufferSize()];
|
||||
int bufferSize = TextField::maxBufferSize();
|
||||
int length = expressionLayoutField->writeTextInBuffer(buffer, bufferSize);
|
||||
int length = layoutField->writeTextInBuffer(buffer, bufferSize);
|
||||
Expression * exp = Expression::parse(buffer);
|
||||
if (exp != nullptr) {
|
||||
delete exp;
|
||||
@@ -45,33 +45,33 @@ bool ExpressionFieldDelegateApp::expressionLayoutFieldDidReceiveEvent(Expression
|
||||
return true;
|
||||
}
|
||||
if (exp == nullptr) {
|
||||
expressionLayoutField->app()->displayWarning(I18n::Message::SyntaxError);
|
||||
layoutField->app()->displayWarning(I18n::Message::SyntaxError);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event == Ion::Events::Var) {
|
||||
if (!expressionLayoutField->isEditing()) {
|
||||
expressionLayoutField->setEditing(true);
|
||||
if (!layoutField->isEditing()) {
|
||||
layoutField->setEditing(true);
|
||||
}
|
||||
AppsContainer * appsContainer = (AppsContainer *)expressionLayoutField->app()->container();
|
||||
AppsContainer * appsContainer = (AppsContainer *)layoutField->app()->container();
|
||||
VariableBoxController * variableBoxController = appsContainer->variableBoxController();
|
||||
variableBoxController->setSender(expressionLayoutField);
|
||||
expressionLayoutField->app()->displayModalViewController(variableBoxController, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
|
||||
variableBoxController->setSender(layoutField);
|
||||
layoutField->app()->displayModalViewController(variableBoxController, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::XNT) {
|
||||
if (!expressionLayoutField->isEditing()) {
|
||||
expressionLayoutField->setEditing(true);
|
||||
if (!layoutField->isEditing()) {
|
||||
layoutField->setEditing(true);
|
||||
}
|
||||
const char xnt[2] = {privateXNT(expressionLayoutField), 0};
|
||||
return expressionLayoutField->handleEventWithText(xnt);
|
||||
const char xnt[2] = {privateXNT(layoutField), 0};
|
||||
return layoutField->handleEventWithText(xnt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Toolbox * ExpressionFieldDelegateApp::toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) {
|
||||
Toolbox * ExpressionFieldDelegateApp::toolboxForLayoutField(LayoutField * layoutField) {
|
||||
Toolbox * toolbox = container()->mathToolbox();
|
||||
toolbox->setSender(expressionLayoutField);
|
||||
toolbox->setSender(layoutField);
|
||||
return toolbox;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
#define SHARED_EXPRESSION_FIELD_DELEGATE_APP_H
|
||||
|
||||
#include "text_field_delegate_app.h"
|
||||
#include <escher/expression_layout_field_delegate.h>
|
||||
#include <escher/layout_field_delegate.h>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class ExpressionFieldDelegateApp : public TextFieldDelegateApp, public ExpressionLayoutFieldDelegate {
|
||||
class ExpressionFieldDelegateApp : public TextFieldDelegateApp, public LayoutFieldDelegate {
|
||||
public:
|
||||
virtual ~ExpressionFieldDelegateApp() = default;
|
||||
bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
virtual bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) override;
|
||||
bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
virtual bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
Toolbox * toolboxForLayoutField(LayoutField * layoutField) override;
|
||||
protected:
|
||||
char privateXNT(ExpressionLayoutField * expressionLayoutField);
|
||||
char privateXNT(LayoutField * layoutField);
|
||||
ExpressionFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "expression_layout_field_delegate.h"
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
bool ExpressionLayoutFieldDelegate::expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
return expressionFieldDelegateApp()->expressionLayoutFieldShouldFinishEditing(expressionLayoutField, event);
|
||||
}
|
||||
|
||||
bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
return expressionFieldDelegateApp()->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event);
|
||||
}
|
||||
|
||||
bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, ExpressionLayout * layout, Ion::Events::Event event) {
|
||||
return expressionFieldDelegateApp()->expressionLayoutFieldDidFinishEditing(expressionLayoutField, layout, event);
|
||||
}
|
||||
|
||||
bool ExpressionLayoutFieldDelegate::expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) {
|
||||
return expressionFieldDelegateApp()->expressionLayoutFieldDidAbortEditing(expressionLayoutField);
|
||||
}
|
||||
|
||||
void ExpressionLayoutFieldDelegate::expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) {
|
||||
return expressionFieldDelegateApp()->expressionLayoutFieldDidChangeSize(expressionLayoutField);
|
||||
}
|
||||
|
||||
Toolbox * ExpressionLayoutFieldDelegate::toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) {
|
||||
return expressionFieldDelegateApp()->toolboxForExpressionLayoutField(expressionLayoutField);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef SHARED_EXPRESSION_LAYOUT_FIELD_DELEGATE_H
|
||||
#define SHARED_EXPRESSION_LAYOUT_FIELD_DELEGATE_H
|
||||
|
||||
#include <escher/expression_layout_field_delegate.h>
|
||||
#include "expression_field_delegate_app.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class ExpressionLayoutFieldDelegate : public ::ExpressionLayoutFieldDelegate {
|
||||
public:
|
||||
bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) override;
|
||||
void expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) override;
|
||||
Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) override;
|
||||
private:
|
||||
virtual ExpressionFieldDelegateApp * expressionFieldDelegateApp() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -33,8 +33,7 @@ KDCoordinate ExpressionModelListController::expressionRowHeight(int j) {
|
||||
void ExpressionModelListController::willDisplayExpressionCellAtIndex(HighlightCell * cell, int j) {
|
||||
EvenOddExpressionCell * myCell = (EvenOddExpressionCell *)cell;
|
||||
ExpressionModel * m = modelStore()->modelAtIndex(j);
|
||||
myCell->setExpressionLayout(nullptr); //TODO
|
||||
//myCell->setExpressionLayout(m->layout());
|
||||
myCell->setLayoutRef(m->layoutRef());
|
||||
}
|
||||
|
||||
/* Responder */
|
||||
|
||||
31
apps/shared/layout_field_delegate.cpp
Normal file
31
apps/shared/layout_field_delegate.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "layout_field_delegate.h"
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
bool LayoutFieldDelegate::layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) {
|
||||
return expressionFieldDelegateApp()->layoutFieldShouldFinishEditing(layoutField, event);
|
||||
}
|
||||
|
||||
bool LayoutFieldDelegate::layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) {
|
||||
return expressionFieldDelegateApp()->layoutFieldDidReceiveEvent(layoutField, event);
|
||||
}
|
||||
|
||||
bool LayoutFieldDelegate::layoutFieldDidFinishEditing(LayoutField * layoutField, LayoutRef layoutR, Ion::Events::Event event) {
|
||||
return expressionFieldDelegateApp()->layoutFieldDidFinishEditing(layoutField, layoutR, event);
|
||||
}
|
||||
|
||||
bool LayoutFieldDelegate::layoutFieldDidAbortEditing(LayoutField * layoutField) {
|
||||
return expressionFieldDelegateApp()->layoutFieldDidAbortEditing(layoutField);
|
||||
}
|
||||
|
||||
void LayoutFieldDelegate::layoutFieldDidChangeSize(LayoutField * layoutField) {
|
||||
return expressionFieldDelegateApp()->layoutFieldDidChangeSize(layoutField);
|
||||
}
|
||||
|
||||
Toolbox * LayoutFieldDelegate::toolboxForLayoutField(LayoutField * layoutField) {
|
||||
return expressionFieldDelegateApp()->toolboxForLayoutField(layoutField);
|
||||
}
|
||||
|
||||
}
|
||||
23
apps/shared/layout_field_delegate.h
Normal file
23
apps/shared/layout_field_delegate.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef SHARED_LAYOUT_FIELD_DELEGATE_H
|
||||
#define SHARED_LAYOUT_FIELD_DELEGATE_H
|
||||
|
||||
#include <escher/layout_field_delegate.h>
|
||||
#include "expression_field_delegate_app.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class LayoutFieldDelegate : public ::LayoutFieldDelegate {
|
||||
public:
|
||||
bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidFinishEditing(LayoutField * layoutField, Poincare::LayoutRef layoutR, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidAbortEditing(LayoutField * layoutField) override;
|
||||
void layoutFieldDidChangeSize(LayoutField * layoutField) override;
|
||||
Toolbox * toolboxForLayoutField(LayoutField * layoutField) override;
|
||||
private:
|
||||
virtual ExpressionFieldDelegateApp * expressionFieldDelegateApp() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -30,7 +30,6 @@ objs += $(addprefix escher/src/,\
|
||||
input_view_controller.o\
|
||||
key_view.o\
|
||||
layout_field.o\
|
||||
layout_field_content_view.o\
|
||||
list_view_data_source.o\
|
||||
message_table_cell.o\
|
||||
message_table_cell_with_buffer.o\
|
||||
@@ -52,8 +51,6 @@ objs += $(addprefix escher/src/,\
|
||||
scroll_view_data_source.o\
|
||||
scroll_view_indicator.o\
|
||||
scrollable_view.o\
|
||||
expression_layout_field.o\
|
||||
expression_layout_field_content_view.o\
|
||||
selectable_table_view.o\
|
||||
selectable_table_view_data_source.o\
|
||||
selectable_table_view_delegate.o\
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <escher/invocation.h>
|
||||
#include <escher/i18n.h>
|
||||
#include <escher/key_view.h>
|
||||
#include <escher/layout_field.h>
|
||||
#include <escher/layout_field_delegate.h>
|
||||
#include <escher/list_view_data_source.h>
|
||||
#include <escher/message_table_cell.h>
|
||||
#include <escher/message_table_cell_with_buffer.h>
|
||||
@@ -53,8 +55,6 @@
|
||||
#include <escher/scroll_view_data_source.h>
|
||||
#include <escher/scroll_view_indicator.h>
|
||||
#include <escher/scrollable_view.h>
|
||||
#include <escher/expression_layout_field.h>
|
||||
#include <escher/expression_layout_field_delegate.h>
|
||||
#include <escher/selectable_table_view.h>
|
||||
#include <escher/selectable_table_view_data_source.h>
|
||||
#include <escher/selectable_table_view_delegate.h>
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
KDColor textColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
|
||||
void setEven(bool even) override;
|
||||
void setHighlighted(bool highlight) override;
|
||||
void setExpressionLayout(Poincare::ExpressionLayout * expressionLayout);
|
||||
void setLayoutRef(Poincare::LayoutRef layoutRef);
|
||||
void setBackgroundColor(KDColor backgroundColor);
|
||||
void setTextColor(KDColor textColor);
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#ifndef ESCHER_EXPRESSION_FIELD_H
|
||||
#define ESCHER_EXPRESSION_FIELD_H
|
||||
|
||||
#include <escher/expression_layout_field.h>
|
||||
#include <escher/expression_layout_field_delegate.h>
|
||||
#include <escher/layout_field.h>
|
||||
#include <escher/layout_field_delegate.h>
|
||||
#include <escher/text_field.h>
|
||||
#include <escher/text_field_delegate.h>
|
||||
#include <poincare/expression_layout.h>
|
||||
#include <poincare/layout_reference.h>
|
||||
|
||||
class ExpressionField : public Responder, public View {
|
||||
public:
|
||||
ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::ExpressionLayout * layout, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate);
|
||||
ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::LayoutRef layout, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
|
||||
|
||||
void setEditing(bool isEditing, bool reinitDraftBuffer = true);
|
||||
bool isEditing() const;
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
KDCoordinate inputViewHeight() const;
|
||||
KDCoordinate maximalHeight() const;
|
||||
TextField m_textField;
|
||||
ExpressionLayoutField m_expressionLayoutField;
|
||||
LayoutField m_layoutField;
|
||||
char * m_textBuffer;
|
||||
int m_textBufferLength;
|
||||
};
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#ifndef ESCHER_EXPRESSION_LAYOUT_FIELD_H
|
||||
#define ESCHER_EXPRESSION_LAYOUT_FIELD_H
|
||||
|
||||
#include <escher/expression_view.h>
|
||||
#include <escher/expression_layout_field_delegate.h>
|
||||
#include <escher/scrollable_view.h>
|
||||
#include <escher/text_cursor_view.h>
|
||||
#include <escher/text_field.h>
|
||||
#include <kandinsky/point.h>
|
||||
#include <poincare/expression_layout.h>
|
||||
#include <poincare/expression_layout_cursor.h>
|
||||
|
||||
class ExpressionLayoutField : public ScrollableView, public ScrollViewDataSource {
|
||||
public:
|
||||
ExpressionLayoutField(Responder * parentResponder, Poincare::ExpressionLayout * expressionLayout, ExpressionLayoutFieldDelegate * delegate = nullptr);
|
||||
void setDelegate(ExpressionLayoutFieldDelegate * delegate) { m_delegate = delegate; }
|
||||
bool isEditing() const;
|
||||
void setEditing(bool isEditing);
|
||||
void clearLayout();
|
||||
void scrollToCursor();
|
||||
void reload();
|
||||
bool hasText() const;
|
||||
int writeTextInBuffer(char * buffer, int bufferLength);
|
||||
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) override;
|
||||
Poincare::ExpressionLayout * expressionLayout() const;
|
||||
char XNTChar();
|
||||
void setBackgroundColor(KDColor c) override;
|
||||
|
||||
/* Responder */
|
||||
Toolbox * toolbox() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
|
||||
bool expressionLayoutFieldShouldFinishEditing(Ion::Events::Event event);
|
||||
|
||||
/* View */
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
|
||||
protected:
|
||||
virtual bool privateHandleEvent(Ion::Events::Event event);
|
||||
bool privateHandleMoveEvent(Ion::Events::Event event, bool * shouldRecomputeLayout);
|
||||
private:
|
||||
constexpr static int k_maxNumberOfLayouts = 152;
|
||||
static_assert(k_maxNumberOfLayouts == TextField::maxBufferSize(), "Maximal number of layouts in a layout field should be equal to max number of char in text field");
|
||||
void scrollRightOfLayout(Poincare::ExpressionLayout * layout);
|
||||
void scrollToBaselinedRect(KDRect rect, KDCoordinate baseline);
|
||||
void insertLayoutAtCursor(Poincare::ExpressionLayout * layout, Poincare::ExpressionLayout * pointedLayout, bool forceCursorRightOfLayout = false);
|
||||
|
||||
class ContentView : public View {
|
||||
public:
|
||||
ContentView(Poincare::ExpressionLayout * expressionLayout);
|
||||
bool isEditing() const { return m_isEditing; }
|
||||
void setEditing(bool isEditing);
|
||||
void setBackgroundColor(KDColor c);
|
||||
void setCursor(Poincare::ExpressionLayoutCursor cursor) { m_cursor = cursor; }
|
||||
void cursorPositionChanged();
|
||||
KDRect cursorRect();
|
||||
Poincare::ExpressionLayoutCursor * cursor() { return &m_cursor; }
|
||||
const ExpressionView * expressionView() const { return &m_expressionView; }
|
||||
ExpressionView * editableExpressionView() { return &m_expressionView; }
|
||||
void clearLayout();
|
||||
/* View */
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
private:
|
||||
enum class Position {
|
||||
Top,
|
||||
Bottom
|
||||
};
|
||||
int numberOfSubviews() const override { return 2; }
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews() override;
|
||||
void layoutCursorSubview();
|
||||
Poincare::ExpressionLayoutCursor m_cursor;
|
||||
ExpressionView m_expressionView;
|
||||
TextCursorView m_cursorView;
|
||||
bool m_isEditing;
|
||||
};
|
||||
ContentView m_contentView;
|
||||
ExpressionLayoutFieldDelegate * m_delegate;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef ESCHER_EXPRESSION_LAYOUT_FIELD_DELEGATE_H
|
||||
#define ESCHER_EXPRESSION_LAYOUT_FIELD_DELEGATE_H
|
||||
|
||||
#include <escher/toolbox.h>
|
||||
#include <ion/events.h>
|
||||
|
||||
class ExpressionLayoutField;
|
||||
|
||||
class ExpressionLayoutFieldDelegate {
|
||||
public:
|
||||
virtual bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) = 0;
|
||||
virtual bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) = 0;
|
||||
virtual bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) { return false; }
|
||||
virtual bool expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) { return false; }
|
||||
virtual void expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) {}
|
||||
virtual Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@ public:
|
||||
ExpressionTableCell(Layout layout = Layout::Horizontal);
|
||||
View * labelView() const override;
|
||||
void setHighlighted(bool highlight) override;
|
||||
void setExpressionLayout(Poincare::ExpressionLayout * expressionLayout);
|
||||
void setLayoutRef(Poincare::LayoutRef layoutR);
|
||||
Poincare::LayoutRef layoutRef() const override { return m_labelExpressionView.layoutRef(); }
|
||||
private:
|
||||
ExpressionView m_labelExpressionView;
|
||||
|
||||
@@ -16,13 +16,8 @@ class ExpressionView : public View {
|
||||
public:
|
||||
ExpressionView(float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f,
|
||||
KDColor textColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
|
||||
|
||||
Poincare::ExpressionLayout * expressionLayout() const;
|
||||
void setExpressionLayout(Poincare::ExpressionLayout * expressionLayout);
|
||||
|
||||
Poincare::LayoutRef layoutRef() const { return m_layoutRef; }
|
||||
void setLayoutRef(Poincare::LayoutRef layoutRef);
|
||||
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
void setBackgroundColor(KDColor backgroundColor);
|
||||
void setTextColor(KDColor textColor);
|
||||
@@ -37,8 +32,7 @@ private:
|
||||
* layout is always possessed by a controller which only gives a pointer to
|
||||
* the expression view (without cloning it). The named controller is then
|
||||
* responsible for freeing the expression layout when required. */
|
||||
Poincare::ExpressionLayout * m_expressionLayout;
|
||||
Poincare::LayoutRef m_layoutRef;
|
||||
mutable Poincare::LayoutRef m_layoutRef; // TODO find better way to have minimalSizeForOptimalDisplay const
|
||||
float m_horizontalAlignment;
|
||||
float m_verticalAlignment;
|
||||
KDColor m_textColor;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define ESCHER_INPUT_VIEW_CONTROLLER_H
|
||||
|
||||
#include <escher/expression_field.h>
|
||||
#include <escher/expression_layout_field_delegate.h>
|
||||
#include <escher/layout_field_delegate.h>
|
||||
#include <escher/modal_view_controller.h>
|
||||
#include <escher/invocation.h>
|
||||
#include <escher/text_field.h>
|
||||
@@ -12,9 +12,9 @@
|
||||
/* TODO Implement a split view. Because we use a modal view, the main view is
|
||||
* redrawn underneath the modal view, which is visible and ugly. */
|
||||
|
||||
class InputViewController : public ModalViewController, TextFieldDelegate, ExpressionLayoutFieldDelegate {
|
||||
class InputViewController : public ModalViewController, TextFieldDelegate, LayoutFieldDelegate {
|
||||
public:
|
||||
InputViewController(Responder * parentResponder, ViewController * child, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate);
|
||||
InputViewController(Responder * parentResponder, ViewController * child, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
|
||||
void edit(Responder * caller, Ion::Events::Event event, void * context, const char * initialText, Invocation::Action successAction, Invocation::Action failureAction);
|
||||
const char * textBody();
|
||||
void abortEditionAndDismiss();
|
||||
@@ -26,19 +26,18 @@ public:
|
||||
bool textFieldDidAbortEditing(TextField * textField) override;
|
||||
Toolbox * toolboxForTextInput(TextInput * textInput) override;
|
||||
|
||||
/* ExpressionLayoutFieldDelegate */
|
||||
bool expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) override;
|
||||
bool expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) override;
|
||||
void expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) override;
|
||||
Toolbox * toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) override;
|
||||
/* LayoutFieldDelegate */
|
||||
bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidFinishEditing(LayoutField * layoutField, Poincare::LayoutRef layoutR, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidAbortEditing(LayoutField * layoutField) override;
|
||||
void layoutFieldDidChangeSize(LayoutField * layoutField) override;
|
||||
Toolbox * toolboxForLayoutField(LayoutField * layoutField) override;
|
||||
|
||||
private:
|
||||
class ExpressionFieldController : public ViewController {
|
||||
public:
|
||||
ExpressionFieldController(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate);
|
||||
~ExpressionFieldController();
|
||||
ExpressionFieldController(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
|
||||
ExpressionFieldController(const ExpressionFieldController& other) = delete;
|
||||
ExpressionFieldController(ExpressionFieldController&& other) = delete;
|
||||
ExpressionFieldController& operator=(const ExpressionFieldController& other) = delete;
|
||||
@@ -48,7 +47,7 @@ private:
|
||||
ExpressionField * expressionField() { return &m_expressionField; }
|
||||
private:
|
||||
static constexpr int k_bufferLength = TextField::maxBufferSize();
|
||||
Poincare::ExpressionLayout * m_layout;
|
||||
Poincare::LayoutRef m_layout;
|
||||
char m_textBuffer[k_bufferLength];
|
||||
ExpressionField m_expressionField;
|
||||
};
|
||||
@@ -58,7 +57,7 @@ private:
|
||||
Invocation m_successAction;
|
||||
Invocation m_failureAction;
|
||||
TextFieldDelegate * m_textFieldDelegate;
|
||||
ExpressionLayoutFieldDelegate * m_expressionLayoutFieldDelegate;
|
||||
LayoutFieldDelegate * m_layoutFieldDelegate;
|
||||
bool m_inputViewHeightIsMaximal;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public:
|
||||
MessageTableCellWithChevronAndExpression(I18n::Message message = (I18n::Message)0, KDText::FontSize size = KDText::FontSize::Small);
|
||||
View * subAccessoryView() const override;
|
||||
void setHighlighted(bool highlight) override;
|
||||
void setExpressionLayout(Poincare::ExpressionLayout * expressionLayout);
|
||||
void setLayoutRef(Poincare::LayoutRef layoutR);
|
||||
private:
|
||||
ExpressionView m_subtitleView;
|
||||
};
|
||||
|
||||
@@ -23,8 +23,8 @@ void EvenOddExpressionCell::setEven(bool even) {
|
||||
m_expressionView.setBackgroundColor(backgroundColor());
|
||||
}
|
||||
|
||||
void EvenOddExpressionCell::setExpressionLayout(ExpressionLayout * expressionLayout) {
|
||||
m_expressionView.setExpressionLayout(expressionLayout);
|
||||
void EvenOddExpressionCell::setLayoutRef(LayoutRef layoutR) {
|
||||
m_expressionView.setLayoutRef(layoutR);
|
||||
}
|
||||
|
||||
void EvenOddExpressionCell::setBackgroundColor(KDColor backgroundColor) {
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
#include <poincare/preferences.h>
|
||||
#include <assert.h>
|
||||
|
||||
ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::ExpressionLayout * layout, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) :
|
||||
ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::LayoutRef layout, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
|
||||
Responder(parentResponder),
|
||||
View(),
|
||||
m_textField(parentResponder, textBuffer, textBuffer, textBufferLength, textFieldDelegate, false, KDText::FontSize::Large, 0.0f, 0.5f, KDColorBlack, KDColorWhite),
|
||||
m_expressionLayoutField(parentResponder, layout, expressionLayoutFieldDelegate),
|
||||
m_layoutField(parentResponder, layout, layoutFieldDelegate),
|
||||
m_textBuffer(textBuffer),
|
||||
m_textBufferLength(textBufferLength)
|
||||
{
|
||||
@@ -15,9 +15,9 @@ ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer,
|
||||
m_textField.setBackgroundColor(KDColorWhite);
|
||||
m_textField.setColorsBackground(true);
|
||||
// Initialize layout field
|
||||
m_expressionLayoutField.setMargins(k_verticalMargin, k_horizontalMargin, k_verticalMargin, k_horizontalMargin);
|
||||
m_expressionLayoutField.setBackgroundColor(KDColorWhite);
|
||||
m_expressionLayoutField.setColorsBackground(true);
|
||||
m_layoutField.setMargins(k_verticalMargin, k_horizontalMargin, k_verticalMargin, k_horizontalMargin);
|
||||
m_layoutField.setBackgroundColor(KDColorWhite);
|
||||
m_layoutField.setColorsBackground(true);
|
||||
}
|
||||
|
||||
void ExpressionField::setEditing(bool isEditing, bool reinitDraftBuffer) {
|
||||
@@ -25,19 +25,19 @@ void ExpressionField::setEditing(bool isEditing, bool reinitDraftBuffer) {
|
||||
m_textField.setEditing(isEditing, reinitDraftBuffer);
|
||||
} else {
|
||||
if (reinitDraftBuffer) {
|
||||
m_expressionLayoutField.clearLayout();
|
||||
m_layoutField.clearLayout();
|
||||
}
|
||||
m_expressionLayoutField.setEditing(isEditing);
|
||||
m_layoutField.setEditing(isEditing);
|
||||
}
|
||||
}
|
||||
|
||||
bool ExpressionField::isEditing() const {
|
||||
return editionIsInTextField() ? m_textField.isEditing() : m_expressionLayoutField.isEditing();
|
||||
return editionIsInTextField() ? m_textField.isEditing() : m_layoutField.isEditing();
|
||||
}
|
||||
|
||||
const char * ExpressionField::text() {
|
||||
if (!editionIsInTextField()) {
|
||||
m_expressionLayoutField.writeTextInBuffer(m_textBuffer, m_textBufferLength);
|
||||
m_layoutField.writeTextInBuffer(m_textBuffer, m_textBufferLength);
|
||||
}
|
||||
return m_textBuffer;
|
||||
}
|
||||
@@ -46,8 +46,8 @@ void ExpressionField::setText(const char * text) {
|
||||
if (editionIsInTextField()) {
|
||||
m_textField.setText(text);
|
||||
} else {
|
||||
m_expressionLayoutField.clearLayout();
|
||||
m_expressionLayoutField.handleEventWithText(text, false, true);
|
||||
m_layoutField.clearLayout();
|
||||
m_layoutField.handleEventWithText(text, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,17 +56,17 @@ View * ExpressionField::subviewAtIndex(int index) {
|
||||
if (editionIsInTextField()) {
|
||||
return &m_textField;
|
||||
}
|
||||
return &m_expressionLayoutField;
|
||||
return &m_layoutField;
|
||||
}
|
||||
|
||||
void ExpressionField::layoutSubviews() {
|
||||
KDRect inputViewFrame(0, k_separatorThickness, bounds().width(), bounds().height() - k_separatorThickness);
|
||||
if (editionIsInTextField()) {
|
||||
m_textField.setFrame(inputViewFrame);
|
||||
m_expressionLayoutField.setFrame(KDRectZero);
|
||||
m_layoutField.setFrame(KDRectZero);
|
||||
return;
|
||||
}
|
||||
m_expressionLayoutField.setFrame(inputViewFrame);
|
||||
m_layoutField.setFrame(inputViewFrame);
|
||||
m_textField.setFrame(KDRectZero);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ void ExpressionField::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
}
|
||||
|
||||
bool ExpressionField::handleEvent(Ion::Events::Event event) {
|
||||
return editionIsInTextField() ? m_textField.handleEvent(event) : m_expressionLayoutField.handleEvent(event);
|
||||
return editionIsInTextField() ? m_textField.handleEvent(event) : m_layoutField.handleEvent(event);
|
||||
}
|
||||
|
||||
KDSize ExpressionField::minimalSizeForOptimalDisplay() const {
|
||||
@@ -93,7 +93,7 @@ bool ExpressionField::editionIsInTextField() const {
|
||||
}
|
||||
|
||||
bool ExpressionField::isEmpty() const {
|
||||
return editionIsInTextField() ? (m_textField.draftTextLength() == 0) : !m_expressionLayoutField.hasText();
|
||||
return editionIsInTextField() ? (m_textField.draftTextLength() == 0) : !m_layoutField.hasText();
|
||||
}
|
||||
|
||||
bool ExpressionField::heightIsMaximal() const {
|
||||
@@ -104,7 +104,7 @@ bool ExpressionField::handleEventWithText(const char * text, bool indentation, b
|
||||
if (editionIsInTextField()) {
|
||||
return m_textField.handleEventWithText(text, indentation, forceCursorRightOfText);
|
||||
} else {
|
||||
return m_expressionLayoutField.handleEventWithText(text, indentation, forceCursorRightOfText);
|
||||
return m_layoutField.handleEventWithText(text, indentation, forceCursorRightOfText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ KDCoordinate ExpressionField::inputViewHeight() const {
|
||||
return k_separatorThickness
|
||||
+ (editionIsInTextField() ? k_textFieldHeight :
|
||||
min(maximalHeight(),
|
||||
max(k_textFieldHeight, m_expressionLayoutField.minimalSizeForOptimalDisplay().height() + 2*k_verticalMargin )));
|
||||
max(k_textFieldHeight, m_layoutField.minimalSizeForOptimalDisplay().height() + 2*k_verticalMargin )));
|
||||
}
|
||||
|
||||
KDCoordinate ExpressionField::maximalHeight() const {
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
#include <escher/expression_layout_field.h>
|
||||
#include <apps/i18n.h>
|
||||
#include <escher/clipboard.h>
|
||||
#include <escher/text_field.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/expression_layout_cursor.h>
|
||||
#include <poincare/src/layout/matrix_layout.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
ExpressionLayoutField::ExpressionLayoutField(Responder * parentResponder, Poincare::ExpressionLayout * expressionLayout, ExpressionLayoutFieldDelegate * delegate) :
|
||||
ScrollableView(parentResponder, &m_contentView, this),
|
||||
m_contentView(expressionLayout),
|
||||
m_delegate(delegate)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::isEditing() const {
|
||||
return m_contentView.isEditing();
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::setEditing(bool isEditing) {
|
||||
m_contentView.setEditing(isEditing);
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::clearLayout() {
|
||||
m_contentView.clearLayout();
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::scrollToCursor() {
|
||||
scrollToBaselinedRect(m_contentView.cursorRect(), m_contentView.cursor()->baseline());
|
||||
}
|
||||
|
||||
Toolbox * ExpressionLayoutField::toolbox() {
|
||||
if (m_delegate) {
|
||||
return m_delegate->toolboxForExpressionLayoutField(this);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::handleEvent(Ion::Events::Event event) {
|
||||
bool didHandleEvent = false;
|
||||
bool shouldRecomputeLayout = m_contentView.cursor()->showEmptyLayoutIfNeeded();
|
||||
bool moveEventChangedLayout = false;
|
||||
if (privateHandleMoveEvent(event, &moveEventChangedLayout)) {
|
||||
if (!isEditing()) {
|
||||
setEditing(true);
|
||||
}
|
||||
shouldRecomputeLayout = shouldRecomputeLayout || moveEventChangedLayout;
|
||||
didHandleEvent = true;
|
||||
} else if (privateHandleEvent(event)) {
|
||||
shouldRecomputeLayout = true;
|
||||
didHandleEvent = true;
|
||||
}
|
||||
if (didHandleEvent) {
|
||||
shouldRecomputeLayout = m_contentView.cursor()->hideEmptyLayoutIfNeeded() || shouldRecomputeLayout;
|
||||
if (!shouldRecomputeLayout) {
|
||||
m_contentView.cursorPositionChanged();
|
||||
scrollToCursor();
|
||||
} else {
|
||||
reload();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
m_contentView.cursor()->hideEmptyLayoutIfNeeded();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::expressionLayoutFieldShouldFinishEditing(Ion::Events::Event event) {
|
||||
return m_delegate->expressionLayoutFieldShouldFinishEditing(this, event);
|
||||
}
|
||||
|
||||
KDSize ExpressionLayoutField::minimalSizeForOptimalDisplay() const {
|
||||
KDSize contentViewSize = m_contentView.minimalSizeForOptimalDisplay();
|
||||
return KDSize(contentViewSize.width(), contentViewSize.height());
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::privateHandleMoveEvent(Ion::Events::Event event, bool * shouldRecomputeLayout) {
|
||||
Poincare::ExpressionLayoutCursor result;
|
||||
if (event == Ion::Events::Left) {
|
||||
result = m_contentView.cursor()->cursorOnLeft(shouldRecomputeLayout);
|
||||
} else if (event == Ion::Events::Right) {
|
||||
result = m_contentView.cursor()->cursorOnRight(shouldRecomputeLayout);
|
||||
} else if (event == Ion::Events::Up) {
|
||||
result = m_contentView.cursor()->cursorAbove(shouldRecomputeLayout);
|
||||
} else if (event == Ion::Events::Down) {
|
||||
result = m_contentView.cursor()->cursorUnder(shouldRecomputeLayout);
|
||||
} else if (event == Ion::Events::ShiftLeft) {
|
||||
*shouldRecomputeLayout = true;
|
||||
if (m_contentView.cursor()->pointedExpressionLayout()->removeGreySquaresFromAllMatrixAncestors()) {
|
||||
*shouldRecomputeLayout = true;
|
||||
}
|
||||
result.setPointedExpressionLayout(expressionLayout());
|
||||
result.setPosition(Poincare::ExpressionLayoutCursor::Position::Left);
|
||||
} else if (event == Ion::Events::ShiftRight) {
|
||||
if (m_contentView.cursor()->pointedExpressionLayout()->removeGreySquaresFromAllMatrixAncestors()) {
|
||||
*shouldRecomputeLayout = true;
|
||||
}
|
||||
result.setPointedExpressionLayout(expressionLayout());
|
||||
result.setPosition(Poincare::ExpressionLayoutCursor::Position::Right);
|
||||
}
|
||||
if (result.isDefined()) {
|
||||
m_contentView.setCursor(result);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::privateHandleEvent(Ion::Events::Event event) {
|
||||
if (m_delegate && m_delegate->expressionLayoutFieldDidReceiveEvent(this, event)) {
|
||||
return true;
|
||||
}
|
||||
if (Responder::handleEvent(event)) {
|
||||
/* The only event Responder handles is 'Toolbox' displaying. In that case,
|
||||
* the ExpressionLayoutField is forced into editing mode. */
|
||||
if (!isEditing()) {
|
||||
setEditing(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (isEditing() && expressionLayoutFieldShouldFinishEditing(event)) {
|
||||
setEditing(false);
|
||||
if (m_delegate->expressionLayoutFieldDidFinishEditing(this, expressionLayout(), event)) {
|
||||
clearLayout();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ((event == Ion::Events::OK || event == Ion::Events::EXE) && !isEditing()) {
|
||||
setEditing(true);
|
||||
m_contentView.cursor()->setPointedExpressionLayout(expressionLayout());
|
||||
m_contentView.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Right);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Back && isEditing()) {
|
||||
clearLayout();
|
||||
setEditing(false);
|
||||
m_delegate->expressionLayoutFieldDidAbortEditing(this);
|
||||
return true;
|
||||
}
|
||||
if (event.hasText() || event == Ion::Events::Paste || event == Ion::Events::Backspace) {
|
||||
if (!isEditing()) {
|
||||
setEditing(true);
|
||||
}
|
||||
if (event.hasText()) {
|
||||
handleEventWithText(event.text());
|
||||
} else if (event == Ion::Events::Paste) {
|
||||
handleEventWithText(Clipboard::sharedClipboard()->storedText(), false, true);
|
||||
} else {
|
||||
assert(event == Ion::Events::Backspace);
|
||||
m_contentView.cursor()->performBackspace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Clear && isEditing()) {
|
||||
clearLayout();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::reload() {
|
||||
KDSize previousSize = minimalSizeForOptimalDisplay();
|
||||
expressionLayout()->invalidAllSizesPositionsAndBaselines();
|
||||
KDSize newSize = minimalSizeForOptimalDisplay();
|
||||
if (m_delegate && previousSize.height() != newSize.height()) {
|
||||
m_delegate->expressionLayoutFieldDidChangeSize(this);
|
||||
}
|
||||
m_contentView.cursorPositionChanged();
|
||||
scrollToCursor();
|
||||
markRectAsDirty(bounds());
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::hasText() const {
|
||||
return expressionLayout()->hasText();
|
||||
}
|
||||
|
||||
int ExpressionLayoutField::writeTextInBuffer(char * buffer, int bufferLength) {
|
||||
return expressionLayout()->writeTextInBuffer(buffer, bufferLength);
|
||||
}
|
||||
|
||||
bool ExpressionLayoutField::handleEventWithText(const char * text, bool indentation, bool forceCursorRightOfText) {
|
||||
if (text[0] == 0) {
|
||||
// The text is empty
|
||||
return true;
|
||||
}
|
||||
|
||||
int currentNumberOfLayouts = m_contentView.expressionView()->numberOfLayouts();
|
||||
if (currentNumberOfLayouts >= k_maxNumberOfLayouts - 6) {
|
||||
/* We add -6 because in some cases (Ion::Events::Division,
|
||||
* Ion::Events::Exp...) we let the layout cursor handle the layout insertion
|
||||
* and these events may add at most 6 layouts (e.g *10^•). */
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle special cases
|
||||
if (strcmp(text, Ion::Events::Division.text()) == 0) {
|
||||
m_contentView.cursor()->addFractionLayoutAndCollapseSiblings();
|
||||
} else if (strcmp(text, Ion::Events::Exp.text()) == 0) {
|
||||
m_contentView.cursor()->addEmptyExponentialLayout();
|
||||
} else if (strcmp(text, Ion::Events::Power.text()) == 0) {
|
||||
m_contentView.cursor()->addEmptyPowerLayout();
|
||||
} else if (strcmp(text, Ion::Events::Sqrt.text()) == 0) {
|
||||
m_contentView.cursor()->addEmptySquareRootLayout();
|
||||
} else if (strcmp(text, Ion::Events::Square.text()) == 0) {
|
||||
m_contentView.cursor()->addEmptySquarePowerLayout();
|
||||
} else if (strcmp(text, Ion::Events::EE.text()) == 0) {
|
||||
m_contentView.cursor()->addEmptyTenPowerLayout();
|
||||
} else if ((strcmp(text, "[") == 0) || (strcmp(text, "]") == 0)) {
|
||||
m_contentView.cursor()->addEmptyMatrixLayout();
|
||||
} else {
|
||||
Poincare::Expression * resultExpression = Poincare::Expression::parse(text);
|
||||
if (resultExpression == nullptr) {
|
||||
m_contentView.cursor()->insertText(text);
|
||||
return true;
|
||||
}
|
||||
Poincare::ExpressionLayout * resultLayout = resultExpression->createLayout();
|
||||
delete resultExpression;
|
||||
if (currentNumberOfLayouts + resultLayout->numberOfDescendants(true) >= k_maxNumberOfLayouts) {
|
||||
delete resultLayout;
|
||||
return true;
|
||||
}
|
||||
// Find the pointed layout.
|
||||
Poincare::ExpressionLayout * pointedLayout = nullptr;
|
||||
if (strcmp(text, I18n::translate(I18n::Message::RandomCommandWithArg)) == 0) {
|
||||
/* Special case: if the text is "random()", the cursor should not be set
|
||||
* inside the parentheses. */
|
||||
pointedLayout = resultLayout;
|
||||
} else if (resultLayout->isHorizontal()) {
|
||||
/* If the layout is horizontal, pick the first open parenthesis. For now,
|
||||
* all horizontal layouts in MathToolbox have parentheses. */
|
||||
for (int i = 0; i < resultLayout->numberOfChildren(); i++) {
|
||||
if (resultLayout->editableChild(i)->isLeftParenthesis()) {
|
||||
pointedLayout = resultLayout->editableChild(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Insert the layout. If pointedLayout is nullptr, the cursor will be on the
|
||||
* right of the inserted layout. */
|
||||
insertLayoutAtCursor(resultLayout, pointedLayout, forceCursorRightOfText);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Poincare::ExpressionLayout * ExpressionLayoutField::expressionLayout() const {
|
||||
return m_contentView.expressionView()->expressionLayout();
|
||||
}
|
||||
|
||||
char ExpressionLayoutField::XNTChar() {
|
||||
return m_contentView.cursor()->pointedExpressionLayout()->XNTChar();
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::setBackgroundColor(KDColor c) {
|
||||
ScrollableView::setBackgroundColor(c);
|
||||
m_contentView.setBackgroundColor(c);
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::scrollRightOfLayout(Poincare::ExpressionLayout * layout) {
|
||||
KDRect layoutRect(layout->absoluteOrigin().translatedBy(m_contentView.expressionView()->drawingOrigin()), layout->size());
|
||||
scrollToBaselinedRect(layoutRect, layout->baseline());
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::scrollToBaselinedRect(KDRect rect, KDCoordinate baseline) {
|
||||
scrollToContentRect(rect, true);
|
||||
// Show the rect area around its baseline
|
||||
KDCoordinate underBaseline = rect.height() - baseline;
|
||||
KDCoordinate minAroundBaseline = min(baseline, underBaseline);
|
||||
minAroundBaseline = min(minAroundBaseline, bounds().height() / 2);
|
||||
KDRect balancedRect(rect.x(), rect.y() + baseline - minAroundBaseline, rect.width(), 2 * minAroundBaseline);
|
||||
scrollToContentRect(balancedRect, true);
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::insertLayoutAtCursor(Poincare::ExpressionLayout * layout, Poincare::ExpressionLayout * pointedLayout, bool forceCursorRightOfLayout) {
|
||||
if (layout == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_contentView.cursor()->showEmptyLayoutIfNeeded();
|
||||
bool layoutWillBeMerged = layout->isHorizontal();
|
||||
Poincare::ExpressionLayout * lastMergedLayoutChild = layoutWillBeMerged ? layout->editableChild(layout->numberOfChildren()-1) : nullptr;
|
||||
m_contentView.cursor()->addLayoutAndMoveCursor(layout);
|
||||
if (!forceCursorRightOfLayout) {
|
||||
if (pointedLayout != nullptr && (pointedLayout != layout || !layoutWillBeMerged)) {
|
||||
m_contentView.cursor()->setPointedExpressionLayout(pointedLayout);
|
||||
m_contentView.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Right);
|
||||
} else if (!layoutWillBeMerged) {
|
||||
m_contentView.cursor()->setPointedExpressionLayout(layout->layoutToPointWhenInserting());
|
||||
m_contentView.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Right);
|
||||
}
|
||||
} else if (!layoutWillBeMerged) {
|
||||
m_contentView.cursor()->setPointedExpressionLayout(layout);
|
||||
m_contentView.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Right);
|
||||
}
|
||||
m_contentView.cursor()->pointedExpressionLayout()->addGreySquaresToAllMatrixAncestors();
|
||||
m_contentView.cursor()->hideEmptyLayoutIfNeeded();
|
||||
reload();
|
||||
if (!layoutWillBeMerged) {
|
||||
scrollRightOfLayout(layout);
|
||||
} else {
|
||||
assert(lastMergedLayoutChild != nullptr);
|
||||
scrollRightOfLayout(lastMergedLayoutChild);
|
||||
}
|
||||
scrollToCursor();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
#include <escher/expression_layout_field.h>
|
||||
#include <kandinsky/rect.h>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
ExpressionLayoutField::ContentView::ContentView(ExpressionLayout * expressionLayout) :
|
||||
m_cursor(expressionLayout, ExpressionLayoutCursor::Position::Right),
|
||||
m_expressionView(0.0f, 0.5f, KDColorBlack, KDColorWhite),
|
||||
m_cursorView(),
|
||||
m_isEditing(false)
|
||||
{
|
||||
m_expressionView.setExpressionLayout(expressionLayout);
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::ContentView::setEditing(bool isEditing) {
|
||||
m_isEditing = isEditing;
|
||||
markRectAsDirty(bounds());
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::ContentView::setBackgroundColor(KDColor c) {
|
||||
m_expressionView.setBackgroundColor(c);
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::ContentView::cursorPositionChanged() {
|
||||
layoutCursorSubview();
|
||||
}
|
||||
|
||||
KDRect ExpressionLayoutField::ContentView::cursorRect() {
|
||||
return m_cursorView.frame();
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::ContentView::clearLayout() {
|
||||
m_cursor.clearLayout();
|
||||
}
|
||||
|
||||
KDSize ExpressionLayoutField::ContentView::minimalSizeForOptimalDisplay() const {
|
||||
KDSize evSize = m_expressionView.minimalSizeForOptimalDisplay();
|
||||
return KDSize(evSize.width() + ExpressionLayoutCursor::k_cursorWidth, evSize.height());
|
||||
}
|
||||
|
||||
View * ExpressionLayoutField::ContentView::subviewAtIndex(int index) {
|
||||
assert(index >= 0 && index < 2);
|
||||
View * m_views[] = {&m_expressionView, &m_cursorView};
|
||||
return m_views[index];
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::ContentView::layoutSubviews() {
|
||||
m_expressionView.setFrame(bounds());
|
||||
layoutCursorSubview();
|
||||
}
|
||||
|
||||
void ExpressionLayoutField::ContentView::layoutCursorSubview() {
|
||||
if (!m_isEditing) {
|
||||
m_cursorView.setFrame(KDRectZero);
|
||||
return;
|
||||
}
|
||||
KDPoint expressionViewOrigin = m_expressionView.absoluteDrawingOrigin();
|
||||
ExpressionLayout * pointedLayout = m_cursor.pointedExpressionLayout();
|
||||
ExpressionLayoutCursor::Position cursorPosition = m_cursor.position();
|
||||
ExpressionLayoutCursor eqCursor = pointedLayout->equivalentCursor(m_cursor);
|
||||
if (pointedLayout->hasChild(eqCursor.pointedExpressionLayout())) {
|
||||
pointedLayout = eqCursor.pointedExpressionLayout();
|
||||
cursorPosition = eqCursor.position();
|
||||
}
|
||||
KDPoint cursoredExpressionViewOrigin = pointedLayout->absoluteOrigin();
|
||||
KDCoordinate cursorX = expressionViewOrigin.x() + cursoredExpressionViewOrigin.x();
|
||||
if (cursorPosition == ExpressionLayoutCursor::Position::Right) {
|
||||
cursorX += pointedLayout->size().width();
|
||||
}
|
||||
KDPoint cursorTopLeftPosition(cursorX, expressionViewOrigin.y() + cursoredExpressionViewOrigin.y() + pointedLayout->baseline() - m_cursor.baseline());
|
||||
m_cursorView.setFrame(KDRect(cursorTopLeftPosition, ExpressionLayoutCursor::k_cursorWidth, m_cursor.cursorHeight()));
|
||||
}
|
||||
@@ -18,7 +18,7 @@ void ExpressionTableCell::setHighlighted(bool highlight) {
|
||||
m_labelExpressionView.setBackgroundColor(backgroundColor);
|
||||
}
|
||||
|
||||
void ExpressionTableCell::setExpressionLayout(Poincare::ExpressionLayout * expressionLayout) {
|
||||
m_labelExpressionView.setExpressionLayout(expressionLayout);
|
||||
void ExpressionTableCell::setLayoutRef(Poincare::LayoutRef layoutR) {
|
||||
m_labelExpressionView.setLayoutRef(layoutR);
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using namespace Poincare;
|
||||
|
||||
ExpressionView::ExpressionView(float horizontalAlignment, float verticalAlignment,
|
||||
KDColor textColor, KDColor backgroundColor) :
|
||||
m_expressionLayout(nullptr),
|
||||
m_layoutRef(nullptr),
|
||||
m_horizontalAlignment(horizontalAlignment),
|
||||
m_verticalAlignment(verticalAlignment),
|
||||
@@ -12,16 +11,6 @@ ExpressionView::ExpressionView(float horizontalAlignment, float verticalAlignmen
|
||||
{
|
||||
}
|
||||
|
||||
//TODO remove
|
||||
ExpressionLayout * ExpressionView::expressionLayout() const {
|
||||
return m_expressionLayout;
|
||||
}
|
||||
|
||||
void ExpressionView::setExpressionLayout(ExpressionLayout * expressionLayout) {
|
||||
m_expressionLayout = expressionLayout;
|
||||
markRectAsDirty(bounds());
|
||||
}
|
||||
|
||||
void ExpressionView::setLayoutRef(LayoutRef layoutR) {
|
||||
m_layoutRef = layoutR;
|
||||
markRectAsDirty(bounds());
|
||||
@@ -48,18 +37,18 @@ void ExpressionView::setAlignment(float horizontalAlignment, float verticalAlign
|
||||
}
|
||||
|
||||
int ExpressionView::numberOfLayouts() const {
|
||||
return m_expressionLayout->numberOfDescendants(true);
|
||||
return m_layoutRef.numberOfDescendants(true);
|
||||
}
|
||||
|
||||
KDSize ExpressionView::minimalSizeForOptimalDisplay() const {
|
||||
if (m_expressionLayout == nullptr) {
|
||||
if (!m_layoutRef.isDefined()) {
|
||||
return KDSizeZero;
|
||||
}
|
||||
return m_expressionLayout->size();
|
||||
return m_layoutRef.layoutSize();
|
||||
}
|
||||
|
||||
KDPoint ExpressionView::drawingOrigin() const {
|
||||
KDSize expressionSize = m_expressionLayout->size();
|
||||
KDSize expressionSize = m_layoutRef.layoutSize();
|
||||
return KDPoint(m_horizontalAlignment*(m_frame.width() - expressionSize.width()), max(0, (m_frame.height() - expressionSize.height())/2));
|
||||
}
|
||||
|
||||
@@ -69,7 +58,7 @@ KDPoint ExpressionView::absoluteDrawingOrigin() const {
|
||||
|
||||
void ExpressionView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, m_backgroundColor);
|
||||
if (m_expressionLayout != nullptr) {
|
||||
m_expressionLayout->draw(ctx, drawingOrigin(), m_textColor, m_backgroundColor);
|
||||
if (m_layoutRef.isDefined()) {
|
||||
m_layoutRef.draw(ctx, drawingOrigin(), m_textColor, m_backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
#include <escher/input_view_controller.h>
|
||||
#include <escher/app.h>
|
||||
#include <escher/palette.h>
|
||||
#include <poincare/src/layout/horizontal_layout.h>
|
||||
#include <poincare/horizontal_layout_node.h>
|
||||
#include <assert.h>
|
||||
|
||||
InputViewController::ExpressionFieldController::ExpressionFieldController(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) :
|
||||
InputViewController::ExpressionFieldController::ExpressionFieldController(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
|
||||
ViewController(parentResponder),
|
||||
m_layout(new Poincare::HorizontalLayout()),
|
||||
m_expressionField(this, m_textBuffer, k_bufferLength, m_layout, textFieldDelegate, expressionLayoutFieldDelegate)
|
||||
m_layout(Poincare::HorizontalLayoutRef()),
|
||||
m_expressionField(this, m_textBuffer, k_bufferLength, m_layout, textFieldDelegate, layoutFieldDelegate)
|
||||
{
|
||||
m_textBuffer[0] = 0;
|
||||
}
|
||||
|
||||
InputViewController::ExpressionFieldController::~ExpressionFieldController() {
|
||||
delete m_layout;
|
||||
}
|
||||
|
||||
void InputViewController::ExpressionFieldController::didBecomeFirstResponder() {
|
||||
app()->setFirstResponder(&m_expressionField);
|
||||
}
|
||||
|
||||
InputViewController::InputViewController(Responder * parentResponder, ViewController * child, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) :
|
||||
InputViewController::InputViewController(Responder * parentResponder, ViewController * child, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
|
||||
ModalViewController(parentResponder, child),
|
||||
m_expressionFieldController(this, this, this),
|
||||
m_successAction(Invocation(nullptr, nullptr)),
|
||||
m_failureAction(Invocation(nullptr, nullptr)),
|
||||
m_textFieldDelegate(textFieldDelegate),
|
||||
m_expressionLayoutFieldDelegate(expressionLayoutFieldDelegate),
|
||||
m_layoutFieldDelegate(layoutFieldDelegate),
|
||||
m_inputViewHeightIsMaximal(false)
|
||||
{
|
||||
}
|
||||
@@ -74,27 +70,27 @@ Toolbox * InputViewController::toolboxForTextInput(TextInput * input) {
|
||||
return m_textFieldDelegate->toolboxForTextInput(input);
|
||||
}
|
||||
|
||||
bool InputViewController::expressionLayoutFieldShouldFinishEditing(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
bool InputViewController::layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) {
|
||||
return event == Ion::Events::OK || event == Ion::Events::EXE;
|
||||
}
|
||||
|
||||
bool InputViewController::expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) {
|
||||
return m_expressionLayoutFieldDelegate->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event);
|
||||
bool InputViewController::layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) {
|
||||
return m_layoutFieldDelegate->layoutFieldDidReceiveEvent(layoutField, event);
|
||||
}
|
||||
|
||||
bool InputViewController::expressionLayoutFieldDidFinishEditing(ExpressionLayoutField * expressionLayoutField, Poincare::ExpressionLayout * layout, Ion::Events::Event event) {
|
||||
bool InputViewController::layoutFieldDidFinishEditing(LayoutField * layoutField, Poincare::LayoutRef layoutR, Ion::Events::Event event) {
|
||||
inputViewDidFinishEditing();
|
||||
m_expressionLayoutFieldDelegate->expressionLayoutFieldDidFinishEditing(expressionLayoutField, layout, event);
|
||||
m_layoutFieldDelegate->layoutFieldDidFinishEditing(layoutField, layoutR, event);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputViewController::expressionLayoutFieldDidAbortEditing(ExpressionLayoutField * expressionLayoutField) {
|
||||
bool InputViewController::layoutFieldDidAbortEditing(LayoutField * layoutField) {
|
||||
inputViewDidAbortEditing();
|
||||
m_expressionLayoutFieldDelegate->expressionLayoutFieldDidAbortEditing(expressionLayoutField);
|
||||
m_layoutFieldDelegate->layoutFieldDidAbortEditing(layoutField);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputViewController::expressionLayoutFieldDidChangeSize(ExpressionLayoutField * expressionLayoutField) {
|
||||
void InputViewController::layoutFieldDidChangeSize(LayoutField * layoutField) {
|
||||
/* Reload the view only if the ExpressionField height actually changes, i.e.
|
||||
* not if the height is already maximal and stays maximal. */
|
||||
bool newInputViewHeightIsMaximal = m_expressionFieldController.expressionField()->heightIsMaximal();
|
||||
@@ -104,8 +100,8 @@ void InputViewController::expressionLayoutFieldDidChangeSize(ExpressionLayoutFie
|
||||
}
|
||||
}
|
||||
|
||||
Toolbox * InputViewController::toolboxForExpressionLayoutField(ExpressionLayoutField * expressionLayoutField) {
|
||||
return m_expressionLayoutFieldDelegate->toolboxForExpressionLayoutField(expressionLayoutField);
|
||||
Toolbox * InputViewController::toolboxForLayoutField(LayoutField * layoutField) {
|
||||
return m_layoutFieldDelegate->toolboxForLayoutField(layoutField);
|
||||
}
|
||||
|
||||
void InputViewController::inputViewDidFinishEditing() {
|
||||
|
||||
@@ -17,8 +17,8 @@ void MessageTableCellWithChevronAndExpression::setHighlighted(bool highlight) {
|
||||
m_subtitleView.setBackgroundColor(backgroundColor);
|
||||
}
|
||||
|
||||
void MessageTableCellWithChevronAndExpression::setExpressionLayout(Poincare::ExpressionLayout * expressionLayout) {
|
||||
m_subtitleView.setExpressionLayout(expressionLayout);
|
||||
void MessageTableCellWithChevronAndExpression::setLayoutRef(Poincare::LayoutRef layoutR) {
|
||||
m_subtitleView.setLayoutRef(layoutR);
|
||||
reloadCell();
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ public:
|
||||
TreeReference<T>::replaceChildAtIndex(oldChildIndex, newChild);
|
||||
}
|
||||
|
||||
void draw(KDContext * ctx, KDPoint p, KDColor expressionColor = KDColorBlack, KDColor backgroundColor = KDColorWhite) {
|
||||
return this->typedNode()->draw(ctx, p, expressionColor, backgroundColor);
|
||||
}
|
||||
|
||||
bool isHorizontal() const { return this->typedNode()->isHorizontal(); }
|
||||
bool isLeftParenthesis() const { return this->typedNode()->isLeftParenthesis(); }
|
||||
bool hasText() { return this->typedNode()->hasText(); }
|
||||
|
||||
@@ -222,7 +222,7 @@ LayoutRef Decimal::privateCreateLayout(PrintFloat::Mode floatDisplayMode, Comple
|
||||
return CharLayoutRef('a'); //TODO
|
||||
/*char buffer[k_maxBufferSize];
|
||||
int numberOfChars = convertToText(buffer, k_maxBufferSize, floatDisplayMode, PrintFloat::k_numberOfStoredSignificantDigits);
|
||||
return LayoutEngine::createStringLayout(buffer, numberOfChars);
|
||||
return LayoutEngine::createStringLayout(buffer, numberOfChars);*/
|
||||
}
|
||||
|
||||
Expression * Decimal::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
@@ -243,7 +243,7 @@ Expression * Decimal::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
} else {
|
||||
denominator = Integer::Power(Integer(10), Integer(numberOfDigits-1-m_exponent));
|
||||
}
|
||||
return replaceWith(new Rational(numerator, denominator), true);*/
|
||||
return replaceWith(new Rational(numerator, denominator), true);
|
||||
}
|
||||
|
||||
Expression * Decimal::shallowBeautify(Context & context, AngleUnit angleUnit) {
|
||||
|
||||
Reference in New Issue
Block a user