[escher] TextField: all text fields use the same draft text buffer

This commit is contained in:
Émilie Feral
2019-08-09 16:26:53 +02:00
parent 70e3bcd8c1
commit 12060e2ae7
55 changed files with 134 additions and 167 deletions

View File

@@ -12,9 +12,8 @@ namespace Calculation {
EditExpressionController::ContentView::ContentView(Responder * parentResponder, TableView * subview, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
View(),
m_mainView(subview),
m_expressionField(parentResponder, m_textBody, k_bufferLength, inputEventHandlerDelegate, textFieldDelegate, layoutFieldDelegate)
m_expressionField(parentResponder, inputEventHandlerDelegate, textFieldDelegate, layoutFieldDelegate)
{
m_textBody[0] = 0;
}
View * EditExpressionController::ContentView::subviewAtIndex(int index) {

View File

@@ -44,9 +44,7 @@ private:
View * subviewAtIndex(int index) override;
void layoutSubviews() override;
private:
static constexpr int k_bufferLength = TextField::maxBufferSize();
TableView * m_mainView;
char m_textBody[k_bufferLength];
ExpressionField m_expressionField;
};
void reloadView();

View File

@@ -9,9 +9,8 @@ namespace Code {
ConsoleEditCell::ConsoleEditCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate) :
HighlightCell(),
Responder(parentResponder),
m_textBuffer{0},
m_promptView(ConsoleController::k_font, nullptr, 0, 0.5),
m_textField(this, m_textBuffer, m_textBuffer, TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, false, ConsoleController::k_font)
m_textField(this, nullptr, TextField::maxBufferSize(), TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, ConsoleController::k_font)
{
}

View File

@@ -33,7 +33,6 @@ public:
bool insertText(const char * text);
void setPrompt(const char * prompt);
private:
char m_textBuffer[TextField::maxBufferSize()];
PointerTextView m_promptView;
TextField m_textField;
};

View File

@@ -126,8 +126,11 @@ void MenuController::renameSelectedScript() {
ScriptNameCell * myCell = static_cast<ScriptNameCell *>(m_selectableTableView.selectedCell());
Container::activeApp()->setFirstResponder(myCell);
myCell->setHighlighted(false);
myCell->textField()->setEditing(true);
myCell->textField()->setCursorLocation(myCell->textField()->text() + strlen(myCell->textField()->text()));
TextField * tf = myCell->textField();
const char * previousText = tf->text();
tf->setEditing(true);
tf->setText(previousText);
tf->setCursorLocation(tf->text() + strlen(previousText));
}
void MenuController::deleteScript(Script script) {

View File

@@ -15,8 +15,10 @@ public:
ScriptNameCell(Responder * parentResponder = nullptr, TextFieldDelegate * delegate = nullptr) :
EvenOddCell(),
Responder(parentResponder),
m_textField(k_extensionLength, this, m_textBody, m_textBody, TextField::maxBufferSize(), nullptr, delegate, false)
{}
m_textField(k_extensionLength, this, m_textBody, TextField::maxBufferSize(), TextField::maxBufferSize(), nullptr, delegate)
{
m_textBody[0] = 0;
}
Shared::TextFieldWithExtension * textField() { return &m_textField; }

View File

@@ -10,7 +10,7 @@ static inline float maxFloat(float x, float y) { return x > y ? x : y; }
TextFieldFunctionTitleCell::TextFieldFunctionTitleCell(ListController * listController, Orientation orientation, const KDFont * font) :
Shared::FunctionTitleCell(orientation),
Responder(listController),
m_textField(Shared::Function::k_parenthesedArgumentLength, this, m_textFieldBuffer, m_textFieldBuffer, k_textFieldBufferSize, nullptr, listController, false, font, 1.0f, 0.5f)
m_textField(Shared::Function::k_parenthesedArgumentLength, this, m_textFieldBuffer, k_textFieldBufferSize, k_textFieldBufferSize, nullptr, listController, font, 1.0f, 0.5f)
{
}

View File

@@ -8,9 +8,9 @@ namespace Probability {
static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; }
static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; }
CalculationCell::CalculationCell(Responder * parentResponder, char * draftTextBuffer, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate) :
CalculationCell::CalculationCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate) :
m_text(KDFont::LargeFont, I18n::Message::Default, 0.5f, 0.5f),
m_calculation(parentResponder, inputEventHandlerDelegate, textFieldDelegate, draftTextBuffer),
m_calculation(parentResponder, inputEventHandlerDelegate, textFieldDelegate),
m_isResponder(true)
{
}

View File

