[apps/code] Fix input(), that did not return the input

This commit is contained in:
Léa Saviot
2020-02-19 13:48:38 +01:00
committed by Quentin Guidée
parent 73bec71db3
commit 84a66d3b31
4 changed files with 62 additions and 14 deletions

View File

@@ -134,7 +134,27 @@ const char * ConsoleController::inputText(const char * prompt) {
const char * previousPrompt = m_editCell.promptText();
m_editCell.setPrompt(promptText);
m_editCell.setText("");
/* The user will input some text that is stored in the edit cell. When the
* input is finished, we want to clear that cell and return the input text.
* We choose to shift the input in the edit cell and put a null char in first
* position, so that the cell seems cleared but we can still use it to store
* the input.
* To do so, we need to reduce the cell buffer size by one, so that the input
* can be shifted afterwards, even if it has maxSize.
*
* Illustration of a input sequence:
* | | | | | | | | | <- the edit cell buffer
* |0| | | | | | |X| <- clear and reduce the size
* |a|0| | | | | |X| <- user input
* |a|b|0| | | | |X| <- user input
* |a|b|c|0| | | |X| <- user input
* |a|b|c|d|0| | |X| <- last user input
* | |a|b|c|d|0| | | <- increase the buffer size and shift the user input by one
* |0|a|b|c|d|0| | | <- put a zero in first position: the edit cell seems empty
*/
m_editCell.clearAndReduceSize();
// Reload the history
m_selectableTableView.reloadData();
@@ -147,16 +167,18 @@ const char * ConsoleController::inputText(const char * prompt) {
return c->inputRunLoopActive();
}, this);
// Handle the input text
// Print the prompt and the input text
if (promptText != nullptr) {
printText(promptText, s - promptText);
}
const char * text = m_editCell.text();
printText(text, strlen(text));
size_t textSize = strlen(text);
printText(text, textSize);
flushOutputAccumulationBufferToStore();
// Clear the edit cell and return the input
text = m_editCell.shiftCurrentTextAndClear();
m_editCell.setPrompt(previousPrompt);
m_editCell.setText("");
refreshPrintOutput();
return text;

View File

@@ -55,4 +55,21 @@ bool ConsoleEditCell::insertText(const char * text) {
return m_textField.handleEventWithText(text);
}
void ConsoleEditCell::clearAndReduceSize() {
setText("");
size_t previousBufferSize = m_textField.draftTextBufferSize();
assert(previousBufferSize > 1);
m_textField.setDraftTextBufferSize(previousBufferSize - 1);
}
const char * ConsoleEditCell::shiftCurrentTextAndClear() {
size_t previousBufferSize = m_textField.draftTextBufferSize();
m_textField.setDraftTextBufferSize(previousBufferSize + 1);
char * textFieldBuffer = m_textField.draftTextBuffer();
char * newTextPosition = textFieldBuffer + 1;
strlcpy(newTextPosition, textFieldBuffer, previousBufferSize);
textFieldBuffer[0] = 0;
return newTextPosition;
}
}

View File

@@ -34,6 +34,8 @@ public:
bool insertText(const char * text);
void setPrompt(const char * prompt);
const char * promptText() const { return m_promptView.text(); }
void clearAndReduceSize();
const char * shiftCurrentTextAndClear();
private:
PointerTextView m_promptView;
TextField m_textField;

View File

@@ -28,6 +28,8 @@ public:
void reinitDraftTextBuffer() { m_contentView.reinitDraftTextBuffer(); }
bool isEditing() const override;
char * draftTextBuffer() const { return const_cast<char *>(m_contentView.editedText()); }
void setDraftTextBufferSize(size_t size) { m_contentView.setDraftTextBufferSize(size); }
size_t draftTextBufferSize() const { return m_contentView.draftTextBufferSize(); }
size_t draftTextLength() const;
void setText(const char * text);
void setEditing(bool isEditing) override { m_contentView.setEditing(isEditing); }
@@ -42,8 +44,19 @@ public:
bool shouldFinishEditing(Ion::Events::Event event) override;
const KDFont * font() const { return m_contentView.font(); }
protected:
class ContentView : public TextInput::ContentView {
public:
/* In some app (ie Calculation), text fields record expression results whose
* lengths can reach 70 (ie
* [[1.234567e-123*e^(1.234567e-123*i), 1.234567e-123*e^(1.234567e-123*i)]]).
* In order to be able to record those output text, k_maxBufferSize must be
* over 70.
* Furthermore, we want ot be able to write an adjacency matrix of size 10
* so we need at least 2 brackets + 10 * (2 brackets + 10 digits + 9 commas)
* = 212 characters. */
constexpr static int k_maxBufferSize = 220;
ContentView(char * textBuffer, size_t textBufferSize, size_t draftTextBufferSize, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor);
void setBackgroundColor(KDColor backgroundColor);
KDColor backgroundColor() const { return m_backgroundColor; }
@@ -56,7 +69,8 @@ protected:
void setText(const char * text);
void setEditing(bool isEditing);
void reinitDraftTextBuffer();
void setDraftTextBufferSize(size_t size) { m_draftTextBufferSize = size; }
void setDraftTextBufferSize(size_t size) { assert(size <= k_maxBufferSize); m_draftTextBufferSize = size; }
size_t draftTextBufferSize() const { return m_draftTextBufferSize; }
/* If the text to be appended is too long to be added without overflowing the
* buffer, nothing is done (not even adding few letters from the text to reach
* the maximum buffer capacity) and false is returned. */
@@ -67,15 +81,6 @@ protected:
void willModifyTextBuffer();
void didModifyTextBuffer();
size_t deleteSelection() override;
/* In some app (ie Calculation), text fields record expression results whose
* lengths can reach 70 (ie
* [[1.234567e-123*e^(1.234567e-123*i), 1.234567e-123*e^(1.234567e-123*i)]]).
* In order to be able to record those output text, k_maxBufferSize must be
* over 70.
* Furthermore, we want ot be able to write an adjacency matrix of size 10
* so we need at least 2 brackets + 10 * (2 brackets + 10 digits + 9 commas)
* = 212 characters. */
constexpr static int k_maxBufferSize = 220;
private:
void layoutSubviews(bool force = false) override;
KDRect glyphFrameAtPosition(const char * buffer, const char * position) const override;
@@ -87,8 +92,10 @@ protected:
KDColor m_textColor;
KDColor m_backgroundColor;
};
const ContentView * nonEditableContentView() const override { return &m_contentView; }
ContentView m_contentView;
private:
bool privateHandleEvent(Ion::Events::Event event);
bool privateHandleMoveEvent(Ion::Events::Event event);