package org.geogebra.web.web.gui.layout;
import org.geogebra.common.awt.GDimension;
import org.geogebra.common.euclidian.event.PointerEventType;
import org.geogebra.common.gui.layout.DockComponent;
import org.geogebra.common.gui.layout.DockPanel;
import org.geogebra.common.gui.toolbar.ToolBar;
import org.geogebra.common.io.layout.DockPanelData;
import org.geogebra.common.javax.swing.SwingConstants;
import org.geogebra.common.main.App;
import org.geogebra.common.main.Feature;
import org.geogebra.common.plugin.Event;
import org.geogebra.common.plugin.EventType;
import org.geogebra.common.util.debug.Log;
import org.geogebra.ggbjdk.java.awt.geom.Rectangle;
import org.geogebra.web.html5.awt.GDimensionW;
import org.geogebra.web.html5.css.GuiResourcesSimple;
import org.geogebra.web.html5.gui.FastClickHandler;
import org.geogebra.web.html5.gui.util.ClickStartHandler;
import org.geogebra.web.html5.gui.util.MathKeyboardListener;
import org.geogebra.web.html5.gui.util.NoDragImage;
import org.geogebra.web.html5.main.AppW;
import org.geogebra.web.web.cas.view.CASStylebarW;
import org.geogebra.web.web.css.GuiResources;
import org.geogebra.web.web.gui.GuiManagerW;
import org.geogebra.web.web.gui.ImageFactory;
import org.geogebra.web.web.gui.app.ShowKeyboardButton;
import org.geogebra.web.web.gui.images.AppResources;
import org.geogebra.web.web.gui.images.ImgResourceHelper;
import org.geogebra.web.web.gui.images.PerspectiveResources;
import org.geogebra.web.web.gui.layout.panels.AlgebraStyleBarW;
import org.geogebra.web.web.gui.util.StandardButton;
import org.geogebra.web.web.gui.util.StyleBarW;
import org.geogebra.web.web.gui.view.spreadsheet.SpreadsheetStyleBarW;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.VerticalAlign;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DragEvent;
import com.google.gwt.event.dom.client.DragHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.ResourcePrototype;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Every object which should be dragged needs to be of type DockPanel. A
* DockPanel will wrap around the component with the real contents (e.g. the
* EuclidianView) and will add a title bar if the user is not in the
* "layout fixed" mode. The user can move the DockPanel by dragging the title
* bar.
*
* To add a new dock panel one has to subclass DockPanel, implement the abstract
* method DockPanel::loadComponent() and maybe replace DockPanel::getIcon() and
* DockPanel::getStyleBar().
*
* One can add a panel using Layout::registerPanel(), the GuiManager also
* provides GuiManager()::initLayoutPanels() as an easy access point to add new
* panels. This is also important because it matters at which point of execution
* a panel is added, see Layout::registerPanel() for further information.
*
* @author Florian Sonner
*/
public abstract class DockPanelW extends ResizeComposite implements
DockPanel,
DockComponent {
/** Dock manager */
protected DockManagerW dockManager;
/** app */
protected AppW app;
/**
* The ID of this dock panel.
*/
protected int id;
/**
* The title of this dock panel.
*/
private String title = " no title";
/**
* If this panel is visible.
*/
protected boolean visible = false;
/**
* If this panel has focus.
*/
protected boolean hasFocus = false;
/**
* The dimensions of the external window of this panel.
*/
protected Rectangle frameBounds = new Rectangle(50, 50, 500, 500);
/**
* If this panel should be opened in a frame the next time it's visible.
*/
protected boolean openInFrame = false;
/**
* If there is a style bar associated with this panel.
*/
private boolean hasStyleBar = false;
/**
* Style bar component.
*/
Widget styleBar;
/**
* If the style bar is visible.
*/
protected boolean showStyleBar = false;
/**
* String which stores the position of the panel in the layout.
*/
protected String embeddedDef = "1";
/**
* The size of the panel in the layout, may be either the width or height
* depending upon embeddedDef.
*/
protected int embeddedSize = 150;
/**
* Panel for the styling bar if one is available.
*/
private FlowPanel styleBarPanel;
/**
* Toolbar definition string associated with this panel or null if this
* panel has no toolbar. Always contains the string of the perspective
* loaded last.
*/
protected String toolbarString;
/**
* Default toolbar definition string associated with this panel or null if
* this panel has no toolbar. This string is specified in the constructor
* and won't change.
*/
private final String defaultToolbarString;
/**
* The component used for this view.
*/
protected Widget component;
/**
* The location of this panel in the view menu. If -1 this panel won't
* appear there at all.
*/
private int menuOrder;
/**
* Shortcut to show this panel, SHIFT is automatically used as modifier,
* \u0000 is the default value.
*/
private char menuShortcut;
/**
* Indicator whether this panel is the last one in the main frame. In this
* case no title bar will be visible, but just the stylebar.
*/
private boolean isAlone;
/**
* Indicator whether this panel is hidden. A hidden panel is not visible,
* but it's View component is still attached to the kernel.
*/
private boolean isHidden;
/**
* Flag to determine if the frame field will be created as a JDialog (true)
* or as a JFram (false). Default is false.
*/
private boolean isDialog = false;
/**
* Images for Stylingbar
*/
private Image triangleRight, triangleLeft, dragIcon, closeIcon;
/**
* For calling the onResize method in a deferred way
*/
Scheduler.ScheduledCommand deferredOnRes = new Scheduler.ScheduledCommand() {
@Override
public void execute() {
onResize();
}
};
/**
* For calling the onResize method in a deferred way
*/
@Override
public void deferredOnResize() {
Scheduler.get().scheduleDeferred(deferredOnRes);
}
/**
* @return true if this dock panel frame will be created as a JDialog. If
* false then it will be created as a JFrame
*
*/
public boolean isDialog() {
return isDialog;
}
/**
* Sets the isDialog flag.
*
* @param isDialog
* true if this dock panel frame will be created as a JDialog. If
* false then it will be created as a JFrame
*/
public void setDialog(boolean isDialog) {
this.isDialog = isDialog;
}
/**
* Prepare dock panel. DockPanel::register() has to be called to make this
* panel fully functional! No shortcut is assigned to the view in this
* construtor.
*
* @param id
* The id of the panel
* @param title
* The title phrase of the view located in plain.properties
* @param toolbar
* The default toolbar string (or null if this view has none)
* @param hasStyleBar
* If a style bar exists
* @param menuOrder
* The location of this view in the view menu, -1 if the view
* should not appear at all
*/
public DockPanelW(int id, String title, String toolbar,
boolean hasStyleBar, int menuOrder) {
this(id, title, toolbar, hasStyleBar, menuOrder, '\u0000');
}
/**
* Prepare dock panel. DockPanel::register() has to be called to make this
* panel fully functional!
*
* @param id
* The id of the panel
* @param title
* The title phrase of the view located in plain.properties
* @param toolbar
* The default toolbar string (or null if this view has none)
* @param hasStyleBar
* If a style bar exists
* @param menuOrder
* The location of this view in the view menu, -1 if the view
* should not appear at all
* @param menuShortcut
* The shortcut character which can be used to make this view
* visible
*/
public DockPanelW(int id, String title, String toolbar,
boolean hasStyleBar, int menuOrder, char menuShortcut) {
this.id = id;
this.title = title;
this.defaultToolbarString = toolbar;
// this is different in Web and Desktop!
setToolbarString(defaultToolbarString);
this.menuOrder = menuOrder;
this.menuShortcut = menuShortcut;
this.hasStyleBar = hasStyleBar;
this.isAlone = false;
}
/**
* @return The icon of the menu item, if this method was not overwritten it
* will return the empty icon or null for Win Vista / 7 to prevent
* the "checkbox bug"
*/
public ResourcePrototype getIcon() {
return AppResources.INSTANCE.empty();
}
/**
* @return The style bar. Note: Unless this method is overridden a dummy
* stylebar is returned.
*/
protected Widget loadStyleBar() {
return new SimplePanel();
}
/**
* @return The main panel of this view.
*/
protected abstract Widget loadComponent();
/**
* @return The main panel of this view (null if none was loaded yet).
*/
public Widget getComponent() {
return component;
}
/**
* Method which is called if this dock panel gained focus. This happens if
* setFocus(true) was called and this panel had no focus before.
*
* @remark If GeoGebra is running as unsigned applet focus is just changed
* between euclidian views (even if other views were selected in the
* meantime).
*/
protected void focusGained() {
// empty by default
}
/**
* Method which is called if this dock panel lost focus. This happens if
* setFocus(false) was called and this panel had focus before.
*
* @remark If GeoGebra is running as unsigned applet focus is just changed
* between euclidian views (even if other views were selected in the
* meantime).
*/
protected void focusLost() {
// empty by default
}
/**
* Bind this view to a dock manager. Also initializes the whole GUI as just
* at this point the application is available.
*
* @param dockManager1
* dock manager
*/
public void register(DockManagerW dockManager1) {
this.dockManager = dockManager1;
app = dockManager1.getLayout().getApplication();
buildDockPanel();
// buildGUI should be called in a lazy way!
// buildGUI();
}
/** dock panel */
MyDockLayoutPanel dockPanel;
/** the main panel of this stylebar */
FlowPanel titleBarPanel;
private FlowPanel titleBarPanelContent;
private PushButton closeButton;
private FlowPanel dragPanel;
private FlowPanel closeButtonPanel;
private VerticalPanel componentPanel;
/** button to collapse / expand stylebar */
protected StandardButton toggleStyleBarButton;
private ResourcePrototype viewImage;
private ImageResource downImage;
// needs to be initialized here, because the button might be added in
// adSouth(), before setLayout() is called
private final SimplePanel kbButtonSpace = new SimplePanel();
/**
* @return height in pixels
*/
public int getHeight() {
return dockPanel.getOffsetHeight();
}
/**
* @return width in pixels
*/
public int getWidth() {
return dockPanel.getOffsetWidth();
}
/**
* Create the UI
*/
protected void buildDockPanel() {
// guard against repeated call
// while creating DockPanel based GUI (problem with early init of EV)
if (dockPanel != null) {
return;
}
dockPanel = new MyDockLayoutPanel(Style.Unit.PX);
initWidget(dockPanel);
}
/**
* Build gui, has no effect when called the second time
*
* @param setlayout
* whether to also set layout
*/
public void buildGUIIfNecessary(boolean setlayout) {
// This way it is safe to call buildGUI multiple times
if (componentPanel != null) {
return;
}
// This also acts as a boolean to show whether this
// method has already been called
componentPanel = new VerticalPanel();
componentPanel.setStyleName("ComponentPanel");
styleBarPanel = new FlowPanel();
styleBarPanel.setStyleName("StyleBarPanel_");
titleBarPanel = new FlowPanel();
titleBarPanel.setStyleName("TitleBarPanel");
titleBarPanel.addStyleName("cursor_drag");
// kbButtonSpace = new SimplePanel();
titleBarPanelContent = new FlowPanel();
titleBarPanelContent.setStyleName("TitleBarPanelContent");
titleBarPanel.add(titleBarPanelContent);
dragPanel = new FlowPanel();
dragPanel.setStyleName("dragPanel");
ClickStartHandler.init(dragPanel, new ClickStartHandler(true, false) {
@Override
public void onClickStart(int x, int y, PointerEventType type) {
startDragging();
}
});
dragPanel.setVisible(false);
if(dragIcon == null){
dragIcon = new Image(GuiResources.INSTANCE.dockbar_drag());
/*
* Prevent default image drag from interfering with view drag --
* needed for IE
*/
dragIcon.addDragHandler(new DragHandler() {
@Override
public void onDrag(DragEvent event) {
event.preventDefault();
}
});
}
dragPanel.add(dragIcon);
if(closeIcon == null){
closeIcon = new Image(GuiResources.INSTANCE.dockbar_close());
}
closeButton = new PushButton(closeIcon);
closeButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
app.getGuiManager().setShowView(false, DockPanelW.this.id);
}
});
closeButtonPanel = new FlowPanel();
closeButtonPanel.setStyleName("closeButtonPanel");
closeButtonPanel.setVisible(isStyleBarEmpty());
closeButtonPanel.add(closeButton);
titleBarPanelContent.add(styleBarPanel);
titleBarPanelContent.add(dragPanel);
if (!this.isStyleBarEmpty()) {
addToggleButton();
}
titleBarPanelContent.setVisible(!isStyleBarEmpty());
if (this.isStyleBarEmpty()) {
titleBarPanel.add(closeButtonPanel);
}
if (app.getGuiManager().isDraggingViews()) {
enableDragging(true);
}
if (setlayout) {
setLayout(false);
}
}
/**
* Switch panel to drag mode
*/
protected void startDragging() {
if (componentPanel == null) {
return;
}
dockManager.drag(DockPanelW.this);
}
private void addToggleButton() {
// always show the view-icon; otherwise use showStylebar as parameter
if (app.has(Feature.DYNAMIC_STYLEBAR)) {
toggleStyleBarButton = new StandardButton(getToggleImage(false), null, 24);
toggleStyleBarButton.addStyleName("toggleStyleBarNew");
downImage = (ImageResource) getResources().back_right();
} else {
toggleStyleBarButton = new StandardButton(getToggleImage(false), null, 32);
toggleStyleBarButton.addStyleName("toggleStyleBar");
}
if(!showStyleBar && viewImage != null){
toggleStyleBarButton.addStyleName("toggleStyleBarViewIcon");
}
FastClickHandler toggleStyleBarHandler = new FastClickHandler() {
@Override
public void onClick(Widget source) {
setShowStyleBar(!showStyleBar);
updateStyleBarVisibility();
if (styleBar instanceof StyleBarW) {
((StyleBarW) styleBar).setOpen(showStyleBar);
}
}
};
toggleStyleBarButton.addFastClickHandler(toggleStyleBarHandler);
titleBarPanelContent.add(toggleStyleBarButton);
}
/**
* Update localization
*/
public final void setLabels() {
if (toggleStyleBarButton != null) {
toggleStyleBarButton
.setTitle(app.getLocalization().getMenu("ToggleStyleBar"));
}
}
/**
* sets the layout of the stylebar and title panel
*
* @param deferred
* whether to set the layout in deferred call
*/
protected void setLayout(boolean deferred) {
if (!isVisible()) {
return;
}
buildGUIIfNecessary(false);
dockPanel.clear();
Log.debug(app.allowStylebar());
if (hasStyleBar()) {
if (app.getSettings().getLayout().showTitleBar()
&& (app.allowStylebar() || needsResetIcon()
|| forceCloseButton())) {
dockPanel.addNorth(titleBarPanel, 0);
}
if (isStyleBarVisible()) {
setStyleBar();
updateStyleBarVisibility();
}
if (styleBar instanceof StyleBarW) {
((StyleBarW) styleBar).setOpen(showStyleBar);
}
updateStyleBarVisibility();
}
if (!app.allowStylebar() && needsResetIcon()) {
showResetIcon();
}
dockPanel.addSouth(kbButtonSpace, 0);
if (component != null) {
dockPanel.add(component);
} else {
dockPanel.add(componentPanel);
}
if (deferred) {
deferredOnResize();
} else {
onResize();
}
}
private boolean forceCloseButton() {
return getViewId() == App.VIEW_PROPERTIES
&& app.getArticleElement().getDataParamEnableRightClick();
}
protected boolean needsResetIcon() {
return false;
}
public int getComponentInteriorHeight() {
if (dockPanel != null) {
int h = (int) dockPanel.getCenterHeight();
if (h == 0 && this.getParentSplitPane() != null) {
return this.getParentSplitPane().getPreferredHeight(this);
}
return h;
}
return 0;
}
public int getComponentInteriorWidth() {
if (dockPanel != null) {
int w = (int) dockPanel.getCenterWidth();
if (w == 0 && this.getParentSplitPane() != null) {
return this.getParentSplitPane().getPreferredWidth(this);
}
return w;
}
return 0;
}
/**
* extends DockLayoutPanel to expose getCenterHeight() and getCenterWidth()
* TODO: move some code above into this class, e.g. setLayout(), or possibly
* extend DockPanelW itself
*/
public static class MyDockLayoutPanel extends DockLayoutPanel {
public MyDockLayoutPanel(Unit unit) {
super(unit);
addStyleName("ggbdockpanelhack");
}
@Override
public double getCenterHeight() {
return super.getCenterHeight();
}
@Override
public double getCenterWidth() {
return super.getCenterWidth();
}
@Override
public void add(Widget w){
if(this.getCenter()!=null){
Log.error("TODO: dock panel filled twice");
this.remove(this.getCenter());
}
super.add(w);
}
}
/**
*
* @return title in plain style
*/
protected String getPlainTitle() {
return app.getLocalization().getMenu(title);
}
/**
*
* @return toolTip text as HTML string with image and title
*/
protected String getToolTip() {
FlowPanel p = new FlowPanel();
String caption;
if (!this.isStyleBarEmpty()) {
Image img = new NoDragImage(ImgResourceHelper.safeURI(getIcon()),
24);
img.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE);
img.getElement().getStyle().setMarginRight(4, Unit.PX);
p.add(img);
caption = app.getLocalization().getMenu(title);
} else {
caption = app.getLocalization().getMenu("Close");
}
p.add(new InlineLabel(caption));
return p.getElement().getInnerHTML();
}
private boolean longStyleBar = false;
/**
* Update all elements in the title bar.
*/
public void updateTitleBar() {
if (componentPanel == null) {
return;
}
updateLabels();
}
public void updateLabels() {
//TODO implement or delete
}
/**
* A panel is 'alone' if no other panel is visible in the main frame. In
* this case no title bar is displayed, but just the style bar. Changing the
* value of the 'alone' state will cause the GUI to update automatically if
* this panel is visible.
*
* @param isAlone
*/
public void setAlone(boolean isAlone) {
if (this.isAlone == isAlone) {
return;
}
this.isAlone = isAlone;
if (isVisible()) {
updatePanel(true);
}
}
/**
* @return If this panel thinks it's the last visible one in the main frame.
*/
public boolean isAlone() {
return isAlone;
}
/**
* @return If this panel is hidden but not permanently removed.
*/
public boolean isHidden() {
return isHidden;
}
/**
* Sets the the isHidden flag (no other action)
*/
public void setHidden(boolean isHidden) {
this.isHidden = isHidden;
}
/**
* Update the panel.
*/
public final void updatePanel(boolean deferred) {
if (!isVisible()) {
return;
}
if (component == null) {
component = loadComponent();
}
setLayout(deferred);
//ignore
}
/**
* Build the toolbar GUI.
*/
public void buildToolbarGui() {
// TODO implement or delete
}
/**
* Update the toolbar GUI.
*/
public void updateToolbar() {
app.getGuiManager().setActivePanelAndToolbar(id);
}
/**
* Update fonts.
*/
public void updateFonts() {
//TODO implement or delete
}
/**
* Close this panel.
*
* @param isPermanent
*/
protected void closePanel(boolean isPermanent) {
dockManager.closePanel(this, isPermanent);
}
@Override
public void closePanel() {
closePanel(true);
}
/** loads the styleBar and puts it into the styleBarPanel */
private void setStyleBar() {
if (styleBar == null) {
buildGUIIfNecessary(false);
styleBar = loadStyleBar();
styleBarPanel.add(styleBar);
}
}
/**
* Update the style bar visibility.
*/
public void updateStyleBarVisibility() {
if (!isVisible()) {
return;
}
buildGUIIfNecessary(true);
if (app.has(Feature.DYNAMIC_STYLEBAR) && toggleStyleBarButton != null) {
if (showStyleBar) {
toggleStyleBarButton.setIcon(downImage);
} else {
toggleStyleBarButton.setIcon((ImageResource) viewImage);
}
}
styleBarPanel.setVisible(isStyleBarVisible());
if (isStyleBarVisible()) {
setStyleBar();
styleBar.setVisible(showStyleBar && !app.getGuiManager().isDraggingViews());
}
if (styleBar instanceof SpreadsheetStyleBarW
|| styleBar instanceof CASStylebarW
|| styleBar instanceof AlgebraStyleBarW) {
setStyleBarLongVisibility(isStyleBarVisible());
}
}
/**
* Sets style bar visibility to true and false.
* When visible, style bar occupies a space of a full row (instead of floating).
* E.g. in CASView and SpreadsheetView
* @param value true to show style bar
*/
private void setStyleBarLongVisibility(boolean value) {
// in applets title bar may be null and view menu still enabled
if (app.allowStylebar() && titleBarPanel != null
&& titleBarPanel.getLayoutData() != null) {
dockPanel.setWidgetSize(titleBarPanel, value ? 44 : 0);
titleBarPanel.setStyleName("TitleBarPanel-open", value);
setLongStyleBar(value);
deferredOnResize();
}
}
/**
* @return The parent DockSplitPane or null.
*/
public DockSplitPaneW getParentSplitPane() {
if (isOpenInFrame()) {
return null;
}
Widget parent = getParent();
if (!(parent instanceof DockSplitPaneW)) {
return null;
}
return (DockSplitPaneW) parent;
}
/**
* @return The embedded def string for this DockPanel.
*/
public String calculateEmbeddedDef() {
StringBuilder def = new StringBuilder();
Widget current = this;
Widget parent = this.getParent();
DockSplitPaneW parentDSP;
while (parent instanceof DockSplitPaneW) {
int defType = -1;
parentDSP = (DockSplitPaneW) parent;
if (parentDSP.getOrientation() == SwingConstants.HORIZONTAL_SPLIT) {
if (current == parentDSP.getLeftComponent()) {
defType = 3;
} else {
// right
defType = 1;
}
} else {
if (current == parentDSP.getLeftComponent()) {
defType = 0;
} else {
// bottom
defType = 2;
}
}
if (def.length() == 0) {
def.append(defType);
} else {
def.append(",");
def.append(defType);
}
current = parent;
parent = current.getParent();
}
// gwt does not support reverse() ??
// return def.reverse().toString();
// reverse is OK for GWT 2.8
return def.reverse().toString();
}
/**
* @return The XML container which stores all relevant information for this
* panel.
*/
public DockPanelData createInfo() {
return new DockPanelData(id, getToolbarString(), visible, openInFrame,
showStyleBar, new Rectangle(frameBounds),
embeddedDef, embeddedSize);
}
/**
* If this view should open in a frame. Has no immediate effect.
*
* @param openInFrame
*/
public void setOpenInFrame(boolean openInFrame) {
this.openInFrame = openInFrame;
}
/**
* @return Whether this view should open in frame.
*/
@Override
public boolean isOpenInFrame() {
// TODO: return openInFrame;
// currently opening in an own frame is not implemented on web,
// so temporarily it will return false all time (see #3468)
return false;
// return openInFrame;
}
/**
* If the stylebar of this view should be visible. Has no immediate effect.
*
* @param showStyleBar
*/
public void setShowStyleBar(boolean showStyleBar) {
this.showStyleBar = showStyleBar;
if (app != null) {
app.dispatchEvent(new Event(EventType.SHOW_STYLE_BAR, null, "["
+ showStyleBar + "," + getViewId() + "]"));
}
// if (this.toggleStyleBarButton != null) {
// this.toggleStyleBarButton.getElement().removeAllChildren();
// this.toggleStyleBarButton.getElement().appendChild(getToggleImage(showStyleBar).getElement());
// if(!showStyleBar && viewImage != null){
// toggleStyleBarButton.addStyleName("toggleStyleBarViewIcon");
// } else {
// toggleStyleBarButton.removeStyleName("toggleStyleBarViewIcon");
// }
// }
}
/**
* @return If the style bar should be visible.
*/
public boolean isStyleBarVisible() {
if (id == App.VIEW_EUCLIDIAN || id == App.VIEW_EUCLIDIAN2
|| id == App.VIEW_ALGEBRA) {
if (!app.getSettings().getLayout().isAllowingStyleBar()) {
return false;
}
}
return (showStyleBar /*
* || !(theRealTitleBarPanel.isVisible() &&
* theRealTitleBarPanel.isAttached())
*/);
}
/**
* just return hasStyleBar - overridden for spreadsheet
*
* @return hasStyleBar
*/
protected boolean hasStyleBar() {
return hasStyleBar;
}
public void setFrameBounds(Rectangle frameBounds) {
this.frameBounds = frameBounds;
}
public Rectangle getFrameBounds() {
return this.frameBounds;
}
/**
* @return return the Window
*/
/*
* public Window getFrame() { return frame; }
*/
/**
* @param embeddedDef
* the embeddedDef to set
*/
public void setEmbeddedDef(String embeddedDef) {
this.embeddedDef = embeddedDef;
}
public String getEmbeddedDef() {
return embeddedDef;
}
/**
* @param embeddedSize
* the embeddedSize to set
*/
public void setEmbeddedSize(int embeddedSize) {
this.embeddedSize = embeddedSize;
}
/**
* @return the embeddedSize
*/
public int getEmbeddedSize() {
return embeddedSize;
}
/**
* @return If this DockPanel is visible.
*/
@Override
public boolean isVisible() {
return visible;
}
/** @return Whether this has focus */
public boolean hasFocus() {
return hasFocus;
}
/**
* Mark this panel as focused. When gaining focus the panel will
* automatically request focus for its parent frame.
*
* @remark The focus system implemented here has nothing to do with swings
* focus system, therefore Swings focus methods won't work.
*
* @param hasFocus
* has the focus
* @param updatePropertiesView
* update properties view
*/
public void setFocus(boolean hasFocus, boolean updatePropertiesView) {
if (hasFocus && updatePropertiesView) {
app.getGuiManager().updatePropertiesView();
}
setFocus(hasFocus);
}
/**
* Mark this panel as focused. When gaining focus the panel will
* automatically request focus for its parent frame.
*
* @remark The focus system implemented here has nothing to do with swings
* focus system, therefore Swings focus methods won't work.
*
* @param hasFocus
* has the focus
*/
protected void setFocus(boolean hasFocus) {
// don't change anything if it's not necessary
if (this.hasFocus == hasFocus) {
return;
}
this.hasFocus = hasFocus;
if (hasFocus) {
// request focus and change toolbar if necessary
if (isOpenInFrame()) {
// TODO frame.requestFocus();
} else {
/*
* TODO if (!app.isApplet()) { JFrame frame = app.getFrame();
*
* if (frame != null) { frame.toFront(); } }
*/
setActiveToolBar();
}
}
// call callback methods for focus changes
if (hasFocus) {
focusGained();
} else {
focusLost();
}
/*
* Mark the focused view in bold if the focus system is available. If
* this isn't the case we always stick with the normal font as it would
* confuse the users that the focus "indicator" just changes if we
* switch between EVs.
*/
setTitleLabelFocus();
}
/**
* sets the active toolbar
*/
protected void setActiveToolBar() {
if (hasToolbar()) {
((GuiManagerW) app.getGuiManager())
.setActivePanelAndToolbar(getViewId());
}
}
/**
* Set the title bar focus style
*
* TODO: Focus is indicated by change in title bar style instead of bold
* text, so refactor to express this correctly
*
*/
protected void setTitleLabelFocus() {
if (titleIsBold()) {
titleBarPanel.addStyleName("TitleBarPanel-focus");
} else {
titleBarPanel.removeStyleName("TitleBarPanel-focus");
}
}
/**
*
* @return true if title has to be in bold
*/
protected boolean titleIsBold() {
return hasFocus;
}
/**
* @return An unique ID for this DockPanel.
*/
@Override
public int getViewId() {
return id;
}
/**
* @return The title of this view.
*/
public String getViewTitle() {
return title;
}
/**
* @return The order of this panel in the view menu, with 0 being "highest".
* Will be -1 if this view does not appear in the menu at all.
*/
public int getMenuOrder() {
return menuOrder;
}
/**
* @return Whether the current view has a menu shortcut to toggle its
* visibility.
*/
public boolean hasMenuShortcut() {
return menuShortcut != '\u0000';
}
/**
* @return The menu shortcut of this view.
*/
public char getMenuShortcut() {
return menuShortcut;
}
/**
* @return If this panel has a toolbar.
*/
public boolean hasToolbar() {
return defaultToolbarString != null;
}
/**
* @return If this panel can customize its toolbar.
*/
public boolean canCustomizeToolbar(){
return hasToolbar();
}
/**
* @return The definition string associated with this toolbar.
*/
@Override
public String getToolbarString() {
return toolbarString;
}
/**
* Set the toolbar string of this view. If the toolbar string is null but
* this panel has a panel normally the default toolbar string is used. This
* is used for backward compability. Has no visible effect.
*
* @param toolbarString
*/
public void setToolbarString(String toolbarString) {
if (toolbarString == null && hasToolbar()) {
this.toolbarString = defaultToolbarString;
} else {
this.toolbarString = toolbarString;
}
}
/**
* @return The default toolbar string of this panel (or null).
*/
@Override
public String getDefaultToolbarString() {
return defaultToolbarString;
}
/**
* @return dock panel information as string for debugging.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[DockPanel,id=");
sb.append(getViewId());
sb.append(",toolbar=");
sb.append(getToolbarString());
sb.append(",visible=");
sb.append(isVisible());
sb.append(",inframe=");
sb.append(isOpenInFrame());
sb.append("]");
return sb.toString();
}
@Override
public String toString(String prefix) {
return "\n" + prefix + this.toString();
}
@Override
public boolean updateResizeWeight() {
return false;
}
@Override
public void saveDividerLocation() {
// no divider here
}
@Override
public void updateDividerLocation(int size, int orientation1) {
// no divider here
}
@Override
public void setDockPanelsVisible(boolean visible) {
setVisible(visible);
}
public void enableDragging(boolean drag) {
if (dragPanel == null) {
return;
}
// titleBarPanelContent is unvisible, when it's empty
// so is has to be shown/hidden when dragmode changes
titleBarPanelContent.setVisible(drag || !isStyleBarEmpty());
dragPanel.setVisible(drag);
// hide close button when in dragmode
closeButtonPanel.setVisible(!drag);
//TODO view menu?
if(drag){
titleBarPanelContent.removeStyleName("TitleBarPanelContent");
titleBarPanelContent.addStyleName("DragPanel");
} else {
titleBarPanelContent.removeStyleName("DragPanel");
titleBarPanelContent.addStyleName("TitleBarPanelContent");
}
if (this.toggleStyleBarButton != null) {
this.toggleStyleBarButton.setVisible(!drag);
}
if (drag) {
this.styleBarPanel.setVisible(false);
} else {
updateStyleBarVisibility();
if (styleBar instanceof StyleBarW) {
((StyleBarW) styleBar).setOpen(showStyleBar);
}
}
}
public boolean isStyleBarEmpty() {
return false;
}
public GDimension getEstimatedSize() {
switch (getViewId()) {
case App.VIEW_EUCLIDIAN:
return new GDimensionW(app.getSettings().getEuclidian(1)
.getPreferredSize().getWidth(), app.getSettings()
.getEuclidian(1).getPreferredSize().getHeight());
case App.VIEW_EUCLIDIAN2:
return new GDimensionW(app.getSettings().getEuclidian(2)
.getPreferredSize().getWidth(), app.getSettings()
.getEuclidian(2).getPreferredSize().getHeight());
case App.VIEW_SPREADSHEET:
return new GDimensionW(app.getSettings().getSpreadsheet()
.preferredSize().getWidth(), app.getSettings()
.getSpreadsheet().preferredSize().getHeight());
}
// probably won't work
return new GDimensionW(getOffsetWidth(), getOffsetHeight());
}
private int embeddedDimWidth, embeddedDimHeight;
private ShowKeyboardButton keyboardButton;
/**
* embedded dimensions (calculated when perspective is set)
*
* @param w
* width
* @param h
* height
*/
public void setEmbeddedDim(int w, int h) {
embeddedDimWidth = w;
embeddedDimHeight = h;
}
/**
*
* @return embedded width
*/
public int getEmbeddedDimWidth() {
return embeddedDimWidth;
}
/**
*
* @return embedded height
*/
public int getEmbeddedDimHeight() {
return embeddedDimHeight;
}
/**
* Initializes the view-specific icon of the DockPanel
*
* @param imageResource: the icon the be shown
*/
public void setViewImage(ResourcePrototype imageResource){
this.viewImage = imageResource;
}
private ResourcePrototype getToggleImage(boolean showing){
if(showing){
if(triangleRight == null){
triangleRight = new Image(
GuiResources.INSTANCE.dockbar_triangle_right());
}
return GuiResources.INSTANCE.dockbar_triangle_right();
}
if(viewImage != null){
return viewImage;
}
if(triangleLeft == null){
triangleLeft = new Image(
GuiResources.INSTANCE.dockbar_triangle_left());
}
return GuiResources.INSTANCE.dockbar_triangle_left();
}
public void setStyleBarRightOffset(int offset){
if(this.titleBarPanel != null){
this.titleBarPanel.getElement().getStyle().setPosition(Position.ABSOLUTE);
this.titleBarPanel.getElement().getStyle().setRight(offset, Unit.PX);
}
}
public void showStyleBarPanel(boolean show){
if(this.titleBarPanel != null){
this.titleBarPanel.setVisible(show);
}
}
public boolean isStyleBarPanelShown() {
if (titleBarPanel != null) {
return this.titleBarPanel.isVisible()
&& titleBarPanel.getParent() != null;
}
return false;
}
protected PerspectiveResources getResources(){
return ((ImageFactory)GWT.create(ImageFactory.class)).getPerspectiveResources();
}
public void addToToolbar(int mode) {
this.toolbarString = ToolBar.addMode(toolbarString, mode);
}
public void setCloseButtonVisible(boolean isVisible) {
if (closeButtonPanel == null) {
return;
}
closeButtonPanel.setVisible(isVisible);
}
public void addSouth(ShowKeyboardButton showKeyboardButton) {
if (this.kbButtonSpace == null) {
return;
}
this.kbButtonSpace.setWidget(showKeyboardButton);
}
/**
* set a ShowKeyBoardButton that will be updated, if this panel is resized
*
* @param button
* the button to be updated
*/
public void setKeyBoardButton(ShowKeyboardButton button) {
this.keyboardButton = button;
}
@Override
public void setVisible(boolean visible) {
if (this.visible != visible) {
this.visible = visible;
if (app.getGuiManager() != null) {
app.getGuiManager().updatePropertiesViewStylebar();
}
}
if(!app.has(Feature.SHOW_ONE_KEYBOARD_BUTTON_IN_FRAME)){
// hide the keyboard-button, when the view is closed
if (keyboardButton != null && !visible) {
keyboardButton.hide();
}
}
if (app.getGuiManager() != null) {
((GuiManagerW) app.getGuiManager()).updatePrintMenu();
}
}
public MathKeyboardListener getKeyboardListener() {
return null;
}
@Override
public void updateNavigationBar() {
// TODO Auto-generated method stub
}
public boolean hasPlane() {
// TODO Auto-generated method stub
return false;
}
public int navHeight() {
return 0;
}
public boolean hasLongStyleBar() {
return longStyleBar;
}
public void setLongStyleBar(boolean longStyleBar) {
this.longStyleBar = longStyleBar;
}
public int navHeightIfShown() {
return app.showConsProtNavigation(getViewId()) ? navHeight() : 0;
}
public void showResetIcon() {
StandardButton resetIcon = new StandardButton(
GuiResourcesSimple.INSTANCE.viewRefresh(), null, 24);
resetIcon.addFastClickHandler(new FastClickHandler() {
@Override
public void onClick(Widget source) {
app.reset();
}
});
if (!app.allowStylebar()) {
titleBarPanel.clear();
titleBarPanel.add(resetIcon);
} else {
titleBarPanelContent.add(resetIcon);
}
}
}