launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/BrowserToolbar.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 30 May 2013 06:09:42 +0200
changeset 1166 16555ef29e9e
child 1167 fd8ac9eb0008
permissions -rw-r--r--
When in debug mode, add toolbar
jaroslav@1166
     1
/**
jaroslav@1166
     2
 * Back 2 Browser Bytecode Translator
jaroslav@1166
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@1166
     4
 *
jaroslav@1166
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@1166
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@1166
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@1166
     8
 *
jaroslav@1166
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@1166
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@1166
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@1166
    12
 * GNU General Public License for more details.
jaroslav@1166
    13
 *
jaroslav@1166
    14
 * You should have received a copy of the GNU General Public License
jaroslav@1166
    15
 * along with this program. Look for COPYING file in the top folder.
jaroslav@1166
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
jaroslav@1166
    17
 */
jaroslav@1166
    18
package org.apidesign.bck2brwsr.launcher.fximpl;
jaroslav@1166
    19
jaroslav@1166
    20
import java.util.ArrayList;
jaroslav@1166
    21
import java.util.List;
jaroslav@1166
    22
import javafx.beans.InvalidationListener;
jaroslav@1166
    23
import javafx.beans.Observable;
jaroslav@1166
    24
import javafx.beans.value.ChangeListener;
jaroslav@1166
    25
import javafx.beans.value.ObservableValue;
jaroslav@1166
    26
import javafx.collections.FXCollections;
jaroslav@1166
    27
import javafx.scene.control.ComboBox;
jaroslav@1166
    28
import javafx.scene.control.ScrollPane;
jaroslav@1166
    29
import javafx.scene.control.Separator;
jaroslav@1166
    30
import javafx.scene.control.Toggle;
jaroslav@1166
    31
import javafx.scene.control.ToggleButton;
jaroslav@1166
    32
import javafx.scene.control.ToggleGroup;
jaroslav@1166
    33
import javafx.scene.control.ToolBar;
jaroslav@1166
    34
import javafx.scene.control.Tooltip;
jaroslav@1166
    35
import javafx.scene.image.Image;
jaroslav@1166
    36
import javafx.scene.image.ImageView;
jaroslav@1166
    37
import javafx.scene.layout.Pane;
jaroslav@1166
    38
import javafx.scene.web.WebView;
jaroslav@1166
    39
jaroslav@1166
    40
