Package gov.nasa.arc.mct.canvas.view

Source Code of gov.nasa.arc.mct.canvas.view.Augmentation

/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package gov.nasa.arc.mct.canvas.view;

import gov.nasa.arc.mct.canvas.MenuManagerAccess;
import gov.nasa.arc.mct.canvas.panel.Panel;
import gov.nasa.arc.mct.gui.View;
import gov.nasa.arc.mct.services.component.MenuManager;
import gov.nasa.arc.mct.services.component.ViewType;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class Augmentation extends JComponent {

    private static final int d = 8;
    private static final int h = d / 2;
    private static final float s = h / 2;
    private Set<Panel> highlightedPanels = new LinkedHashSet<Panel>();
    private static final Color ORIG_COLOR = UIManager.getColor("textHighlight").darker();
    private static final Color HIGHLIGHT_COLOR = new Color(ORIG_COLOR.getRed(), ORIG_COLOR
                    .getGreen(), ORIG_COLOR.getBlue(), 200);
   
    private CanvasManifestation canvasManifestation;
    private JPanel augmentedPanel;
    private boolean hasPanelChanged = false;

    private Component lastMouseEnteredWidget;
    /**
     * This variable represents the widget the mouse was pressed in. The matching mouse released and mouse dragged
     * must be dispatched to the same event.
     */
    private Component mousePressedWidget;
   
    private Point oldLocation;

    private Point selectedPointIfNothingHappens;
   
    boolean spotlightMode = false;
    String spotlightText;

    public Augmentation(JPanel augmentedPanel, CanvasManifestation canvasManifestation) {
        this.augmentedPanel = augmentedPanel;
        this.canvasManifestation = canvasManifestation;
        addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                if (highlightedPanels.isEmpty()) {
                    redispatchEvent(e);
                    return;
                }
               
                if (Augmentation.this.canvasManifestation.isLocked()) {
                    redispatchEvent(e);
                    return;
                }

                selectedPointIfNothingHappens = null;
                Augmentation augmentation = (Augmentation) e.getSource();
                int cursorType = augmentation.getCursor().getType();
                Point newLocation = e.getPoint();
                switch (cursorType) {
                case Cursor.MOVE_CURSOR:
                    newLocation = marshalNewLocation(newLocation, e.getLocationOnScreen());

                    int diffX = newLocation.x - oldLocation.x,
                    diffY = newLocation.y - oldLocation.y;
                    for (Panel panel : highlightedPanels) {
                        Rectangle panelOldBounds = panel.getBounds();
                        panel.setBounds(panelOldBounds.x + diffX, panelOldBounds.y + diffY,
                                        panelOldBounds.width, panelOldBounds.height);
                    }
                    oldLocation = newLocation;
                    break;

                case Cursor.NE_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldNECornerX = panelOldBounds.x + panelOldBounds.width, oldNECornerY = panelOldBounds.y;
                        int diffWidth = newLocation.x - oldNECornerX, diffHeight = newLocation.y
                                        - oldNECornerY;
                        int newWidth = panelOldBounds.width + diffWidth;
                        int newHeight = panelOldBounds.height - diffHeight;
                        if (newWidth > 0 && newHeight > 0)
                            panel.setBounds(panelOldBounds.x, panelOldBounds.y + diffHeight,
                                            newWidth, newHeight);
                    }
                    break;

                case Cursor.SE_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldSECornerX = panelOldBounds.x + panelOldBounds.width, oldSECornerY = panelOldBounds.y
                                        + panelOldBounds.height;
                        int diffWidth = newLocation.x - oldSECornerX, diffHeight = newLocation.y
                                        - oldSECornerY;
                        int newWidth = panelOldBounds.width + diffWidth;
                        int newHeight = panelOldBounds.height + diffHeight;
                        if (newWidth > 0 && newHeight > 0)
                            panel
                                            .setBounds(panelOldBounds.x, panelOldBounds.y,
                                                            newWidth, newHeight);
                    }
                    break;

                case Cursor.SW_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldSWCornerX = panelOldBounds.x, oldSWCornerY = panelOldBounds.y
                                        + panelOldBounds.height;
                        int diffWidth = newLocation.x - oldSWCornerX, diffHeight = newLocation.y
                                        - oldSWCornerY;
                        int newWidth = panelOldBounds.width - diffWidth;
                        int newHeight = panelOldBounds.height + diffHeight;
                        if (newWidth > 0 && newHeight > 0)
                            panel.setBounds(panelOldBounds.x + diffWidth, panelOldBounds.y,
                                            newWidth, newHeight);
                    }
                    break;

                case Cursor.NW_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldSWCornerX = panelOldBounds.x, oldSWCornerY = panelOldBounds.y;
                        int diffWidth = newLocation.x - oldSWCornerX, diffHeight = newLocation.y
                                        - oldSWCornerY;
                        int newWidth = panelOldBounds.width - diffWidth;
                        int newHeight = panelOldBounds.height - diffHeight;
                        if (newWidth > 0 && newHeight > 0)
                            panel.setBounds(panelOldBounds.x + diffWidth, panelOldBounds.y
                                            + diffHeight, newWidth, newHeight);
                    }
                    break;
                case Cursor.E_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldEEdgeX = panelOldBounds.x + panelOldBounds.width;
                        int diffWidth = newLocation.x - oldEEdgeX;
                        int newWidth = panelOldBounds.width + diffWidth;
                        if (newWidth > 0)
                            panel.setBounds(panelOldBounds.x, panelOldBounds.y, newWidth,
                                            panelOldBounds.height);
                    }
                    break;

                case Cursor.S_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldSEdgeY = panelOldBounds.y + panelOldBounds.height;
                        int diffHeight = newLocation.y - oldSEdgeY;
                        int newHeight = panelOldBounds.height + diffHeight;
                        if (newHeight > 0)
                            panel.setBounds(panelOldBounds.x, panelOldBounds.y,
                                            panelOldBounds.width, newHeight);
                    }
                    break;

                case Cursor.W_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldWEdgeX = panelOldBounds.x;
                        int diffWidth = newLocation.x - oldWEdgeX;
                        int newWidth = panelOldBounds.width - diffWidth;
                        if (newWidth > 0)
                            panel.setBounds(panelOldBounds.x + diffWidth, panelOldBounds.y,
                                            newWidth, panelOldBounds.height);
                    }
                    break;

                case Cursor.N_RESIZE_CURSOR:
                    if (highlightedPanels.size() == 1) {
                        Panel panel = highlightedPanels.iterator().next();
                        Rectangle panelOldBounds = panel.getBounds();
                        int oldNEdgeY = panelOldBounds.y;
                        int diffHeight = newLocation.y - oldNEdgeY;
                        int newHeight = panelOldBounds.height - diffHeight;
                        if (newHeight > 0)
                            panel.setBounds(panelOldBounds.x, panelOldBounds.y + diffHeight,
                                            panelOldBounds.width, newHeight);
                    }
                    break;

                default:
                    redispatchEvent(e);
                    return;
                }
                redispatchEvent(e);
                hasPanelChanged = true;
            }

            private Point marshalNewLocation(Point mouseLocation, Point mouseLocationOnScreen) {
                if (highlightedPanels.isEmpty()) {
                    return mouseLocation;
                }

                int smallestX;
                int smallestY;
                Iterator<Panel> it = highlightedPanels.iterator();
                Panel panel = it.next();
                Point bound = panel.getLocationOnScreen();
                smallestX = bound.x;
                smallestY = bound.y;
                while (it.hasNext()) {
                    panel = it.next();
                    bound = panel.getLocationOnScreen();
                    if (bound.x < smallestX) {
                        smallestX = bound.x;
                    }
                    if (bound.y < smallestY) {
                        smallestY = bound.y;
                    }
                }
                Point smallestPoint = new Point(smallestX, smallestY);
                Point returnLocation = new Point(mouseLocation.x, mouseLocation.y);
                if (invalidHorizontalMovement(smallestPoint, mouseLocationOnScreen,
                                Augmentation.this.canvasManifestation,
                                mouseLocation.x < oldLocation.x)) {
                    returnLocation.x = oldLocation.x
                                    + Augmentation.this.canvasManifestation.getLocationOnScreen().x
                                    - smallestX;
                }
                if (invalidVerticalMovement(smallestPoint, mouseLocationOnScreen,
                                Augmentation.this.canvasManifestation,
                                mouseLocation.y < oldLocation.y)) {
                    returnLocation.y = oldLocation.y
                                    + Augmentation.this.canvasManifestation.getLocationOnScreen().y
                                    - smallestY;
                }
                return returnLocation;
            }

            private boolean invalidHorizontalMovement(Point checkPoint, Point mouseLocation,
                            Container parent, boolean leftMoving) {
                Point parentLoc = parent.getLocationOnScreen();
                if ((checkPoint.x <= parentLoc.x) && leftMoving) {
                    return true;
                }
                return false;
            }

            private boolean invalidVerticalMovement(Point checkPoint, Point mouseLocation,
                            Container parent, boolean upMoving) {
                Point parentLoc = parent.getLocationOnScreen();
                if ((checkPoint.y <= parentLoc.y) && upMoving) {
                    return true;
                }
                return false;
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                Augmentation augmentation = (Augmentation) e.getSource();
                if (highlightedPanels.isEmpty()) {
                    augmentation.setAugmentationCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                } else {
                  for (Panel panel : highlightedPanels) {               
                      int currentCursorType = augmentation.getCursor().getType();
                      setCursorType(augmentation, panel, e.getPoint());
                      int newCursorType = augmentation.getCursor().getType();
                      oldLocation = e.getPoint();
                      if (currentCursorType != newCursorType) {
                          return;
                      }
                  }
                }
                redispatchEvent(e);
            }
        });

        // if popup trigger is in title bar, then show popup otherwise redispatchEvent
        //
       
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                redispatchEvent(e);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                redispatchEvent(e);
            }

            @Override
            public void mousePressed(MouseEvent e) {
                selectedPointIfNothingHappens = null;
                // point is not in title area, pass the underlying event to the contents of the panel
                Augmentation augmentation = (Augmentation) e.getSource();
                Point p = e.getLocationOnScreen();
                CanvasManifestation canvas = Augmentation.this.canvasManifestation;
                Panel panel = canvas.findImmediatePanel(p);
               
                // Detects if cursor is within the move or resize region. This region includes
                // d pixels (see field declaration) beyond a panel's width and height.
                if (panel == null && augmentation.getCursor().getType() != Cursor.DEFAULT_CURSOR) {
                    redispatchEvent(e);
                    return;
                }
                   
                if (panel != null && !panel.pointOnBorder(p)) {
                    redispatchEvent(e);
                    return;
                }
               
                if (isPopupTrigger(e)) {
                    showPopupMenu(e);
                    return;
                }
                if (e.getClickCount() == 1) {
                    oldLocation = e.getPoint();
                    if (isDiscontinuousMultiSelection(e)) {
                        canvas.addSingleSelection(p);
                    } else if(canvas.getSelectedPanels().contains(panel)) {
                        canvas.addSingleSelection(p);
                        selectedPointIfNothingHappens = p;
                    } else {
                        canvas.setSingleSelection(p);
                    }
                    if(panel != null) {
                        panel.setTitleBounds();
                        setCursorType(augmentation, panel, e.getPoint());
                    }
                    augmentation.repaint();
                } else if (isDoubleClick(e)) {
                    panel = augmentation.canvasManifestation.setSingleSelection(p);
                    if (panel != null) {
                        panel.getWrappedManifestation().getManifestedComponent().open();
                    }
                }
                redispatchEvent(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (isPopupTrigger(e)) {
                    showPopupMenu(e);
                    return;
                }
                for (Panel panel : highlightedPanels) {
                    Rectangle r = panel.getBounds();
                    r = panel.marshalBound(r);
                    panel.setBounds(r);
                }
                if(selectedPointIfNothingHappens != null) {
                    Augmentation.this.canvasManifestation.setSingleSelection(selectedPointIfNothingHappens);
                    hasPanelChanged = true;
                }
                if (hasPanelChanged) {
                    Augmentation.this.canvasManifestation.fireFocusPersist();
                    Augmentation.this.repaint();
                    Augmentation.this.canvasManifestation.computePreferredSize();
                    hasPanelChanged = false;
                    Augmentation.this.canvasManifestation.updateController(highlightedPanels);
                }
                redispatchEvent(e);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                redispatchEvent(e);
            }

            private boolean isDiscontinuousMultiSelection(MouseEvent e) {
                return e.isControlDown() || e.isMetaDown();
            }

            private boolean isPopupTrigger(MouseEvent e) {
                return e.isPopupTrigger();
            }

            private boolean isDoubleClick(MouseEvent e) {
                return (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e));
            }

            private void showPopupMenu(MouseEvent e) {
                Augmentation augmentation = (Augmentation) e.getSource();
                Point p = e.getLocationOnScreen();
                Panel panel = augmentation.canvasManifestation.findImmediatePanel(p);
               
                if (panel != null && !panel.pointInTitle(p)) {
                    redispatchEvent(e);
                    return;
                }
               
                if (!augmentation.canvasManifestation.getSelectedPanels().contains(panel)) {
                    panel = augmentation.canvasManifestation.setSingleSelection(p);
                }
               
                // Don't show the popup if the canvas is in the inspector.
                // This is because the actions don't use the right canvas.
                // This causes bug MCT-2250.
                // This should be re-enabled once the actions use the correct canvas.
                View m = augmentation.canvasManifestation;
                while (m != null && m.getInfo() != null) {
                    if (m.getInfo().getViewType() == ViewType.INSPECTOR || m.getInfo().getViewType() == ViewType.CENTER_OWNED_INSPECTOR) {
                        return;
                    }
                    m = (View) SwingUtilities.getAncestorOfClass(View.class, m);
                }

                if (panel == null) {
                    MenuManager menuManager = MenuManagerAccess.getMenuManager();
                    JPopupMenu popupMenu = menuManager.getViewPopupMenu(augmentation.canvasManifestation);
                    if (popupMenu != null)
                        popupMenu.show(augmentation.canvasManifestation, e.getX(), e.getY());                   
                } else {
                    Point panelPoint = panel.getLocationOnScreen();
                    JPopupMenu popupMenu = panel.getWrappedManifestation()
                                    .getManifestationPopupMenu();
                    if (popupMenu != null)
                        popupMenu.show(panel, p.x - panelPoint.x, p.y - panelPoint.y);
                }
                augmentation.repaint();
            }
        });

        MarqueSelectionListener marqueSelectionListener = new MarqueSelectionListener(
                        augmentedPanel, new MarqueSelectionListener.MultipleSelectionProvider() {

                            @Override
                            public void selectPanels(Collection<Panel> selection) {
                                Augmentation.this.canvasManifestation.setSelection(selection);
                                Augmentation.this.repaint();
                            }

                            @Override
                            public boolean pointInTopLevelPanel(Point p) {
                                return !Augmentation.this.canvasManifestation
                                                .isPointinaPanel(p);
                            }
                        });

        addMouseListener(marqueSelectionListener);
        addMouseMotionListener(marqueSelectionListener);       
    }

    private void setCursorType(Augmentation augmentation, Panel panel, Point cursorPoint) {
        Point panelLocaion = panel.getLocation();
        /*
         * (x0, y0) (x1, y0) (x2, y0)
         * (x0, y1)          (x2, y1)
         * (x0, y2) (x1, y2) (x2, y2)
         */
        int x0 = panelLocaion.x, x1 = panelLocaion.x + panel.getWidth() / 2, x2 = panelLocaion.x
                        + panel.getWidth();
        int y0 = panelLocaion.y, y1 = panelLocaion.y + panel.getHeight() / 2, y2 = panelLocaion.y
                        + panel.getHeight();

        // Check if cursorPoint falls on the highlight area.
        int x0_left = x0 - h;
        int x0_right = x0 + h;
        int x2_left = x2 - h;
        int x2_right = x2 + h;
        int y0_top = y0 - h;
        int y0_bottom = y0 + h;
        int y2_top = y2 - h;
        int y2_bottom = y2 + h;
        if (cursorPoint.x >= x0_left
                        && cursorPoint.x <= x2_right
                        && cursorPoint.y >= y0_top
                        && cursorPoint.y <= y2_bottom
                        && (!(cursorPoint.x >= x0_right && cursorPoint.x <= x2_left
                                        && cursorPoint.y >= y0_bottom && cursorPoint.y <= y2_top))) {
            if (cursorPoint.x >= x0_left && cursorPoint.x <= x0_right
                            && cursorPoint.y >= y0_top && cursorPoint.y <= y0_bottom) {
                augmentation.setAugmentationCursor(Cursor
                                .getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
            } else {
                int y1_top = y1 - h;
                int y1_bottom = y1 + h;
                if (cursorPoint.x >= x0_left && cursorPoint.x <= x0_right
                                && cursorPoint.y >= y1_top && cursorPoint.y <= y1_bottom) {
                    augmentation.setAugmentationCursor(Cursor
                                    .getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
                } else if (cursorPoint.x >= x0_left && cursorPoint.x <= x0_right
                                && cursorPoint.y >= y2_top && cursorPoint.y <= y2_bottom) {
                    augmentation.setAugmentationCursor(Cursor
                                    .getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
                } else {
                    int x1_left = x1 - h;
                    int x1_right = x1 + h;
                    if (cursorPoint.x >= x1_left && cursorPoint.x <= x1_right
                                    && cursorPoint.y >= y0_top
                                    && cursorPoint.y <= y0_bottom) {
                        augmentation.setAugmentationCursor(Cursor
                                        .getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
                    } else if (cursorPoint.x >= x1_left && cursorPoint.x <= x1_right
                                    && cursorPoint.y >= y2_top
                                    && cursorPoint.y <= y2_bottom) {
                        augmentation.setAugmentationCursor(Cursor
                                        .getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
                    } else if (cursorPoint.x >= x2_left && cursorPoint.x <= x2_right
                                    && cursorPoint.y >= y0_top
                                    && cursorPoint.y <= y0_bottom) {
                        augmentation.setAugmentationCursor(Cursor
                                        .getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
                    } else if (cursorPoint.x >= x2_left && cursorPoint.x <= x2_right
                                    && cursorPoint.y >= y1_top
                                    && cursorPoint.y <= y1_bottom) {
                        augmentation.setAugmentationCursor(Cursor
                                        .getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
                    } else if (cursorPoint.x >= x2_left && cursorPoint.x <= x2_right
                                    && cursorPoint.y >= y2_top
                                    && cursorPoint.y <= y2_bottom) {
                        augmentation.setAugmentationCursor(Cursor
                                        .getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
                    } else
                        augmentation.setAugmentationCursor(Cursor
                                        .getPredefinedCursor(Cursor.MOVE_CURSOR));
                }
            }
        } else
            augmentation.setAugmentationCursor(Cursor
                            .getPredefinedCursor(Cursor.DEFAULT_CURSOR));

        // Check if cursor falls into the panel title area
        if (panel.getTitleBounds().contains(cursorPoint)) {
            if(panel.getIconBounds().contains(cursorPoint)) {
                augmentation.setAugmentationCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            } else {
                augmentation.setAugmentationCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
            }
        }
           
    }

    private void redispatchEvent(MouseEvent e) {
        Component destination;
        if (e.getID() == MouseEvent.MOUSE_DRAGGED || e.getID() == MouseEvent.MOUSE_RELEASED) {
            destination = mousePressedWidget;
        } else  {
            destination = getDeepestComponentWithMouseListeners(e);
        }
        if (destination != null) {
            if (e.getID() == MouseEvent.MOUSE_PRESSED) {
                mousePressedWidget = destination;
            }
            MouseEvent newEvent;
            MouseEvent parentNewEvent;
           
            Point newPoint = SwingUtilities.convertPoint(Augmentation.this.augmentedPanel, e.getPoint(), destination);
           
            if (destination != lastMouseEnteredWidget) {
                newEvent = new MouseEvent(destination, MouseEvent.MOUSE_ENTERED, e.getWhen(), e
                                .getModifiers(), newPoint.x, newPoint.y, e.getXOnScreen(), e
                                .getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e
                                .getButton());
               
                if (destination.getParent() != null) {
               
                    newPoint = SwingUtilities.convertPoint(Augmentation.this.augmentedPanel, e.getPoint(), destination.getParent());
                   
                    parentNewEvent = new MouseEvent(destination.getParent(), MouseEvent.MOUSE_ENTERED, e.getWhen(), e
                                .getModifiers(), newPoint.x, newPoint.y, e.getXOnScreen(), e
                                .getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e
                                .getButton());
                    destination.getParent().dispatchEvent(parentNewEvent);
                   
                }
               
                destination.dispatchEvent(newEvent);
               
             
                if (lastMouseEnteredWidget != null) {
                    newPoint = SwingUtilities.convertPoint(Augmentation.this.augmentedPanel, e
                                    .getPoint(), lastMouseEnteredWidget);
                    newEvent = new MouseEvent(lastMouseEnteredWidget, MouseEvent.MOUSE_EXITED, e
                                    .getWhen(), e.getModifiers(), newPoint.x, newPoint.y, e
                                    .getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e
                                    .isPopupTrigger(), e.getButton());
                   
                    if (lastMouseEnteredWidget.getParent() != null) {
                        parentNewEvent = new MouseEvent(lastMouseEnteredWidget.getParent(), MouseEvent.MOUSE_EXITED, e.getWhen(), e
                                    .getModifiers(), newPoint.x, newPoint.y, e.getXOnScreen(), e
                                    .getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e
                                    .getButton());
                        lastMouseEnteredWidget.getParent().dispatchEvent(parentNewEvent);

                    }
                   
                   
                    lastMouseEnteredWidget.dispatchEvent(newEvent);
                  
                }
                lastMouseEnteredWidget = destination;
            }
                     
                newEvent = new MouseEvent(destination, e.getID(), e.getWhen(), e.getModifiersEx(),
                            newPoint.x, newPoint.y, e.getXOnScreen(), e.getYOnScreen(), e
                                            .getClickCount(), e.isPopupTrigger(), e.getButton());
           
            if (destination.getParent() != null) {
                newPoint = SwingUtilities.convertPoint(Augmentation.this.augmentedPanel, e.getPoint(), destination.getParent());
               
                parentNewEvent = new MouseEvent(destination.getParent(), e.getID(), e.getWhen(), e
                            .getModifiersEx(), newPoint.x, newPoint.y, e.getXOnScreen(), e
                            .getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e
                            .getButton());
                destination.getParent().dispatchEvent(parentNewEvent);
               
            }
           
            destination.dispatchEvent(newEvent);
           
           
        } else if (lastMouseEnteredWidget != null) {           
            Point newPoint = SwingUtilities.convertPoint(Augmentation.this.augmentedPanel, e
                            .getPoint(), lastMouseEnteredWidget);
            MouseEvent newEvent = new MouseEvent(lastMouseEnteredWidget, MouseEvent.MOUSE_EXITED, e
                            .getWhen(), e.getModifiers(), newPoint.x, newPoint.y, e
                            .getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e
                            .isPopupTrigger(), e.getButton());
            lastMouseEnteredWidget.dispatchEvent(newEvent);
            lastMouseEnteredWidget = null;
        }
    }

    private Component getDeepestComponentWithMouseListeners(MouseEvent e) {
        Component widget = SwingUtilities.getDeepestComponentAt(Augmentation.this.augmentedPanel, e
                        .getX(), e.getY());
        while (widget != null && widget != Augmentation.this.augmentedPanel
                        && widget.getMouseListeners().length == 0
                        && widget.getMouseMotionListeners().length == 0)
            widget = widget.getParent();
               
        return widget;
    }

    public void addHighlights(Collection<Panel> panels) {
        for (Panel panel : panels) {
            highlightedPanels.add(panel);
        }
    }

    private Shape createSpotlight(Component c, Rectangle rect, String labelText, FontMetrics fontMetrics, int xOffset) {
        Point convertedPoint = SwingUtilities.convertPoint(c, rect.getLocation(), augmentedPanel);
        int x = convertedPoint.x;
        int y = convertedPoint.y;
        int substringStart = labelText.toLowerCase().indexOf(spotlightText.toLowerCase());
        int substringEnd = substringStart + spotlightText.length();
        RoundRectangle2D roundRectangle2D = new RoundRectangle2D.Double(xOffset + x + fontMetrics.charsWidth(labelText.substring(0, substringStart).toCharArray(), 0, substringStart), y,
                        fontMetrics.charsWidth(labelText.substring(substringStart, substringEnd).toCharArray(), 0, spotlightText.length()),
                        rect.getHeight(), rect.getHeight()/2, rect.getHeight()/2);
        return roundRectangle2D;
    }
   
    private void spotlightText(Container container, Area mask) {       
        for (Component c : container.getComponents()) {
            if (c.isShowing() && c instanceof JLabel) {
                String labelText = ((JLabel) c).getText();
                if (labelText != null && !labelText.isEmpty()) {
                    if (labelText.toLowerCase().contains(spotlightText.toLowerCase())) {
                        Shape spotlight = createSpotlight(c, new Rectangle(0, 0, c.getWidth(), c.getHeight()), labelText, c.getFontMetrics(c.getFont()), 0);
                        mask.subtract(new Area(spotlight));                       
                    }
                }
            } else if (c instanceof JList) {
                JList list = (JList) c;
                ListModel listModel = list.getModel();
                for (int i = 0; i < listModel.getSize(); i++) {
                    Object elementAt = listModel.getElementAt(i);
                    if (elementAt instanceof String) {
                        if (((String) elementAt).toLowerCase().contains(spotlightText.toLowerCase())) {
                            String labelText = (String) elementAt;
                            Rectangle cellBounds = list.getCellBounds(i, i);
                            JLabel label = (JLabel) list.getCellRenderer().getListCellRendererComponent(list, elementAt, i, false, false);                           
                            Shape shape = createSpotlight(c, cellBounds, labelText, label.getFontMetrics(label.getFont()), label.getInsets().left);
                            mask.subtract(new Area(shape));
                        }
                    }
                }
            } else if (c instanceof Container) {
                spotlightText((Container) c, mask);               
            }
        }
    }
   
    @Override
    protected void paintComponent(Graphics g) {
        if (isInSpotlightMode()) {
            spotlight((Graphics2D) g);
            return;
        }
       
        for (Panel panel : highlightedPanels)
            highlight(panel, (Graphics2D) g);
    }
   
    private void spotlight(Graphics2D g2) {
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
       
        g2.setColor(Color.black);
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
        Rectangle2D screen = new Rectangle2D.Double(0, 0, getWidth(), getHeight());
        Area mask = new Area(screen);
       
        spotlightText(augmentedPanel, mask);
       
        g2.fill(mask);       
    }
   
    private boolean isInSpotlightMode() {
        return spotlightText != null && !spotlightText.isEmpty();
    }

    private void highlight(Panel panel, Graphics2D g) {
        highlightedPanels.add(panel);
        panel.setTitleBounds();

        g.setColor(HIGHLIGHT_COLOR);
        g.setStroke(new BasicStroke(s));
        Point location = panel.getLocation();
        g.drawRect(location.x, location.y, panel.getWidth(), panel.getHeight());

        /*
         * (x0, y0) (x1, y0) (x2, y0) (x0, y1) (x2, y1) (x0, y2) (x1, y2) (x2,
         * y2)
         */

        int x0 = location.x, x1 = location.x + panel.getWidth() / 2, x2 = location.x
                        + panel.getWidth();
        int y0 = location.y, y1 = location.y + panel.getHeight() / 2, y2 = location.y
                        + panel.getHeight();

        g.drawRect(x0 - h, y0 - h, d, d);
        g.drawRect(x1 - h, y0 - h, d, d);
        g.drawRect(x2 - h, y0 - h, d, d);

        g.drawRect(x0 - h, y1 - h, d, d);
        g.drawRect(x2 - h, y1 - h, d, d);

        g.drawRect(x0 - h, y2 - h, d, d);
        g.drawRect(x1 - h, y2 - h, d, d);
        g.drawRect(x2 - h, y2 - h, d, d);

        g.setColor(HIGHLIGHT_COLOR.brighter());

        g.fill3DRect(x0 - h, y0 - h, d, d, true);
        g.fill3DRect(x1 - h, y0 - h, d, d, true);
        g.fill3DRect(x2 - h, y0 - h, d, d, true);

        g.fill3DRect(x0 - h, y1 - h, d, d, true);
        g.fill3DRect(x2 - h, y1 - h, d, d, true);

        g.fill3DRect(x0 - h, y2 - h, d, d, true);
        g.fill3DRect(x1 - h, y2 - h, d, d, true);
        g.fill3DRect(x2 - h, y2 - h, d, d, true);
    }

    public void removeHighlights(Collection<Panel> panels) {
        for (Panel panel : panels) {
            highlightedPanels.remove(panel);

            Rectangle bounds = panel.getBounds();
            repaint(new Rectangle(Math.max(bounds.x - h, 0), Math.max(bounds.y - h, 0),
                            bounds.width + d, bounds.height + d));

        }
        setAugmentationCursor(Cursor.getPredefinedCursor(Cursor.getDefaultCursor().getType()));
    }
   
    private void setAugmentationCursor(Cursor cursor) {
        // Get the top level Augmentation
        Augmentation augmentation = this, originator = this;
        Container parent = augmentation.getParent();
        while (parent != null) {
            if (parent instanceof CanvasManifestation)
                augmentation = ((CanvasManifestation) parent).augmentation;
            parent = parent.getParent();
        }
        originator.setCursor(cursor);
        augmentation.setCursor(cursor);
    }

}
TOP

Related Classes of gov.nasa.arc.mct.canvas.view.Augmentation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.