Home | History | Annotate | Download | only in gle2
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
     18 
     19 import static com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor.DEPRECATED_CATEGORY;
     20 
     21 import org.eclipse.jface.action.IStatusLineManager;
     22 import org.eclipse.swt.SWT;
     23 import org.eclipse.swt.events.MouseAdapter;
     24 import org.eclipse.swt.events.MouseEvent;
     25 import org.eclipse.swt.graphics.Color;
     26 import org.eclipse.swt.graphics.GC;
     27 import org.eclipse.swt.graphics.Point;
     28 import org.eclipse.swt.graphics.Rectangle;
     29 import org.eclipse.swt.layout.FillLayout;
     30 import org.eclipse.swt.widgets.Composite;
     31 import org.eclipse.swt.widgets.Display;
     32 import org.eclipse.swt.widgets.Event;
     33 import org.eclipse.swt.widgets.Label;
     34 import org.eclipse.swt.widgets.Listener;
     35 import org.eclipse.swt.widgets.Shell;
     36 import org.eclipse.swt.widgets.Tree;
     37 import org.eclipse.swt.widgets.TreeItem;
     38 import org.eclipse.ui.IActionBars;
     39 import org.eclipse.ui.views.properties.IPropertySheetEntry;
     40 import org.eclipse.ui.views.properties.PropertySheetEntry;
     41 import org.eclipse.ui.views.properties.PropertySheetSorter;
     42 
     43 /**
     44  * A customized property sheet page for the graphical layout editor v2.
     45  * <p/>
     46  * Currently it just provides a custom tooltip to display attributes javadocs.
     47  * <p/>
     48  * The property sheet is linked to the current site's selection service.
     49  * <p/>
     50  * Note: this is an exact copy of GLE1's UiPropertySheetPage implementation.
     51  * The idea is that eventually GLE1 will go away and we'll upgrade this to be
     52  * a more robust property editor (it currently lacks on so many levels, it's not
     53  * even worth listing the flaws.)
     54  *
     55  * @since GLE2
     56  */
     57 public class PropertySheetPage extends org.eclipse.ui.views.properties.PropertySheetPage {
     58     private static final String MISC_CATEGORY = "Misc";
     59 
     60     public PropertySheetPage() {
     61         super();
     62 
     63         setSorter(new PropertySheetSorter() {
     64             @Override
     65             public int compareCategories(String categoryA, String categoryB) {
     66                 // Sort the "Deprecated" category to the bottom, and the "Misc"
     67                 // category second to last.
     68                 if (categoryA.equals(DEPRECATED_CATEGORY)) {
     69                     return 1;
     70                 } else if (categoryB.equals(DEPRECATED_CATEGORY)) {
     71                     return -1;
     72                 }
     73                 if (categoryA.equals(MISC_CATEGORY)) {
     74                     return 1;
     75                 } else if (categoryB.equals(MISC_CATEGORY)) {
     76                     return -1;
     77                 }
     78 
     79                 return super.compareCategories(categoryA, categoryB);
     80             }
     81         });
     82     }
     83 
     84     @Override
     85     public void createControl(Composite parent) {
     86         super.createControl(parent);
     87 
     88         setupTooltip();
     89 
     90         // Override parent class' "set status message" behavior. The parent will set
     91         // the status message to the property's "getDescription()" field. That field
     92         // may contain newlines, which means the text gets cut off. We want to instead
     93         // show ALL the text, fit on a single line, and since we don't get to subclass
     94         // the viewer we will just replace the status message with our own, which works
     95         // since our mouse listener is registered later so runs later.
     96         final Tree tree = (Tree) getControl();
     97         tree.addMouseListener(new MouseAdapter() {
     98             @Override
     99             public void mouseDown(MouseEvent event) {
    100                 Point pt = new Point(event.x, event.y);
    101                 TreeItem item = tree.getItem(pt);
    102                 if (item != null) {
    103                     Object object = item.getData();
    104                     if (object instanceof IPropertySheetEntry) {
    105                         IPropertySheetEntry entry = (IPropertySheetEntry) object;
    106                         String help = entry.getDescription();
    107                         if (help != null) {
    108                             // Strip out newlines to make this a single line entry
    109                             help = help.replace('\n', ' ');
    110                             // Remove repeated spaces in case there were trailing spaces
    111                             help = help.replaceAll("  ", " "); //$NON-NLS-1$ //$NON-NLS-2$
    112                             IActionBars actionBars = getSite().getActionBars();
    113                             IStatusLineManager status = actionBars.getStatusLineManager();
    114                             status.setMessage(help);
    115                         }
    116                     }
    117                 }
    118             }
    119         });
    120 
    121         // Fix the selection background. In Eclipse 3.5 and 3.6, the selection color
    122         // is white, painted on top of a white or light blue background (table striping),
    123         // which is practically unreadable.  This is fixed in 3.7M3, but we need a workaround
    124         // for earlier releases. This just paints a solid color under the current line in
    125         // the left column.
    126         tree.addListener(SWT.EraseItem, new Listener() {
    127             public void handleEvent(Event event) {
    128                 if ((event.detail & SWT.SELECTED) != 0 && event.index == 0) {
    129                     GC gc = event.gc;
    130                     Rectangle rect = event.getBounds();
    131                     Color background = gc.getBackground();
    132                     Display display = tree.getDisplay();
    133                     gc.setBackground(display.getSystemColor(SWT.COLOR_LIST_SELECTION));
    134                     gc.fillRectangle(rect.x, rect.y, rect.width, rect.height);
    135                     gc.setBackground(background);
    136                 }
    137             }
    138         });
    139     }
    140 
    141     /**
    142      * Sets up a custom tooltip when hovering over tree items.
    143      * <p/>
    144      * The tooltip will display the element's javadoc, if any, or the item's getText otherwise.
    145      */
    146     private void setupTooltip() {
    147         final Tree tree = (Tree) getControl();
    148 
    149         /*
    150          * Reference:
    151          * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
    152          */
    153 
    154         final Listener listener = new Listener() {
    155             Shell tip = null;
    156             Label label  = null;
    157 
    158             public void handleEvent(Event event) {
    159                 switch(event.type) {
    160                 case SWT.Dispose:
    161                 case SWT.KeyDown:
    162                 case SWT.MouseExit:
    163                 case SWT.MouseDown:
    164                 case SWT.MouseMove:
    165                     if (tip != null) {
    166                         tip.dispose();
    167                         tip = null;
    168                         label = null;
    169                     }
    170                     break;
    171                 case SWT.MouseHover:
    172                     if (tip != null) {
    173                         tip.dispose();
    174                         tip = null;
    175                         label = null;
    176                     }
    177 
    178                     String tooltip = null;
    179 
    180                     TreeItem item = tree.getItem(new Point(event.x, event.y));
    181                     if (item != null) {
    182                         Object data = item.getData();
    183                         if (data instanceof PropertySheetEntry) {
    184                             tooltip = ((PropertySheetEntry) data).getDescription();
    185                         }
    186 
    187                         if (tooltip == null) {
    188                             tooltip = item.getText();
    189                         } else {
    190                             tooltip = item.getText() + ":\r" + tooltip;
    191                         }
    192 
    193                         if (tooltip != null) {
    194                             Shell shell = tree.getShell();
    195                             Display display = tree.getDisplay();
    196 
    197                             tip = new Shell(shell, SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
    198                             tip.setBackground(display .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
    199                             FillLayout layout = new FillLayout();
    200                             layout.marginWidth = 2;
    201                             tip.setLayout(layout);
    202                             label = new Label(tip, SWT.NONE);
    203                             label.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
    204                             label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
    205                             label.setData("_TABLEITEM", item);
    206                             label.setText(tooltip);
    207                             label.addListener(SWT.MouseExit, this);
    208                             label.addListener(SWT.MouseDown, this);
    209                             Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
    210                             Rectangle rect = item.getBounds(0);
    211                             // Display the tooltip on the same line as the property,
    212                             // but offset to the right of wherever the mouse cursor was,
    213                             // such that it does not obscure the list of properties.
    214                             Point pt = tree.toDisplay(event.x + 15, rect.y);
    215                             tip.setBounds(pt.x, pt.y, size.x, size.y);
    216                             tip.setVisible(true);
    217                         }
    218                     }
    219                 }
    220             }
    221         };
    222 
    223         tree.addListener(SWT.Dispose, listener);
    224         tree.addListener(SWT.KeyDown, listener);
    225         tree.addListener(SWT.MouseMove, listener);
    226         tree.addListener(SWT.MouseHover, listener);
    227 
    228     }
    229 
    230 }
    231