Blame view

build4/epsilon-master/poincare/src/layout/conjugate_layout.cpp 4.67 KB
6663b6c9   adorian   projet complet av...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  #include "conjugate_layout.h"
  #include "empty_layout.h"
  #include "horizontal_layout.h"
  #include <escher/metric.h>
  #include <poincare/expression_layout_cursor.h>
  extern "C" {
  #include <assert.h>
  #include <stdlib.h>
  }
  
  namespace Poincare {
  
  ExpressionLayout * ConjugateLayout::clone() const {
    ConjugateLayout * layout = new ConjugateLayout(const_cast<ConjugateLayout *>(this)->operandLayout(), true);
    return layout;
  }
  
  void ConjugateLayout::collapseSiblingsAndMoveCursor(ExpressionLayoutCursor * cursor) {
    // If the operand layouts is not HorizontalLayouts, replace it with one.
    if (!operandLayout()->isHorizontal()) {
      ExpressionLayout * previousOperand = operandLayout();
      HorizontalLayout * horizontalOperandLayout = new HorizontalLayout(previousOperand, false);
      replaceChild(previousOperand, horizontalOperandLayout, false);
    }
    ExpressionLayout::collapseOnDirection(HorizontalDirection::Right, 0);
    cursor->setPointedExpressionLayout(operandLayout());
    cursor->setPosition(ExpressionLayoutCursor::Position::Left);
  }
  
  void ConjugateLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) {
    assert(oldChild == operandLayout());
    if (newChild->isEmpty()) {
      if (!deleteOldChild) {
        detachChild(oldChild);
      }
      replaceWithAndMoveCursor(newChild, true, cursor);
      return;
    }
    ExpressionLayout::replaceChildAndMoveCursor(oldChild, newChild, deleteOldChild, cursor);
  }
  
  void ConjugateLayout::removePointedChildAtIndexAndMoveCursor(int index, bool deleteAfterRemoval, ExpressionLayoutCursor * cursor) {
    assert(index >= 0 && index < numberOfChildren());
    assert(cursor->pointedExpressionLayout()->hasAncestor(child(index), true));
    replaceChildAndMoveCursor(child(index), new EmptyLayout(), deleteAfterRemoval, cursor);
  }
  
  ExpressionLayoutCursor ConjugateLayout::cursorLeftOf(ExpressionLayoutCursor cursor, bool * shouldRecomputeLayout) {
    // Case: Left of the operand. Move Left.
    if (operandLayout()
        && cursor.pointedExpressionLayout() == operandLayout()
        && cursor.position() == ExpressionLayoutCursor::Position::Left)
    {
      return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
    }
    assert(cursor.pointedExpressionLayout() == this);
    // Case: Right. Go to the operand.
    if (cursor.position() == ExpressionLayoutCursor::Position::Right) {
      assert(operandLayout() != nullptr);
      return ExpressionLayoutCursor(operandLayout(), ExpressionLayoutCursor::Position::Right);
    }
    // Case: Left. Ask the parent.
    assert(cursor.position() == ExpressionLayoutCursor::Position::Left);
    if (m_parent) {
      return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
    }
    return ExpressionLayoutCursor();
  }
  
  ExpressionLayoutCursor ConjugateLayout::cursorRightOf(ExpressionLayoutCursor cursor, bool * shouldRecomputeLayout) {
    // Case: Right of the operand. Move Right.
    if (operandLayout()
        && cursor.pointedExpressionLayout() == operandLayout()
        && cursor.position() == ExpressionLayoutCursor::Position::Right)
    {
      return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
    }
    assert(cursor.pointedExpressionLayout() == this);
    // Case: Left. Go to the operand.
    if (cursor.position() == ExpressionLayoutCursor::Position::Left) {
      assert(operandLayout() != nullptr);
      return ExpressionLayoutCursor(operandLayout(), ExpressionLayoutCursor::Position::Left);
    }
    // Case: Right. Ask the parent.
    assert(cursor.position() == ExpressionLayoutCursor::Position::Right);
    if (m_parent) {
      return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
    }
    return ExpressionLayoutCursor();
  }
  
  void ConjugateLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
    ctx->fillRect(KDRect(p.x()+Metric::FractionAndConjugateHorizontalMargin, p.y(), operandLayout()->size().width()+2*Metric::FractionAndConjugateHorizontalOverflow, k_overlineWidth), expressionColor);
  }
  
  KDSize ConjugateLayout::computeSize() {
    KDSize operandSize = operandLayout()->size();
    return KDSize(Metric::FractionAndConjugateHorizontalMargin+Metric::FractionAndConjugateHorizontalOverflow+operandSize.width()+Metric::FractionAndConjugateHorizontalOverflow+Metric::FractionAndConjugateHorizontalMargin, operandSize.height()+k_overlineWidth+k_overlineVerticalMargin);
  }
  
  void ConjugateLayout::computeBaseline() {
    m_baseline = operandLayout()->baseline()+k_overlineWidth+k_overlineVerticalMargin;
    m_baselined = true;
  }
  
  KDPoint ConjugateLayout::positionOfChild(ExpressionLayout * child) {
    return KDPoint(Metric::FractionAndConjugateHorizontalMargin+Metric::FractionAndConjugateHorizontalOverflow, k_overlineWidth+k_overlineVerticalMargin);
  }
  
  }