final class BrowserToolbar extends ToolBar {
jaroslav@1166
    41
    private final ArrayList<ResizeBtn> resizeButtons;
jaroslav@1166
    42
    private final WebView webView;
jaroslav@1166
    43
    private final Pane container;
jaroslav@1166
    44
    private final ToggleGroup resizeGroup = new ToggleGroup();
jaroslav@1166
    45
    private final ComboBox<String> comboZoom = new ComboBox<String>();
jaroslav@1166
    46
    
jaroslav@1166
    47
    private BrowserToolbar( WebView webView, Pane container ) {
jaroslav@1166
    48
        this.webView = webView;
jaroslav@1166
    49
        this.container = container;
jaroslav@1166
    50
        
jaroslav@1166
    51
        List<ResizeOption> options = ResizeOption.loadAll();
jaroslav@1166
    52
        options.add( 0, ResizeOption.SIZE_TO_FIT );
jaroslav@1166
    53
        resizeButtons = new ArrayList<ResizeBtn>( options.size() );
jaroslav@1166
    54
jaroslav@1166
    55
        for( ResizeOption ro : options ) {
jaroslav@1166
    56
            ResizeBtn button = new ResizeBtn(ro);
jaroslav@1166
    57
            resizeButtons.add( button );
jaroslav@1166
    58
            resizeGroup.getToggles().add( button );
jaroslav@1166
    59
            getItems().add( button );
jaroslav@1166
    60
        }
jaroslav@1166
    61
        resizeButtons.get( 0 ).setSelected( true );
jaroslav@1166
    62
        resizeGroup.selectedToggleProperty().addListener( new InvalidationListener() {
jaroslav@1166
    63
jaroslav@1166
    64
            @Override
jaroslav@1166
    65
            public void invalidated( Observable o ) {
jaroslav@1166
    66
                resize();
jaroslav@1166
    67
            }
jaroslav@1166
    68
        });
jaroslav@1166
    69
        
jaroslav@1166
    70
        getItems().add( new Separator() );
jaroslav@1166
    71
jaroslav@1166
    72
        getItems().add( comboZoom );
jaroslav@1166
    73
        ArrayList<String> zoomModel = new ArrayList<String>( 6 );
jaroslav@1166
    74
        zoomModel.add( "200%" ); //NOI18N
jaroslav@1166
    75
        zoomModel.add( "150%" ); //NOI18N
jaroslav@1166
    76
        zoomModel.add( "100%" ); //NOI18N
jaroslav@1166
    77
        zoomModel.add( "75%" ); //NOI18N
jaroslav@1166
    78
        zoomModel.add( "50%" ); //NOI18N
jaroslav@1166
    79
        comboZoom.setItems( FXCollections.observableList( zoomModel ) );
jaroslav@1166
    80
        comboZoom.setEditable( true );
jaroslav@1166
    81
        comboZoom.setValue( "100%" ); //NOI18N
jaroslav@1166
    82
        comboZoom.valueProperty().addListener( new ChangeListener<String>() {
jaroslav@1166
    83
jaroslav@1166
    84
            @Override
jaroslav@1166
    85
            public void changed( ObservableValue<? extends String> ov, String t, String t1 ) {
jaroslav@1166
    86
                String newZoom = zoom( t1 );
jaroslav@1166
    87
                comboZoom.setValue( newZoom );
jaroslav@1166
    88
            }
jaroslav@1166
    89
        });
jaroslav@1166
    90
jaroslav@1166
    91
        /*
jaroslav@1166
    92
        final ToggleButton btnSelMode = new ToggleButton( null, new ImageView(
jaroslav@1166
    93
            new Image(BrowserToolbar.class.getResourceAsStream("selectionMode.png"))
jaroslav@1166
    94
        ));
jaroslav@1166
    95
        btnSelMode.setTooltip( new Tooltip( "Toggle selection mode" ) );
jaroslav@1166
    96
        btnSelMode.selectedProperty().addListener( new InvalidationListener() {
jaroslav@1166
    97
jaroslav@1166
    98
            @Override
jaroslav@1166
    99
            public void invalidated( Observable o ) {
jaroslav@1166
   100
                toggleSelectionMode( btnSelMode.isSelected() );
jaroslav@1166
   101
            }
jaroslav@1166
   102
        });
jaroslav@1166
   103
        getItems().add( btnSelMode );
jaroslav@1166
   104
        */
jaroslav@1166
   105
    }
jaroslav@1166
   106
jaroslav@1166
   107
    public static ToolBar create( WebView view, Pane container ) {
jaroslav@1166
   108
        return new BrowserToolbar( view, container );
jaroslav@1166
   109
    }
jaroslav@1166
   110
jaroslav@1166
   111
    private String zoom( String zoomFactor ) {
jaroslav@1166
   112
        if( zoomFactor.trim().isEmpty() )
jaroslav@1166
   113
            return null;
jaroslav@1166
   114
jaroslav@1166
   115
        try {
jaroslav@1166
   116
            zoomFactor = zoomFactor.replaceAll( "\\%", ""); //NOI18N
jaroslav@1166
   117
            zoomFactor = zoomFactor.trim();
jaroslav@1166
   118
            double zoom = Double.parseDouble( zoomFactor );
jaroslav@1166
   119
            zoom = Math.abs( zoom )/100;
jaroslav@1166
   120
            if( zoom <= 0.0 )
jaroslav@1166
   121
                return null;
jaroslav@1166
   122
            webView.impl_setScale( zoom );
jaroslav@1166
   123
            return (int)(100*zoom) + "%"; //NOI18N
jaroslav@1166
   124
        } catch( NumberFormatException nfe ) {
jaroslav@1166
   125
            //ignore
jaroslav@1166
   126
        }
jaroslav@1166
   127
        return null;
jaroslav@1166
   128
    }
jaroslav@1166
   129
jaroslav@1166
   130
    private void resize() {
jaroslav@1166
   131
        Toggle selection = resizeGroup.getSelectedToggle();
jaroslav@1166
   132
        if( selection instanceof ResizeBtn ) {
jaroslav@1166
   133
            ResizeOption ro = ((ResizeBtn)selection).getResizeOption();
jaroslav@1166
   134
            if( ro == ResizeOption.SIZE_TO_FIT ) {
jaroslav@1166
   135
                _autofit();
jaroslav@1166
   136
            } else {
jaroslav@1166
   137
                _resize( ro.getWidth(), ro.getHeight() );
jaroslav@1166
   138
            }
jaroslav@1166
   139
        }
jaroslav@1166
   140
jaroslav@1166
   141
    }
jaroslav@1166
   142
jaroslav@1166
   143
    private void _resize( final double width, final double height ) {
jaroslav@1166
   144
        ScrollPane scroll;
jaroslav@1166
   145
        if( !(container.getChildren().get( 0) instanceof ScrollPane) ) {
jaroslav@1166
   146
            scroll = new ScrollPane();
jaroslav@1166
   147
            scroll.setContent( webView );
jaroslav@1166
   148
            container.getChildren().clear();
jaroslav@1166
   149
            container.getChildren().add( scroll );
jaroslav@1166
   150
        } else {
jaroslav@1166
   151
            scroll = ( ScrollPane ) container.getChildren().get( 0 );
jaroslav@1166
   152
        }
jaroslav@1166
   153
        scroll.setPrefViewportWidth( width );
jaroslav@1166
   154
        scroll.setPrefViewportHeight(height );
jaroslav@1166
   155
        webView.setMaxWidth( width );
jaroslav@1166
   156
        webView.setMaxHeight( height );
jaroslav@1166
   157
        webView.setMinWidth( width );
jaroslav@1166
   158
        webView.setMinHeight( height );
jaroslav@1166
   159
    }
jaroslav@1166
   160
jaroslav@1166
   161
    private void _autofit() {
jaroslav@1166
   162
        if( container.getChildren().get( 0) instanceof ScrollPane ) {
jaroslav@1166
   163
            container.getChildren().clear();
jaroslav@1166
   164
            container.getChildren().add( webView );
jaroslav@1166
   165
        }
jaroslav@1166
   166
        webView.setMaxWidth( Integer.MAX_VALUE );
jaroslav@1166
   167
        webView.setMaxHeight( Integer.MAX_VALUE );
jaroslav@1166
   168
        webView.setMinWidth( -1 );
jaroslav@1166
   169
        webView.setMinHeight( -1 );
jaroslav@1166
   170
        webView.autosize();
jaroslav@1166
   171
    }
jaroslav@1166
   172
jaroslav@1166
   173
    private void toggleSelectionMode( boolean selMode ) {
jaroslav@1166
   174
        System.err.println( "selection mode: " + selMode );
jaroslav@1166
   175
    }
jaroslav@1166
   176
jaroslav@1166
   177
    /**
jaroslav@1166
   178
     * Button to resize the browser window.
jaroslav@1166
   179
     * Taken from NetBeans. Kept GPLwithCPEx license.
jaroslav@1166
   180
     * Portions Copyrighted 2012 Sun Microsystems, Inc.
jaroslav@1166
   181
     *
jaroslav@1166
   182
     * @author S. Aubrecht
jaroslav@1166
   183
     */
jaroslav@1166
   184
    static final class ResizeBtn extends ToggleButton {
jaroslav@1166
   185
jaroslav@1166
   186
        private final ResizeOption resizeOption;
jaroslav@1166
   187
jaroslav@1166
   188
        ResizeBtn(ResizeOption resizeOption) {
jaroslav@1166
   189
            super(null, new ImageView(toImage(resizeOption)));
jaroslav@1166
   190
            this.resizeOption = resizeOption;
jaroslav@1166
   191
            setTooltip(new Tooltip(resizeOption.getToolTip()));
jaroslav@1166
   192
        }
jaroslav@1166
   193
jaroslav@1166
   194
        ResizeOption getResizeOption() {
jaroslav@1166
   195
            return resizeOption;
jaroslav@1166
   196
        }
jaroslav@1166
   197
jaroslav@1166
   198
        static Image toImage(ResizeOption ro) {
jaroslav@1166
   199
            if (ro == ResizeOption.SIZE_TO_FIT) {
jaroslav@1166
   200
                return ResizeOption.Type.CUSTOM.getImage();
jaroslav@1166
   201
            }
jaroslav@1166
   202
            return ro.getType().getImage();
jaroslav@1166
   203
        }
jaroslav@1166
   204
    }
jaroslav@1166
   205
jaroslav@1166
   206
    /**
jaroslav@1166
   207
     * Immutable value class describing a single button to resize web browser window.
jaroslav@1166
   208
     * Taken from NetBeans. Kept GPLwithCPEx license.
jaroslav@1166
   209
     * Portions Copyrighted 2012 Sun Microsystems, Inc.
jaroslav@1166
   210
     *
jaroslav@1166
   211
     * @author S. Aubrecht
jaroslav@1166
   212
     */
jaroslav@1166
   213
    static final class ResizeOption {
jaroslav@1166
   214
jaroslav@1166
   215
        private final Type type;
jaroslav@1166
   216
        private final String displayName;
jaroslav@1166
   217
        private final int width;
jaroslav@1166
   218
        private final int height;
jaroslav@1166
   219
        private final boolean isDefault;
jaroslav@1166
   220
jaroslav@1166
   221
        enum Type {
jaroslav@1166
   222
            DESKTOP("desktop.png"), 
jaroslav@1166
   223
            TABLET_PORTRAIT("tabletPortrait.png"), 
jaroslav@1166
   224
            TABLET_LANDSCAPE("tabletLandscape.png"), 
jaroslav@1166
   225
            SMARTPHONE_PORTRAIT("handheldPortrait.png"), 
jaroslav@1166
   226
            SMARTPHONE_LANDSCAPE("handheldLandscape.png"), 
jaroslav@1166
   227
            WIDESCREEN("widescreen.png"), 
jaroslav@1166
   228
            NETBOOK("netbook.png"), 
jaroslav@1166
   229
            CUSTOM("sizeToFit.png");
jaroslav@1166
   230
            
jaroslav@1166
   231
            
jaroslav@1166
   232
            private final String resource;
jaroslav@1166
   233
jaroslav@1166
   234
            private Type(String r) {
jaroslav@1166
   235
                resource = r;
jaroslav@1166
   236
            }
jaroslav@1166
   237
jaroslav@1166
   238
            public Image getImage() {
jaroslav@1166
   239
                return new Image(Type.class.getResourceAsStream(resource));
jaroslav@1166
   240
            }
jaroslav@1166
   241
        }
jaroslav@1166
   242
jaroslav@1166
   243
        private ResizeOption(Type type, String displayName, int width, int height, boolean showInToolbar, boolean isDefault) {
jaroslav@1166
   244
            super();
jaroslav@1166
   245
            this.type = type;
jaroslav@1166
   246
            this.displayName = displayName;
jaroslav@1166
   247
            this.width = width;
jaroslav@1166
   248
            this.height = height;
jaroslav@1166
   249
            this.isDefault = isDefault;
jaroslav@1166
   250
        }
jaroslav@1166
   251
jaroslav@1166
   252
        static List<ResizeOption> loadAll() {
jaroslav@1166
   253
            List<ResizeOption> res = new ArrayList<ResizeOption>(10);
jaroslav@1166
   254
            res.add(ResizeOption.create(ResizeOption.Type.DESKTOP, "Desktop", 1280, 1024, true, true));
jaroslav@1166
   255
            res.add(ResizeOption.create(ResizeOption.Type.TABLET_LANDSCAPE, "Tablet Landscape", 1024, 768, true, true));
jaroslav@1166
   256
            res.add(ResizeOption.create(ResizeOption.Type.TABLET_PORTRAIT, "Tablet Portrait", 768, 1024, true, true));
jaroslav@1166
   257
            res.add(ResizeOption.create(ResizeOption.Type.SMARTPHONE_LANDSCAPE, "Smartphone Landscape", 480, 320, true, true));
jaroslav@1166
   258
            res.add(ResizeOption.create(ResizeOption.Type.SMARTPHONE_PORTRAIT, "Smartphone Portrait", 320, 480, true, true));
jaroslav@1166
   259
            res.add(ResizeOption.create(ResizeOption.Type.WIDESCREEN, "Widescreen", 1680, 1050, false, true));
jaroslav@1166
   260
            res.add(ResizeOption.create(ResizeOption.Type.NETBOOK, "Netbook", 1024, 600, false, true));
jaroslav@1166
   261
            return res;
jaroslav@1166
   262
        }
jaroslav@1166
   263
        
jaroslav@1166
   264
        /**
jaroslav@1166
   265
         * Creates a new instance.
jaroslav@1166
   266
         * @param type
jaroslav@1166
   267
         * @param displayName Display name to show in tooltip, cannot be empty.
jaroslav@1166
   268
         * @param width Screen width
jaroslav@1166
   269
         * @param height Screen height
jaroslav@1166
   270
         * @param showInToolbar True to show in web developer toolbar.
jaroslav@1166
   271
         * @param isDefault True if this is a predefined option that cannot be removed.
jaroslav@1166
   272
         * @return New instance.
jaroslav@1166
   273
         */
jaroslav@1166
   274
        public static ResizeOption create(Type type, String displayName, int width, int height, boolean showInToolbar, boolean isDefault) {
jaroslav@1166
   275
            if (width <= 0 || height <= 0) {
jaroslav@1166
   276
                throw new IllegalArgumentException("Invalid screen dimensions: " + width + " x " + height); //NOI18N
jaroslav@1166
   277
            }
jaroslav@1166
   278
            return new ResizeOption(type, displayName, width, height, showInToolbar, isDefault);
jaroslav@1166
   279
        }
jaroslav@1166
   280
        /**
jaroslav@1166
   281
         * An extra option to size the browser content to fit its window.
jaroslav@1166
   282
         */
jaroslav@1166
   283
        public static final ResizeOption SIZE_TO_FIT = new ResizeOption(Type.CUSTOM, "Size To Fit", -1, -1, true, true);
jaroslav@1166
   284
jaroslav@1166
   285
        public String getDisplayName() {
jaroslav@1166
   286
            return displayName;
jaroslav@1166
   287
        }
jaroslav@1166
   288
jaroslav@1166
   289
        public Type getType() {
jaroslav@1166
   290
            return type;
jaroslav@1166
   291
        }
jaroslav@1166
   292
jaroslav@1166
   293
        public int getWidth() {
jaroslav@1166
   294
            return width;
jaroslav@1166
   295
        }
jaroslav@1166
   296
jaroslav@1166
   297
        public int getHeight() {
jaroslav@1166
   298
            return height;
jaroslav@1166
   299
        }
jaroslav@1166
   300
jaroslav@1166
   301
        public boolean isDefault() {
jaroslav@1166
   302
            return isDefault;
jaroslav@1166
   303
        }
jaroslav@1166
   304
jaroslav@1166
   305
        @Override
jaroslav@1166
   306
        public String toString() {
jaroslav@1166
   307
            return displayName;
jaroslav@1166
   308
        }
jaroslav@1166
   309
jaroslav@1166
   310
        public String getToolTip() {
jaroslav@1166
   311
            if (width < 0 || height < 0) {
jaroslav@1166
   312
                return displayName;
jaroslav@1166
   313
            }
jaroslav@1166
   314
            StringBuilder sb = new StringBuilder();
jaroslav@1166
   315
            sb.append(width);
jaroslav@1166
   316
            sb.append(" x "); //NOI18N
jaroslav@1166
   317
            sb.append(height);
jaroslav@1166
   318
            sb.append(" ("); //NOI18N
jaroslav@1166
   319
            sb.append(displayName);
jaroslav@1166
   320
            sb.append(')'); //NOI18N
jaroslav@1166
   321
            return sb.toString();
jaroslav@1166
   322
        }
jaroslav@1166
   323
jaroslav@1166
   324
        @Override
jaroslav@1166
   325
        public boolean equals(Object obj) {
jaroslav@1166
   326
            if (obj == null) {
jaroslav@1166
   327
                return false;
jaroslav@1166
   328
            }
jaroslav@1166
   329
            if (getClass() != obj.getClass()) {
jaroslav@1166
   330
                return false;
jaroslav@1166
   331
            }
jaroslav@1166
   332
            final ResizeOption other = (ResizeOption) obj;
jaroslav@1166
   333
            if (this.type != other.type) {
jaroslav@1166
   334
                return false;
jaroslav@1166
   335
            }
jaroslav@1166
   336
            if ((this.displayName == null) ? (other.displayName != null) : !this.displayName.equals(other.displayName)) {
jaroslav@1166
   337
                return false;
jaroslav@1166
   338
            }
jaroslav@1166
   339
            if (this.width != other.width) {
jaroslav@1166
   340
                return false;
jaroslav@1166
   341
            }
jaroslav@1166
   342
            if (this.height != other.height) {
jaroslav@1166
   343
                return false;
jaroslav@1166
   344
            }
jaroslav@1166
   345
            if (this.isDefault != other.isDefault) {
jaroslav@1166
   346
                return false;
jaroslav@1166
   347
            }
jaroslav@1166
   348
            return true;
jaroslav@1166
   349
        }
jaroslav@1166
   350
jaroslav@1166
   351
        @Override
jaroslav@1166
   352
        public int hashCode() {
jaroslav@1166
   353
            int hash = 7;
jaroslav@1166
   354
            hash = 11 * hash + (this.type != null ? this.type.hashCode() : 0);
jaroslav@1166
   355
            hash = 11 * hash + (this.displayName != null ? this.displayName.hashCode() : 0);
jaroslav@1166
   356
            hash = 11 * hash + this.width;
jaroslav@1166
   357
            hash = 11 * hash + this.height;
jaroslav@1166
   358
            hash = 11 * hash + (this.isDefault ? 1 : 0);
jaroslav@1166
   359
            return hash;
jaroslav@1166
   360
        }
jaroslav@1166
   361
    }
jaroslav@1166
   362
}