[escher/expression_field] Methods on layout

Added some methods to manipulate the layout of a LayoutField from an
ExpressionField, like storing into and restoring from a buffer.

Change-Id: I7b7b5b53626f19237a5215bd196e897a518e9577
This commit is contained in:
Gabriel Ozouf
2020-06-11 11:40:42 +02:00
committed by Émilie Feral
parent 9527894b25
commit 8ab23f66b5
4 changed files with 54 additions and 0 deletions

View File

@@ -26,6 +26,8 @@ public:
bool inputViewHeightDidChange();
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false);
void setLayoutInsertionCursorEvent(Ion::Events::Event event) { m_layoutField.setInsertionCursorEvent(event); }
size_t dumpLayout(char * buffer, size_t bufferSize) const;
void restoreLayout(const char * buffer, size_t size);
/* View */
int numberOfSubviews() const override { return 1; }

View File

@@ -35,6 +35,7 @@ public:
CodePoint XNTCodePoint(CodePoint defaultXNTCodePoint) override;
void putCursorRightOfLayout();
void setInsertionCursorEvent(Ion::Events::Event event) { m_insertionCursorEvent = event; }
void setLayout(Poincare::Layout newLayout);
// ScrollableView
void setBackgroundColor(KDColor c) override {

View File

@@ -121,3 +121,46 @@ KDCoordinate ExpressionField::inputViewHeight() const {
std::min(k_maximalHeight,
std::max(k_minimalHeight, m_layoutField.minimalSizeForOptimalDisplay().height())));
}
size_t ExpressionField::dumpLayout(char * buffer, size_t bufferSize) const {
size_t size;
size_t returnValue;
char * currentLayout;
if (editionIsInTextField()) {
size = strlen(m_textField.draftTextBuffer()) + 1;
currentLayout = m_textField.draftTextBuffer();
/* We take advantage of the fact that draftTextBuffer is null terminated to
* use a size of 0 as a shorthand for "The buffer contains raw text instead
* of layouts", since the size of a layout is at least 32 (the size of an
* empty horizontal layout). This way, we can detect when the edition mode
* has changed and invalidate the data.*/
returnValue = 0;
} else {
size = m_layoutField.layout().size();
currentLayout = reinterpret_cast<char *>(m_layoutField.layout().node());
returnValue = size;
}
if (size > bufferSize - 1) {
buffer[0] = 0;
return 0;
}
memcpy(buffer, currentLayout, size);
return returnValue;
}
void ExpressionField::restoreLayout(const char * buffer, size_t size) {
if (editionIsInTextField()) {
if (size != 0 || buffer[0] == 0) {
/* A size other than 0 means the buffer contains Layout information
* (instead of raw text) that we don't want to restore. This is most
* likely because the edition mode has been changed between use. */
return;
}
setText(buffer);
return;
}
if (size == 0) {
return;
}
m_layoutField.setLayout(Poincare::Layout::LayoutFromAddress(buffer, size));
}

View File

@@ -314,6 +314,14 @@ void LayoutField::clearLayout() {
reloadScroll(); // Put the scroll to offset 0
}
void LayoutField::setLayout(Poincare::Layout newLayout) {
m_contentView.clearLayout();
KDSize previousSize = minimalSizeForOptimalDisplay();
const_cast<ExpressionView *>(m_contentView.expressionView())->setLayout(newLayout);
putCursorRightOfLayout();
reload(previousSize);
}
Context * LayoutField::context() const {
return (m_delegate != nullptr) ? m_delegate->context() : nullptr;
}