Home | History | Annotate | Download | only in table
      1 /*******************************************************************************
      2  * Copyright (c) 2011 Google, Inc.
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *    Google, Inc. - initial API and implementation
     10  *******************************************************************************/
     11 package org.eclipse.wb.internal.core.model.property.table;
     12 
     13 import org.eclipse.swt.SWT;
     14 import org.eclipse.swt.graphics.Point;
     15 import org.eclipse.swt.widgets.Control;
     16 import org.eclipse.swt.widgets.Display;
     17 import org.eclipse.swt.widgets.Event;
     18 import org.eclipse.swt.widgets.Listener;
     19 import org.eclipse.swt.widgets.Shell;
     20 import org.eclipse.wb.internal.core.EnvironmentUtils;
     21 import org.eclipse.wb.internal.core.model.property.Property;
     22 import org.eclipse.wb.internal.core.utils.ui.GridLayoutFactory;
     23 
     24 /**
     25  * Helper class for displaying tooltips.
     26  *
     27  * @author scheglov_ke
     28  * @coverage core.model.property.table
     29  */
     30 class PropertyTableTooltipHelper implements IPropertyTooltipSite {
     31   private final PropertyTable m_table;
     32   private Shell m_tooltip;
     33 
     34   ////////////////////////////////////////////////////////////////////////////
     35   //
     36   // Constructor
     37   //
     38   ////////////////////////////////////////////////////////////////////////////
     39   public PropertyTableTooltipHelper(PropertyTable table) {
     40     m_table = table;
     41     m_table.addListener(SWT.MouseHover, new Listener() {
     42       @Override
     43     public void handleEvent(Event event) {
     44         if (event.stateMask == 0) {
     45           showTooltip();
     46         }
     47       }
     48     });
     49     m_table.addListener(SWT.MouseExit, new Listener() {
     50       @Override
     51     public void handleEvent(Event event) {
     52         // check, may be cursor is now on tooltip, so ignore this MouseExit
     53         {
     54           Control control = Display.getCurrent().getCursorControl();
     55           while (control != null) {
     56             if (control == m_tooltip) {
     57               return;
     58             }
     59             control = control.getParent();
     60           }
     61         }
     62         // no, we should hide tooltip
     63         hideTooltip();
     64       }
     65     });
     66   }
     67 
     68   ////////////////////////////////////////////////////////////////////////////
     69   //
     70   // Access
     71   //
     72   ////////////////////////////////////////////////////////////////////////////
     73   private Property m_property;
     74   private boolean m_onTitle;
     75   private boolean m_onValue;
     76   private int m_beginX;
     77   private int m_endX;
     78   private int m_y;
     79   private int m_rowHeight;
     80 
     81   /**
     82    * {@link PropertyTable} call this method to inform that cursor location was changed.
     83    */
     84   public void update(Property property,
     85       boolean onTitle,
     86       boolean onValue,
     87       int beginX,
     88       int endX,
     89       int y,
     90       int rowHeight) {
     91     m_property = property;
     92     m_onTitle = onTitle;
     93     m_onValue = onValue;
     94     m_beginX = beginX;
     95     m_endX = endX;
     96     m_y = y;
     97     m_rowHeight = rowHeight;
     98   }
     99 
    100   ////////////////////////////////////////////////////////////////////////////
    101   //
    102   // IPropertyTooltipSite
    103   //
    104   ////////////////////////////////////////////////////////////////////////////
    105   @Override
    106 public PropertyTable getTable() {
    107     return m_table;
    108   }
    109 
    110   @Override
    111 public void hideTooltip() {
    112     if (m_tooltip != null && !m_tooltip.isDisposed()) {
    113       m_tooltip.dispose();
    114     }
    115     m_tooltip = null;
    116   }
    117 
    118   ////////////////////////////////////////////////////////////////////////////
    119   //
    120   // Showing tooltip
    121   //
    122   ////////////////////////////////////////////////////////////////////////////
    123   private void showTooltip() {
    124     hideTooltip();
    125     // check for property
    126     if (m_property == null) {
    127       return;
    128     }
    129     //
    130     if (m_onTitle) {
    131       showTooltip(m_property.getAdapter(PropertyTooltipProvider.class), m_beginX, m_endX);
    132     }
    133     if (m_onValue) {
    134       showTooltip(m_property.getEditor().getAdapter(PropertyTooltipProvider.class),
    135               m_beginX, m_endX);
    136     }
    137   }
    138 
    139   private void showTooltip(PropertyTooltipProvider provider, int startX, int endX) {
    140       if (provider == null) {
    141         return;
    142       }
    143     // create Shell
    144     {
    145       m_tooltip = new Shell(m_table.getShell(), SWT.NO_FOCUS | SWT.ON_TOP | SWT.TOOL | SWT.SINGLE);
    146       configureColors(m_tooltip);
    147       GridLayoutFactory.create(m_tooltip).noMargins();
    148     }
    149     // prepare control
    150     Control control = provider.createTooltipControl(m_property, m_tooltip, endX - startX, this);
    151     if (control == null) {
    152       hideTooltip();
    153       return;
    154     }
    155     // show Shell
    156     {
    157       // prepare tooltip location
    158       Point tooltipLocation;
    159       if (provider.getTooltipPosition() == PropertyTooltipProvider.ON) {
    160         tooltipLocation = m_table.toDisplay(new Point(startX, m_y));
    161       } else {
    162         tooltipLocation = m_table.toDisplay(new Point(startX, m_y + m_rowHeight));
    163       }
    164       // set location/size and open
    165       m_tooltip.setLocation(tooltipLocation.x, tooltipLocation.y);
    166       // for non-windows systems the tooltip may have invalid tooltip bounds
    167       // because some widget's API functions may fail if tooltip content is not visible
    168       // ex., on MacOSX tree widget's items has zero bounds since they are not yet visible.
    169       // the workaround is to preset tooltip size to big values before any computeSize called.
    170       if (!EnvironmentUtils.IS_WINDOWS) {
    171         m_tooltip.setSize(1000, 1000);
    172       }
    173       m_tooltip.setSize(m_tooltip.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    174       provider.show(m_tooltip);
    175     }
    176   }
    177 
    178   ////////////////////////////////////////////////////////////////////////////
    179   //
    180   // Utils
    181   //
    182   ////////////////////////////////////////////////////////////////////////////
    183   /**
    184    * Sets given {@link Control} correct background/foreground for tooltips.
    185    */
    186   private void configureColors(Control control) {
    187     Display display = Display.getCurrent();
    188     control.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
    189     control.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
    190   }
    191 }
    192