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