Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
      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.hierarchyviewerlib.ui;
     18 
     19 import com.android.hierarchyviewerlib.device.ViewNode;
     20 import com.android.hierarchyviewerlib.device.ViewNode.Property;
     21 import com.android.hierarchyviewerlib.models.TreeViewModel;
     22 import com.android.hierarchyviewerlib.models.TreeViewModel.ITreeChangeListener;
     23 import com.android.hierarchyviewerlib.ui.util.DrawableViewNode;
     24 import com.android.hierarchyviewerlib.ui.util.TreeColumnResizer;
     25 
     26 import org.eclipse.jface.viewers.ILabelProviderListener;
     27 import org.eclipse.jface.viewers.ITableLabelProvider;
     28 import org.eclipse.jface.viewers.ITreeContentProvider;
     29 import org.eclipse.jface.viewers.TreeViewer;
     30 import org.eclipse.jface.viewers.Viewer;
     31 import org.eclipse.swt.SWT;
     32 import org.eclipse.swt.events.ControlAdapter;
     33 import org.eclipse.swt.events.ControlEvent;
     34 import org.eclipse.swt.events.ControlListener;
     35 import org.eclipse.swt.events.DisposeEvent;
     36 import org.eclipse.swt.events.DisposeListener;
     37 import org.eclipse.swt.graphics.Image;
     38 import org.eclipse.swt.layout.FillLayout;
     39 import org.eclipse.swt.widgets.Composite;
     40 import org.eclipse.swt.widgets.Display;
     41 import org.eclipse.swt.widgets.Tree;
     42 import org.eclipse.swt.widgets.TreeColumn;
     43 
     44 import java.util.ArrayList;
     45 
     46 public class PropertyViewer extends Composite implements ITreeChangeListener {
     47     private TreeViewModel mModel;
     48 
     49     private TreeViewer mTreeViewer;
     50 
     51     private Tree mTree;
     52 
     53     private DrawableViewNode mSelectedNode;
     54 
     55     private class ContentProvider implements ITreeContentProvider, ITableLabelProvider {
     56 
     57         @Override
     58         public Object[] getChildren(Object parentElement) {
     59             synchronized (PropertyViewer.this) {
     60                 if (mSelectedNode != null && parentElement instanceof String) {
     61                     String category = (String) parentElement;
     62                     ArrayList<Property> returnValue = new ArrayList<Property>();
     63                     for (Property property : mSelectedNode.viewNode.properties) {
     64                         if (category.equals(ViewNode.MISCELLANIOUS)) {
     65                             if (property.name.indexOf(':') == -1) {
     66                                 returnValue.add(property);
     67                             }
     68                         } else {
     69                             if (property.name.startsWith(((String) parentElement) + ":")) {
     70                                 returnValue.add(property);
     71                             }
     72                         }
     73                     }
     74                     return returnValue.toArray(new Property[returnValue.size()]);
     75                 }
     76                 return new Object[0];
     77             }
     78         }
     79 
     80         @Override
     81         public Object getParent(Object element) {
     82             synchronized (PropertyViewer.this) {
     83                 if (mSelectedNode != null && element instanceof Property) {
     84                     if (mSelectedNode.viewNode.categories.size() == 0) {
     85                         return null;
     86                     }
     87                     String name = ((Property) element).name;
     88                     int index = name.indexOf(':');
     89                     if (index == -1) {
     90                         return ViewNode.MISCELLANIOUS;
     91                     }
     92                     return name.substring(0, index);
     93                 }
     94                 return null;
     95             }
     96         }
     97 
     98         @Override
     99         public boolean hasChildren(Object element) {
    100             synchronized (PropertyViewer.this) {
    101                 if (mSelectedNode != null && element instanceof String) {
    102                     String category = (String) element;
    103                     for (String name : mSelectedNode.viewNode.namedProperties.keySet()) {
    104                         if (category.equals(ViewNode.MISCELLANIOUS)) {
    105                             if (name.indexOf(':') == -1) {
    106                                 return true;
    107                             }
    108                         } else {
    109                             if (name.startsWith(((String) element) + ":")) {
    110                                 return true;
    111                             }
    112                         }
    113                     }
    114                 }
    115                 return false;
    116             }
    117         }
    118 
    119         @Override
    120         public Object[] getElements(Object inputElement) {
    121             synchronized (PropertyViewer.this) {
    122                 if (mSelectedNode != null && inputElement instanceof TreeViewModel) {
    123                     if (mSelectedNode.viewNode.categories.size() == 0) {
    124                         return mSelectedNode.viewNode.properties
    125                                 .toArray(new Property[mSelectedNode.viewNode.properties.size()]);
    126                     } else {
    127                         return mSelectedNode.viewNode.categories
    128                                 .toArray(new String[mSelectedNode.viewNode.categories.size()]);
    129                     }
    130                 }
    131                 return new Object[0];
    132             }
    133         }
    134 
    135         @Override
    136         public void dispose() {
    137             // pass
    138         }
    139 
    140         @Override
    141         public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    142             // pass
    143         }
    144 
    145         @Override
    146         public Image getColumnImage(Object element, int column) {
    147             return null;
    148         }
    149 
    150         @Override
    151         public String getColumnText(Object element, int column) {
    152             synchronized (PropertyViewer.this) {
    153                 if (mSelectedNode != null) {
    154                     if (element instanceof String && column == 0) {
    155                         String category = (String) element;
    156                         return Character.toUpperCase(category.charAt(0)) + category.substring(1);
    157                     } else if (element instanceof Property) {
    158                         if (column == 0) {
    159                             String returnValue = ((Property) element).name;
    160                             int index = returnValue.indexOf(':');
    161                             if (index != -1) {
    162                                 return returnValue.substring(index + 1);
    163                             }
    164                             return returnValue;
    165                         } else if (column == 1) {
    166                             return ((Property) element).value;
    167                         }
    168                     }
    169                 }
    170                 return "";
    171             }
    172         }
    173 
    174         @Override
    175         public void addListener(ILabelProviderListener listener) {
    176             // pass
    177         }
    178 
    179         @Override
    180         public boolean isLabelProperty(Object element, String property) {
    181             // pass
    182             return false;
    183         }
    184 
    185         @Override
    186         public void removeListener(ILabelProviderListener listener) {
    187             // pass
    188         }
    189     }
    190 
    191     public PropertyViewer(Composite parent) {
    192         super(parent, SWT.NONE);
    193         setLayout(new FillLayout());
    194         mTreeViewer = new TreeViewer(this, SWT.NONE);
    195 
    196         mTree = mTreeViewer.getTree();
    197         mTree.setLinesVisible(true);
    198         mTree.setHeaderVisible(true);
    199 
    200         TreeColumn propertyColumn = new TreeColumn(mTree, SWT.NONE);
    201         propertyColumn.setText("Property");
    202         TreeColumn valueColumn = new TreeColumn(mTree, SWT.NONE);
    203         valueColumn.setText("Value");
    204 
    205         mModel = TreeViewModel.getModel();
    206         ContentProvider contentProvider = new ContentProvider();
    207         mTreeViewer.setContentProvider(contentProvider);
    208         mTreeViewer.setLabelProvider(contentProvider);
    209         mTreeViewer.setInput(mModel);
    210         mModel.addTreeChangeListener(this);
    211 
    212         addDisposeListener(mDisposeListener);
    213 
    214         new TreeColumnResizer(this, propertyColumn, valueColumn);
    215 
    216         addControlListener(mControlListener);
    217 
    218         treeChanged();
    219     }
    220 
    221     private DisposeListener mDisposeListener = new DisposeListener() {
    222         @Override
    223         public void widgetDisposed(DisposeEvent e) {
    224             mModel.removeTreeChangeListener(PropertyViewer.this);
    225         }
    226     };
    227 
    228     // If the window gets too small, hide the data, otherwise SWT throws an
    229     // ERROR.
    230 
    231     private ControlListener mControlListener = new ControlAdapter() {
    232         private boolean noInput = false;
    233 
    234         private boolean noHeader = false;
    235 
    236         @Override
    237         public void controlResized(ControlEvent e) {
    238             if (getBounds().height <= 20) {
    239                 mTree.setHeaderVisible(false);
    240                 noHeader = true;
    241             } else if (noHeader) {
    242                 mTree.setHeaderVisible(true);
    243                 noHeader = false;
    244             }
    245             if (getBounds().height <= 38) {
    246                 mTreeViewer.setInput(null);
    247                 noInput = true;
    248             } else if (noInput) {
    249                 mTreeViewer.setInput(mModel);
    250                 noInput = false;
    251             }
    252         }
    253     };
    254 
    255     @Override
    256     public void selectionChanged() {
    257         synchronized (this) {
    258             mSelectedNode = mModel.getSelection();
    259         }
    260         doRefresh();
    261     }
    262 
    263     @Override
    264     public void treeChanged() {
    265         synchronized (this) {
    266             mSelectedNode = mModel.getSelection();
    267         }
    268         doRefresh();
    269     }
    270 
    271     @Override
    272     public void viewportChanged() {
    273         // pass
    274     }
    275 
    276     @Override
    277     public void zoomChanged() {
    278         // pass
    279     }
    280 
    281     private void doRefresh() {
    282         Display.getDefault().syncExec(new Runnable() {
    283             @Override
    284             public void run() {
    285                 mTreeViewer.refresh();
    286             }
    287         });
    288     }
    289 }
    290