package org.geogebra.web.web.gui.toolbar.mow;
import java.util.Vector;
import org.geogebra.common.euclidian.EuclidianConstants;
import org.geogebra.common.gui.toolbar.ToolBar;
import org.geogebra.common.gui.toolbar.ToolbarItem;
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.app.GGWToolBar;
import org.geogebra.web.web.gui.images.ImgResourceHelper;
import org.geogebra.web.web.gui.util.StandardButton;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Base class of submenus of MOWToorbar
*
* @author Laszlo Gal, Alicia Hofstaetter
*
*/
public abstract class SubMenuPanel extends FlowPanel
implements ClickHandler, FastClickHandler {
/** app **/
AppW app;
private boolean info;
/**
* Scrollpanel to larger toolbars like 'Tools'
*/
ScrollPanel scrollPanel;
/**
* Here goes the toolbar contents ie the buttons
*/
FlowPanel contentPanel;
/**
* The info (help) panel for the selected tool.
*/
FlowPanel infoPanel;
/**
* icon of the tool for
*/
NoDragImage infoImage;
/** '?' image */
NoDragImage questionMark;
/** the brief info itself */
HTML infoLabel;
/** link to more info. */
String infoURL;
/**
*
* @param app
* GGB application.
* @param info
* true if submenu should have an info panel.
*/
public SubMenuPanel(AppW app, boolean info) {
this.app=app;
this.info = info;
createGUI();
}
/**
* Makes the content panel and the info panel, if needed.
*/
protected void createGUI() {
addStyleName("mowSubMenu");
createContentPanel();
if (hasInfo()) {
createInfoPanel();
add(LayoutUtilW.panelRow(scrollPanel, infoPanel));
} else {
add(scrollPanel);
}
}
/**
* Creates the scrollable panel of contents.
*/
protected void createContentPanel() {
scrollPanel = new ScrollPanel();
scrollPanel.addStyleName("mowSubMenuContent");
contentPanel = new FlowPanel();
scrollPanel.add(contentPanel);
}
/**
* Creates the info panel.
*/
protected void createInfoPanel() {
infoPanel = new FlowPanel();
infoPanel.addStyleName("mowSubMenuInfo");
}
/**
*
* @param toolbarString
* GGB toolbar definition string.
* @return The vector of modes.
*/
protected Vector<ToolbarItem> getToolbarVec(String toolbarString) {
Vector<ToolbarItem> toolbarVec;
try {
toolbarVec = ToolBar.parseToolbarString(toolbarString);
} catch (Exception e) {
toolbarVec = ToolBar.parseToolbarString(ToolBar.getAllTools(app));
}
return toolbarVec;
}
/**
* Adds tool buttons to content panel depending on a toolbar definition
* string.
*
* @param toolbarString
* The toolbar definition string
*/
protected void addModesToToolbar(String toolbarString) {
addModesToToolbar(contentPanel, toolbarString);
}
/**
* Adds tool buttons to an arbitrary panel depending on a toolbar definition
* string.
*
* @param panel
* The panel to add mode buttons.
* @param toolbarString
* The toolbar definition string
*/
protected void addModesToToolbar(FlowPanel panel, String toolbarString) {
Vector<ToolbarItem> toolbarVec = getToolbarVec(toolbarString);
for (int i = 0; i < toolbarVec.size(); i++) {
ToolbarItem ob = toolbarVec.get(i);
Vector<Integer> menu = ob.getMenu();
addModeMenu(panel, menu);
}
}
/**
* Add buttons to a panel depending a mode vector.
*
* @param panel
* The panel to add the mode buttons.
* @param menu
* The vector of modes to add buttons.
*/
protected void addModeMenu(FlowPanel panel, Vector<Integer> menu) {
if (app.isModeValid(menu.get(0).intValue())) {
panel.add(createButton(menu.get(0).intValue()));
}
}
/**
* Creates a toolbar button from a mode.
*
* @param mode
* The mode the button will stand for.
* @return Newly created toolbar button to set its mode.
*/
protected StandardButton createButton(int mode) {
NoDragImage im = new NoDragImage(GGWToolBar.getImageURL(mode, app));
// opacity hack: old icons don't need opacity, new ones do
if (imageNeedsOpacity(mode)) {
im.addStyleName("opacityFixForOldIcons");
}
StandardButton button = new StandardButton(null, "", 32);
button.getUpFace().setImage(im);
button.addFastClickHandler(this);
button.addStyleName("mowToolButton");
button.getElement().setAttribute("mode", mode + "");
button.getElement().setId("mode" + mode);
return button;
}
/**
*
* @return true if submenu has info panel.
*/
public boolean hasInfo() {
return info;
}
/**
*
* @param info
* true if submenu should have info panel, false if not.
*/
public void setInfo(boolean info) {
this.info = info;
}
/**
* Initializes the submenu when it is opened from MOWToolbar.
*/
public void onOpen() {
int mode = app.getMode();
setMode(mode);
}
/**
* reset
*/
public void reset() {
deselectAllCSS();
infoPanel.clear();
}
@Override
public void onClick(Widget source) {
int pos = scrollPanel.getHorizontalScrollPosition();
int mode = Integer.parseInt(source.getElement().getAttribute("mode"));
setCSStoSelected(source);
app.setMode(mode);
if (hasInfo()) {
infoPanel.clear();
showToolTip(mode);
}
scrollPanel.setHorizontalScrollPosition(pos);
}
@Override
public void onClick(ClickEvent event) {
if (event.getSource() == questionMark) {
app.getFileManager().open(infoURL);
}
}
/**
* Sets CSS of active tool to selected
*
* @param source
* The widget to select.
*/
public void setCSStoSelected(Widget source) {
FlowPanel parent = (FlowPanel) source.getParent();
for (int i = 0; i < parent.getWidgetCount(); i++) {
Widget w = parent.getWidget(i);
if (w != source) {
w.getElement().setAttribute("selected", "false");
} else {
w.getElement().setAttribute("selected", "true");
}
}
}
/**
* unselect all tools
*/
public void deselectAllCSS() {
// override in subclasses
}
/**
* Add tooltips to info panel
*
* @param mode
* The mode of the tool that needs info.
*/
protected void showToolTip(int mode) {
if (mode >= 0) {
infoImage = new NoDragImage(GGWToolBar.getImageURL(mode, app));
infoImage.addStyleName("mowToolButton");
// opacity hack: old icons don't need opacity, new ones do
if (imageNeedsOpacity(mode)) {
infoImage.addStyleName("opacityFixForOldIconsSelected");
} else {
infoImage.addStyleName("selected");
}
infoLabel = new HTML(app.getToolTooltipHTML(mode));
infoLabel.addStyleName("mowInfoLabel");
infoURL = app.getGuiManager().getTooltipURL(mode);
questionMark = new NoDragImage(ImgResourceHelper.safeURI(GGWToolBar.getMyIconResourceBundle().help_32()));
infoPanel.add(infoImage);
infoPanel.add(infoLabel);
boolean online = app.getNetworkOperation() == null || app.getNetworkOperation().isOnline();
if (infoURL != null && infoURL.length() > 0 && online) {
questionMark.addClickHandler(this);
questionMark.addStyleName("mowQuestionMark");
infoPanel.add(questionMark);
}
}
}
/**
* Decide if icon needs opacity or not. New icons are black with opacity.
* Old icons don't need opacity so they get a style fix.
*
* @param mode
* app mode
* @return true if icon needs a style fix
*/
protected boolean imageNeedsOpacity(int mode) {
if ((mode < 101 && mode != EuclidianConstants.MODE_TEXT && mode != EuclidianConstants.MODE_IMAGE
&& mode != EuclidianConstants.MODE_PEN && mode != EuclidianConstants.MODE_FREEHAND_SHAPE)
|| (mode > 110 && mode != EuclidianConstants.MODE_VIDEO && mode != EuclidianConstants.MODE_AUDIO
&& mode != EuclidianConstants.MODE_GEOGEBRA)) {
return true;
}
return false;
}
/**
* Select tool and show its info.
*
* @param mode
* The mode to select and display info from.
*/
public void setMode(int mode) {
reset();
Element btn = DOM.getElementById("mode" + mode);
if (btn != null) {
btn.setAttribute("selected", "true");
showToolTip(mode);
}
}
/**
* @return first mode; to be selected once this submenu is opened
*/
public abstract int getFirstMode();
}