View Javadoc
1   /**
2    * 
3    * Copyright (c) 2013-2015, Openflexo
4    * Copyright (c) 2011-2012, AgileBirds
5    * 
6    * This file is part of Gina-core, 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.view.container.layout;
41  
42  import java.awt.Component;
43  import java.awt.Dimension;
44  import java.awt.Rectangle;
45  import java.util.ArrayList;
46  import java.util.List;
47  import java.util.logging.Logger;
48  
49  import javax.swing.Box;
50  import javax.swing.JComponent;
51  import javax.swing.JPanel;
52  
53  import org.openflexo.gina.model.FIBComponent;
54  import org.openflexo.gina.model.container.layout.GridBagLayoutConstraints;
55  import org.openflexo.gina.swing.editor.view.FIBSwingEditableContainerView;
56  import org.openflexo.gina.swing.editor.view.FIBSwingEditableView;
57  import org.openflexo.gina.swing.editor.view.PlaceHolder;
58  import org.openflexo.gina.swing.editor.view.container.JFIBEditablePanelView;
59  import org.openflexo.gina.swing.view.JFIBView;
60  import org.openflexo.gina.swing.view.container.layout.JGridBagLayout;
61  import org.openflexo.gina.view.FIBView;
62  import org.openflexo.gina.view.impl.FIBContainerViewImpl;
63  import org.openflexo.logging.FlexoLogger;
64  
65  /**
66   * Swing implementation for edition of a GridBag layout
67   * 
68   * @author sylvain
69   */
70  public class JEditableGridBagLayout extends JGridBagLayout
71  		implements JFIBEditableLayoutManager<JPanel, JComponent, GridBagLayoutConstraints> {
72  
73  	private static final Logger logger = FlexoLogger.getLogger(JFIBEditablePanelView.class.getPackage().getName());
74  
75  	public JEditableGridBagLayout(FIBContainerViewImpl<?, JPanel, JComponent> panelView) {
76  		super(panelView);
77  	}
78  
79  	/*@Override
80  	public JFIBPanelView getContainerView() {
81  		return (JFIBPanelView) super.getContainerView();
82  	}*/
83  
84  	@Override
85  	public List<PlaceHolder> makePlaceHolders(final Dimension preferredSize) {
86  
87  		List<PlaceHolder> returned = new ArrayList<>();
88  
89  		if (!getComponent().getProtectContent()) {
90  
91  			JPanel panel = new JPanel();
92  			panel.setLayout(makeGridBagLayout());
93  			panel.setPreferredSize(((JFIBView<?, ?>) getContainerView()).getResultingJComponent().getSize());
94  			panel.setSize(((JFIBView<?, ?>) getContainerView()).getResultingJComponent().getSize());
95  
96  			// final Dimension placeHolderSize = new Dimension(30, 20);
97  			int deltaX = 0; // -preferredSize.width / 2;
98  			int deltaY = 0; // -preferredSize.height / 2;
99  
100 			/*if (getComponent().getBoxLayoutAxis() == BoxLayoutAxis.X_AXIS) {
101 				deltaX = -preferredSize.width / 2;
102 				deltaY = 0;
103 			}
104 			else if (getComponent().getBoxLayoutAxis() == BoxLayoutAxis.Y_AXIS) {
105 				deltaX = 0;
106 				deltaY = -preferredSize.height / 2;
107 			}*/
108 
109 			if (getComponent().getSubComponents().size() == 0) {
110 				// Special case: do not delta placeholders for empty container
111 				deltaX = 0;
112 				deltaY = 0;
113 			}
114 
115 			List<FIBView<?, JComponent>> flattenedContents = getFlattenedContents();
116 
117 			// Before each component, we will add an empty panel to compute
118 			// placeholder location
119 			for (int i = 0; i < flattenedContents.size(); i++) {
120 				panel.removeAll();
121 				for (int j = 0; j < i; j++) {
122 					JFIBView<?, ?> childView = (JFIBView<?, ?>) flattenedContents.get(j);
123 					FIBComponent c = childView.getComponent();
124 					Component child = Box.createRigidArea(childView.getResultingJComponent().getSize());
125 					_addChildToContainerWithConstraints(child, panel, (GridBagLayoutConstraints) c.getConstraints());
126 					// panel.add(Box.createRigidArea(childView.getResultingJComponent().getSize()));
127 				}
128 				JComponent phComponent = new JPanel() {
129 					@Override
130 					public Dimension getPreferredSize() {
131 						return preferredSize;
132 					}
133 				};
134 				// phComponent.setAlignmentX(0.5f);
135 				// phComponent.setAlignmentY(0.5f);
136 				// panel.add(phComponent);
137 				_addChildToContainerWithConstraints(phComponent, panel, new GridBagLayoutConstraints());
138 				for (int j = i; j < flattenedContents.size(); j++) {
139 					JFIBView<?, ?> childView = (JFIBView<?, ?>) flattenedContents.get(j);
140 					FIBComponent c = childView.getComponent();
141 					Component child = Box.createRigidArea(childView.getResultingJComponent().getSize());
142 					_addChildToContainerWithConstraints(child, panel, (GridBagLayoutConstraints) c.getConstraints());
143 					// panel.add(Box.createRigidArea(childView.getResultingJComponent().getSize()));
144 				}
145 				panel.doLayout();
146 				// System.out.println("OK placeholder i=" + i + ", bounds=" +
147 				// phComponent.getBounds());
148 				final int insertionIndex = i;
149 
150 				Rectangle placeHolderBounds = makePlaceHolderBounds(phComponent, deltaX, deltaY, preferredSize);
151 				/*
152 				 * Rectangle placeHolderBounds = new
153 				 * Rectangle(phComponent.getBounds().x + deltaX,
154 				 * phComponent.getBounds().y + deltaY, phComponent.getWidth(),
155 				 * phComponent.getHeight()); if (placeHolderBounds.x < 0) {
156 				 * placeHolderBounds.width = placeHolderBounds.width +
157 				 * placeHolderBounds.x; placeHolderBounds.x = 0; }
158 				 */
159 				PlaceHolder newPlaceHolder = new PlaceHolder((FIBSwingEditableContainerView<?, ?>) getContainerView(), "< item >",
160 						placeHolderBounds) {
161 					@Override
162 					public void insertComponent(FIBComponent newComponent, int oldIndex) {
163 						GridBagLayoutConstraints constraints = new GridBagLayoutConstraints();
164 						newComponent.setConstraints(constraints);
165 						putSubComponentsAtIndex(newComponent, insertionIndex);
166 					}
167 				};
168 				newPlaceHolder.setVisible(false);
169 				// System.out.println(">>> Add placeholder bounds=" + placeHolderBounds);
170 				returned.add(newPlaceHolder);
171 			}
172 
173 			// Then add a placeholder at the end
174 			panel.removeAll();
175 			for (int i = 0; i < flattenedContents.size(); i++) {
176 				JFIBView<?, ?> childView = (JFIBView<?, ?>) flattenedContents.get(i);
177 				FIBComponent c = childView.getComponent();
178 				Component child = Box.createRigidArea(childView.getResultingJComponent().getSize());
179 				_addChildToContainerWithConstraints(child, panel, (GridBagLayoutConstraints) c.getConstraints());
180 				// panel.add(Box.createRigidArea(childView.getResultingJComponent().getSize()));
181 			}
182 			JComponent phComponent = new JPanel() {
183 				@Override
184 				public Dimension getPreferredSize() {
185 					return preferredSize;
186 				}
187 			};
188 			phComponent.setAlignmentX(0.5f);
189 			phComponent.setAlignmentY(0.5f);
190 			_addChildToContainerWithConstraints(phComponent, panel, new GridBagLayoutConstraints());
191 			// panel.add(phComponent);
192 			panel.doLayout();
193 
194 			// System.out.println("OK last placeholder bounds=" +
195 			// phComponent.getBounds());
196 			Rectangle placeHolderBounds = makePlaceHolderBounds(phComponent, deltaX, deltaY, preferredSize);
197 			// Rectangle placeHolderBounds = new
198 			// Rectangle(phComponent.getBounds().x + deltaX,
199 			// phComponent.getBounds().y
200 			// + deltaY, phComponent.getWidth(), phComponent.getHeight());
201 			PlaceHolder newPlaceHolder = new PlaceHolder((FIBSwingEditableContainerView<?, ?>) getContainerView(), "< item >",
202 					placeHolderBounds) {
203 				@Override
204 				public void insertComponent(FIBComponent newComponent, int oldIndex) {
205 					GridBagLayoutConstraints constraints = new GridBagLayoutConstraints();
206 					newComponent.setConstraints(constraints);
207 					putSubComponentsAtIndex(newComponent, getComponent().getSubComponents().size());
208 				}
209 			};
210 			newPlaceHolder.setVisible(false);
211 			// System.out.println("*** Add placeholder bounds=" + placeHolderBounds);
212 			returned.add(newPlaceHolder);
213 		}
214 
215 		return returned;
216 	}
217 
218 	private Rectangle makePlaceHolderBounds(Component component, int deltaX, int deltaY, Dimension preferredSize) {
219 		Rectangle placeHolderBounds = new Rectangle(component.getBounds().x + deltaX, component.getBounds().y + deltaY,
220 				/*(int) preferredSize.getWidth(), (int) preferredSize.getHeight()*/ component.getWidth(), component.getHeight());
221 
222 		if (placeHolderBounds.width < preferredSize.getWidth()) {
223 			placeHolderBounds.width = (int) preferredSize.getWidth();
224 		}
225 		if (placeHolderBounds.height < preferredSize.getHeight()) {
226 			placeHolderBounds.height = (int) preferredSize.getHeight();
227 		}
228 
229 		if (placeHolderBounds.x < 0) {
230 			// placeHolderBounds.width = placeHolderBounds.width + placeHolderBounds.x;
231 			placeHolderBounds.x = 0;
232 		}
233 		if (placeHolderBounds.y < 0) {
234 			// placeHolderBounds.height = placeHolderBounds.height + placeHolderBounds.y;
235 			placeHolderBounds.y = 0;
236 		}
237 		if (placeHolderBounds.x + placeHolderBounds.width > ((JFIBView<?, ?>) getContainerView()).getResultingJComponent().getWidth()) {
238 			// placeHolderBounds.width = getContainerView().getResultingJComponent().getWidth() - placeHolderBounds.x;
239 			placeHolderBounds.x = ((JFIBView<?, ?>) getContainerView()).getResultingJComponent().getWidth() - placeHolderBounds.width;
240 		}
241 		if (placeHolderBounds.y + placeHolderBounds.height > ((JFIBView<?, ?>) getContainerView()).getResultingJComponent().getHeight()) {
242 			// placeHolderBounds.height = getContainerView().getResultingJComponent().getHeight() - placeHolderBounds.y;
243 			placeHolderBounds.y = ((JFIBView<?, ?>) getContainerView()).getResultingJComponent().getHeight() - placeHolderBounds.height;
244 		}
245 		return placeHolderBounds;
246 	}
247 
248 	protected void putSubComponentsAtIndex(FIBComponent subComponent, int index) {
249 		if (getComponent().getSubComponents().contains(subComponent)) {
250 			// This is a simple move
251 			// System.out.println("Moving component at index " + index);
252 			getComponent().moveToSubComponentsAtIndex(subComponent, index);
253 		}
254 		else {
255 			// System.out.println("Inserting component at index " + index);
256 			getComponent().insertToSubComponentsAtIndex(subComponent, index);
257 		}
258 
259 	}
260 
261 	@Override
262 	public void setOperatorContentsStart(FIBView<?, ?> view) {
263 		if (view instanceof FIBSwingEditableView) {
264 			((FIBSwingEditableView<?, ?>) view).setOperatorContentsStart(true);
265 		}
266 	}
267 
268 }