@@ -7,7 +7,7 @@ namespace Probability {
class CalculationCell : public HighlightCell {
public:
CalculationCell(Responder * parentResponder = nullptr, char * draftTextBuffer = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr);
CalculationCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr);
Responder * responder() override;
void setResponder(bool shouldbeResponder);
void setHighlighted(bool highlight) override;

View File

@@ -59,7 +59,6 @@ CalculationController::CalculationController(Responder * parentResponder, InputE
m_contentView(&m_selectableTableView, law, calculation),
m_selectableTableView(this),
m_imageCell(&m_selectableTableView, law, calculation, this),
m_draftTextBuffer{},
m_calculation(calculation),
m_law(law)
{
@@ -74,7 +73,6 @@ CalculationController::CalculationController(Responder * parentResponder, InputE
for (int i = 0; i < k_numberOfCalculationCells; i++) {
m_calculationCells[i].editableTextCell()->setParentResponder(&m_selectableTableView);
m_calculationCells[i].editableTextCell()->textField()->setDelegates(inputEventHandlerDelegate, this);
m_calculationCells[i].editableTextCell()->textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -66,7 +66,6 @@ private:
ContentView m_contentView;
SelectableTableView m_selectableTableView;
ResponderImageCell m_imageCell;
char m_draftTextBuffer[TextField::maxBufferSize()];
CalculationCell m_calculationCells[k_numberOfCalculationCells];
Calculation * m_calculation;
Law * m_law;

View File

@@ -79,7 +79,6 @@ ParametersController::ParametersController(Responder * parentResponder, InputEve
for (int i = 0; i < k_maxNumberOfCells; i++) {
m_menuListCell[i].setParentResponder(&m_selectableTableView);
m_menuListCell[i].textField()->setDelegates(inputEventHandlerDelegate, this);
m_menuListCell[i].textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -45,7 +45,6 @@ private:
SelectableTableView * m_selectableTableView;
};
constexpr static int k_maxNumberOfCells = 2;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
ContentView m_contentView;
MessageTableCellWithEditableText m_menuListCell[k_maxNumberOfCells];
Law * m_law;

View File

@@ -11,7 +11,7 @@ namespace Sequence {
ListParameterController::ListParameterController(::InputEventHandlerDelegate * inputEventHandlerDelegate, ListController * listController) :
Shared::ListParameterController(listController, I18n::Message::SequenceColor, I18n::Message::DeleteSequence, this),
m_typeCell(I18n::Message::SequenceType),
m_initialRankCell(&m_selectableTableView, inputEventHandlerDelegate, this, m_draftTextBuffer, I18n::Message::FirstTermIndex),
m_initialRankCell(&m_selectableTableView, inputEventHandlerDelegate, this, I18n::Message::FirstTermIndex),
m_typeParameterController(this, listController, TableCell::Layout::Horizontal, Metric::CommonTopMargin, Metric::CommonRightMargin,
Metric::CommonBottomMargin, Metric::CommonLeftMargin)
{

View File

@@ -35,7 +35,6 @@ private:
bool hasInitialRankRow() const;
MessageTableCellWithChevronAndExpression m_typeCell;
MessageTableCellWithEditableText m_initialRankCell;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
TypeParameterController m_typeParameterController;
};

View File

@@ -13,7 +13,7 @@ namespace Settings {
DisplayModeController::DisplayModeController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) :
PreferencesController(parentResponder),
m_editableCell(&m_selectableTableView, inputEventHandlerDelegate, this, m_draftTextBuffer)
m_editableCell(&m_selectableTableView, inputEventHandlerDelegate, this)
{
m_editableCell.messageTableCellWithEditableText()->setMessage(I18n::Message::SignificantFigures);
m_editableCell.messageTableCellWithEditableText()->setMessageFont(KDFont::LargeFont);

View File

@@ -21,7 +21,6 @@ public:
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
private:
MessageTableCellWithEditableTextWithSeparator m_editableCell;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
};
}

View File

@@ -2,9 +2,9 @@
namespace Settings {
MessageTableCellWithEditableTextWithSeparator::MessageTableCellWithEditableTextWithSeparator(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, char * draftTextBuffer, I18n::Message message) :
MessageTableCellWithEditableTextWithSeparator::MessageTableCellWithEditableTextWithSeparator(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, I18n::Message message) :
HighlightCell(),
m_cell(parentResponder, inputEventHandlerDelegate, textFieldDelegate, draftTextBuffer, message)
m_cell(parentResponder, inputEventHandlerDelegate, textFieldDelegate, message)
{
}

View File

@@ -7,7 +7,7 @@ namespace Settings {
class MessageTableCellWithEditableTextWithSeparator : public HighlightCell {
public:
MessageTableCellWithEditableTextWithSeparator(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr, char * draftTextBuffer = nullptr, I18n::Message message = (I18n::Message)0);
MessageTableCellWithEditableTextWithSeparator(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr, I18n::Message message = (I18n::Message)0);
void drawRect(KDContext * ctx, KDRect rect) const override;
void setHighlighted(bool highlight) override;
void reloadCell() override { m_cell.reloadCell(); }

View File

@@ -7,8 +7,7 @@ BufferTextViewWithTextField::BufferTextViewWithTextField(Responder * parentRespo
View(),
Responder(parentResponder),
m_bufferTextView(font, 0.0f, 0.5f),
m_textField(this, m_textFieldBuffer, m_textFieldBuffer, k_textFieldBufferSize, inputEventHandlerDelegate, delegate, false, font, 0.0f, 0.5f),
m_textFieldBuffer{}
m_textField(this, nullptr, TextField::maxBufferSize(), TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, font, 0.0f, 0.5f)
{
}

View File

@@ -15,7 +15,6 @@ public:
// Responder
void didBecomeFirstResponder() override;
private:
constexpr static int k_textFieldBufferSize = TextField::maxBufferSize();
constexpr static KDCoordinate k_bufferTextWidth = 35;
constexpr static KDCoordinate k_textFieldVerticalMargin = 3;
constexpr static KDCoordinate k_borderWidth = 1;
@@ -25,7 +24,6 @@ private:
KDRect textFieldFrame() const;
BufferTextView m_bufferTextView;
TextField m_textField;
char m_textFieldBuffer[k_textFieldBufferSize];
};
}

View File

@@ -7,7 +7,7 @@ GoToParameterController::GoToParameterController(Responder * parentResponder, In
FloatParameterController(parentResponder),
m_cursor(cursor),
m_graphRange(graphRange),
m_abscisseCell(&m_selectableTableView, inputEventHandlerDelegate, this, m_draftTextBuffer, symbol)
m_abscisseCell(&m_selectableTableView, inputEventHandlerDelegate, this, symbol)
{
}

View File

@@ -20,7 +20,6 @@ private:
void buttonAction() override;
HighlightCell * reusableParameterCell(int index, int type) override;
int reusableParameterCellCount(int type) override;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
MessageTableCellWithEditableText m_abscisseCell;
};

View File

@@ -9,8 +9,8 @@ namespace Shared {
class HideableEvenOddEditableTextCell : public EvenOddEditableTextCell, public Hideable {
public:
HideableEvenOddEditableTextCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr, char * draftTextBuffer = nullptr) :
EvenOddEditableTextCell(parentResponder, inputEventHandlerDelegate, delegate, draftTextBuffer, KDFont::SmallFont),
HideableEvenOddEditableTextCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr) :
EvenOddEditableTextCell(parentResponder, inputEventHandlerDelegate, delegate, KDFont::SmallFont),
Hideable()
{}
KDColor backgroundColor() const override;

View File

@@ -11,7 +11,6 @@ IntervalParameterController::IntervalParameterController(Responder * parentRespo
for (int i = 0; i < k_totalNumberOfCell; i++) {
m_intervalCells[i].setParentResponder(&m_selectableTableView);
m_intervalCells[i].textField()->setDelegates(inputEventHandlerDelegate, this);
m_intervalCells[i].textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -24,7 +24,6 @@ private:
int reusableParameterCellCount(int type) override;
double parameterAtIndex(int index) override;
void buttonAction() override;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
MessageTableCellWithEditableText m_intervalCells[k_totalNumberOfCell];
};

View File

@@ -15,13 +15,11 @@ RangeParameterController::RangeParameterController(Responder * parentResponder,
for (int i = 0; i < k_numberOfEditableTextCell; i++) {
m_xRangeCells[i].setParentResponder(&m_selectableTableView);
m_xRangeCells[i].textField()->setDelegates(inputEventHandlerDelegate, this);
m_xRangeCells[i].textField()->setDraftTextBuffer(m_draftTextBuffer);
}
for (int i = 0; i < k_numberOfConvertibleTextCell; i++) {
m_yRangeCells[i].setParentResponder(&m_selectableTableView);
m_yRangeCells[i].setInteractiveCurveViewRange(m_interactiveRange);
m_yRangeCells[i].textField()->setDelegates(inputEventHandlerDelegate, this);
m_yRangeCells[i].textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -38,7 +38,6 @@ private:
constexpr static int k_numberOfConvertibleTextCell = 2;
constexpr static int k_numberOfTextCell = k_numberOfEditableTextCell+k_numberOfConvertibleTextCell;
InteractiveCurveViewRange * m_interactiveRange;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
MessageTableCellWithEditableText m_xRangeCells[k_numberOfEditableTextCell];
MessageTableCellWithConvertibleEditableText m_yRangeCells[k_numberOfConvertibleTextCell];
MessageTableCellWithSwitch m_yAutoCell;

View File

@@ -7,8 +7,8 @@ namespace Shared {
class StoreCell : public HideableEvenOddEditableTextCell {
public:
StoreCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr, char * draftTextBuffer = nullptr) :
HideableEvenOddEditableTextCell(parentResponder, inputEventHandlerDelegate, delegate, draftTextBuffer),
StoreCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr) :
HideableEvenOddEditableTextCell(parentResponder, inputEventHandlerDelegate, delegate),
m_separatorLeft(false)
{}
void setSeparatorLeft(bool separator);

View File

@@ -65,7 +65,6 @@ StoreController::StoreController(Responder * parentResponder, InputEventHandlerD
for (int i = 0; i < k_maxNumberOfEditableCells; i++) {
m_editableCells[i].setParentResponder(m_contentView.dataView());
m_editableCells[i].editableTextCell()->textField()->setDelegates(inputEventHandlerDelegate, this);
m_editableCells[i].editableTextCell()->textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -82,7 +82,6 @@ protected:
int numberOfElements() override;
int maxNumberOfElements() const override;
virtual HighlightCell * titleCells(int index) = 0;
char m_draftTextBuffer[TextField::maxBufferSize()];
int seriesAtColumn(int column) const { return column / DoublePairStore::k_numberOfColumnsPerSeries; }
bool privateFillColumnWithFormula(Poincare::Expression formula, Poincare::ExpressionNode::isVariableTest isVariable);
virtual StoreParameterController * storeParameterController() = 0;

View File

@@ -157,11 +157,9 @@ SumGraphController::LegendView::LegendView(SumGraphController * controller, Inpu
m_sum(0.0f, 0.5f, KDColorBlack, Palette::GreyMiddle),
m_sumLayout(),
m_legend(k_font, I18n::Message::Default, 0.0f, 0.5f, KDColorBlack, Palette::GreyMiddle),
m_editableZone(controller, m_draftText, m_draftText, TextField::maxBufferSize(), inputEventHandlerDelegate, controller, false, k_font, 0.0f, 0.5f, KDColorBlack, Palette::GreyMiddle),
m_editableZone(controller, nullptr, TextField::maxBufferSize(), TextField::maxBufferSize(), inputEventHandlerDelegate, controller, k_font, 0.0f, 0.5f, KDColorBlack, Palette::GreyMiddle),
m_sumSymbol(sumSymbol)
{
m_draftText[0] = 0;
}
{}
void SumGraphController::LegendView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(bounds(), Palette::GreyMiddle);

View File

@@ -70,7 +70,6 @@ private:
Poincare::Layout m_sumLayout;
MessageTextView m_legend;
TextField m_editableZone;
char m_draftText[TextField::maxBufferSize()];
CodePoint m_sumSymbol;
};
FunctionGraphView * m_graphView;

View File

@@ -5,7 +5,7 @@ namespace Shared {
void TextFieldWithExtension::willSetCursorLocation(const char * * location) {
size_t textLength = strlen(text());
assert(textLength >= m_extensionLength);
const char * maxLocation = m_contentView.draftTextBuffer() + (textLength - m_extensionLength);
const char * maxLocation = m_contentView.editedText() + (textLength - m_extensionLength);
if (*location > maxLocation) {
*location = maxLocation;
}
@@ -22,16 +22,16 @@ void TextFieldWithExtension::removeWholeText() {
bool TextFieldWithExtension::removeTextBeforeExtension(bool whole) {
assert(isEditing());
const char * extension = m_contentView.draftTextBuffer() + (strlen(text()) - m_extensionLength);
assert(extension >= m_contentView.draftTextBuffer() && extension < m_contentView.draftTextBuffer() + (ContentView::k_maxBufferSize - m_extensionLength));
char * destination = whole ? m_contentView.draftTextBuffer() : const_cast<char *>(cursorLocation());
const char * extension = m_contentView.editedText() + (strlen(text()) - m_extensionLength);
assert(extension >= m_contentView.editedText() && extension < m_contentView.editedText() + (ContentView::k_maxBufferSize - m_extensionLength));
char * destination = const_cast<char *>(whole ? m_contentView.editedText() : cursorLocation());
if (destination == extension) {
return false;
}
assert(destination >= m_contentView.draftTextBuffer());
assert(destination >= m_contentView.editedText());
assert(destination < extension);
m_contentView.willModifyTextBuffer();
strlcpy(destination, extension, ContentView::k_maxBufferSize - (destination - m_contentView.draftTextBuffer()));
strlcpy(destination, extension, ContentView::k_maxBufferSize - (destination - m_contentView.editedText()));
m_contentView.setCursorLocation(destination);
m_contentView.didModifyTextBuffer();
layoutSubviews();

View File

@@ -10,17 +10,16 @@ public:
TextFieldWithExtension(size_t extensionLength,
Responder * parentResponder,
char * textBuffer,
char * draftTextBuffer,
size_t textBufferSize,
size_t draftTextBufferSize,
::InputEventHandlerDelegate * inputEventHandlerDelegate,
::TextFieldDelegate * delegate = nullptr,
bool hasTwoBuffers = true,
const KDFont * size = KDFont::LargeFont,
float horizontalAlignment = 0.0f,
float verticalAlignment = 0.5f,
KDColor textColor = KDColorBlack,
KDColor backgroundColor = KDColorWhite) :
TextField(parentResponder, textBuffer, draftTextBuffer, textBufferSize, inputEventHandlerDelegate, delegate, hasTwoBuffers, size, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
TextField(parentResponder, textBuffer, textBufferSize, draftTextBufferSize, inputEventHandlerDelegate, delegate, size, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
m_extensionLength(extensionLength)
{}
private:

View File

@@ -35,7 +35,6 @@ ValuesController::ValuesController(Responder * parentResponder, InputEventHandle
for (int i = 0; i < k_maxNumberOfAbscissaCells; i++) {
m_abscissaCells[i].setParentResponder(&m_selectableTableView);
m_abscissaCells[i].editableTextCell()->textField()->setDelegates(inputEventHandlerDelegate, this);
m_abscissaCells[i].editableTextCell()->textField()->setDraftTextBuffer(m_draftTextBuffer);
m_abscissaCells[i].editableTextCell()->textField()->setFont(k_font);
}
}

View File

@@ -70,7 +70,6 @@ private:
EvenOddMessageTextCell m_abscissaTitleCell;
virtual FunctionTitleCell * functionTitleCells(int j) = 0;
virtual EvenOddBufferTextCell * floatCells(int j) = 0;
char m_draftTextBuffer[TextField::maxBufferSize()];
EvenOddEditableTextCell m_abscissaCells[k_maxNumberOfAbscissaCells];
virtual ValuesFunctionParameterController * functionParameterController() = 0;
ValuesParameterController m_abscissaParameterController;

View File

@@ -11,12 +11,11 @@ XYBannerView::XYBannerView(
m_abscissaSymbol(Font(), 1.0f, 0.5f, TextColor(), BackgroundColor()),
m_abscissaValue(
parentResponder,
m_draftTextBuffer,
m_draftTextBuffer,
TextField::maxBufferSize(),
m_textBody,
k_abscissaBufferSize,
k_abscissaBufferSize,
inputEventHandlerDelegate,
textFieldDelegate,
false,
Font(),
0.0f, 0.5f,
TextColor(),
@@ -24,7 +23,6 @@ XYBannerView::XYBannerView(
),
m_ordinateView(Font(), 0.5f, 0.5f, TextColor(), BackgroundColor())
{
m_draftTextBuffer[0] = 0;
}
View * XYBannerView::subviewAtIndex(int index) {

View File

@@ -2,6 +2,7 @@
#define SHARED_XY_BANNER_VIEW_H
#include "banner_view.h"
#include <poincare/print_float.h>
namespace Shared {
@@ -19,11 +20,12 @@ public:
protected:
View * subviewAtIndex(int index) override;
private:
constexpr static KDCoordinate k_abscissaBufferSize = Poincare::PrintFloat::k_maxFloatBufferSize;
int numberOfSubviews() const override { return k_numberOfSubviews; }
BufferTextView m_abscissaSymbol;
TextField m_abscissaValue;
char m_textBody[k_abscissaBufferSize];
BufferTextView m_ordinateView;
char m_draftTextBuffer[TextField::maxBufferSize()];
};
}

View File

@@ -52,7 +52,6 @@ IntervalController::IntervalController(Responder * parentResponder, InputEventHa
for (int i = 0; i < k_maxNumberOfCells; i++) {
m_intervalCell[i].setParentResponder(&m_selectableTableView);
m_intervalCell[i].textField()->setDelegates(inputEventHandlerDelegate, this);
m_intervalCell[i].textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -36,7 +36,6 @@ private:
};
ContentView m_contentView;
constexpr static int k_maxNumberOfCells = 2;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
MessageTableCellWithEditableText m_intervalCell[k_maxNumberOfCells];
EquationStore * m_equationStore;
};

View File

@@ -15,7 +15,6 @@ HistogramParameterController::HistogramParameterController(Responder * parentRes
for (int i = 0; i < k_numberOfCells; i++) {
m_cells[i].setParentResponder(&m_selectableTableView);
m_cells[i].textField()->setDelegates(inputEventHandlerDelegate, this);
m_cells[i].textField()->setDraftTextBuffer(m_draftTextBuffer);
}
}

View File

@@ -19,7 +19,6 @@ private:
int reusableParameterCellCount(int type) override { return k_numberOfCells; }
double parameterAtIndex(int index) override;
bool setParameterAtIndex(int parameterIndex, double f) override;
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
MessageTableCellWithEditableText m_cells[k_numberOfCells];
Store * m_store;
};

View File

@@ -5,10 +5,11 @@
#include <escher/highlight_cell.h>
#include <escher/text_field_delegate.h>
#include <escher/text_field.h>
#include <poincare/print_float.h>
class EditableTextCell : public HighlightCell, public Responder {
public:
EditableTextCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr, char * draftTextBuffer = nullptr, const KDFont * font = KDFont::LargeFont,
EditableTextCell(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr, const KDFont * font = KDFont::LargeFont,
float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f, KDColor textColor = KDColorBlack, KDColor = KDColorWhite, KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate leftMargin = 0);
TextField * textField();
void setMargins(KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate leftMargin = 0);
@@ -30,7 +31,7 @@ public:
private:
constexpr static KDCoordinate k_separatorThickness = 1;
TextField m_textField;
char m_textBody[TextField::maxBufferSize()];
char m_textBody[Poincare::PrintFloat::k_maxFloatBufferSize];
KDCoordinate m_topMargin;
KDCoordinate m_rightMargin;
KDCoordinate m_bottomMargin;

View File

@@ -7,7 +7,7 @@
class EvenOddEditableTextCell : public EvenOddCell, public Responder {
public:
EvenOddEditableTextCell(Responder * parentResponder = nullptr,InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr, char * draftTextBuffer = nullptr, const KDFont * font = KDFont::LargeFont, float horizontalAlignment = 1.0f, float verticalAlignment = 0.5f, KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate leftMargin = 0);
EvenOddEditableTextCell(Responder * parentResponder = nullptr,InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * delegate = nullptr, const KDFont * font = KDFont::LargeFont, float horizontalAlignment = 1.0f, float verticalAlignment = 0.5f, KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate leftMargin = 0);
EditableTextCell * editableTextCell();
void setEven(bool even) override;
void setHighlighted(bool highlight) override;

View File

@@ -9,7 +9,7 @@
class ExpressionField : public Responder, public View {
public:
ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, InputEventHandlerDelegate * inputEventHandler, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
ExpressionField(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandler, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
void setEditing(bool isEditing, bool reinitDraftBuffer = true);
bool isEditing() const;
@@ -45,8 +45,6 @@ private:
KDCoordinate maximalHeight() const;
TextField m_textField;
LayoutField m_layoutField;
char * m_textBuffer;
int m_textBufferLength;
};
#endif

View File

@@ -48,8 +48,6 @@ private:
View * view() override { return &m_expressionField; }
ExpressionField * expressionField() { return &m_expressionField; }
private:
static constexpr int k_bufferLength = TextField::maxBufferSize();
char m_textBuffer[k_bufferLength];
ExpressionField m_expressionField;
};
bool inputViewDidFinishEditing();

View File

@@ -4,10 +4,11 @@
#include <escher/editable_text_cell.h>
#include <escher/message_table_cell.h>
#include <escher/responder.h>
#include <poincare/print_float.h>
class MessageTableCellWithEditableText : public Responder, public MessageTableCell {
public:
MessageTableCellWithEditableText(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr, char * draftTextBuffer = nullptr, I18n::Message message = (I18n::Message)0);
MessageTableCellWithEditableText(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr, I18n::Message message = (I18n::Message)0);
View * accessoryView() const override;
TextField * textField() { return &m_textField; }
const char * editedText() const;
@@ -26,12 +27,10 @@ public:
}
void setAccessoryText(const char * text);
void setTextColor(KDColor color) override;
constexpr static int k_bufferLength = TextField::maxBufferSize();
private:
void layoutSubviews() override;
constexpr static int k_maxNumberOfEditableCharacters = 14;
TextField m_textField;
char m_textBody[k_bufferLength];
char m_textBody[Poincare::PrintFloat::k_maxFloatBufferSize];
};
#endif

View File

@@ -8,16 +8,19 @@
class TextField : public TextInput, public EditableField {
public:
TextField(Responder * parentResponder, char * textBuffer, char * draftTextBuffer, size_t textBufferSize,
InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate = nullptr, bool hasTwoBuffers = true, const KDFont * font = KDFont::LargeFont,
float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f, KDColor textColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
TextField(Responder * parentResponder, char * textBuffer, size_t textBufferSize, size_t draftTextBufferSize,
InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate = nullptr,
const KDFont * font = KDFont::LargeFont, float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f,
KDColor textColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
void setBackgroundColor(KDColor backgroundColor) override;
void setTextColor(KDColor textColor);
void setDelegates(InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate) { m_inputEventHandlerDelegate = inputEventHandlerDelegate; m_delegate = delegate; }
void reinitDraftTextBuffer() { m_contentView.reinitDraftTextBuffer(); }
void setDraftTextBuffer(char * draftTextBuffer);
bool isEditing() const override;
const char * draftTextBuffer() const { return const_cast<TextField *>(this)->m_contentView.draftTextBuffer(); }
// Which one is usefull?
const char * draftTextBuffer() const { return const_cast<TextField *>(this)->m_contentView.editedText(); }
size_t textBufferSize() const { return m_contentView.textBufferSize(); }
char * textBuffer() { return m_contentView.textBuffer(); }
size_t draftTextLength() const; //TODO keep ?
void setText(const char * text);
void setAlignment(float horizontalAlignment, float verticalAlignment);
@@ -34,19 +37,17 @@ public:
protected:
class ContentView : public TextInput::ContentView {
public:
ContentView(char * textBuffer, char * draftTextBuffer, size_t textBufferSize, const KDFont * font, float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f, KDColor textColor = KDColorBlack, KDColor = KDColorWhite);
ContentView(char * textBuffer, size_t textBufferSize, size_t draftTextBufferSize, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor);
void setBackgroundColor(KDColor backgroundColor);
KDColor backgroundColor() const { return m_backgroundColor; }
void setTextColor(KDColor textColor);
void setDraftTextBuffer(char * draftTextBuffer);
void drawRect(KDContext * ctx, KDRect rect) const override;
bool isEditing() const { return m_isEditing; }
const char * text() const override;
const char * editedText() const override { return m_draftTextBuffer; }
const char * editedText() const override;
size_t editedTextLength() const override { return m_currentDraftTextLength; } //TODO keep ?
size_t textBufferSize() const { return m_textBufferSize; }
char * textBuffer() { return m_textBuffer; }
char * draftTextBuffer() { return m_draftTextBuffer; }
int bufferSize() { return k_maxBufferSize; }
void setText(const char * text);
void setAlignment(float horizontalAlignment, float verticalAlignment);
void setEditing(bool isEditing);
@@ -74,9 +75,9 @@ protected:
KDRect glyphFrameAtPosition(const char * buffer, const char * position) const override;
bool m_isEditing;
char * m_textBuffer;
char * m_draftTextBuffer;
size_t m_currentDraftTextLength; //TODO keep ?
size_t m_textBufferSize;
size_t m_draftTextBufferSize;
size_t m_currentDraftTextLength; //TODO keep ?
float m_horizontalAlignment;
float m_verticalAlignment;
KDColor m_textColor;
@@ -88,7 +89,6 @@ private:
bool privateHandleEvent(Ion::Events::Event event);
bool privateHandleMoveEvent(Ion::Events::Event event);
virtual void removeWholeText();
bool m_hasTwoBuffers;
TextFieldDelegate * m_delegate;
};

View File

@@ -1,13 +1,14 @@
#include <escher/editable_text_cell.h>
#include <escher/container.h>
#include <escher/palette.h>
#include <poincare/print_float.h>
#include <assert.h>
EditableTextCell::EditableTextCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate, char * draftTextBuffer,
EditableTextCell::EditableTextCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate,
const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) :
HighlightCell(),
Responder(parentResponder),
m_textField(this, m_textBody, draftTextBuffer, TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, true, font, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
m_textField(this, m_textBody, Poincare::PrintFloat::k_maxFloatBufferSize, TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, font, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
m_topMargin(topMargin),
m_rightMargin(rightMargin),
m_bottomMargin(bottomMargin),

View File

@@ -2,10 +2,10 @@
#include <escher/container.h>
#include <assert.h>
EvenOddEditableTextCell::EvenOddEditableTextCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate, char * draftTextBuffer, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) :
EvenOddEditableTextCell::EvenOddEditableTextCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) :
EvenOddCell(),
Responder(parentResponder),
m_editableCell(this, inputEventHandlerDelegate, delegate, draftTextBuffer, font, horizontalAlignment, verticalAlignment, KDColorBlack, KDColorWhite, topMargin, rightMargin, bottomMargin, leftMargin)
m_editableCell(this, inputEventHandlerDelegate, delegate, font, horizontalAlignment, verticalAlignment, KDColorBlack, KDColorWhite, topMargin, rightMargin, bottomMargin, leftMargin)
{
}

View File

@@ -5,13 +5,11 @@
static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; }
static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; }
ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
ExpressionField::ExpressionField(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
Responder(parentResponder),
View(),
m_textField(parentResponder, textBuffer, textBuffer, textBufferLength, inputEventHandlerDelegate, textFieldDelegate, false, KDFont::LargeFont, 0.0f, 0.5f, KDColorBlack, KDColorWhite),
m_layoutField(parentResponder, inputEventHandlerDelegate, layoutFieldDelegate),
m_textBuffer(textBuffer),
m_textBufferLength(textBufferLength)
m_textField(parentResponder, nullptr, TextField::maxBufferSize(), TextField::maxBufferSize(), inputEventHandlerDelegate, textFieldDelegate, KDFont::LargeFont, 0.0f, 0.5f, KDColorBlack, KDColorWhite),
m_layoutField(parentResponder, inputEventHandlerDelegate, layoutFieldDelegate)
{
// Initialize text field
m_textField.setMargins(0, k_horizontalMargin, 0, k_horizontalMargin);
@@ -41,9 +39,9 @@ bool ExpressionField::isEditing() const {
const char * ExpressionField::text() {
if (!editionIsInTextField()) {
m_layoutField.layout().serializeParsedExpression(m_textBuffer, m_textBufferLength);
m_layoutField.layout().serializeParsedExpression(m_textField.textBuffer(), m_textField.textBufferSize());
}
return m_textBuffer;
return m_textField.textBuffer();
}
void ExpressionField::setText(const char * text) {

View File

@@ -5,9 +5,8 @@
InputViewController::ExpressionFieldController::ExpressionFieldController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
ViewController(parentResponder),
m_expressionField(this, m_textBuffer, k_bufferLength, inputEventHandlerDelegate, textFieldDelegate, layoutFieldDelegate)
m_expressionField(this, inputEventHandlerDelegate, textFieldDelegate, layoutFieldDelegate)
{
m_textBuffer[0] = 0;
}
void InputViewController::ExpressionFieldController::didBecomeFirstResponder() {

View File

@@ -2,10 +2,10 @@
#include <escher/palette.h>
#include <escher/container.h>
MessageTableCellWithEditableText::MessageTableCellWithEditableText(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, char * draftTextBuffer, I18n::Message message) :
MessageTableCellWithEditableText::MessageTableCellWithEditableText(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, I18n::Message message) :
Responder(parentResponder),
MessageTableCell(message),
m_textField(this, m_textBody, draftTextBuffer, TextField::maxBufferSize(), inputEventHandlerDelegate, textFieldDelegate, true, KDFont::LargeFont, 1.0f, 0.5f)
m_textField(this, m_textBody, Poincare::PrintFloat::k_maxFloatBufferSize, TextField::maxBufferSize(), inputEventHandlerDelegate, textFieldDelegate, KDFont::LargeFont, 1.0f, 0.5f)
{
m_textBody[0] = '\0';
}

View File

@@ -7,25 +7,28 @@
#include <assert.h>
static inline int minInt(int x, int y) { return x < y ? x : y; }
static char s_draftTextBuffer[TextField::maxBufferSize()];
/* TextField::ContentView */
TextField::ContentView::ContentView(char * textBuffer, char * draftTextBuffer, size_t textBufferSize, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor) :
TextField::ContentView::ContentView(char * textBuffer, size_t textBufferSize, size_t draftTextBufferSize, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor) :
TextInput::ContentView(font),
m_isEditing(false),
m_textBuffer(textBuffer),
m_draftTextBuffer(draftTextBuffer),
m_currentDraftTextLength(0),
m_textBufferSize(textBufferSize),
m_draftTextBufferSize(draftTextBufferSize),
m_currentDraftTextLength(0),
m_horizontalAlignment(horizontalAlignment),
m_verticalAlignment(verticalAlignment),
m_textColor(textColor),
m_backgroundColor(backgroundColor)
{
assert(m_textBufferSize <= k_maxBufferSize);
if (m_draftTextBuffer) {
reinitDraftTextBuffer();
if (textBuffer == nullptr) {
m_textBuffer = s_draftTextBuffer;
}
assert(m_draftTextBufferSize <= k_maxBufferSize);
assert(m_textBufferSize <= k_maxBufferSize);
reinitDraftTextBuffer();
}
void TextField::ContentView::setBackgroundColor(KDColor backgroundColor) {
@@ -38,10 +41,6 @@ void TextField::ContentView::setTextColor(KDColor textColor) {
markRectAsDirty(bounds());
}
void TextField::ContentView::setDraftTextBuffer(char * draftTextBuffer) {
m_draftTextBuffer = draftTextBuffer;
}
void TextField::ContentView::drawRect(KDContext * ctx, KDRect rect) const {
KDColor backgroundColor = m_backgroundColor;
if (m_isEditing) {
@@ -52,16 +51,26 @@ void TextField::ContentView::drawRect(KDContext * ctx, KDRect rect) const {
}
const char * TextField::ContentView::text() const {
return const_cast<const char *>(m_isEditing ? m_draftTextBuffer : m_textBuffer);
return const_cast<const char *>(m_isEditing ? s_draftTextBuffer : m_textBuffer);
}
const char * TextField::ContentView::editedText() const {
return s_draftTextBuffer;
}
void TextField::ContentView::setText(const char * text) {
size_t textRealLength = strlen(text);
int textLength = minInt(textRealLength, m_textBufferSize - 1);
size_t maxBufferSize = m_textBufferSize;
char * buffer = m_textBuffer;
if (m_isEditing) {
maxBufferSize = m_draftTextBufferSize;
buffer = s_draftTextBuffer;
}
int textLength = minInt(textRealLength, maxBufferSize - 1);
// Copy the text
strlcpy(m_isEditing ? m_draftTextBuffer : m_textBuffer, text, m_textBufferSize);
// Update the draft text length and cursor location
if (m_isEditing || m_textBuffer == m_draftTextBuffer) {
strlcpy(buffer, text, maxBufferSize);
// Update the draft text length
if (m_isEditing || m_textBuffer == s_draftTextBuffer) {
m_currentDraftTextLength = textLength;
}
markRectAsDirty(bounds());
@@ -78,11 +87,11 @@ void TextField::ContentView::setEditing(bool isEditing) {
return;
}
m_isEditing = isEditing;
m_currentDraftTextLength = strlen(m_draftTextBuffer);
if (m_cursorLocation < m_draftTextBuffer
|| m_cursorLocation > m_draftTextBuffer + m_currentDraftTextLength)
m_currentDraftTextLength = strlen(s_draftTextBuffer);
if (m_cursorLocation < s_draftTextBuffer
|| m_cursorLocation > s_draftTextBuffer + m_currentDraftTextLength)
{
m_cursorLocation = m_draftTextBuffer + m_currentDraftTextLength;
m_cursorLocation = s_draftTextBuffer + m_currentDraftTextLength;
}
markRectAsDirty(bounds());
layoutSubviews();
@@ -92,46 +101,46 @@ void TextField::ContentView::reinitDraftTextBuffer() {
/* We first need to clear the buffer, otherwise setCursorLocation might do
* various operations on a buffer with maybe non-initialized content, such as
* stringSize, etc. Those operation might be perilous on non-UTF8 content. */
m_draftTextBuffer[0] = 0;
s_draftTextBuffer[0] = 0;
m_currentDraftTextLength = 0;
setCursorLocation(m_draftTextBuffer);
setCursorLocation(s_draftTextBuffer);
}
bool TextField::ContentView::insertTextAtLocation(const char * text, const char * location) {
assert(m_isEditing);
int textSize = strlen(text);
if (m_currentDraftTextLength + textSize >= m_textBufferSize || textSize == 0) {
if (m_currentDraftTextLength + textSize >= m_draftTextBufferSize || textSize == 0) {
return false;
}
memmove(const_cast<char *>(location + textSize), location, (m_draftTextBuffer + m_currentDraftTextLength + 1) - location);
memmove(const_cast<char *>(location + textSize), location, (s_draftTextBuffer + m_currentDraftTextLength + 1) - location);
// Caution! One byte will be overridden by the null-terminating char of strlcpy
char * overridenByteLocation = const_cast<char *>(location + strlen(text));
char overridenByte = *overridenByteLocation;
strlcpy(const_cast<char *>(location), text, (m_draftTextBuffer + m_textBufferSize) - location);
assert(overridenByteLocation < m_draftTextBuffer + m_textBufferSize);
strlcpy(const_cast<char *>(location), text, (s_draftTextBuffer + m_draftTextBufferSize) - location);
assert(overridenByteLocation < s_draftTextBuffer + m_draftTextBufferSize);
*overridenByteLocation = overridenByte;
m_currentDraftTextLength += textSize;
UTF8Decoder decoder(m_draftTextBuffer);
UTF8Decoder decoder(s_draftTextBuffer);
const char * codePointPointer = decoder.stringPosition();
CodePoint codePoint = decoder.nextCodePoint();
assert(!codePoint.isCombining());
while (codePoint != UCodePointNull) {
assert(codePointPointer < m_draftTextBuffer + m_textBufferSize);
assert(codePointPointer < s_draftTextBuffer + m_draftTextBufferSize);
if (codePoint == '\n') {
assert(UTF8Decoder::CharSizeOfCodePoint('\n') == 1);
*(const_cast<char *>(codePointPointer)) = 0;
m_currentDraftTextLength = codePointPointer - m_draftTextBuffer;
m_currentDraftTextLength = codePointPointer - s_draftTextBuffer;
break;
}
codePointPointer = decoder.stringPosition();
codePoint = decoder.nextCodePoint();
}
reloadRectFromPosition(m_horizontalAlignment == 0.0f ? location : m_draftTextBuffer);
reloadRectFromPosition(m_horizontalAlignment == 0.0f ? location : s_draftTextBuffer);
return true;
}
@@ -150,21 +159,21 @@ bool TextField::ContentView::removePreviousGlyph() {
if (m_horizontalAlignment > 0.0f) {
/* Reload the view. If we do it later, the text beins supposedly shorter, we
* will not clean the first char. */
reloadRectFromPosition(m_draftTextBuffer);
reloadRectFromPosition(s_draftTextBuffer);
}
// Remove the glyph if possible
int removedSize = UTF8Helper::RemovePreviousGlyph(m_draftTextBuffer, const_cast<char *>(cursorLocation()));
int removedSize = UTF8Helper::RemovePreviousGlyph(s_draftTextBuffer, const_cast<char *>(cursorLocation()));
if (removedSize == 0) {
assert(cursorLocation() == m_draftTextBuffer);
assert(cursorLocation() == s_draftTextBuffer);
return false;
}
// Update the draft buffer length
m_currentDraftTextLength-= removedSize;
assert(m_draftTextBuffer[m_currentDraftTextLength] == 0);
assert(s_draftTextBuffer[m_currentDraftTextLength] == 0);
// Set the cursor location and reload the view
assert(cursorLocation() - removedSize >= m_draftTextBuffer);
assert(cursorLocation() - removedSize >= s_draftTextBuffer);
setCursorLocation(cursorLocation() - removedSize);
if (m_horizontalAlignment == 0.0f) {
reloadRectFromPosition(cursorLocation());
@@ -175,11 +184,11 @@ bool TextField::ContentView::removePreviousGlyph() {
bool TextField::ContentView::removeEndOfLine() {
assert(m_isEditing);
size_t lengthToCursor = (size_t)(cursorLocation() - m_draftTextBuffer);
size_t lengthToCursor = (size_t)(cursorLocation() - s_draftTextBuffer);
if (m_currentDraftTextLength == lengthToCursor) {
return false;
}
reloadRectFromPosition(m_horizontalAlignment == 0.0f ? cursorLocation() : m_draftTextBuffer);
reloadRectFromPosition(m_horizontalAlignment == 0.0f ? cursorLocation() : s_draftTextBuffer);
m_currentDraftTextLength = lengthToCursor;
*(const_cast<char *>(cursorLocation())) = 0;
layoutSubviews();
@@ -190,13 +199,13 @@ void TextField::ContentView::willModifyTextBuffer() {
assert(m_isEditing);
/* This method should be called when the buffer is modified outside the
* content view, for instance from the textfield directly. */
reloadRectFromPosition(m_draftTextBuffer);
reloadRectFromPosition(s_draftTextBuffer);
}
void TextField::ContentView::didModifyTextBuffer() {
/* This method should be called when the buffer is modified outside the
* content view, for instance from the textfield directly. */
m_currentDraftTextLength = strlen(m_draftTextBuffer);
m_currentDraftTextLength = strlen(s_draftTextBuffer);
layoutSubviews();
}
@@ -223,13 +232,12 @@ KDRect TextField::ContentView::glyphFrameAtPosition(const char * buffer, const c
/* TextField */
TextField::TextField(Responder * parentResponder, char * textBuffer, char * draftTextBuffer,
size_t textBufferSize, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate, bool hasTwoBuffers, const KDFont * font,
TextField::TextField(Responder * parentResponder, char * textBuffer, size_t textBufferSize, size_t draftTextBufferSize,
InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate, const KDFont * font,
float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor) :
TextInput(parentResponder, &m_contentView),
EditableField(inputEventHandlerDelegate),
m_contentView(textBuffer, draftTextBuffer, textBufferSize, font, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
m_hasTwoBuffers(hasTwoBuffers),
m_contentView(textBuffer, textBufferSize, draftTextBufferSize, font, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
m_delegate(delegate)
{
}
@@ -243,11 +251,6 @@ void TextField::setTextColor(KDColor textColor) {
m_contentView.setTextColor(textColor);
}
void TextField::setDraftTextBuffer(char * draftTextBuffer) {
m_contentView.setDraftTextBuffer(draftTextBuffer);
reinitDraftTextBuffer();
}
bool TextField::isEditing() const {
return m_contentView.isEditing();
}
@@ -262,7 +265,7 @@ void TextField::setText(const char * text) {
m_contentView.setText(text);
/* Set the cursor location here and not in ContentView::setText so that
* TextInput::willSetCursorLocation is called. */
setCursorLocation(m_contentView.draftTextBuffer()+strlen(text));
setCursorLocation(m_contentView.editedText()+strlen(text));
}
void TextField::setAlignment(float horizontalAlignment, float verticalAlignment) {
@@ -278,8 +281,8 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) {
return true;
}
if (isEditing() && shouldFinishEditing(event)) {
if (m_hasTwoBuffers) {
strlcpy(m_contentView.textBuffer(), m_contentView.draftTextBuffer(), m_contentView.bufferSize());
if (m_contentView.textBuffer() != m_contentView.editedText()) {
strlcpy(m_contentView.textBuffer(), m_contentView.editedText(), m_contentView.textBufferSize());
}
/* If textFieldDidFinishEditing displays a pop-up (because of an unvalid
* text for instance), the text field will call willResignFirstResponder.
@@ -290,9 +293,7 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) {
setEditing(false);
if (m_delegate->textFieldDidFinishEditing(this, text(), event)) {
// Clean draft text for next use
if (m_hasTwoBuffers) {
reinitDraftTextBuffer();
}
reinitDraftTextBuffer();
/* We allow overscroll to avoid calling layoutSubviews twice because the
* content might have changed. */
reloadScroll(true);
@@ -347,7 +348,7 @@ CodePoint TextField::XNTCodePoint(CodePoint defaultXNTCodePoint) {
/* Let's assume everything before the cursor is nested correctly, which is
* reasonable if the expression is being entered left-to-right. */
const char * text = this->text();
assert(text == m_contentView.draftTextBuffer());
assert(text == m_contentView.editedText());
const char * location = cursorLocation();
UTF8Decoder decoder(text, location);
unsigned level = 0;
@@ -426,7 +427,7 @@ bool TextField::privateHandleMoveEvent(Ion::Events::Event event) {
if (!isEditing()) {
return false;
}
const char * draftBuffer = m_contentView.draftTextBuffer();
const char * draftBuffer = m_contentView.editedText();
if (event == Ion::Events::Left && cursorLocation() > draftBuffer) {
return TextInput::moveCursorLeft();
}
@@ -454,7 +455,7 @@ bool TextField::handleEventWithText(const char * eventText, bool indentation, bo
if (eventText[0] == 0) {
/* For instance, the event might be EXE on a non-editing text field to start
* edition. */
setCursorLocation(m_contentView.draftTextBuffer());
setCursorLocation(m_contentView.editedText());
return m_delegate->textFieldDidHandleEvent(this, true, previousTextLength != 0);
}
@@ -466,7 +467,7 @@ bool TextField::handleEventWithText(const char * eventText, bool indentation, bo
// Replace System parentheses (used to keep layout tree structure) by normal parentheses
Poincare::SerializationHelper::ReplaceSystemParenthesesByUserParentheses(buffer);
const char * nextCursorLocation = m_contentView.draftTextBuffer() + draftTextLength();
const char * nextCursorLocation = m_contentView.editedText() + draftTextLength();
if (insertTextAtLocation(buffer, cursorLocation())) {
/* The cursor position depends on the text as we sometimes want to position
* the cursor at the end of the text and sometimes after the first