Skip to main content
summaryrefslogtreecommitdiffstats
blob: 3f54470f7761a97127a3e52a6d885bb0dbdf8b61 (plain) (blame)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
 * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Andre Dietisheim - initial API and implementation
 */
package org.eclipse.emf.cdo.ui.internal.branch.layout;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.ui.internal.branch.geometry.GeometryUtils;
import org.eclipse.emf.cdo.ui.internal.branch.item.AbstractBranchPointNode;
import org.eclipse.emf.cdo.ui.internal.branch.item.BranchPointNodeUtils;
import org.eclipse.emf.cdo.ui.internal.branch.item.RootNode;

import org.eclipse.zest.layouts.LayoutStyles;
import org.eclipse.zest.layouts.algorithms.AbstractLayoutAlgorithm;
import org.eclipse.zest.layouts.dataStructures.DisplayIndependentDimension;
import org.eclipse.zest.layouts.dataStructures.DisplayIndependentRectangle;
import org.eclipse.zest.layouts.dataStructures.InternalNode;
import org.eclipse.zest.layouts.dataStructures.InternalRelationship;

/**
 * A layout algorithm that builds a tree of branch nodes. Nodes on the same branch are centered horizontally below each
 * other. Nodes on a new branch are shifted to the left/right - they sprout to the left/right. The description above
 * applies to a vertical layout of the branch tree. A horizontal strategy is not implemented yet.
 * 
 * @author Andre Dietisheim
 */
public class BranchTreeLayoutAlgorithm extends AbstractLayoutAlgorithm
{
  private static final int LAYOUT_STEPS = 2;

  private RootNode rootNode;

  private DisplayIndependentRectangle layoutBounds = null;

  private DisplayIndependentDimension borders = new DisplayIndependentDimension(60, 60);

  private BranchViewLayoutStrategy branchViewLayoutStrategy;

  /**
   * A layout algorithm that displays trees of cdo branches.
   * 
   * @see CDOBranch
   */
  public BranchTreeLayoutAlgorithm(int styles, BranchViewLayoutStrategy branchViewLayoutStrategy)
  {
    super(styles);
    this.branchViewLayoutStrategy = branchViewLayoutStrategy;
  }

  /**
   * Tree layout algorithm Constructor with NO Style
   */
  public BranchTreeLayoutAlgorithm(BranchViewLayoutStrategy branchViewLayoutStrategy)
  {
    this(LayoutStyles.NONE, branchViewLayoutStrategy);
  }

  @Override
  public void setLayoutArea(double x, double y, double width, double height)
  {
  }

  @Override
  protected int getCurrentLayoutStep()
  {
    return 0;
  }

  @Override
  protected int getTotalNumberOfLayoutSteps()
  {
    return LAYOUT_STEPS;
  }

  @Override
  protected void preLayoutAlgorithm(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider,
      double x, double y, double width, double height)
  {
    if (entitiesToLayout.length > 0)
    {
      initRootNode(entitiesToLayout);
    }
    layoutBounds = new DisplayIndependentRectangle(x, y, width, height);
  }

  /**
   * Searches the given entities and stores the root node
   * 
   * @param entitiesToLayout
   *          the entities to layout
   * @see RootNode
   * @see AbstractBranchPointNode
   */
  private void initRootNode(InternalNode[] entitiesToLayout)
  {
    for (InternalNode internalNode : entitiesToLayout)
    {
      AbstractBranchPointNode node = BranchPointNodeUtils.getBranchPointNode(internalNode);
      if (node != null)
      {
        if (node instanceof RootNode)
        {
          rootNode = (RootNode)node.getLater(rootNode);
        }
      }
    }
  }

  @Override
  protected void applyLayoutInternal(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider,
      double boundsX, double boundsY, double boundsWidth, double boundsHeight)
  {

    if (entitiesToLayout.length > 0)
    {
      BranchView branchView = buildBranch(rootNode, branchViewLayoutStrategy);
      fireProgressEvent(1, LAYOUT_STEPS);
      // defaultFitWithinBounds(entitiesToLayout, layoutBounds);
      fitWithinBounds(branchView);
    }
  }

  private void fitWithinBounds(BranchView branchView)
  {
    DisplayIndependentRectangle boundsWithBorder = GeometryUtils.substractBorders(borders, layoutBounds);
    branchView.getLayoutStrategy().scale(branchView, boundsWithBorder);
  }

  private BranchView buildBranch(AbstractBranchPointNode branchRootNode,
      BranchViewLayoutStrategy branchViewLayoutStrategy)
  {
    return new BranchView(branchRootNode, branchViewLayoutStrategy);
    // return new BranchView(branchRootNode, new RightHandSubBranches());
  }

  @Override
  protected void postLayoutAlgorithm(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider)
  {
    updateLayoutLocations(entitiesToLayout);
    fireProgressEvent(LAYOUT_STEPS, LAYOUT_STEPS);
  }

  @Override
  protected boolean isValidConfiguration(boolean asynchronous, boolean continueous)
  {
    if (asynchronous && continueous)
    {
      return false;
    }
    else if (asynchronous && !continueous)
    {
      return true;
    }
    else if (!asynchronous && continueous)
    {
      return false;
    }
    else if (!asynchronous && !continueous)
    {
      return true;
    }

    return false;
  }
}

Back to the top