package org.geogebra.web.web.gui.toolbar.mow; import org.geogebra.common.euclidian.EuclidianConstants; import org.geogebra.web.html5.gui.FastClickHandler; import org.geogebra.web.html5.gui.util.LayoutUtilW; import org.geogebra.web.html5.gui.util.NoDragImage; import org.geogebra.web.html5.main.AppW; import org.geogebra.web.web.gui.ImageFactory; import org.geogebra.web.web.gui.app.GGWToolBar; import org.geogebra.web.web.gui.images.ImgResourceHelper; import org.geogebra.web.web.gui.toolbar.images.ToolbarResources; import org.geogebra.web.web.gui.util.StandardButton; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.resources.client.ResourcePrototype; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; /** * The toolbar for MOW. * * @author Laszlo Gal, Alicia Hofstaetter * */ public class MOWToolbar extends FlowPanel implements FastClickHandler { private static final int DEFAULT_SUBMENU_HEIGHT = 120; // private static final int TOOLS_SUBMENU_HEIGHT = 120; // private static final int MEDIA_SUBMENU_HEIGHT = 55; private AppW app; private StandardButton redoButton; private StandardButton undoButton; private StandardButton moveButton; private StandardButton penButton; private StandardButton toolsButton; private StandardButton mediaButton; private FlowPanel leftPanel; private FlowPanel middlePanel; private FlowPanel rightPanel; private SubMenuPanel currentMenu = null; private SubMenuPanel penMenu; private SubMenuPanel toolsMenu; private SubMenuPanel mediaMenu; private FlowPanel subMenuPanel; private int submenuHeight; private int lastSubmenuHeight; private ToolbarResources pr; private boolean stayClosed; /** * * @param app * application */ public MOWToolbar(AppW app) { this.app = app; buildGUI(); } /** * Builds main GUI parts: left (undo/redo), middle (pen/tools/media) and * right (move) panels */ protected void buildGUI() { pr = ((ImageFactory) GWT.create(ImageFactory.class)).getToolbarResources(); leftPanel = new FlowPanel(); leftPanel.addStyleName("left"); middlePanel = new FlowPanel(); middlePanel.addStyleName("middle"); rightPanel = new FlowPanel(); rightPanel.addStyleName("right"); createUndoRedo(); // midddle buttons open submenus createMiddleButtons(); createMoveButton(); add(LayoutUtilW.panelRow(leftPanel, middlePanel, rightPanel)); subMenuPanel = new FlowPanel(); add(subMenuPanel); // hack submenuHeight = DEFAULT_SUBMENU_HEIGHT; lastSubmenuHeight = 0; stayClosed = false; addStyleName("mowToolbar"); // sets the horizontal position of the toolbar setResponsivePosition(); Window.addResizeHandler(new ResizeHandler() { @Override public void onResize(ResizeEvent event) { setResponsivePosition(); } }); } private void createMiddleButtons() { createPenButton(); createToolsButton(); createMediaButton(); middlePanel .add(LayoutUtilW.panelRow(penButton, toolsButton, mediaButton)); } /** * Creates a button for MOW main toolbar. * * @param url * The image URL for the button. * @param handler * The handler of the button. * @return the newly created button for the toolbar. */ public static StandardButton createButton(String url, FastClickHandler handler) { NoDragImage im = new NoDragImage(url); StandardButton btn = new StandardButton(null, "", 32); btn.getUpFace().setImage(im); btn.addFastClickHandler(handler); return btn; } private void createPenButton() { penButton = createButton(GGWToolBar.getImageURL(EuclidianConstants.MODE_PEN_PANEL, app), this); penMenu = new PenSubMenu(app); } private void createToolsButton() { toolsButton = createButton(GGWToolBar.getImageURL(EuclidianConstants.MODE_TOOLS_PANEL, app), this); toolsMenu = new ToolsSubMenu(app); } private void createMediaButton() { mediaButton = createButton(GGWToolBar.getImageURL(EuclidianConstants.MODE_MEDIA_PANEL, app), this); mediaMenu = new MediaSubMenu(app); } private void createMoveButton() { moveButton = new StandardButton(""); moveButton.getUpFace().setImage(getImage(pr.move_pointer_32(), 32)); rightPanel.add(moveButton); moveButton.addFastClickHandler(this); } /** * Toggles the pen panel icon * * @param toggle * true = highlighted icon, false = gray icon */ private void togglePenButton(boolean toggle) { NoDragImage upFace = getImage(pr.pen_panel_32(), 32); NoDragImage downFace = getImage(pr.pen_panel_active_32(), 32); if (toggle) { penButton.getUpFace().setImage(downFace); } else { penButton.getUpFace().setImage(upFace); } } /** * Toggles the tools panel icon * * @param toggle * true = highlighted icon, false = gray icon */ private void toggleToolsButton(boolean toggle) { NoDragImage upFace = getImage(pr.tools_panel_32(), 32); NoDragImage downFace = getImage(pr.tools_panel_active_32(), 32); if (toggle) { toolsButton.getUpFace().setImage(downFace); } else { toolsButton.getUpFace().setImage(upFace); } } /** * Toggles the media panel icon * * @param toggle * true = highlighted icon, false = gray icon */ private void toggleMediaButton(boolean toggle) { NoDragImage upFace = getImage(pr.media_panel_32(), 32); NoDragImage downFace = getImage(pr.media_panel_active_32(), 32); if (toggle) { mediaButton.getUpFace().setImage(downFace); } else { mediaButton.getUpFace().setImage(upFace); } } /** * Toggles the move hand icon * * @param toggle * true = highlighted icon, false = gray icon */ public void toggleMoveButton(boolean toggle) { NoDragImage upFace = getImage(pr.move_pointer_32(), 32); NoDragImage downFace = getImage(pr.move_pointer_active_32(), 32); if (toggle) { moveButton.getUpFace().setImage(downFace); } else { moveButton.getUpFace().setImage(upFace); } } /** * Toggles the toolbar icons - only 1 icon highlighted at a time * * @param button * the button to be highlighted */ private void setButtonActive(Widget button) { if (button == penButton) { togglePenButton(true); toggleToolsButton(false); toggleMediaButton(false); toggleMoveButton(false); } if (button == toolsButton) { togglePenButton(false); toggleToolsButton(true); toggleMediaButton(false); toggleMoveButton(false); } if (button == mediaButton) { togglePenButton(false); toggleToolsButton(false); toggleMediaButton(true); toggleMoveButton(false); } if (button == moveButton) { togglePenButton(false); toggleToolsButton(false); toggleMediaButton(false); toggleMoveButton(true); } } /** * Updates the toolbar ie. undo/redo button states */ public void update() { updateUndoActions(); } private void createUndoRedo() { redoButton = new StandardButton(pr.redo_32(), null, 32); redoButton.getUpHoveringFace() .setImage(getImage(pr.redo_32(), 32)); redoButton.addFastClickHandler(this); redoButton.addStyleName("redoButton"); undoButton = new StandardButton(pr.undo_32(), null, 32); undoButton.getUpHoveringFace() .setImage(getImage(pr.undo_32(), 32)); undoButton.addFastClickHandler(this); undoButton.addStyleName("undoButton"); leftPanel.add(LayoutUtilW.panelRow(undoButton, redoButton)); updateUndoActions(); } /** * Update enabled/disabled state of undo and redo buttons. */ public void updateUndoActions() { if (undoButton != null) { this.undoButton.setEnabled(app.getKernel().undoPossible()); } if (this.redoButton != null) { this.redoButton.setVisible(app.getKernel().redoPossible()); } } /** * @param uri * image URI * @param width * size * @return image wrapped in no-dragging widget */ public static NoDragImage getImage(ResourcePrototype uri, int width) { return new NoDragImage(ImgResourceHelper.safeURI(uri), width); } @Override public void onClick(Widget source) { if (source == redoButton) { app.getGuiManager().redo(); app.hideKeyboard(); } else if (source == undoButton) { app.getGuiManager().undo(); app.hideKeyboard(); } else if (source == moveButton) { app.setMoveMode(); if (currentMenu != null) { setCurrentMenu(null); } } else if (source == penButton) { if (subMenuPanel.isVisible() && currentMenu == penMenu) { stayClosed = true; } else { stayClosed = false; } setCurrentMenu(penMenu); } else if (source == toolsButton) { setCurrentMenu(toolsMenu); } else if (source == mediaButton) { setCurrentMenu(mediaMenu); } setButtonActive(source); } private SubMenuPanel getSubMenuForMode(int mode) { if (mode == EuclidianConstants.MODE_TEXT || mode == EuclidianConstants.MODE_IMAGE || mode == EuclidianConstants.MODE_VIDEO || mode == EuclidianConstants.MODE_AUDIO || mode == EuclidianConstants.MODE_GEOGEBRA) { return mediaMenu; } else if (mode == EuclidianConstants.MODE_PEN || mode == EuclidianConstants.MODE_FREEHAND_SHAPE || mode == EuclidianConstants.MODE_ERASER) { return penMenu; } else { return toolsMenu; } } /** * Set the toolbar state for the selected mode * * @param mode * the mode to set. */ public void setMode(int mode) { if(mode == EuclidianConstants.MODE_MOVE){ setButtonActive(moveButton); if (currentMenu != null) { currentMenu.reset(); } return; } toggleMoveButton(false); if (mode == EuclidianConstants.MODE_PEN) { setButtonActive(penButton); } // make sure the pen panel stays closed if it was closed manually // (MOW-247) if (!(mode == EuclidianConstants.MODE_PEN && currentMenu == penMenu && stayClosed)) { doSetCurrentMenu(getSubMenuForMode(mode)); } if (currentMenu != null) { currentMenu.setMode(mode); } } /** * * @return The current submenu panel that is visible or last used. */ public SubMenuPanel getCurrentMenu() { return currentMenu; } /** * Sets the actual submenu, and opens it if it is different than the last * one, toggles its visibility otherwise. * * @param submenu * The submenu panel to set. */ public void setCurrentMenu(SubMenuPanel submenu) { if (submenu == null) { setSubmenuVisible(false); currentMenu = null; return; } if (currentMenu == submenu) { if (!subMenuPanel.isVisible()) { currentMenu.onOpen(); } setSubmenuVisible(!subMenuPanel.isVisible()); return; } // this will call setMode => submenu is open app.setMode(submenu.getFirstMode()); } private void doSetCurrentMenu(SubMenuPanel submenu) { subMenuPanel.clear(); this.currentMenu = submenu; subMenuPanel.add(currentMenu); setSubmenuVisible(true); } /** * Set the submenu visible / invisible and adds the animation * * @param visible * true if submenu should be visible */ private void setSubmenuVisible(final boolean visible) { submenuHeight = DEFAULT_SUBMENU_HEIGHT; if (visible) { subMenuPanel.setVisible(visible); if (lastSubmenuHeight == 0) { setStyleName("animateBaseToDouble"); } lastSubmenuHeight = 120; } else { if (submenuHeight == 120) { setStyleName("animateDoubleToBase"); } Timer timer = new Timer() { @Override public void run() { doShowSubmenu(visible); } }; timer.schedule(500); lastSubmenuHeight = 0; } addStyleName("mowToolbar"); setResponsivePosition(); /* * if (currentMenu == toolsMenu) { submenuHeight = TOOLS_SUBMENU_HEIGHT; * } else { submenuHeight = DEFAULT_SUBMENU_HEIGHT; } * * if (visible) { subMenuPanel.setVisible(visible); if (submenuHeight == * 120) { if (lastSubmenuHeight == 0) { * setStyleName("animateBaseToDouble"); * * } if (lastSubmenuHeight == 55) { * setStyleName("animateSimpleToDouble"); } lastSubmenuHeight = 120; } * if (submenuHeight == 55) { if (lastSubmenuHeight == 0) { * setStyleName("animateBaseToSimple"); } if (lastSubmenuHeight == 120) * { setStyleName("animateDoubleToSimple"); } lastSubmenuHeight = 55; } * } else { if (submenuHeight == 120) { * setStyleName("animateDoubleToBase"); } if (submenuHeight == 55) { * setStyleName("animateSimpleToBase"); } // timer delays hiding the * submenu so it stays visible until the end // of the animation Timer * timer = new Timer() { * * @Override public void run() { doShowSubmenu(visible); } }; * timer.schedule(500); lastSubmenuHeight = 0; } * addStyleName("mowToolbar"); setResponsivePosition(); */ } /** * @param visible * whether to show the subpanel */ protected void doShowSubmenu(boolean visible) { subMenuPanel.setVisible(visible); } /** * Sets the horizontal position of the toolbar depending on screen size */ public void setResponsivePosition() { // small screen if (app.getWidth() < 700) { removeStyleName("BigScreen"); addStyleName("SmallScreen"); getElement().getStyle().setLeft(0, Unit.PX); } // big screen else { removeStyleName("SmallScreen"); addStyleName("BigScreen"); getElement().getStyle().setLeft((app.getWidth() - 700) / 2, Unit.PX); } } }