Changeset 5628 for trunk

Show
Ignore:
Timestamp:
10/10/08 13:45:38 (6 weeks ago)
Author:
marc.englund@…
Message:

More for Sampler; view mode switcher etc

Location:
trunk
Files:
11 added
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/WebContent/ITMILL/themes/example/styles.css

    r5590 r5628  
    4444} 
    4545 
     46/****************************************************************************** 
     47 * For Sampler 
     48 ******************************************************************************/ 
     49#sampler { 
     50        background-color: white; 
     51} 
     52#sampler .i-expandlayout-topbar { 
     53        border-bottom: 1px solid #999; 
     54} 
     55 
     56#sampler .feature-info { 
     57        background-color: #999; 
     58        color: white; 
     59        padding: 20px; 
     60        line-height: 30px; 
     61} 
     62#sampler .feature-name { 
     63        font-size: 18px; 
     64        font-weight: bold; 
     65} 
     66.i-customcomponent-ModeSwitch .i-button { 
     67        height: 28px; 
     68        border: none; 
     69        border-right: 1px solid #736a60; 
     70        margin: 0px; 
     71} 
     72.i-customcomponent-ModeSwitch .i-button-first-on { 
     73        background: transparent url(sampler/left-on.gif) no-repeat; 
     74} 
     75.i-customcomponent-ModeSwitch .i-button-first { 
     76        background: transparent url(sampler/left.gif) no-repeat; 
     77} 
     78.i-customcomponent-ModeSwitch .i-button-mid-on { 
     79        background: transparent url(sampler/mid-on.gif) no-repeat; 
     80} 
     81.i-customcomponent-ModeSwitch .i-button-mid { 
     82        background: transparent url(sampler/mid.gif) no-repeat; 
     83} 
     84.i-customcomponent-ModeSwitch .i-button-last-on { 
     85        border: none; 
     86        background: transparent url(sampler/right-on.gif) no-repeat right top; 
     87} 
     88.i-customcomponent-ModeSwitch .i-button-last { 
     89        border: none; 
     90        background: transparent url(sampler/right.gif) no-repeat right top; 
     91} 
  • trunk/src/com/itmill/toolkit/demo/sampler/Feature.java

    r5618 r5628  
    1818    protected Example example = null; 
    1919 
     20    public String getPathName() { 
     21        return getClass().getSimpleName(); 
     22    } 
     23 
    2024    /** Get the name of the feature. Override if needed. */ 
    2125    public String getName() { 
    22         String[] cn = this.getClass().getName().split("\\."); 
    23         return cn[cn.length - 1]; 
     26        return getClass().getSimpleName(); 
    2427    } 
    2528 
  • trunk/src/com/itmill/toolkit/demo/sampler/SamplerApplication.java

    r5618 r5628  
    11package com.itmill.toolkit.demo.sampler; 
    22 
     3import java.net.URL; 
     4import java.util.Collection; 
    35import java.util.Collections; 
     6import java.util.Iterator; 
    47import java.util.LinkedList; 
    58 
    69import com.itmill.toolkit.Application; 
    7 import com.itmill.toolkit.data.Container; 
    810import com.itmill.toolkit.data.Item; 
    911import com.itmill.toolkit.data.Property; 
     
    1113import com.itmill.toolkit.data.util.HierarchicalContainer; 
    1214import com.itmill.toolkit.data.util.ObjectProperty; 
     15import com.itmill.toolkit.demo.sampler.ModeSwitch.ModeSwitchEvent; 
    1316import com.itmill.toolkit.demo.sampler.features.DummyFeature; 
    1417import com.itmill.toolkit.terminal.ClassResource; 
     18import com.itmill.toolkit.terminal.DownloadStream; 
     19import com.itmill.toolkit.terminal.ExternalResource; 
    1520import com.itmill.toolkit.terminal.Resource; 
    1621import com.itmill.toolkit.terminal.ThemeResource; 
    1722import com.itmill.toolkit.ui.Button; 
    1823import com.itmill.toolkit.ui.Component; 
     24import com.itmill.toolkit.ui.CustomComponent; 
    1925import com.itmill.toolkit.ui.Embedded; 
    2026import com.itmill.toolkit.ui.ExpandLayout; 
     27import com.itmill.toolkit.ui.GridLayout; 
     28import com.itmill.toolkit.ui.Label; 
    2129import com.itmill.toolkit.ui.SplitPanel; 
    2230import com.itmill.toolkit.ui.Table; 
     
    2836public class SamplerApplication extends Application { 
    2937 
     38    // Main structure, root is always a FeatureSet that is not shown 
    3039    private static final FeatureSet features = new FeatureSet("All", 
    3140            new Feature[] { 
     
    7584            }); 
    7685 
    77     SplitPanel split = null; 
    78  
    79     FeatureList currentList = null; 
    80     FeatureView featureView = null; 
    81  
    82     Container.Ordered allFeatures = null; 
    83     Property currentFeature = new ObjectProperty(null, Feature.class); 
     86    // All features in one container 
     87    private static final HierarchicalContainer allFeatures = features 
     88            .getContainer(true); 
    8489 
    8590    public void init() { 
    8691        setTheme("example"); 
    87         setMainWindow(new MainWindow()); 
    88     } 
    89  
    90     private class MainWindow extends Window { 
    91  
    92         MainWindow() { 
    93             allFeatures = (Container.Ordered) features.getContainer(true); 
    94  
    95             ExpandLayout main = new ExpandLayout(); 
    96             setLayout(main); 
    97             main.setSizeFull(); 
    98  
     92        setMainWindow(new SamplerWindow()); 
     93    } 
     94 
     95    // Supports multiple browser windows 
     96    public Window getWindow(String name) { 
     97        Window w = super.getWindow(name); 
     98        if (w == null) { 
     99            w = new SamplerWindow(); 
     100            w.setName(name); 
     101            addWindow(w); 
     102            // secondary windows will support normal reload if this is 
     103            // enabled, but the url gets ugly: 
     104            // w.open(new ExternalResource(w.getURL())); 
     105 
     106        } 
     107        return w; 
     108    } 
     109 
     110    /** 
     111     * Gets absolute path for given Feature 
     112     *  
     113     * @param f 
     114     *            the Feature whose path to get, of null if not found 
     115     * @return the path of the Feature 
     116     */ 
     117    String getPathFor(Feature f) { 
     118        if (allFeatures.containsId(f)) { 
     119            String path = f.getPathName(); 
     120            f = (Feature) allFeatures.getParent(f); 
     121            while (f != null) { 
     122                path = f.getPathName() + "/" + path; 
     123            } 
     124            return path; 
     125        } 
     126        return null; 
     127    } 
     128 
     129    /** 
     130     * The main window for Sampler, contains the full application UI. 
     131     *  
     132     */ 
     133    private class SamplerWindow extends Window { 
     134        private FeatureList currentList = new FeatureGrid(); 
     135        private FeatureView featureView = new FeatureView(); 
     136        private Property currentFeature = new ObjectProperty(null, 
     137                Feature.class); 
     138 
     139        private MainArea mainArea = new MainArea(); 
     140 
     141        SamplerWindow() { 
     142            // Main top/expanded-bottom layout 
     143            ExpandLayout mainExpand = new ExpandLayout(); 
     144            setLayout(mainExpand); 
     145            mainExpand.setSizeFull(); 
     146 
     147            // topbar (navigation) 
    99148            ExpandLayout nav = new ExpandLayout( 
    100149                    ExpandLayout.ORIENTATION_HORIZONTAL); 
    101             main.addComponent(nav); 
     150            mainExpand.addComponent(nav); 
    102151            nav.setHeight("40px"); 
    103152            nav.setWidth("100%"); 
    104153            nav.setStyleName("topbar"); 
    105154 
    106             split = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); 
     155            // Upper left logo 
     156            Component logo = createLogo(); 
     157            nav.addComponent(logo); 
     158            nav.setComponentAlignment(logo, ExpandLayout.ALIGNMENT_LEFT, 
     159                    ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
     160            nav.expand(logo); 
     161 
     162            // Previous sample 
     163            Button b = createPrevButton(); 
     164            nav.addComponent(b); 
     165            nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, 
     166                    ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
     167            // Next sample 
     168            b = createNextButton(); 
     169            nav.addComponent(b); 
     170            nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, 
     171                    ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
     172 
     173            // Main left/right split; hidden menu tree 
     174            SplitPanel split = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); 
    107175            split.setSizeFull(); 
    108176            split.setSplitPosition(0, SplitPanel.UNITS_PIXELS); 
    109             main.addComponent(split); 
    110             main.expand(split); 
    111  
     177            mainExpand.addComponent(split); 
     178            mainExpand.expand(split); 
     179 
     180            // Menu tree, initially hidden 
     181            Tree tree = createMenuTree(); 
     182            split.addComponent(tree); 
     183 
     184            // Main Area 
     185            split.addComponent(mainArea); 
     186 
     187            // List/grid/coverflow 
     188            Component mode = createModeSwitch(); 
     189            nav.addComponent(mode); 
     190            nav.setComponentAlignment(mode, ExpandLayout.ALIGNMENT_RIGHT, 
     191                    ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
     192 
     193        } 
     194 
     195        /** 
     196         * Displays a Feature(Set) 
     197         *  
     198         * @param f 
     199         *            the Feature(Set) to show 
     200         */ 
     201        public void setFeature(Feature f) { 
     202            currentFeature.setValue(f); 
     203        } 
     204 
     205        /** 
     206         * Displays a Feature(Set) matching the given path, or the main view if 
     207         * no matching Feature(Set) is found. 
     208         *  
     209         * @param path 
     210         *            the path of the Feature(Set) to show 
     211         */ 
     212        public void setFeature(String path) { 
     213            Feature f = features.getFeatureByPath(path); 
     214            setFeature(f); 
     215        } 
     216 
     217        // Handle REST -style urls 
     218        public DownloadStream handleURI(URL context, String relativeUri) { 
     219            Feature f = features.getFeatureByPath(relativeUri); 
     220            if (f != null) { 
     221                setFeature(f); 
     222                open(new ExternalResource(context)); 
     223            } 
     224            return super.handleURI(context, relativeUri); 
     225        } 
     226 
     227        /* 
     228         * SamplerWindow helpers 
     229         */ 
     230 
     231        private Component createLogo() { 
    112232            Button logo = new Button("", new Button.ClickListener() { 
    113233                public void buttonClick(ClickEvent event) { 
     
    115235                } 
    116236            }); 
    117             logo.setDescription("Home"); 
     237            logo.setDescription("↶ Home"); 
    118238            logo.setStyleName(Button.STYLE_LINK); 
    119239            logo.setIcon(new ThemeResource("sampler/logo.png")); 
    120240            logo.setWidth("160px"); 
    121             nav.addComponent(logo); 
    122             nav.setComponentAlignment(logo, ExpandLayout.ALIGNMENT_LEFT, 
    123                     ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
    124  
    125             Button b = new Button("< Previous", new ClickListener() { 
     241            return logo; 
     242        } 
     243 
     244        private Button createNextButton() { 
     245            Button b = new Button("Next sample →", new ClickListener() { 
     246                public void buttonClick(ClickEvent event) { 
     247                    Object curr = currentFeature.getValue(); 
     248                    Object next = allFeatures.nextItemId(curr); 
     249                    while (next != null && next instanceof FeatureSet) { 
     250                        next = allFeatures.nextItemId(next); 
     251                    } 
     252                    currentFeature.setValue(next); 
     253                } 
     254            }); 
     255            b.setStyleName(Button.STYLE_LINK); 
     256            return b; 
     257        } 
     258 
     259        private Button createPrevButton() { 
     260            Button b = new Button("← Previous sample", new ClickListener() { 
    126261                public void buttonClick(ClickEvent event) { 
    127262                    Object curr = currentFeature.getValue(); 
     
    131266                    } 
    132267                    currentFeature.setValue(prev); 
    133  
    134                 } 
    135             }); 
    136             nav.addComponent(b); 
    137             nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, 
    138                     ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
    139  
    140             b = new Button("Next >", new ClickListener() { 
    141                 public void buttonClick(ClickEvent event) { 
    142                     Object curr = currentFeature.getValue(); 
    143                     Object next = allFeatures.nextItemId(curr); 
    144                     while (next != null && next instanceof FeatureSet) { 
    145                         next = allFeatures.nextItemId(next); 
     268                } 
     269            }); 
     270            b.setStyleName(Button.STYLE_LINK); 
     271            return b; 
     272        } 
     273 
     274        private Component createModeSwitch() { 
     275            ModeSwitch m = new ModeSwitch(); 
     276            m.addMode(currentList, "", "View as Icons", new ThemeResource( 
     277                    "sampler/grid.gif")); 
     278            m.addMode(new FeatureGrid(), "", "View as Icons", 
     279                    new ThemeResource("sampler/flow.gif")); 
     280            m.addMode(new FeatureTable(), "", "View as List", 
     281                    new ThemeResource("sampler/list.gif")); 
     282            m.addListener(new ModeSwitch.ModeSwitchListener() { 
     283                public void componentEvent(Event event) { 
     284                    if (event instanceof ModeSwitchEvent) { 
     285                        updateFeatureList((FeatureList) ((ModeSwitchEvent) event) 
     286                                .getMode()); 
    146287                    } 
    147                     currentFeature.setValue(next); 
    148  
    149                 } 
    150             }); 
    151             nav.addComponent(b); 
    152             nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, 
    153                     ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
    154  
    155             b = new Button(":: | \\⊡/ | ≣"); 
    156             nav.addComponent(b); 
    157             nav.expand(b); 
    158             nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_RIGHT, 
    159                     ExpandLayout.ALIGNMENT_VERTICAL_CENTER); 
    160  
     288                } 
     289            }); 
     290            m.setMode(currentList); 
     291            return m; 
     292        } 
     293 
     294        private Tree createMenuTree() { 
    161295            Tree tree = new Tree(); 
    162296            tree.setImmediate(true); 
    163             split.addComponent(tree); 
    164297            tree.setContainerDataSource(allFeatures); 
    165298            tree.setPropertyDataSource(currentFeature); 
     
    170303            tree.addListener(new Table.ValueChangeListener() { 
    171304                public void valueChange(ValueChangeEvent event) { 
    172                     Feature val = (Feature) event.getProperty().getValue(); 
    173                     if (val == null) { 
    174                         currentList.setFeatureContainer(features 
    175                                 .getContainer(true)); 
    176                         if (currentList.getParent() != split) { 
    177                             split.replaceComponent(featureView, currentList); 
    178                         } 
    179  
    180                     } else if (val instanceof FeatureSet) { 
    181                         currentList.setFeatureContainer(((FeatureSet) val) 
    182                                 .getContainer(false)); 
    183                         if (currentList.getParent() != split) { 
    184                             split.replaceComponent(featureView, currentList); 
    185                         } 
    186                     } else { 
    187                         if (featureView.getParent() != split) { 
    188                             split.replaceComponent(currentList, featureView); 
    189                         } 
    190                         featureView.setFeature(val); 
    191                     } 
    192                 } 
    193             }); 
    194  
    195             FeatureTable tbl = new FeatureTable(); 
    196             tbl.setFeatureContainer(allFeatures); 
    197             currentList = tbl; 
    198  
    199             split.addComponent(tbl); 
    200  
    201             featureView = new FeatureView(); 
    202  
    203             Feature f = features.getFeatureByPath("Components/c/DummyFeature"); 
    204             tree.setValue(f); 
    205         } 
    206     } 
    207  
     305                    updateFeatureList(currentList); 
     306                } 
     307            }); 
     308            return tree; 
     309        } 
     310 
     311        private void updateFeatureList(FeatureList list) { 
     312            currentList = list; 
     313            Feature val = (Feature) currentFeature.getValue(); 
     314            if (val == null) { 
     315                currentList.setFeatureContainer(allFeatures); 
     316                mainArea.show(currentList); 
     317            } else if (val instanceof FeatureSet) { 
     318                currentList.setFeatureContainer(((FeatureSet) val) 
     319                        .getContainer(true)); 
     320                mainArea.show(currentList); 
     321            } else { 
     322                mainArea.show(featureView); 
     323                featureView.setFeature(val); 
     324            } 
     325 
     326        } 
     327 
     328    } 
     329 
     330    /** 
     331     * Main area used to show Feature of FeatureList. In effect a one-component 
     332     * container, to minimize repaints. 
     333     */ 
     334    private class MainArea extends CustomComponent { 
     335        MainArea() { 
     336            setSizeFull(); 
     337            setCompositionRoot(new Label()); 
     338        } 
     339 
     340        public void show(Component c) { 
     341            if (getCompositionRoot() != c) { 
     342                setCompositionRoot(c); 
     343            } 
     344        } 
     345    } 
     346 
     347    /** 
     348     * Components capable of listing Features should implement this. 
     349     *  
     350     */ 
     351    interface FeatureList extends Component { 
     352        /** 
     353         * Shows the given Features 
     354         *  
     355         * @param c 
     356         *            Container with Features to show. 
     357         */ 
     358        public void setFeatureContainer(HierarchicalContainer c); 
     359    } 
     360 
     361    /** 
     362     * Table -mode FeatureList. Displays the features in a Table. 
     363     */ 
    208364    private class FeatureTable extends Table implements FeatureList { 
    209365        FeatureTable() { 
     
    230386                public Component generateCell(Table source, Object itemId, 
    231387                        Object columnId) { 
     388                    final Feature feature = (Feature) itemId; 
    232389                    Button b = new Button( 
    233                             itemId instanceof FeatureSet ? "See samples ‣" 
     390                            feature instanceof FeatureSet ? "See samples ‣" 
    234391                                    : "See sample ‣"); 
    235                     b.setData(itemId); 
    236392                    b.addListener(new Button.ClickListener() { 
    237393                        public void buttonClick(ClickEvent event) { 
    238                             currentFeature 
    239                                     .setValue(event.getButton().getData()); 
     394                            ((SamplerWindow) getWindow()).setFeature(feature); 
     395 
    240396                        } 
    241397                    }); 
     
    247403        } 
    248404 
    249         public void setFeatureContainer(Container c) { 
     405        public void setFeatureContainer(HierarchicalContainer c) { 
    250406            setContainerDataSource(c); 
    251407            setVisibleColumns(new Object[] { Feature.PROPERTY_ICON, 
     
    258414    } 
    259415 
     416    private class FeatureGrid extends GridLayout implements FeatureList { 
     417 
     418        FeatureGrid() { 
     419            super(5, 1); 
     420            setWidth("100%"); 
     421        } 
     422 
     423        private void newRow() { 
     424            while (getCursorX() > 0) { 
     425                space(); 
     426            } 
     427        } 
     428 
     429        @Override 
     430        public void setFeatureContainer(HierarchicalContainer c) { 
     431            removeAllComponents(); 
     432            Collection features = c.getItemIds(); 
     433            for (Iterator it = features.iterator(); it.hasNext();) { 
     434                final Feature f = (Feature) it.next(); 
     435                if (f instanceof FeatureSet) { 
     436                    newRow(); 
     437                    addComponent(new Label(f.getName())); 
     438                    if (c.isRoot(f)) { 
     439                        newRow(); 
     440                    } 
     441                } else { 
     442                    Button b = new Button(); 
     443                    b.setWidth("130px"); 
     444                    b.setHeight("130px"); 
     445                    b.setSizeFull(); 
     446                    b.setStyleName(Button.STYLE_LINK); 
     447                    b.setIcon(new ClassResource(f.getClass(), f.getIconName(), 
     448                            SamplerApplication.this)); 
     449                    b.setDescription("<h3>" + f.getName() + "</h3>" 
     450                            + f.getDescription()); 
     451                    b.addListener(new Button.ClickListener() { 
     452                        public void buttonClick(ClickEvent event) { 
     453                            ((SamplerWindow) getWindow()).setFeature(f); 
     454                        } 
     455                    }); 
     456                    addComponent(b); 
     457                } 
     458            } 
     459        } 
     460    } 
     461 
     462    /** 
     463     * A set of features. 
     464     */ 
    260465    static class FeatureSet extends Feature { 
    261466 
    262         String name; 
    263  
    264         Feature[] content; 
    265  
    266         HierarchicalContainer container = null; 
    267  
    268         FeatureSet(String name, Feature[] content) { 
     467        private String pathname; 
     468 
     469        private String name; 
     470 
     471        private String desc; 
     472 
     473        private String icon = "FeatureSet.png"; 
     474 
     475        private Feature[] content; 
     476 
     477        private HierarchicalContainer container = null; 
     478 
     479        private boolean containerRecursive = false; 
     480 
     481        FeatureSet(String pathname, Feature[] content) { 
     482            this(pathname, pathname, "", content); 
     483        } 
     484 
     485        FeatureSet(String pathname, String name, Feature[] content) { 
     486            this(pathname, name, "", content); 
     487        } 
     488 
     489        FeatureSet(String pathname, String name, String desc, Feature[] content) { 
     490            this.pathname = pathname; 
    269491            this.name = name; 
     492            this.desc = desc; 
    270493            this.content = content; 
    271494        } 
     
    284507                String part = parts.remove(0); 
    285508                for (int i = 0; i < fs.length; i++) { 
    286                     if (fs[i].getName().equals(part)) { 
     509                    if (fs[i].getPathName().equals(part)) { 
    287510                        if (parts.isEmpty()) { 
    288511                            return fs[i]; 
     
    299522        } 
    300523 
    301         Container.Hierarchical getContainer(boolean recurse) { 
    302             if (container == null) { 
     524        HierarchicalContainer getContainer(boolean recurse) { 
     525            if (container == null || containerRecursive != recurse) { 
    303526                container = new HierarchicalContainer(); 
    304527                container.addContainerProperty(PROPERTY_NAME, String.class, ""); 
     
    311534        } 
    312535 
    313         private void addFeatures(FeatureSet f, Container.Hierarchical c, 
     536        private void addFeatures(FeatureSet f, HierarchicalContainer c, 
    314537                boolean recurse) { 
    315538            Feature[] features = f.getFeatures(); 
     
    334557        @Override 
    335558        public String getDescription() { 
    336             return null; 
     559            return desc; 
     560        } 
     561 
     562        @Override 
     563        public String getPathName() { 
     564            return pathname; 
    337565        } 
    338566