View Javadoc
1   /**
2    * 
3    * Copyright (c) 2013-2014, Openflexo
4    * Copyright (c) 2011-2012, AgileBirds
5    * 
6    * This file is part of Diana-drawing-editor, a component of the software infrastructure 
7    * developed at Openflexo.
8    * 
9    * 
10   * Openflexo is dual-licensed under the European Union Public License (EUPL, either 
11   * version 1.1 of the License, or any later version ), which is available at 
12   * https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
13   * and the GNU General Public License (GPL, either version 3 of the License, or any 
14   * later version), which is available at http://www.gnu.org/licenses/gpl.html .
15   * 
16   * You can redistribute it and/or modify under the terms of either of these licenses
17   * 
18   * If you choose to redistribute it and/or modify under the terms of the GNU GPL, you
19   * must include the following additional permission.
20   *
21   *          Additional permission under GNU GPL version 3 section 7
22   *
23   *          If you modify this Program, or any covered work, by linking or 
24   *          combining it with software containing parts covered by the terms 
25   *          of EPL 1.0, the licensors of this Program grant you additional permission
26   *          to convey the resulting work. * 
27   * 
28   * This software is distributed in the hope that it will be useful, but WITHOUT ANY 
29   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
30   * PARTICULAR PURPOSE. 
31   *
32   * See http://www.openflexo.org/license.html for details.
33   * 
34   * 
35   * Please contact Openflexo (openflexo-contacts@openflexo.org)
36   * or visit www.openflexo.org if you need additional information.
37   * 
38   */
39  
40  package org.openflexo.gina.swing.editor;
41  
42  import java.awt.BorderLayout;
43  import java.awt.Color;
44  import java.awt.Graphics2D;
45  import java.awt.Paint;
46  import java.awt.Point;
47  import java.awt.RadialGradientPaint;
48  import java.awt.Rectangle;
49  import java.awt.event.WindowAdapter;
50  import java.awt.event.WindowEvent;
51  import java.util.logging.Logger;
52  
53  import javax.swing.JFrame;
54  import javax.swing.WindowConstants;
55  
56  import org.openflexo.gina.FIBLibrary;
57  import org.openflexo.gina.model.FIBComponent;
58  import org.openflexo.gina.swing.editor.controller.FIBEditorController;
59  import org.openflexo.gina.swing.editor.inspector.FIBEditorInspectorController;
60  import org.openflexo.gina.swing.editor.palette.FIBEditorPalettes;
61  import org.openflexo.gina.swing.editor.widget.FIBLibraryBrowser;
62  import org.openflexo.gina.swing.utils.JFIBPreferences;
63  import org.openflexo.gina.utils.InteractiveFIBEditor;
64  import org.openflexo.logging.FlexoLogger;
65  import org.openflexo.rm.Resource;
66  import org.openflexo.rm.ResourceLocator;
67  import org.openflexo.swing.ComponentBoundSaver;
68  import org.openflexo.swing.layout.JXMultiSplitPane;
69  import org.openflexo.swing.layout.JXMultiSplitPane.DividerPainter;
70  import org.openflexo.swing.layout.MultiSplitLayout;
71  import org.openflexo.swing.layout.MultiSplitLayout.Divider;
72  import org.openflexo.swing.layout.MultiSplitLayout.Leaf;
73  import org.openflexo.swing.layout.MultiSplitLayout.Node;
74  import org.openflexo.swing.layout.MultiSplitLayout.Split;
75  import org.openflexo.swing.layout.MultiSplitLayoutFactory;
76  import org.openflexo.toolbox.ToolBox;
77  
78  /**
79   * Swing packaging (frame-based) of a full featured FIB editor working on a {@link FIBLibrary}
80   * 
81   * @author sylvain
82   *
83   */
84  public class JFIBEditor extends JFrame implements InteractiveFIBEditor {
85  
86  	private static final Logger logger = FlexoLogger.getLogger(JFIBEditor.class.getPackage().getName());
87  
88  	private static final MultiSplitLayoutFactory MSL_FACTORY = new MultiSplitLayoutFactory.DefaultMultiSplitLayoutFactory();
89  
90  	private FIBLibrary fibLibrary;
91  	private FIBEditor editor;
92  	private JXMultiSplitPane centerPanel;
93  
94  	private FIBLibraryBrowser libraryBrowser;
95  	private FIBEditorPalettes palette;
96  	// private JFIBDialogInspectorController inspector;
97  	private MainPanel mainPanel;
98  
99  	private FIBEditor getFIBEditor() {
100 		if (editor == null) {
101 			editor = new FIBEditor(fibLibrary) {
102 				@Override
103 				public boolean activate(FIBEditorController editorController) {
104 					if (super.activate(editorController)) {
105 						centerPanel.add(editorController.getEditorBrowser(), LayoutPosition.BOTTOM_LEFT.name());
106 						centerPanel.revalidate();
107 						centerPanel.repaint();
108 						return true;
109 					}
110 					return false;
111 				}
112 
113 				@Override
114 				public boolean disactivate(FIBEditorController editorController) {
115 					if (super.disactivate(editorController)) {
116 						centerPanel.remove(editorController.getEditorBrowser());
117 						centerPanel.revalidate();
118 						centerPanel.repaint();
119 						return true;
120 					}
121 					return false;
122 				}
123 			};
124 
125 			editor.makeMenuBar(this);
126 
127 			libraryBrowser = new FIBLibraryBrowser(editor.getFIBLibrary()) {
128 				@Override
129 				public void doubleClickOnComponentResource(Resource selectedComponentResource) {
130 					System.out.println("doubleClickOnComponentResource " + selectedComponentResource);
131 					if (selectedComponentResource != null) {
132 						editor.openFIBComponent(selectedComponentResource, null, null, JFIBEditor.this);
133 					}
134 				}
135 			};
136 			palette = editor.makePalette();
137 			FIBEditorInspectorController inspectors = editor.makeInspectors();
138 
139 			// inspector = editor.makeInspector(this);
140 			// inspector.setVisible(false);
141 
142 			mainPanel = editor.makeMainPanel();
143 
144 			centerPanel.add(libraryBrowser, LayoutPosition.TOP_LEFT.name());
145 			centerPanel.add(mainPanel, LayoutPosition.CENTER.name());
146 			centerPanel.add(palette, LayoutPosition.TOP_RIGHT.name());
147 			centerPanel.add(inspectors.getPanelGroup(), LayoutPosition.BOTTOM_RIGHT.name());
148 
149 			centerPanel.revalidate();
150 		}
151 
152 		return editor;
153 	}
154 
155 	public JFIBEditor(FIBLibrary fibLibrary) {
156 
157 		if (ToolBox.isMacOS()) {
158 			System.setProperty("apple.laf.useScreenMenuBar", "true");
159 		}
160 
161 		this.fibLibrary = fibLibrary;
162 		setBounds(JFIBPreferences.getFrameBounds());
163 
164 		new ComponentBoundSaver(this) {
165 
166 			@Override
167 			public void saveBounds(Rectangle bounds) {
168 				JFIBPreferences.setFrameBounds(bounds);
169 			}
170 		};
171 
172 		setTitle("GINA FIB Editor");
173 
174 		setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
175 		addWindowListener(new WindowAdapter() {
176 			@Override
177 			public void windowClosing(WindowEvent e) {
178 				// we dont want to quit application
179 				// editor.quit();
180 			}
181 		});
182 
183 		Split<?> defaultLayout = getDefaultLayout();
184 
185 		MultiSplitLayout centerLayout = new MultiSplitLayout(true, MSL_FACTORY);
186 		centerLayout.setLayoutMode(MultiSplitLayout.NO_MIN_SIZE_LAYOUT);
187 		centerLayout.setModel(defaultLayout);
188 
189 		centerPanel = new JXMultiSplitPane(centerLayout);
190 		centerPanel.setDividerSize(DIVIDER_SIZE);
191 		centerPanel.setDividerPainter(new DividerPainter() {
192 
193 			@Override
194 			protected void doPaint(Graphics2D g, Divider divider, int width, int height) {
195 				if (!divider.isVisible()) {
196 					return;
197 				}
198 				if (divider.isVertical()) {
199 					int x = (width - KNOB_SIZE) / 2;
200 					int y = (height - DIVIDER_KNOB_SIZE) / 2;
201 					for (int i = 0; i < 3; i++) {
202 						Graphics2D graph = (Graphics2D) g.create(x, y + i * (KNOB_SIZE + KNOB_SPACE), KNOB_SIZE + 1, KNOB_SIZE + 1);
203 						graph.setPaint(KNOB_PAINTER);
204 						graph.fillOval(0, 0, KNOB_SIZE, KNOB_SIZE);
205 					}
206 				}
207 				else {
208 					int x = (width - DIVIDER_KNOB_SIZE) / 2;
209 					int y = (height - KNOB_SIZE) / 2;
210 					for (int i = 0; i < 3; i++) {
211 						Graphics2D graph = (Graphics2D) g.create(x + i * (KNOB_SIZE + KNOB_SPACE), y, KNOB_SIZE + 1, KNOB_SIZE + 1);
212 						graph.setPaint(KNOB_PAINTER);
213 						graph.fillOval(0, 0, KNOB_SIZE, KNOB_SIZE);
214 					}
215 				}
216 
217 			}
218 		});
219 
220 		editor = getFIBEditor();
221 
222 		getContentPane().setLayout(new BorderLayout());
223 		getContentPane().add(centerPanel, BorderLayout.CENTER);
224 
225 		validate();
226 
227 		// setVisible(true);
228 
229 	}
230 
231 	public static enum LayoutPosition {
232 		TOP_LEFT, BOTTOM_LEFT, CENTER, TOP_RIGHT, BOTTOM_RIGHT;
233 	}
234 
235 	public static enum LayoutColumns {
236 		LEFT, CENTER, RIGHT;
237 	}
238 
239 	private static final int KNOB_SIZE = 5;
240 	private static final int KNOB_SPACE = 2;
241 	private static final int DIVIDER_SIZE = KNOB_SIZE + 2 * KNOB_SPACE;
242 	private static final int DIVIDER_KNOB_SIZE = 3 * KNOB_SIZE + 2 * KNOB_SPACE;
243 
244 	private static final Paint KNOB_PAINTER = new RadialGradientPaint(new Point((KNOB_SIZE - 1) / 2, (KNOB_SIZE - 1) / 2),
245 			(KNOB_SIZE - 1) / 2, new float[] { 0.0f, 1.0f }, new Color[] { Color.GRAY, Color.LIGHT_GRAY });
246 
247 	private static Split<?> getDefaultLayout() {
248 		Split root = MSL_FACTORY.makeSplit();
249 		root.setName("ROOT");
250 		Split<?> left = getVerticalSplit(LayoutPosition.TOP_LEFT, 0.5, LayoutPosition.BOTTOM_LEFT, 0.5);
251 		left.setWeight(0.2);
252 		left.setName(LayoutColumns.LEFT.name());
253 		Node<?> center = MSL_FACTORY.makeLeaf(LayoutPosition.CENTER.name());
254 		center.setWeight(0.6);
255 		center.setName(LayoutColumns.CENTER.name());
256 		Split<?> right = getVerticalSplit(LayoutPosition.TOP_RIGHT, 0.4, LayoutPosition.BOTTOM_RIGHT, 0.6);
257 		right.setWeight(0.2);
258 		right.setName(LayoutColumns.RIGHT.name());
259 		root.setChildren(left, MSL_FACTORY.makeDivider(), center, MSL_FACTORY.makeDivider(), right);
260 		return root;
261 	}
262 
263 	private static Split<?> getVerticalSplit(LayoutPosition position1, double weight1, LayoutPosition position2, double weight2) {
264 		Split split = MSL_FACTORY.makeSplit();
265 		split.setRowLayout(false);
266 		Leaf<?> l1 = MSL_FACTORY.makeLeaf(position1.name());
267 		l1.setWeight(weight1);
268 		Leaf<?> l2 = MSL_FACTORY.makeLeaf(position2.name());
269 		l2.setWeight(weight2);
270 		split.setChildren(l1, MSL_FACTORY.makeDivider(), l2);
271 		return split;
272 	}
273 
274 	private static Split<?> getVerticalSplit(LayoutPosition position1, LayoutPosition position2, LayoutPosition position3) {
275 		Split split = MSL_FACTORY.makeSplit();
276 		split.setRowLayout(false);
277 		Leaf<?> l1 = MSL_FACTORY.makeLeaf(position1.name());
278 		l1.setWeight(0.2);
279 		Leaf<?> l2 = MSL_FACTORY.makeLeaf(position2.name());
280 		l2.setWeight(0.6);
281 		Leaf<?> l3 = MSL_FACTORY.makeLeaf(position3.name());
282 		l3.setWeight(0.2);
283 		split.setChildren(l1, MSL_FACTORY.makeDivider(), l2, MSL_FACTORY.makeDivider(), l3);
284 		return split;
285 	}
286 
287 	@Override
288 	public void openResource(Resource fibResource, FIBComponent component, Object dataObject) {
289 		if (fibLibrary == null) {
290 			return;
291 		}
292 		if (!isVisible()) {
293 			setVisible(true);
294 		}
295 		getFIBEditor().openFIBComponent(fibResource, component, dataObject, this);
296 
297 		// editor.loadFIB(fibResource, dataObject, this);
298 		toFront();
299 
300 		Resource sourceResource = ResourceLocator.locateSourceCodeResource(fibResource);
301 		if (sourceResource != null) {
302 			System.out.println("On selectionne " + sourceResource);
303 			libraryBrowser.getController().setSelectedComponentResource(sourceResource);
304 		}
305 		else {
306 			System.out.println("On selectionne 2 " + fibResource);
307 			libraryBrowser.getController().setSelectedComponentResource(fibResource);
308 		}
309 	}
310 
311 }