locationURI="toolbar:org.simantics.sysdyn.ui.chartPanel">\r
<command\r
commandId="org.simantics.sysdyn.ui.chartPanelOrientation"\r
- icon="platform:/plugin/com.famfamfam.silk/icons/page_white_text.png"\r
+ icon="platform:/plugin/com.famfamfam.silk/icons/page_white_text_width.png"\r
label="Change Orientation"\r
style="push"\r
tooltip="Change orientation">\r
\r
String orientation = settings.get(ChartPanel.CHART_PANEL_ORIENTATION);\r
if(orientation == null)\r
- settings.put(ChartPanel.CHART_PANEL_ORIENTATION, ChartPanel.CHART_PANEL_VERTICAL);\r
+ settings.put(ChartPanel.CHART_PANEL_ORIENTATION, ChartPanel.CHART_PANEL_HORIZONTAL);\r
\r
if(ChartPanel.CHART_PANEL_VERTICAL.equals(orientation))\r
orientation = ChartPanel.CHART_PANEL_HORIZONTAL;\r
return;\r
\r
IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(ChartPanel.CHART_PANEL_SETTINGS);\r
- if (settings == null) {\r
- settings = Activator.getDefault().getDialogSettings().addNewSection(ChartPanel.CHART_PANEL_SETTINGS);\r
- }\r
+ if(settings == null)\r
+ return;\r
\r
String orientation = settings.get(ChartPanel.CHART_PANEL_ORIENTATION);\r
if(orientation == null)\r
import org.eclipse.jface.layout.GridLayoutFactory;\r
import org.eclipse.swt.SWT;\r
import org.eclipse.swt.custom.ScrolledComposite;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetAdapter;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Control;\r
import org.eclipse.ui.IMemento;\r
import org.eclipse.ui.PartInitException;\r
import org.eclipse.ui.part.ViewPart;\r
import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
\r
/**\r
* Chart panel displays multiple charts in a single view. The view can be oriented \r
for(String m : minimizedURIs)\r
minimizedCharts.add(m);\r
\r
- \r
String orientation = settings.get(CHART_PANEL_ORIENTATION);\r
if(CHART_PANEL_VERTICAL.equals(orientation))\r
this.vertical = true;\r
- else\r
+ else if(CHART_PANEL_HORIZONTAL.equals(orientation))\r
this.vertical = false;\r
}\r
\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
sc.setExpandHorizontal(true);\r
sc.setExpandVertical(true);\r
+ sc.getVerticalBar().setIncrement(sc.getVerticalBar().getIncrement()*3);\r
+ setupDropTarget(sc);\r
\r
body = new Composite(sc, SWT.NONE);\r
GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(body);\r
\r
sc.setContent(body);\r
\r
- createContents(body);\r
+ createContents();\r
}\r
\r
/**\r
* \r
* @param parent Body located inside a scrolled composite and containing the charts. (always private Composite body?)\r
*/\r
- private void createContents(Composite parent) {\r
- for(Control c : parent.getChildren()) \r
+ private void createContents() {\r
+ for(Control c : body.getChildren()) \r
c.dispose();\r
\r
- Composite composite = new Composite(parent, SWT.NONE);\r
-\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ int separator;\r
if(vertical) {\r
GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ separator = SWT.VERTICAL;\r
} else {\r
- int en = expandedCharts.size();\r
- int mn = minimizedCharts.isEmpty() ? 0 : 1;\r
- GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(en + mn).applyTo(composite);\r
+ int chartPanels = expandedCharts.size();\r
+ int minimizedPanel = minimizedCharts.isEmpty() ? 0 : 1;\r
+ int separators = 1 + expandedCharts.size() + minimizedCharts.size();\r
+ \r
+ GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(chartPanels + minimizedPanel + separators).applyTo(composite);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ separator = SWT.HORIZONTAL;\r
}\r
\r
- for(String e : expandedCharts)\r
+ new ChartPanelSeparator(composite, separator);\r
+ \r
+ for(String e : expandedCharts) {\r
new ChartPanelElement(composite, this, e, SWT.NONE);\r
+ new ChartPanelSeparator(composite, separator).addMouseListener(new SCFocusListener());\r
+ }\r
\r
if(!minimizedCharts.isEmpty()) {\r
Composite minimized = new Composite(composite, SWT.NONE);\r
- GridDataFactory.fillDefaults().hint(ChartPanelHeader.HEADER_MINIMUM_WIDTH, SWT.DEFAULT).applyTo(minimized);\r
+ GridDataFactory.fillDefaults().grab(true, false).hint(ChartPanelHeader.HEADER_MINIMUM_WIDTH, SWT.DEFAULT).applyTo(minimized);\r
GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(minimized);\r
\r
- for(String m : minimizedCharts)\r
+ for(String m : minimizedCharts) {\r
new ChartPanelHeader(minimized, this, m, SWT.BORDER);\r
+ new ChartPanelSeparator(minimized, SWT.VERTICAL).addMouseListener(new SCFocusListener());\r
+ }\r
}\r
\r
- parent.layout();\r
+ body.layout();\r
\r
sc.setMinSize(body.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
saveState();\r
\r
@Override\r
public void setFocus() {\r
- if(!body.isDisposed())\r
- body.setFocus();\r
+ if(!sc.isDisposed())\r
+ sc.setFocus();\r
}\r
\r
@Override\r
expandedCharts.add(expandedCharts.isEmpty() ? 0 : expandedCharts.size(), chart);\r
else\r
minimizedCharts.add(0, chart);\r
- \r
- createContents(body);\r
+ refresh();\r
}\r
\r
/**\r
this.vertical = true;\r
else\r
this.vertical = false;\r
+ refresh();\r
+ }\r
+ \r
+ /**\r
+ * Removes a chart from this panel\r
+ * \r
+ * @param chart The name of the chart to be removed\r
+ */\r
+ public void removeChart(String chart) {\r
+ if(this.expandedCharts.contains(chart))\r
+ this.expandedCharts.remove(chart);\r
+ else if(this.minimizedCharts.contains(chart))\r
+ this.minimizedCharts.remove(chart);\r
+ refresh(); \r
+ }\r
+ \r
+ \r
+ /**\r
+ * Convenience method for refreshing the contents of the panel\r
+ */\r
+ private void refresh() {\r
+ createContents();\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Sets up drag-scrolling for a scrolled composite \r
+ * \r
+ * @param control\r
+ */\r
+ protected void setupDropTarget(final ScrolledComposite sc) {\r
+ DropTarget target = new DropTarget(sc, DND.DROP_NONE);\r
+ target.setTransfer(new Transfer[] { LocalObjectTransfer.getTransfer() });\r
\r
- createContents(body);\r
+ target.addDropListener(new DropTargetAdapter() {\r
+ \r
+ private int activeMargin = 20;\r
+ private int moveAmount = 1;\r
+ \r
+ @Override\r
+ public void dragOver(DropTargetEvent event) { \r
+ Point original = sc.getOrigin();\r
+ Point origin = sc.getOrigin();\r
+ Point pointer = sc.toControl(event.x, event.y);\r
+ Rectangle bounds = sc.getBounds();\r
+ \r
+ if(pointer.y < activeMargin)\r
+ origin.y = origin.y - moveAmount;\r
+ else if(bounds.height - pointer.y < activeMargin)\r
+ origin.y = origin.y + moveAmount;\r
+ if(pointer.x < activeMargin)\r
+ origin.x = origin.x - moveAmount;\r
+ else if(bounds.width - pointer.x < activeMargin)\r
+ origin.x = origin.x + moveAmount;\r
+ \r
+ if(origin != original) {\r
+ sc.setOrigin (origin.x, origin.y);\r
+ sc.redraw();\r
+ }\r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Listener for directing focus to scrollableComposite\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+ private class SCFocusListener extends MouseAdapter {\r
+ public void mouseDown(MouseEvent e) {\r
+ ChartPanel.this.setFocus();\r
+ }\r
}\r
}\r
import org.eclipse.swt.events.MouseEvent;\r
import org.eclipse.swt.events.MouseListener;\r
import org.eclipse.swt.graphics.Cursor;\r
+import org.eclipse.swt.graphics.Rectangle;\r
import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
import org.eclipse.swt.widgets.Label;\r
\r
/**\r
GridLayoutFactory.fillDefaults().numColumns(3).applyTo(this);\r
GridDataFactory.fillDefaults().grab(true, false).applyTo(this);\r
\r
+ // Label for the chart name (also minimize/expand)\r
Label label = new Label(this, SWT.NONE);\r
label.setText(name);\r
GridDataFactory.fillDefaults().grab(true, false).applyTo(label);\r
- \r
+ label.addMouseListener(new MinimizeListener(label));\r
+ label.setCursor(new Cursor(label.getDisplay(), SWT.CURSOR_HAND));\r
+\r
+ // Label for minimizing/expanding chart\r
label = new Label(this, SWT.NONE);\r
label.setText("^");\r
GridDataFactory.fillDefaults().applyTo(label);\r
- label.addMouseListener(new MinimizeListener());\r
+ label.addMouseListener(new MinimizeListener(label));\r
label.setCursor(new Cursor(label.getDisplay(), SWT.CURSOR_HAND));\r
\r
-\r
+ // Label for closing/removing the chart\r
label = new Label(this, SWT.NONE);\r
label.setText("x");\r
GridDataFactory.fillDefaults().applyTo(label);\r
- \r
+ label.addMouseListener(new RemoveChartListener(label));\r
+ label.setCursor(new Cursor(label.getDisplay(), SWT.CURSOR_HAND));\r
}\r
\r
/**\r
*/\r
private class MinimizeListener implements MouseListener {\r
\r
+ private Control control;\r
+ \r
+ public MinimizeListener(Control control) {\r
+ this.control = control;\r
+ }\r
+ \r
@Override\r
public void mouseDoubleClick(MouseEvent e) {\r
}\r
@Override\r
public void mouseDown(MouseEvent e) {\r
+ panel.setFocus();\r
}\r
\r
@Override\r
public void mouseUp(MouseEvent e) {\r
- if(!ChartPanelHeader.this.isDisposed())\r
+ if(ChartPanelHeader.this.isDisposed())\r
+ return;\r
+ \r
+ // Expand only if mouse was released inside the control\r
+ Rectangle bounds = control.getBounds();\r
+ bounds.x = 0;\r
+ bounds.y = 0;\r
+ if(bounds.contains(e.x, e.y))\r
panel.expandChart(name);\r
}\r
\r
}\r
\r
+ /**\r
+ * Mouse listener for removing this chart from the chart panel.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+ private class RemoveChartListener implements MouseListener {\r
+\r
+ Control control;\r
+ \r
+ public RemoveChartListener(Control control) {\r
+ this.control = control;\r
+ }\r
+\r
+ @Override\r
+ public void mouseDoubleClick(MouseEvent e) {\r
+ }\r
+\r
+ @Override\r
+ public void mouseDown(MouseEvent e) {\r
+ panel.setFocus();\r
+ }\r
+\r
+ @Override\r
+ public void mouseUp(MouseEvent e) {\r
+ if(!ChartPanelHeader.this.isDisposed()) {\r
+ // Remove only if mouse was released inside the control\r
+ Rectangle bounds = control.getBounds();\r
+ bounds.x = 0;\r
+ bounds.y = 0;\r
+ if(bounds.contains(e.x, e.y))\r
+ panel.removeChart(name);\r
+ }\r
+ \r
+ \r
+ }\r
+ \r
+ }\r
}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetAdapter;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
+\r
+/**\r
+ * Class for separating charts in {@link ChartPanel}. Acts as a drop participant for adding\r
+ * and moving charts in {@link ChartPanel}.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartPanelSeparator extends Composite {\r
+\r
+ /**\r
+ * Set up a small horizontal or vertical separator depending on SWT style\r
+ * \r
+ * @param parent\r
+ * @param style\r
+ */\r
+ public ChartPanelSeparator(Composite parent, int style) {\r
+ super(parent, SWT.NONE);\r
+ if((style & SWT.VERTICAL) > 0) { \r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(this);\r
+ GridLayoutFactory.fillDefaults().margins(0, 2).applyTo(this);\r
+ } else if((style & SWT.HORIZONTAL) > 0) {\r
+ GridDataFactory.fillDefaults().grab(false, true).applyTo(this);\r
+ GridLayoutFactory.fillDefaults().margins(2, 0).applyTo(this);\r
+ }\r
+ setupDropTarget(this);\r
+ }\r
+\r
+ /**\r
+ * Set up the drop target for this separator\r
+ * \r
+ * @param control\r
+ */\r
+ protected void setupDropTarget(Control control) {\r
+ DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK);\r
+ target.setTransfer(new Transfer[] { LocalObjectTransfer.getTransfer() });\r
+ target.addDropListener(new DropTargetAdapter() {\r
+\r
+ Composite composite = ChartPanelSeparator.this;\r
+ Display display = composite.getDisplay();\r
+ \r
+ @Override\r
+ public void dragEnter(DropTargetEvent event) {\r
+ event.detail = DND.DROP_COPY;\r
+ composite.setBackground(display.getSystemColor(SWT.COLOR_BLACK));\r
+ }\r
+\r
+ @Override\r
+ public void dragLeave(DropTargetEvent event) { \r
+ composite.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));\r
+ }\r
+\r
+ @Override\r
+ public void drop(DropTargetEvent event) {\r
+ }\r
+\r
+ @Override\r
+ public void dropAccept(DropTargetEvent event) {\r
+ }\r
+\r
+ @Override\r
+ public void dragOver(DropTargetEvent event) { \r
+ }\r
+ });\r
+ }\r
+}\r