001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.vmd.screen.device;
042:
043: import org.netbeans.modules.vmd.api.io.PopupUtil;
044: import org.netbeans.modules.vmd.api.model.ComponentProducer;
045: import org.netbeans.modules.vmd.api.model.DesignComponent;
046: import org.netbeans.modules.vmd.api.model.DesignDocument;
047: import org.netbeans.modules.vmd.api.model.common.AcceptSuggestion;
048: import org.netbeans.modules.vmd.api.model.common.AcceptSupport;
049: import org.netbeans.modules.vmd.api.model.common.DesignComponentDataFlavorSupport;
050: import org.netbeans.modules.vmd.api.model.common.DocumentSupport;
051: import org.netbeans.modules.vmd.api.model.presenters.actions.ActionsSupport;
052: import org.netbeans.modules.vmd.api.screen.display.ScreenDeviceInfo;
053: import org.netbeans.modules.vmd.api.screen.display.ScreenDisplayDataFlavorSupport;
054: import org.netbeans.modules.vmd.api.screen.display.ScreenDisplayPresenter;
055: import org.netbeans.modules.vmd.api.screen.display.ScreenPropertyDescriptor;
056: import org.netbeans.modules.vmd.api.screen.display.injector.ScreenInjectorPresenter;
057: import org.netbeans.modules.vmd.screen.MainPanel;
058: import org.netbeans.modules.vmd.screen.ScreenAccessController;
059: import org.netbeans.modules.vmd.screen.ScreenViewController;
060: import org.openide.util.Exceptions;
061: import org.openide.util.NbBundle;
062: import org.openide.util.Utilities;
063:
064: import javax.swing.*;
065: import javax.swing.border.BevelBorder;
066: import java.awt.*;
067: import java.awt.datatransfer.DataFlavor;
068: import java.awt.datatransfer.Transferable;
069: import java.awt.datatransfer.UnsupportedFlavorException;
070: import java.awt.dnd.*;
071: import java.awt.event.InputEvent;
072: import java.awt.event.MouseEvent;
073: import java.awt.event.MouseListener;
074: import java.awt.event.MouseMotionListener;
075: import java.io.IOException;
076: import java.lang.ref.WeakReference;
077: import java.util.*;
078: import java.util.List;
079:
080: /**
081: * @author David Kaspar
082: */
083: public class TopPanel extends JPanel {
084:
085: // private static final Color COLOR_SELECTION_FILL = new Color (235, 235, 231, 64);
086: private static final Color COLOR_SELECTION_DRAW = MainPanel.SELECT_COLOR;
087:
088: // private static final Color COLOR_HOVER_FILL = new Color (0xB9, 0xDF, 0xC0, 128);
089: private static final Color COLOR_HOVER_DRAW = MainPanel.HOVER_COLOR;
090: private static final Color COLOR_DRAW_DND_LINE = new Color(36, 76,
091: 114);
092: //private static final Color COLOR_DRAW_DND_SHAPE = Color.GREEN;
093: private static final Stroke STROKE = new BasicStroke(2.0f);
094: //private static final Stroke STROKE_DND_SHAPE = new BasicStroke(1.0f);
095: private static final Stroke STROKE_DND_LINE = new BasicStroke(3.0f,
096: BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 2.0f,
097: new float[] { 5.0f, 10.0f }, 0.0f);
098:
099: private static final Image IMAGE_INJECT = Utilities
100: .loadImage("org/netbeans/modules/vmd/screen/resources/inject.png"); // NOI18N
101:
102: private DevicePanel devicePanel;
103: private List<SelectionShape> selectionShapes = Collections
104: .emptyList();
105: private ScreenDeviceInfo.Edge horizontalPosition;
106: private ScreenDeviceInfo.Edge verticalPosition;
107:
108: private Point lastHoverPoint = null;
109: private SelectionShape hoverShape = null;
110: private DragSource dragSource;
111: private DesignComponent dragedComponent;
112: private boolean innerDragingInProgress;
113:
114: //private boolean outerGraggingInProgress;
115:
116: public TopPanel(final DevicePanel devicePanel) {
117: this .devicePanel = devicePanel;
118: setOpaque(false);
119: dragSource = DragSource.getDefaultDragSource();
120: dragSource.createDefaultDragGestureRecognizer(this ,
121: DnDConstants.ACTION_COPY_OR_MOVE,
122: new DragGestureListener() {
123: public void dragGestureRecognized(
124: final DragGestureEvent dgEvent) {
125: devicePanel.getController().getDocument()
126: .getTransactionManager().readAccess(
127: new Runnable() {
128: public void run() {
129: dragedComponent = devicePanel
130: .getDesignComponentAt(dgEvent
131: .getDragOrigin());
132: if (dragedComponent == null)
133: return;
134: ScreenDisplayPresenter presenter = dragedComponent
135: .getPresenter(ScreenDisplayPresenter.class);
136: if (presenter == null
137: || presenter
138: .isDraggable() == false) {
139: innerDragingInProgress = false;
140: return;
141: }
142: dragSource
143: .startDrag(
144: dgEvent,
145: null,
146: new ScreenDisplaylTransferable(
147: dragedComponent),
148: null);
149: }
150: });
151: }
152: });
153:
154: addMouseListener(new MouseListener() {
155: public void mouseClicked(MouseEvent e) {
156: if (injectorWindow(e, true))
157: return;
158: select(e);
159: if (e.getButton() == MouseEvent.BUTTON1
160: && e.getClickCount() == 2)
161: editProperty(e);
162: if (e.isPopupTrigger())
163: popupMenu(e);
164: }
165:
166: public void mousePressed(MouseEvent e) {
167: if (injectorWindow(e, false))
168: return;
169: select(e);
170: if (e.isPopupTrigger())
171: popupMenu(e);
172: }
173:
174: public void mouseReleased(MouseEvent e) {
175: if (injectorWindow(e, false))
176: return;
177: select(e);
178: if (e.isPopupTrigger())
179: popupMenu(e);
180: }
181:
182: public void mouseEntered(MouseEvent e) {
183: hover(e.getPoint());
184: }
185:
186: public void mouseExited(MouseEvent e) {
187: hover(e.getPoint());
188: }
189:
190: });
191:
192: addMouseMotionListener(new MouseMotionListener() {
193: public void mouseDragged(MouseEvent e) {
194: hover(e.getPoint());
195: }
196:
197: public void mouseMoved(MouseEvent e) {
198: hover(e.getPoint());
199: }
200: });
201:
202: setDropTarget(new DropTarget(this , new DropTargetListener() {
203:
204: public void dragEnter(DropTargetDragEvent dtde) {
205: if (dtde
206: .getTransferable()
207: .isDataFlavorSupported(
208: ScreenDisplayDataFlavorSupport.HORIZONTAL_POSITION_DATA_FLAVOR))
209: innerDragingInProgress = true;
210: updatePosition(dtde.getLocation());
211: AcceptSuggestion suggestion = getSugestion(dtde
212: .getTransferable());
213: if (isAcceptable(dtde.getLocation(), dtde
214: .getTransferable(), suggestion))
215: dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
216: else
217: dtde.rejectDrag();
218: }
219:
220: public void dragOver(final DropTargetDragEvent dtde) {
221: updatePosition(dtde.getLocation());
222: AcceptSuggestion suggestion = getSugestion(dtde
223: .getTransferable());
224: if (isAcceptable(dtde.getLocation(), dtde
225: .getTransferable(), suggestion)) {
226: dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
227: hoverDnD(dtde.getLocation());
228: } else {
229: hover(dtde.getLocation());
230: dtde.rejectDrag();
231: }
232: }
233:
234: public void dropActionChanged(DropTargetDragEvent dtde) {
235: updatePosition(dtde.getLocation());
236: AcceptSuggestion suggestion = getSugestion(dtde
237: .getTransferable());
238: if (isAcceptable(dtde.getLocation(), dtde
239: .getTransferable(), suggestion)) {
240: dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
241: } else
242: dtde.rejectDrag();
243: }
244:
245: public void dragExit(DropTargetEvent dte) {
246: innerDragingInProgress = false;
247: hover(lastHoverPoint);
248: }
249:
250: public void drop(DropTargetDropEvent dtde) {
251: updatePosition(dtde.getLocation());
252: AcceptSuggestion suggestion = getSugestion(dtde
253: .getTransferable());
254: if (isAcceptable(dtde.getLocation(), dtde
255: .getTransferable(), suggestion)) {
256: accept(dtde.getLocation(), dtde.getTransferable(),
257: suggestion);
258: dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
259: } else {
260: dtde.rejectDrop();
261: }
262: innerDragingInProgress = false;
263: hover(dtde.getLocation());
264: }
265: }));
266: }
267:
268: @Override
269: protected void paintComponent(Graphics g) {
270: super .paintComponent(g);
271: Graphics2D gr = (Graphics2D) g;
272:
273: Stroke previousStroke = gr.getStroke();
274: gr.setStroke(STROKE);
275:
276: for (SelectionShape shape : selectionShapes) {
277: gr.translate(shape.x, shape.y);
278: // gr.setColor (COLOR_SELECTION_FILL);
279: // gr.fill (shape.shape);
280: gr.setColor(COLOR_SELECTION_DRAW);
281: gr.draw(shape.shape);
282: gr.translate(-shape.x, -shape.y);
283: }
284:
285: if (hoverShape != null) {
286: gr.translate(hoverShape.x, hoverShape.y);
287: // gr.setColor (COLOR_HOVER_FILL);
288: // gr.fill (hoverShape.shape);
289:
290: if (innerDragingInProgress) {
291: gr.translate(-hoverShape.x, -hoverShape.y);
292: gr.setColor(COLOR_DRAW_DND_LINE);
293: gr.setStroke(STROKE_DND_LINE);
294: gr.setColor(COLOR_DRAW_DND_LINE);
295: int space = 3;
296: if (verticalPosition == ScreenDeviceInfo.Edge.BOTTOM) {
297: int x1 = (int) hoverShape.x + space;
298: int y1 = hoverShape.y
299: + (int) hoverShape.shape.getBounds()
300: .getHeight();
301: int x2 = (int) hoverShape.x
302: + (int) hoverShape.shape.getBounds()
303: .getWidth() - space;
304: int y2 = (int) hoverShape.y
305: + (int) hoverShape.shape.getBounds()
306: .getHeight();
307: gr.drawLine(x1, y1, x2, y2);
308: } else if (verticalPosition == ScreenDeviceInfo.Edge.TOP) {
309: int x1 = (int) hoverShape.x + space;
310: int y1 = hoverShape.y;
311: int x2 = (int) hoverShape.x
312: + (int) hoverShape.shape.getBounds()
313: .getWidth() - space;
314: int y2 = (int) hoverShape.y;
315: gr.drawLine(x1, y1, x2, y2);
316: }
317: } else {
318: gr.setColor(COLOR_HOVER_DRAW);
319: gr.draw(hoverShape.shape);
320: gr.translate(-hoverShape.x, -hoverShape.y);
321: }
322: }
323:
324: gr.setStroke(previousStroke);
325:
326: for (SelectionShape shape : selectionShapes) {
327: if (shape.enableInjector) {
328: gr.translate(shape.x, shape.y);
329: Rectangle rectangle = shape.shape.getBounds();
330: gr.drawImage(IMAGE_INJECT, rectangle.x
331: + rectangle.width - 20, rectangle.y - 8, null);
332: gr.translate(-shape.x, -shape.y);
333: }
334: }
335: }
336:
337: public void reload() {
338: ScreenAccessController controller = devicePanel.getController();
339: DesignComponent editedScreen = controller.getEditedScreen();
340: ArrayList<SelectionShape> newSelectionShapes = new ArrayList<SelectionShape>();
341: reloadSelectionShapes(newSelectionShapes, editedScreen);
342: selectionShapes = newSelectionShapes;
343: repaint();
344: }
345:
346: private void reloadSelectionShapes(
347: ArrayList<SelectionShape> newSelectionShapes,
348: DesignComponent component) {
349: ScreenDisplayPresenter presenter = component != null ? component
350: .getPresenter(ScreenDisplayPresenter.class)
351: : null;
352: if (presenter == null)
353: return;
354: if (devicePanel.getController().getDocument()
355: .getSelectedComponents().contains(component)) {
356: Shape shape = presenter.getSelectionShape();
357: if (shape != null) {
358: Point point = devicePanel
359: .calculateTranslation(presenter.getView());
360: boolean containsInjector = false;
361: for (ScreenInjectorPresenter injector : component
362: .getPresenters(ScreenInjectorPresenter.class)) {
363: if (injector.isEnabled()) {
364: containsInjector = true;
365: break;
366: }
367: }
368: newSelectionShapes.add(new SelectionShape(point.x,
369: point.y, shape, component.getComponentID(),
370: containsInjector));
371: }
372: }
373: for (DesignComponent child : presenter.getChildren())
374: reloadSelectionShapes(newSelectionShapes, child);
375: }
376:
377: public void select(final MouseEvent e) {
378: final DesignDocument document = devicePanel.getController()
379: .getDocument();
380: if (document == null)
381: return;
382: document.getTransactionManager().writeAccess(new Runnable() {
383: public void run() {
384: DesignComponent component = devicePanel
385: .getDesignComponentAt(e.getPoint());
386: if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) {
387: if (component != null) {
388: ArrayList<DesignComponent> list = new ArrayList<DesignComponent>(
389: document.getSelectedComponents());
390: if (!list.remove(component))
391: list.add(component);
392: document.setSelectedComponents(
393: ScreenViewController.SCREEN_ID, list);
394: }
395: } else {
396: if (component == null)
397: document.setSelectedComponents(
398: ScreenViewController.SCREEN_ID,
399: Collections
400: .<DesignComponent> emptySet());
401: else if (!document.getSelectedComponents()
402: .contains(component))
403: document.setSelectedComponents(
404: ScreenViewController.SCREEN_ID,
405: Collections.singleton(component));
406: }
407: }
408: });
409: }
410:
411: private void hover(final Point point) {
412: lastHoverPoint = point != null ? point : null;
413: final DesignDocument document = devicePanel.getController()
414: .getDocument();
415: if (lastHoverPoint != null && document != null)
416: document.getTransactionManager().readAccess(new Runnable() {
417: public void run() {
418: DesignComponent component = devicePanel
419: .getDesignComponentAt(lastHoverPoint);
420: ScreenDisplayPresenter presenter = component != null ? component
421: .getPresenter(ScreenDisplayPresenter.class)
422: : null;
423: Collection<ScreenPropertyDescriptor> properties = presenter != null ? presenter
424: .getPropertyDescriptors()
425: : Collections
426: .<ScreenPropertyDescriptor> emptySet();
427: if (properties == null)
428: return;
429: for (ScreenPropertyDescriptor property : properties) {
430: Point editorOrigin = devicePanel
431: .calculateTranslation(property
432: .getRelatedView());
433: Shape shape = property.getSelectionShape();
434: if (shape.contains(new Point(point.x
435: - editorOrigin.x, point.y
436: - editorOrigin.y))) {
437: hoverShape = new SelectionShape(
438: editorOrigin.x, editorOrigin.y,
439: shape, Long.MIN_VALUE, false);
440: return;
441: }
442: }
443: hoverShape = null;
444: }
445: });
446: repaint();
447: }
448:
449: private void hoverDnD(final Point point) {
450: lastHoverPoint = point != null ? point : null;
451: final DesignDocument document = devicePanel.getController()
452: .getDocument();
453: if (lastHoverPoint != null && document != null)
454: document.getTransactionManager().readAccess(new Runnable() {
455: public void run() {
456: DesignComponent component = devicePanel
457: .getDesignComponentAt(lastHoverPoint);
458: ScreenDisplayPresenter presenter = component != null ? component
459: .getPresenter(ScreenDisplayPresenter.class)
460: : null;
461: Point editorOrigin = devicePanel
462: .calculateTranslation(presenter.getView());
463: Shape shape = presenter.getSelectionShape();
464: if (shape
465: .contains(new Point(point.x
466: - editorOrigin.x, point.y
467: - editorOrigin.y))) {
468: hoverShape = new SelectionShape(editorOrigin.x,
469: editorOrigin.y, shape, Long.MIN_VALUE,
470: false);
471: return;
472: }
473: hoverShape = null;
474: }
475: });
476: repaint();
477: }
478:
479: private void updatePosition(final Point point) {
480: final DesignDocument document = devicePanel.getController()
481: .getDocument();
482: if (document != null)
483: document.getTransactionManager().readAccess(new Runnable() {
484: public void run() {
485: if (point == null)
486: return;
487: DesignComponent component = devicePanel
488: .getDesignComponentAt(point);
489: ScreenDisplayPresenter presenter = component != null ? component
490: .getPresenter(ScreenDisplayPresenter.class)
491: : null;
492: if (presenter == null)
493: return;
494: Point editorOrigin = devicePanel
495: .calculateTranslation(presenter.getView());
496: double halfVertical = presenter.getView()
497: .getHeight() / 2;
498: double halfHorizontal = presenter.getView()
499: .getWidth() / 2;
500: if ((editorOrigin.getY() + halfVertical) > point
501: .getY())
502: verticalPosition = ScreenDeviceInfo.Edge.TOP;
503: else if ((editorOrigin.getY() + halfVertical) < point
504: .getY())
505: verticalPosition = ScreenDeviceInfo.Edge.BOTTOM;
506: if ((editorOrigin.getX() + halfHorizontal) > point
507: .getX())
508: horizontalPosition = ScreenDeviceInfo.Edge.LEFT;
509: else if ((editorOrigin.getX() + halfHorizontal) < point
510: .getX())
511: horizontalPosition = ScreenDeviceInfo.Edge.RIGHT;
512: }
513: });
514: }
515:
516: public boolean isAcceptable(final Point point,
517: final Transferable transferable,
518: final AcceptSuggestion suggestion) {
519: final DesignDocument document = devicePanel.getController()
520: .getDocument();
521: if (document == null)
522: return false;
523: final boolean[] ret = new boolean[1];
524: document.getTransactionManager().readAccess(new Runnable() {
525: public void run() {
526: DesignComponent component = devicePanel
527: .getDesignComponentAt(point);
528: ret[0] = AcceptSupport.isAcceptable(component,
529: transferable, suggestion);
530: }
531: });
532: return ret[0];
533: }
534:
535: public void accept(final Point point,
536: final Transferable transferable,
537: final AcceptSuggestion suggestion) {
538: final DesignDocument document = devicePanel.getController()
539: .getDocument();
540: if (document == null)
541: return;
542: document.getTransactionManager().writeAccess(new Runnable() {
543: public void run() {
544: DesignComponent component = devicePanel
545: .getDesignComponentAt(point);
546: ComponentProducer.Result result = AcceptSupport.accept(
547: component, transferable, suggestion);
548: AcceptSupport.selectComponentProducerResult(result);
549: }
550: });
551: }
552:
553: public void popupMenu(final MouseEvent e) {
554: final DesignDocument document = devicePanel.getController()
555: .getDocument();
556: if (document == null)
557: return;
558: document.getTransactionManager().readAccess(new Runnable() {
559: public void run() {
560: DesignComponent component = devicePanel
561: .getDesignComponentAt(e.getPoint());
562: if (component == null)
563: return;
564: JPopupMenu menu = Utilities.actionsToPopup(
565: ActionsSupport.createActionsArray(component),
566: TopPanel.this );
567: menu.show(TopPanel.this , e.getX(), e.getY());
568: }
569: });
570: }
571:
572: private boolean injectorWindow(MouseEvent e, boolean invoke) {
573: for (SelectionShape shape : selectionShapes) {
574: if (!shape.enableInjector)
575: continue;
576: Rectangle bounds = shape.shape.getBounds();
577: if (new Rectangle(bounds.x + bounds.width - 20,
578: bounds.y - 8, 16, 16).contains(e.getX() - shape.x,
579: e.getY() - shape.y)) {
580: if (invoke)
581: invokeInjectorWindow(shape.componentID, shape.x
582: + bounds.x + bounds.width - 20, shape.y
583: + bounds.y + 8);
584: return true;
585: }
586: }
587: return false;
588: }
589:
590: private void invokeInjectorWindow(final long componentID,
591: final int x, final int y) {
592: final DesignDocument document = devicePanel.getController()
593: .getDocument();
594: if (document == null)
595: return;
596: final ArrayList<JComponent> views = new ArrayList<JComponent>();
597: document.getTransactionManager().readAccess(new Runnable() {
598: public void run() {
599: DesignComponent component = document
600: .getComponentByUID(componentID);
601: ArrayList<ScreenInjectorPresenter> list = new ArrayList<ScreenInjectorPresenter>(
602: component
603: .getPresenters(ScreenInjectorPresenter.class));
604: DocumentSupport.sortPresentersByOrder(list);
605: for (ScreenInjectorPresenter presenter : list) {
606: if (!presenter.isEnabled())
607: continue;
608: JComponent view = presenter.getViewComponent();
609: if (view == null)
610: continue;
611: views.add(view);
612: }
613: }
614: });
615: if (views.isEmpty())
616: return;
617:
618: JPanel pane = new JPanel();
619: pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory
620: .createBevelBorder(BevelBorder.RAISED), BorderFactory
621: .createEmptyBorder(12, 12, 12, 12)));
622: pane.setLayout(new GridBagLayout());
623: for (JComponent view : views)
624: pane.add(view, new GridBagConstraints(
625: GridBagConstraints.REMAINDER, 0, 1, 1, 1.0, 0.0,
626: GridBagConstraints.NORTHWEST,
627: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
628: 6));
629:
630: Point screen = getLocationOnScreen();
631: PopupUtil.showPopup(pane, NbBundle.getMessage(TopPanel.class,
632: "TITLE_ActionsMenu"), screen.x + x, screen.y + y, true); // NOI18N
633: }
634:
635: private void editProperty(final MouseEvent e) {
636: final DesignDocument document = devicePanel.getController()
637: .getDocument();
638: if (document == null)
639: return;
640: document.getTransactionManager().readAccess(new Runnable() {
641: public void run() {
642: DesignComponent component = devicePanel
643: .getDesignComponentAt(e.getPoint());
644: ScreenDisplayPresenter presenter = component != null ? component
645: .getPresenter(ScreenDisplayPresenter.class)
646: : null;
647: if (presenter == null)
648: return;
649: Collection<ScreenPropertyDescriptor> properties = presenter
650: .getPropertyDescriptors();
651: if (properties == null)
652: return;
653: for (ScreenPropertyDescriptor property : properties) {
654: JComponent relatedView = property.getRelatedView();
655: Shape shape = property.getSelectionShape();
656: Point editorOrigin = devicePanel
657: .calculateTranslation(relatedView);
658: if (shape
659: .contains(new Point(e.getX()
660: - editorOrigin.x, e.getY()
661: - editorOrigin.y))) {
662: Rectangle bounds = shape.getBounds();
663: JComponent editorView = property.getEditor()
664: .createEditorComponent(property);
665: if (editorView == null)
666: return;
667: Insets insets = property.getEditor()
668: .getEditorComponentInsets(editorView);
669: bounds.x -= insets.left;
670: bounds.width += insets.left + insets.right;
671: bounds.y -= insets.top;
672: bounds.height += insets.top + insets.bottom;
673: editorView.setPreferredSize(bounds.getSize());
674: Point relatedViewLocationOnScreen = relatedView
675: .getLocationOnScreen();
676: bounds.translate(relatedViewLocationOnScreen.x,
677: relatedViewLocationOnScreen.y);
678: PopupUtil.showPopup(editorView, NbBundle
679: .getMessage(TopPanel.class,
680: "TITLE_EditorMenu"), bounds.x,
681: bounds.y, true); // NOI18N
682: }
683: }
684: }
685: });
686: }
687:
688: private static class SelectionShape {
689:
690: private int x, y;
691: private Shape shape;
692: private long componentID;
693: private boolean enableInjector;
694:
695: public SelectionShape(int x, int y, Shape shape,
696: long componentID, boolean enableInjector) {
697: this .x = x;
698: this .y = y;
699: this .shape = shape;
700: this .componentID = componentID;
701: this .enableInjector = enableInjector;
702: }
703: }
704:
705: private AcceptSuggestion getSugestion(
706: final Transferable transferable) {
707: final ScreenDisplayPresenter[] displayPresenterWrapper = new ScreenDisplayPresenter[1];
708: if (!(transferable
709: .isDataFlavorSupported(DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR)))
710: return null;
711: devicePanel.getController().getDocument()
712: .getTransactionManager().readAccess(new Runnable() {
713: public void run() {
714: try {
715: DesignComponent component = (DesignComponent) transferable
716: .getTransferData(DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR);
717: displayPresenterWrapper[0] = component
718: .getPresenter(ScreenDisplayPresenter.class);
719: } catch (UnsupportedFlavorException ex) {
720: Exceptions.printStackTrace(ex);
721: } catch (IOException ex) {
722: Exceptions.printStackTrace(ex);
723: }
724: }
725: });
726: if (displayPresenterWrapper[0] == null)
727: return null;
728: return displayPresenterWrapper[0]
729: .createSuggestion(transferable);
730: }
731:
732: private class ScreenDisplaylTransferable implements Transferable {
733: private List DATA_FLAVORS = Arrays
734: .asList(new DataFlavor[] {
735: DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR,
736: ScreenDisplayDataFlavorSupport.HORIZONTAL_POSITION_DATA_FLAVOR,
737: ScreenDisplayDataFlavorSupport.VERTICAL_POSITION_DATA_FLAVOR
738:
739: });
740:
741: private WeakReference<DesignComponent> component;
742:
743: public ScreenDisplaylTransferable(DesignComponent component) {
744: this .component = new WeakReference<DesignComponent>(
745: component);
746: }
747:
748: public DataFlavor[] getTransferDataFlavors() {
749: return (DataFlavor[]) DATA_FLAVORS.toArray();
750: }
751:
752: public boolean isDataFlavorSupported(DataFlavor flavor) {
753: if (DATA_FLAVORS.contains(flavor))
754: return true;
755: return false;
756: }
757:
758: public Object getTransferData(DataFlavor flavor)
759: throws UnsupportedFlavorException, IOException {
760: if (flavor == DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR)
761: return component.get();
762: if (flavor == ScreenDisplayDataFlavorSupport.HORIZONTAL_POSITION_DATA_FLAVOR)
763: return horizontalPosition;
764: if (flavor == ScreenDisplayDataFlavorSupport.VERTICAL_POSITION_DATA_FLAVOR)
765: return verticalPosition;
766: return null;
767: }
768:
769: }
770:
771: }
|