mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[escher] TextField: all text fields use the same draft text buffer
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@ private:
|
||||
bool hasInitialRankRow() const;
|
||||
MessageTableCellWithChevronAndExpression m_typeCell;
|
||||
MessageTableCellWithEditableText m_initialRankCell;
|
||||
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
|
||||
TypeParameterController m_typeParameterController;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user