# HG changeset patch # User Jaroslav Tulach # Date 1369886982 -7200 # Node ID 16555ef29e9e4bc224026a2e72c360d426433f50 # Parent 06e7a74c72cf49614e6538f078718aff778cc6a6 When in debug mode, add toolbar diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java Tue May 28 21:49:38 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java Thu May 30 06:09:42 2013 +0200 @@ -67,7 +67,11 @@ public void run() { LOG.log(Level.INFO, "In FX thread. Launching!"); try { - FXBrwsr.launch(FXBrwsr.class, url.toString()); + if (isDebugged()) { + FXBrwsr.launch(FXBrwsr.class, url.toString(), "--toolbar=true"); + } else { + FXBrwsr.launch(FXBrwsr.class, url.toString()); + } LOG.log(Level.INFO, "Launcher is back. Closing"); close(); System.exit(0); diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/BrowserToolbar.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/BrowserToolbar.java Thu May 30 06:09:42 2013 +0200 @@ -0,0 +1,362 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.launcher.fximpl; + +import java.util.ArrayList; +import java.util.List; +import javafx.beans.InvalidationListener; +import javafx.beans.Observable; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.scene.control.ComboBox; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.Separator; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.ToggleGroup; +import javafx.scene.control.ToolBar; +import javafx.scene.control.Tooltip; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Pane; +import javafx.scene.web.WebView; + +final class BrowserToolbar extends ToolBar { + private final ArrayList resizeButtons; + private final WebView webView; + private final Pane container; + private final ToggleGroup resizeGroup = new ToggleGroup(); + private final ComboBox comboZoom = new ComboBox(); + + private BrowserToolbar( WebView webView, Pane container ) { + this.webView = webView; + this.container = container; + + List options = ResizeOption.loadAll(); + options.add( 0, ResizeOption.SIZE_TO_FIT ); + resizeButtons = new ArrayList( options.size() ); + + for( ResizeOption ro : options ) { + ResizeBtn button = new ResizeBtn(ro); + resizeButtons.add( button ); + resizeGroup.getToggles().add( button ); + getItems().add( button ); + } + resizeButtons.get( 0 ).setSelected( true ); + resizeGroup.selectedToggleProperty().addListener( new InvalidationListener() { + + @Override + public void invalidated( Observable o ) { + resize(); + } + }); + + getItems().add( new Separator() ); + + getItems().add( comboZoom ); + ArrayList zoomModel = new ArrayList( 6 ); + zoomModel.add( "200%" ); //NOI18N + zoomModel.add( "150%" ); //NOI18N + zoomModel.add( "100%" ); //NOI18N + zoomModel.add( "75%" ); //NOI18N + zoomModel.add( "50%" ); //NOI18N + comboZoom.setItems( FXCollections.observableList( zoomModel ) ); + comboZoom.setEditable( true ); + comboZoom.setValue( "100%" ); //NOI18N + comboZoom.valueProperty().addListener( new ChangeListener() { + + @Override + public void changed( ObservableValue ov, String t, String t1 ) { + String newZoom = zoom( t1 ); + comboZoom.setValue( newZoom ); + } + }); + + /* + final ToggleButton btnSelMode = new ToggleButton( null, new ImageView( + new Image(BrowserToolbar.class.getResourceAsStream("selectionMode.png")) + )); + btnSelMode.setTooltip( new Tooltip( "Toggle selection mode" ) ); + btnSelMode.selectedProperty().addListener( new InvalidationListener() { + + @Override + public void invalidated( Observable o ) { + toggleSelectionMode( btnSelMode.isSelected() ); + } + }); + getItems().add( btnSelMode ); + */ + } + + public static ToolBar create( WebView view, Pane container ) { + return new BrowserToolbar( view, container ); + } + + private String zoom( String zoomFactor ) { + if( zoomFactor.trim().isEmpty() ) + return null; + + try { + zoomFactor = zoomFactor.replaceAll( "\\%", ""); //NOI18N + zoomFactor = zoomFactor.trim(); + double zoom = Double.parseDouble( zoomFactor ); + zoom = Math.abs( zoom )/100; + if( zoom <= 0.0 ) + return null; + webView.impl_setScale( zoom ); + return (int)(100*zoom) + "%"; //NOI18N + } catch( NumberFormatException nfe ) { + //ignore + } + return null; + } + + private void resize() { + Toggle selection = resizeGroup.getSelectedToggle(); + if( selection instanceof ResizeBtn ) { + ResizeOption ro = ((ResizeBtn)selection).getResizeOption(); + if( ro == ResizeOption.SIZE_TO_FIT ) { + _autofit(); + } else { + _resize( ro.getWidth(), ro.getHeight() ); + } + } + + } + + private void _resize( final double width, final double height ) { + ScrollPane scroll; + if( !(container.getChildren().get( 0) instanceof ScrollPane) ) { + scroll = new ScrollPane(); + scroll.setContent( webView ); + container.getChildren().clear(); + container.getChildren().add( scroll ); + } else { + scroll = ( ScrollPane ) container.getChildren().get( 0 ); + } + scroll.setPrefViewportWidth( width ); + scroll.setPrefViewportHeight(height ); + webView.setMaxWidth( width ); + webView.setMaxHeight( height ); + webView.setMinWidth( width ); + webView.setMinHeight( height ); + } + + private void _autofit() { + if( container.getChildren().get( 0) instanceof ScrollPane ) { + container.getChildren().clear(); + container.getChildren().add( webView ); + } + webView.setMaxWidth( Integer.MAX_VALUE ); + webView.setMaxHeight( Integer.MAX_VALUE ); + webView.setMinWidth( -1 ); + webView.setMinHeight( -1 ); + webView.autosize(); + } + + private void toggleSelectionMode( boolean selMode ) { + System.err.println( "selection mode: " + selMode ); + } + + /** + * Button to resize the browser window. + * Taken from NetBeans. Kept GPLwithCPEx license. + * Portions Copyrighted 2012 Sun Microsystems, Inc. + * + * @author S. Aubrecht + */ + static final class ResizeBtn extends ToggleButton { + + private final ResizeOption resizeOption; + + ResizeBtn(ResizeOption resizeOption) { + super(null, new ImageView(toImage(resizeOption))); + this.resizeOption = resizeOption; + setTooltip(new Tooltip(resizeOption.getToolTip())); + } + + ResizeOption getResizeOption() { + return resizeOption; + } + + static Image toImage(ResizeOption ro) { + if (ro == ResizeOption.SIZE_TO_FIT) { + return ResizeOption.Type.CUSTOM.getImage(); + } + return ro.getType().getImage(); + } + } + + /** + * Immutable value class describing a single button to resize web browser window. + * Taken from NetBeans. Kept GPLwithCPEx license. + * Portions Copyrighted 2012 Sun Microsystems, Inc. + * + * @author S. Aubrecht + */ + static final class ResizeOption { + + private final Type type; + private final String displayName; + private final int width; + private final int height; + private final boolean isDefault; + + enum Type { + DESKTOP("desktop.png"), + TABLET_PORTRAIT("tabletPortrait.png"), + TABLET_LANDSCAPE("tabletLandscape.png"), + SMARTPHONE_PORTRAIT("handheldPortrait.png"), + SMARTPHONE_LANDSCAPE("handheldLandscape.png"), + WIDESCREEN("widescreen.png"), + NETBOOK("netbook.png"), + CUSTOM("sizeToFit.png"); + + + private final String resource; + + private Type(String r) { + resource = r; + } + + public Image getImage() { + return new Image(Type.class.getResourceAsStream(resource)); + } + } + + private ResizeOption(Type type, String displayName, int width, int height, boolean showInToolbar, boolean isDefault) { + super(); + this.type = type; + this.displayName = displayName; + this.width = width; + this.height = height; + this.isDefault = isDefault; + } + + static List loadAll() { + List res = new ArrayList(10); + res.add(ResizeOption.create(ResizeOption.Type.DESKTOP, "Desktop", 1280, 1024, true, true)); + res.add(ResizeOption.create(ResizeOption.Type.TABLET_LANDSCAPE, "Tablet Landscape", 1024, 768, true, true)); + res.add(ResizeOption.create(ResizeOption.Type.TABLET_PORTRAIT, "Tablet Portrait", 768, 1024, true, true)); + res.add(ResizeOption.create(ResizeOption.Type.SMARTPHONE_LANDSCAPE, "Smartphone Landscape", 480, 320, true, true)); + res.add(ResizeOption.create(ResizeOption.Type.SMARTPHONE_PORTRAIT, "Smartphone Portrait", 320, 480, true, true)); + res.add(ResizeOption.create(ResizeOption.Type.WIDESCREEN, "Widescreen", 1680, 1050, false, true)); + res.add(ResizeOption.create(ResizeOption.Type.NETBOOK, "Netbook", 1024, 600, false, true)); + return res; + } + + /** + * Creates a new instance. + * @param type + * @param displayName Display name to show in tooltip, cannot be empty. + * @param width Screen width + * @param height Screen height + * @param showInToolbar True to show in web developer toolbar. + * @param isDefault True if this is a predefined option that cannot be removed. + * @return New instance. + */ + public static ResizeOption create(Type type, String displayName, int width, int height, boolean showInToolbar, boolean isDefault) { + if (width <= 0 || height <= 0) { + throw new IllegalArgumentException("Invalid screen dimensions: " + width + " x " + height); //NOI18N + } + return new ResizeOption(type, displayName, width, height, showInToolbar, isDefault); + } + /** + * An extra option to size the browser content to fit its window. + */ + public static final ResizeOption SIZE_TO_FIT = new ResizeOption(Type.CUSTOM, "Size To Fit", -1, -1, true, true); + + public String getDisplayName() { + return displayName; + } + + public Type getType() { + return type; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public boolean isDefault() { + return isDefault; + } + + @Override + public String toString() { + return displayName; + } + + public String getToolTip() { + if (width < 0 || height < 0) { + return displayName; + } + StringBuilder sb = new StringBuilder(); + sb.append(width); + sb.append(" x "); //NOI18N + sb.append(height); + sb.append(" ("); //NOI18N + sb.append(displayName); + sb.append(')'); //NOI18N + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ResizeOption other = (ResizeOption) obj; + if (this.type != other.type) { + return false; + } + if ((this.displayName == null) ? (other.displayName != null) : !this.displayName.equals(other.displayName)) { + return false; + } + if (this.width != other.width) { + return false; + } + if (this.height != other.height) { + return false; + } + if (this.isDefault != other.isDefault) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 11 * hash + (this.type != null ? this.type.hashCode() : 0); + hash = 11 * hash + (this.displayName != null ? this.displayName.hashCode() : 0); + hash = 11 * hash + this.width; + hash = 11 * hash + this.height; + hash = 11 * hash + (this.isDefault ? 1 : 0); + return hash; + } + } +} diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java Tue May 28 21:49:38 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java Thu May 30 06:09:42 2013 +0200 @@ -34,8 +34,11 @@ import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Button; +import javafx.scene.control.ToolBar; +import javafx.scene.layout.BorderPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; @@ -58,27 +61,42 @@ @Override public void start(Stage primaryStage) throws Exception { - Pane root = new WebViewPane(getParameters().getUnnamed()); - primaryStage.setScene(new Scene(root, 1024, 768)); - LOG.info("Showing the stage"); + WebView view = new WebView(); + WebController wc = new WebController(view, getParameters().getUnnamed()); + + final VBox vbox = new VBox(); + vbox.setAlignment( Pos.CENTER ); + vbox.setStyle( "-fx-background-color: #808080;"); + + + HBox hbox = new HBox(); + hbox.setStyle( "-fx-background-color: #808080;"); + hbox.setAlignment(Pos.CENTER); + hbox.getChildren().add(vbox); + vbox.getChildren().add(view); + + BorderPane root = new BorderPane(); + if ("true".equals(this.getParameters().getNamed().get("toolbar"))) { // NOI18N + final ToolBar toolbar = BrowserToolbar.create(view, vbox); + root.setTop( toolbar ); + } + root.setCenter(hbox); + + Scene scene = new Scene(root, 800, 600); + + primaryStage.setTitle( "Device Emulator" ); + primaryStage.setScene( scene ); primaryStage.show(); - LOG.log(Level.INFO, "State shown: {0}", primaryStage.isShowing()); } /** * Create a resizable WebView pane */ - private class WebViewPane extends Pane { + private static class WebController { private final JVMBridge bridge = new JVMBridge(); - public WebViewPane(List params) { + public WebController(WebView view, List params) { LOG.log(Level.INFO, "Initializing WebView with {0}", params); - VBox.setVgrow(this, Priority.ALWAYS); - setMaxWidth(Double.MAX_VALUE); - setMaxHeight(Double.MAX_VALUE); - WebView view = new WebView(); - view.setMinSize(500, 400); - view.setPrefSize(500, 400); final WebEngine eng = view.getEngine(); try { JVMBridge.addBck2BrwsrLoad(new InitBck2Brwsr(eng)); @@ -120,13 +138,6 @@ dialogStage.showAndWait(); } }); - GridPane grid = new GridPane(); - grid.setVgap(5); - grid.setHgap(5); - GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS); - grid.getColumnConstraints().addAll(new ColumnConstraints(100, 100, Double.MAX_VALUE, Priority.ALWAYS, HPos.CENTER, true), new ColumnConstraints(40, 40, 40, Priority.NEVER, HPos.CENTER, true)); - grid.getChildren().addAll(view); - getChildren().add(grid); } boolean initBck2Brwsr(WebEngine webEngine) { @@ -141,21 +152,6 @@ return false; } - @Override - protected void layoutChildren() { - List managed = getManagedChildren(); - double width = getWidth(); - double height = getHeight(); - double top = getInsets().getTop(); - double right = getInsets().getRight(); - double left = getInsets().getLeft(); - double bottom = getInsets().getBottom(); - for (int i = 0; i < managed.size(); i++) { - Node child = managed.get(i); - layoutInArea(child, left, top, width - left - right, height - top - bottom, 0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER); - } - } - private class InitBck2Brwsr implements ChangeListener, Runnable { private final WebEngine eng; diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/desktop.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/desktop.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/handheldLandscape.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/handheldLandscape.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/handheldPortrait.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/handheldPortrait.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/netbook.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/netbook.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/selectionMode.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/selectionMode.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/sizeToFit.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/sizeToFit.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/tabletLandscape.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/tabletLandscape.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/tabletPortrait.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/tabletPortrait.png has changed diff -r 06e7a74c72cf -r 16555ef29e9e launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/widescreen.png Binary file launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/widescreen.png has changed