mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 08:41:01 +01:00
[poincare] Added UneditableHorizontalTrioLayout.
Change-Id: Ifd9fd6a0a0714853c1a8cd428b65076b704a8211
This commit is contained in:
@@ -114,6 +114,7 @@ objs += $(addprefix poincare/src/layout/,\
|
||||
static_layout_hierarchy.o\
|
||||
string_layout.o\
|
||||
sum_layout.o\
|
||||
uneditable_horizontal_trio_layout.o\
|
||||
uneditable_parenthesis_left_layout.o\
|
||||
uneditable_parenthesis_right_layout.o\
|
||||
)
|
||||
|
||||
@@ -28,5 +28,6 @@
|
||||
#include <poincare/src/layout/sequence_layout.h>
|
||||
#include <poincare/src/layout/string_layout.h>
|
||||
#include <poincare/src/layout/sum_layout.h>
|
||||
#include <poincare/src/layout/uneditable_horizontal_trio_layout.h>
|
||||
|
||||
#endif
|
||||
|
||||
156
poincare/src/layout/uneditable_horizontal_trio_layout.cpp
Normal file
156
poincare/src/layout/uneditable_horizontal_trio_layout.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "uneditable_horizontal_trio_layout.h"
|
||||
#include "empty_visible_layout.h"
|
||||
#include <poincare/expression_layout_cursor.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
ExpressionLayout * UneditableHorizontalTrioLayout::clone() const {
|
||||
UneditableHorizontalTrioLayout * layout = new UneditableHorizontalTrioLayout(
|
||||
const_cast<UneditableHorizontalTrioLayout *>(this)->leftLayout(),
|
||||
const_cast<UneditableHorizontalTrioLayout *>(this)->centerLayout(),
|
||||
const_cast<UneditableHorizontalTrioLayout *>(this)->rightLayout(),
|
||||
true);
|
||||
return layout;
|
||||
}
|
||||
|
||||
void UneditableHorizontalTrioLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) {
|
||||
if (cursor->pointedExpressionLayout() == this
|
||||
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
|
||||
{
|
||||
ExpressionLayout * previousParent = m_parent;
|
||||
int indexInParent = previousParent->indexOfChild(this);
|
||||
replaceWith(new EmptyVisibleLayout(), true);
|
||||
if (indexInParent == 0) {
|
||||
cursor->setPointedExpressionLayout(previousParent);
|
||||
return;
|
||||
}
|
||||
cursor->setPointedExpressionLayout(previousParent->editableChild(indexInParent - 1));
|
||||
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
|
||||
return;
|
||||
}
|
||||
ExpressionLayout::backspaceAtCursor(cursor);
|
||||
}
|
||||
|
||||
bool UneditableHorizontalTrioLayout::moveLeft(ExpressionLayoutCursor * cursor) {
|
||||
if (cursor->pointedExpressionLayout() == centerLayout()) {
|
||||
// Case: Center layout.
|
||||
// Go Left.
|
||||
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
|
||||
cursor->setPointedExpressionLayout(this);
|
||||
return true;
|
||||
}
|
||||
assert(cursor->pointedExpressionLayout() == this);
|
||||
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
|
||||
// Case: Right.
|
||||
// Go Right of the center layout's last child if it has one, else go Right
|
||||
// of the center layout.
|
||||
ExpressionLayout * grandChild = centerLayout()->editableChild(centerLayout()->numberOfChildren()-1);
|
||||
if (grandChild != nullptr) {
|
||||
cursor->setPointedExpressionLayout(grandChild);
|
||||
return true;
|
||||
}
|
||||
cursor->setPointedExpressionLayout(centerLayout());
|
||||
return true;
|
||||
}
|
||||
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
|
||||
// Case: Left.
|
||||
// Ask the parent.
|
||||
if (m_parent) {
|
||||
return m_parent->moveLeft(cursor);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UneditableHorizontalTrioLayout::moveRight(ExpressionLayoutCursor * cursor) {
|
||||
if (cursor->pointedExpressionLayout() == centerLayout()) {
|
||||
// Case: Center layout.
|
||||
// Go Right.
|
||||
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
|
||||
cursor->setPointedExpressionLayout(this);
|
||||
return true;
|
||||
}
|
||||
assert(cursor->pointedExpressionLayout() == this);
|
||||
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
|
||||
// Case: Left.
|
||||
// Go Left of the center layout's first child if it has one, else go Left of
|
||||
// the center layout.
|
||||
ExpressionLayout * grandChild = centerLayout()->editableChild(0);
|
||||
if (grandChild != nullptr) {
|
||||
cursor->setPointedExpressionLayout(grandChild);
|
||||
return true;
|
||||
}
|
||||
cursor->setPointedExpressionLayout(centerLayout());
|
||||
return true;
|
||||
}
|
||||
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
|
||||
// Case: Right.
|
||||
// Ask the parent.
|
||||
if (m_parent) {
|
||||
return m_parent->moveRight(cursor);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UneditableHorizontalTrioLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
|
||||
}
|
||||
|
||||
KDSize UneditableHorizontalTrioLayout::computeSize() {
|
||||
// TODO: This code is duplicated from horizontal_layout.cpp.
|
||||
KDCoordinate totalWidth = 0;
|
||||
int i = 0;
|
||||
KDCoordinate max_under_baseline = 0;
|
||||
KDCoordinate max_above_baseline = 0;
|
||||
while (ExpressionLayout * c = editableChild(i++)) {
|
||||
KDSize childSize = c->size();
|
||||
totalWidth += childSize.width();
|
||||
if (childSize.height() - c->baseline() > max_under_baseline) {
|
||||
max_under_baseline = childSize.height() - c->baseline() ;
|
||||
}
|
||||
if (c->baseline() > max_above_baseline) {
|
||||
max_above_baseline = c->baseline();
|
||||
}
|
||||
}
|
||||
return KDSize(totalWidth, max_under_baseline + max_above_baseline);
|
||||
}
|
||||
|
||||
void UneditableHorizontalTrioLayout::computeBaseline() {
|
||||
// TODO: This code is duplicated from horizontal_layout.cpp.
|
||||
m_baseline = 0;
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
if (editableChild(i)->baseline() > m_baseline) {
|
||||
m_baseline = editableChild(i)->baseline();
|
||||
}
|
||||
}
|
||||
m_baselined = true;
|
||||
}
|
||||
|
||||
KDPoint UneditableHorizontalTrioLayout::positionOfChild(ExpressionLayout * child) {
|
||||
// TODO: This code is duplicated from horizontal_layout.cpp.
|
||||
KDCoordinate x = 0;
|
||||
KDCoordinate y = 0;
|
||||
int index = indexOfChild(child);
|
||||
if (index > 0) {
|
||||
ExpressionLayout * previousChild = editableChild(index-1);
|
||||
assert(previousChild != nullptr);
|
||||
x = previousChild->origin().x() + previousChild->size().width();
|
||||
}
|
||||
y = baseline() - child->baseline();
|
||||
return KDPoint(x, y);
|
||||
}
|
||||
|
||||
ExpressionLayout * UneditableHorizontalTrioLayout::leftLayout() {
|
||||
return editableChild(0);
|
||||
}
|
||||
|
||||
ExpressionLayout * UneditableHorizontalTrioLayout::centerLayout() {
|
||||
return editableChild(1);
|
||||
}
|
||||
|
||||
ExpressionLayout * UneditableHorizontalTrioLayout::rightLayout() {
|
||||
return editableChild(2);
|
||||
}
|
||||
|
||||
}
|
||||
42
poincare/src/layout/uneditable_horizontal_trio_layout.h
Normal file
42
poincare/src/layout/uneditable_horizontal_trio_layout.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef POINCARE_UNEDITABLE_HORIZONTAL_TRIO_LAYOUT_H
|
||||
#define POINCARE_UNEDITABLE_HORIZONTAL_TRIO_LAYOUT_H
|
||||
|
||||
#include <poincare/static_layout_hierarchy.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* UneditableHorizontalTrioLayout has 3 children: a left and a right layout
|
||||
* (usually parentheses or brackets), and a central layout.
|
||||
* The cursor can only be:
|
||||
* - Left or Right of the UneditableHorizontalTrioLayout,
|
||||
* - Left or Right of the central layout if it is not an horizontal layout,
|
||||
* - Inside the central layout if it is an horizontal layout.
|
||||
* This way, the lateral children of an UneditableHorizontalTrioLayout cannot be
|
||||
* edited, and it it will always have only 3 children.
|
||||
* This layout can be used to create binomial coefficient layouts, matrix
|
||||
* layouts or the argument of sum and product layouts. */
|
||||
|
||||
class UneditableHorizontalTrioLayout : public StaticLayoutHierarchy<3> {
|
||||
public:
|
||||
using StaticLayoutHierarchy::StaticLayoutHierarchy;
|
||||
ExpressionLayout * clone() const override;
|
||||
void backspaceAtCursor(ExpressionLayoutCursor * cursor) override;
|
||||
|
||||
/* Navigation */
|
||||
bool moveLeft(ExpressionLayoutCursor * cursor) override;
|
||||
bool moveRight(ExpressionLayoutCursor * cursor) override;
|
||||
|
||||
protected:
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;
|
||||
KDSize computeSize() override;
|
||||
void computeBaseline() override;
|
||||
KDPoint positionOfChild(ExpressionLayout * child) override;
|
||||
private:
|
||||
ExpressionLayout * leftLayout();
|
||||
ExpressionLayout * centerLayout();
|
||||
ExpressionLayout * rightLayout();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user