/** * */ package org.jboss.tools.smooks.gef.tree.figures; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.draw2d.ActionEvent; import org.eclipse.draw2d.ActionListener; import org.eclipse.draw2d.Clickable; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.LayoutManager; import org.eclipse.draw2d.MarginBorder; import org.eclipse.draw2d.MouseEvent; import org.eclipse.draw2d.MouseMotionListener; import org.eclipse.draw2d.ToolbarLayout; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.jboss.tools.smooks.configuration.editors.GraphicsConstants; import org.jboss.tools.smooks.gef.tree.editpolicy.IShowHighlighFigure; import org.jboss.tools.smooks.gef.tree.model.TreeNodeModel; /** * @author DartPeng * */ public class TreeNodeFigure extends Figure implements ISelectableFigure, IShowHighlighFigure { private List<ITreeFigureListener> treeListener = new ArrayList<ITreeFigureListener>(); private Color oldLabelColor = null; protected int SPACE_INT = 14; protected int CLICKNODE_HEIGHT = 18; protected int CLICKNODE_WIDTH = 18; private Figure contentFigure; private Figure labelContainer; private Figure clickNode; private Label label; private boolean mouseEnter = false; protected boolean expand = false; private TreeNodeModel model; private boolean focus; private boolean selected; private Image labelImage = null; private boolean showHighlight; public TreeNodeFigure(TreeNodeModel model) { super(); this.model = model; this.setBorder(new MarginBorder(2, 2, 2, 2)); this.setLayoutManager(createTreeNodeFigureLayout()); createLabelContainer(); createContentFigure(); initFigure(); } protected ToolbarLayout createTreeNodeFigureLayout() { return new ToolbarLayout(); } protected void initFigure() { } public void addTreeListener(ITreeFigureListener listener) { treeListener.add(listener); } public void removeTreeListener(ITreeFigureListener listener) { treeListener.remove(listener); } public TreeNodeModel getModel() { return model; } public boolean isExpand() { return expand; } public void setModel(TreeNodeModel model) { this.model = model; } public Label getLabel() { return label; } /** * @return the focus */ public boolean isFocus() { return focus; } /** * @param focus * the focus to set */ public void setFocus(boolean focus) { this.focus = focus; repaint(); } /** * @return the selected */ public boolean isSelected() { return selected; } /** * @param selected * the selected to set */ public void setSelected(boolean selected) { this.selected = selected; repaint(); } private void createContentFigure() { Figure panelFigure = new Figure(); ToolbarLayout layout = new ToolbarLayout(); layout.setVertical(false); panelFigure.setLayoutManager(layout); Figure spaceFigure = new Figure() { @Override public Dimension getPreferredSize(int hint, int hint2) { return new Dimension(SPACE_INT, 0); } }; if (needSpaceFigure()) { panelFigure.add(spaceFigure); } contentFigure = new Figure() { @Override protected void paintFigure(Graphics graphics) { super.paintFigure(graphics); // graphics.drawRectangle(getBounds().x + 1, getBounds().y + 1, // getBounds().width - 2, // getBounds().height - 2); } }; panelFigure.add(contentFigure); contentFigure.setLayoutManager(createContentFigureLayout()); this.add(panelFigure); } protected boolean needSpaceFigure() { return true; } public Figure getContentFigure() { return contentFigure; } @Override public Dimension getPreferredSize(int hint, int hint2) { if (expand) { // contentFigure.setSize(-1, -1); // LayoutManager manager = contentFigure.getLayoutManager(); // if(manager != null){ // manager.invalidate(); // } return super.getPreferredSize(hint, hint2); } else { LayoutManager layout = labelContainer.getLayoutManager(); if (layout != null) layout.invalidate(); labelContainer.invalidateTree(); try { Dimension size = labelContainer.getPreferredSize(hint, hint2); Insets insets = getBorder().getInsets(null); return new Dimension(size.width + insets.left + insets.right, size.height + insets.bottom + insets.top); } catch (Throwable t) { return new Dimension(100, 100); } // return super.getPreferredSize(hint, hint2); } } /** * @return the clickNode */ public Figure getClickNode() { return clickNode; } protected void createLabelContainer() { labelContainer = new Figure() { /* * (non-Javadoc) * * @see * org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics * ) */ @Override protected void paintFigure(Graphics graphics) { super.paintFigure(graphics); // graphics.drawRectangle(getBounds().x + 1, getBounds().y + 1, // getBounds().width - 2, // getBounds().height - 2); } }; clickNode = new Clickable() { public void paintBorder(Graphics graphics) { } public void paintFigure(Graphics graphics) { drawClickFigure(clickNode, graphics); } }; ((Clickable) clickNode).addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { boolean hasChildren = model.hasChildren(); if (!hasChildren) return; changeTreeExpansionState(); } }); ((Clickable) clickNode).addMouseMotionListener(new MouseMotionListener() { public void mouseDragged(MouseEvent me) { } public void mouseEntered(MouseEvent me) { boolean hasChildren = model.hasChildren(); if (!hasChildren) return; mouseEnter = true; clickNode.repaint(); } public void mouseExited(MouseEvent me) { boolean hasChildren = model.hasChildren(); if (!hasChildren) return; mouseEnter = false; clickNode.repaint(); } public void mouseHover(MouseEvent me) { } public void mouseMoved(MouseEvent me) { } }); clickNode.setSize(new Dimension(CLICKNODE_WIDTH, CLICKNODE_HEIGHT)); Figure imageFigure = new Figure() { @Override protected void paintFigure(Graphics graphics) { super.paintFigure(graphics); if (labelImage != null) { graphics.drawImage(labelImage, getBounds().getTopLeft().x, getBounds().getTopLeft().y + 2); } } }; imageFigure.setSize(new Dimension(18, 18)); label = new Label(); if (isFocus()) { } if (model != null) { label.setText(model.getText()); } else { label.setText(""); //$NON-NLS-1$ } if (needClickFigure()) { labelContainer.add(clickNode); } labelContainer.add(imageFigure); labelContainer.add(label); labelContainer.setLayoutManager(createLabelContainerLayout()); this.add(labelContainer); } protected boolean needClickFigure() { return true; } protected LayoutManager createLabelContainerLayout() { ToolbarLayout tl = new ToolbarLayout(); tl.setVertical(false); return tl; } public void updateLabel() { if (model != null) { label.setText(model.getText()); } else { label.setText(""); //$NON-NLS-1$ } } /** * @param labelImage * the labelImage to set */ public void setLabelImage(Image labelImage) { this.labelImage = labelImage; } public void setLabelText(String text) { label.setText(text); } protected ToolbarLayout createContentFigureLayout() { ToolbarLayout layout = new ToolbarLayout(); return layout; } public void paint(Graphics graphics) { if (oldLabelColor == null){ oldLabelColor = label.getForegroundColor(); } label.setOpaque(false); label.setForegroundColor(oldLabelColor); if (isFocus() || isSelected() || showHighlight) { label.setOpaque(true); label.setBackgroundColor(GraphicsConstants.FONT_COLOR); label.setForegroundColor(ColorConstants.white); } super.paint(graphics); } public void setNodeLabelForegroundColor(Color color){ this.oldLabelColor = color; } protected void drawClickFigure(IFigure clickFigure, Graphics graphics) { Rectangle rect = clickFigure.getBounds(); Point center = rect.getCenter(); int width = 8; PointList pointList = new PointList(); boolean hasChildren = model.hasChildren(); if (hasChildren) { if (expand) { Point point1 = new Point(center.x - width / 2, center.y - width / 4); Point point2 = new Point(point1.x + width, point1.y); Point point3 = new Point(point1.x + width / 2, point1.y + width / 2); pointList.addPoint(point1); pointList.addPoint(point2); pointList.addPoint(point3); } else { Point point1 = new Point(center.x - width / 4, center.y - width / 2); Point point2 = new Point(point1.x, point1.y + width); Point point3 = new Point(point1.x + width / 2, point1.y + width / 2); pointList.addPoint(point1); pointList.addPoint(point2); pointList.addPoint(point3); } graphics.drawPolygon(pointList); } if (mouseEnter) { graphics.pushState(); graphics.setBackgroundColor(ColorConstants.black); graphics.fillPolygon(pointList); graphics.popState(); } } public void expandNode() { expand = false; changeTreeExpansionState(); } public void collapsedNode() { expand = true; changeTreeExpansionState(); } private void changeTreeExpansionState() { try { IFigure parent = contentFigure.getParent(); while (parent != null) { if (parent instanceof TreeContainerFigure) { break; } parent = parent.getParent(); } if (parent != null) { Rectangle oldRectangle = parent.getClientArea(); expand = !expand; for (Iterator<ITreeFigureListener> iterator = this.treeListener.iterator(); iterator.hasNext();) { ITreeFigureListener listener = (ITreeFigureListener) iterator.next(); TreeFigureExpansionEvent event = new TreeFigureExpansionEvent(this); if (!expand) { listener.treeCollapsed(event); } else { listener.treeExpanded(event); } } if (!expand) { contentFigure.setLayoutManager(null); contentFigure.setSize(new Dimension(0, 0)); } else { contentFigure.setLayoutManager(createContentFigureLayout()); contentFigure.setSize(contentFigure.getPreferredSize()); } Rectangle newRectangle = parent.getClientArea(); int w = Math.max(oldRectangle.width, newRectangle.width); int h = Math.max(oldRectangle.height, newRectangle.height); // IFigure currentParent = contentFigure.getParent(); // currentParent.invalidateTree(); // LayoutManager layout = currentParent.getLayoutManager(); // if(layout != null){ // layout.layout(currentParent); // } IFigure panel = parent.getParent(); if (panel != null) { // panel.repaint(); panel.repaint(oldRectangle.x, oldRectangle.y, w, h); } } } catch (Exception e) { e.printStackTrace(); } } public void showHighlightBackgroudColor(Color color) { showHighlight = true; repaint(); } public void showbackOldbackgroundColor(Color color) { showHighlight = false; repaint(); } }