package org.geogebra.web.web.gui.layout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import org.geogebra.common.euclidian.EuclidianView;
import org.geogebra.common.gui.Layout;
import org.geogebra.common.io.layout.DockPanelData;
import org.geogebra.common.io.layout.Perspective;
import org.geogebra.common.javax.swing.SwingConstants;
import org.geogebra.common.main.App;
import org.geogebra.common.main.App.InputPosition;
import org.geogebra.common.main.Feature;
import org.geogebra.common.main.settings.AbstractSettings;
import org.geogebra.common.main.settings.SettingListener;
import org.geogebra.common.plugin.Event;
import org.geogebra.common.plugin.EventType;
import org.geogebra.common.util.debug.Log;
import org.geogebra.web.html5.main.AppW;
import org.geogebra.web.web.gui.GuiManagerW;
public class LayoutW extends Layout implements SettingListener {
private AppW app;
private DockManagerW dockManager;
/**
* instantiates layout for Web
*
* @param app
* application
*/
public LayoutW(App app) {
initializeDefaultPerspectives(app, 0.2);
this.perspectives = new ArrayList<Perspective>(
getDefaultPerspectivesLength());
}
/**
* Initialize the layout component.
*
* @param appw
* application
*/
public void initialize(AppW appw) {
if (!initializeCommon(appw)) {
return;
}
this.app = appw;
this.dockManager = new DockManagerW(this);
// change inputPosition to default inputPosition
for (int i = 0; i < Layout.getDefaultPerspectivesLength(); i++) {
Perspective p = Layout.getDefaultPerspectives(i);
if (p != null) {
p.setInputPosition(appw.getInputPosition());
}
}
}
/**
* Add a new dock panel to the list of known panels.
*
* Attention: This method has to be called as early as possible in the application
* life cycle (e.g. before loading a file, before constructing the ViewMenu).
*
* @param dockPanel
*/
public void registerPanel(DockPanelW dockPanel) {
dockManager.registerPanel(dockPanel);
}
/* Many of this not implemented yet, later we can make it togehter */
@Override
public boolean applyPerspective(Perspective perspective) {
// ignore axes & grid settings for the document perspective
boolean changed = setEVsettingsFromPerspective(app, perspective);
app.getGuiManager().setGeneralToolBarDefinition(
perspective.getToolbarDefinition());
app.setToolbarPosition(perspective.getToolBarPosition(), false);
// override the previous command with the data-param-customToolBar
// setting
if (app.isApplet()) {
app.setCustomToolBar();
app.setShowToolBarNoUpdate(
/*
* perspective.getShowToolBar() &&
* app.getArticleElement().getDataParamShowToolBarDefaultTrue() ||
*/
app.getArticleElement().getDataParamShowToolBar(false));
app.setShowAlgebraInput(
/*
* perspective.getShowInputPanel() &&
* app.getArticleElement().getDataParamShowAlgebraInputDefaultTrue()
* ||
*/
app.getArticleElement().getDataParamShowAlgebraInput(false), false);
}
// app.setShowInputTop(perspective.getShowInputPanelOnTop(), false);
app.setInputPosition(
app.getArticleElement()
.getAlgebraPosition(perspective.getInputPosition()), false);
String toolbar3D = "";
// change the dock panel layout
app.setKeyboardNeeded(false);
for (DockPanelData dp : perspective.getDockPanelData()) {
if(app.has(Feature.SHOW_ONE_KEYBOARD_BUTTON_IN_FRAME)){
if (dp.isVisible()) {
// && (dp.getViewId() == App.VIEW_ALGEBRA
// || dp.getViewId() == App.VIEW_CAS ||
// dp.getViewId() == App.VIEW_PROBABILITY_CALCULATOR
// || dp.getViewId() == App.VIEW_SPREADSHEET)) {
app.setKeyboardNeeded(true);
}
} else if (dp.isVisible() && (dp.getViewId() == App.VIEW_ALGEBRA
|| dp.getViewId() == App.VIEW_CAS)) {
app.setKeyboardNeeded(true);
}
if (dp.getViewId() == App.VIEW_EUCLIDIAN3D) {
toolbar3D = dp.getToolbarString();
// Log.debug("TADAM " + toolbar3D);
}
}
dockManager.applyPerspective(perspective.getSplitPaneData(),
perspective.getDockPanelData());
app.setMacroViewIds(toolbar3D);
if (!app.isIniting()) {
app.updateToolBar();
app.updateMenubar();
app.updateContentPane();
app.getGuiManager().refreshCustomToolsInToolBar();
app.updateToolBar();
} else if (app.showAlgebraInput()
&& app.getInputPosition() != InputPosition.algebraView) {
app.updateContentPane();
}
app.dispatchEvent(new Event(EventType.PERSPECTIVE_CHANGE, null));
return changed;
// old behaviour: just updating center, instead of updateContentPane
// app.refreshSplitLayoutPanel();
}
/**
* Apply a new perspective using its id.
*
* This is a wrapper for #applyPerspective(Perspective) to simplify the loading of default
* perspectives by name.
*
* @param id The ID of the perspective. For default perspectives the hard-coded ID is used, ie
* the translation key, for all other perspectives the ID chosen by the user is
* used.
* @throws IllegalArgumentException If no perspective with the given name could be found.
*/
@Override
public void applyPerspective(String id) throws IllegalArgumentException {
Perspective perspective = getPerspective(id);
if(perspective != null) {
applyPerspective(perspective);
} else {
throw new IllegalArgumentException("Could not find perspective with the given name.");
}
}
/**
* Get all current perspectives as array.
*
* @return all current perspectives as array.
*/
public Perspective[] getPerspectives() {
Perspective[] array = new Perspective[perspectives.size()];
return perspectives.toArray(array);
}
/**
* @param index
* @return perspective at given index
*/
public Perspective getPerspective(int index) {
if(index >= perspectives.size()) {
throw new IndexOutOfBoundsException();
}
return perspectives.get(index);
}
/**
* @param id name of the perspective
* @return perspective with 'id' as name or null
*/
public Perspective getPerspective(String id) {
for (int i = 0; i < getDefaultPerspectivesLength(); ++i) {
if (id.equals(getDefaultPerspectives(i).getId())) {
return getDefaultPerspectives(i);
}
}
for(Perspective perspective : perspectives) {
if(id.equals(perspective.getId())) {
return perspective;
}
}
return null;
}
/**
* Add a new perspective to the list of available perspectives.
*
* @param perspective
*/
public void addPerspective(Perspective perspective) {
perspectives.add(perspective);
}
/**
* Remove a perspective identified by the object.
*
* @param perspective
*/
public void removePerspective(Perspective perspective) {
if(perspectives.contains(perspective)) {
perspectives.remove(perspective);
}
}
/**
* Remove a perspective identified by the index.
*
* @param index
*/
public void removePerspective(int index) {
if(index >= 0 && index < perspectives.size()) {
perspectives.remove(index);
} else {
Log.debug("Invalid perspective index: " + index);
}
}
@Override
public void settingsChanged(AbstractSettings settings) {
// TODO Auto-generated method stub
}
/**
* Create a perspective for the current layout.
*
* @param id
* @return a perspective for the current layout.
*/
@Override
public Perspective createPerspective(String id) {
if(app == null || dockManager.getRoot() == null) {
return null;
}
// return the default perspective in case we're creating new preferences of
// a virgin application.
EuclidianView ev = app.getEuclidianView1();
Perspective perspective = new Perspective(id);
// get the information about the split panes
DockSplitPaneW.TreeReader spTreeReader = new DockSplitPaneW.TreeReader(
app);
perspective.setSplitPaneData(spTreeReader.getInfo(dockManager.getRoot()));
// get the information about the dock panels
DockPanelW[] panels = dockManager.getPanels();
DockPanelData[] dockPanelInfo = new DockPanelData[panels.length];
for (int i = 0; i < panels.length; ++i) {
// just the width of the panels isn't updated every time the panel
// is updated, so we have to take care of this by ourself
if (!panels[i].isOpenInFrame() && panels[i].isVisible()) {
DockSplitPaneW parent = panels[i].getParentSplitPane();
if (parent.getOrientation() == SwingConstants.HORIZONTAL_SPLIT) {
panels[i].setEmbeddedSize(panels[i].getWidth());
} else {
panels[i].setEmbeddedSize(panels[i].getHeight());
}
panels[i].setEmbeddedDef(panels[i].calculateEmbeddedDef());
}
dockPanelInfo[i] = panels[i].createInfo();
}
// Sort the dock panels as the entries with the smallest amount of
// definition should
// be read first by the loading algorithm.
Arrays.sort(dockPanelInfo, new Comparator<DockPanelData>() {
@Override
public int compare(DockPanelData o1, DockPanelData o2) {
int diff = o2.getEmbeddedDef().length()
- o1.getEmbeddedDef().length();
return diff;
}
});
perspective.setDockPanelData(dockPanelInfo);
perspective.setToolbarDefinition(((GuiManagerW) app.getGuiManager())
.getGeneralToolbarDefinition());
perspective.setShowToolBar(app.showToolBar());
perspective.setShowAxes(ev.getShowXaxis() && ev.getShowYaxis());
perspective.setShowGrid(ev.getShowGrid());
perspective.setShowInputPanel(app.showAlgebraInput());
perspective.setShowInputPanelCommands(app.showInputHelpToggle());
perspective.setInputPosition(app.getInputPosition());
perspective.setToolBarPosition(app.getToolbarPosition());
//perspective.setShowToolBarHelp(app.showToolBarHelp());
//perspective.setShowDockBar(app.isShowDockBar());
//perspective.setDockBarEast(app.isDockBarEast());
return perspective;
}
/**
* @param viewId
* @return If just the view associated to viewId is visible
*/
@Override
public boolean isOnlyVisible(int viewId) {
DockPanelW[] panels = dockManager.getPanels();
boolean foundView = false;
for(int i = 0; i < panels.length; ++i) {
// check if the view is visible at all
if(panels[i].getViewId() == viewId) {
foundView = true;
if(!panels[i].isVisible()) {
return false;
}
}
// abort if any other view is visible
else {
if(panels[i].isVisible()) {
return false;
}
}
}
// if we reach this point each other view is invisible, but
// if the view wasn't found at all we return false as well
return foundView;
}
public AppW getApplication() {
return app;
}
/**
* @return The management class for the docking behavior.
*/
@Override
public DockManagerW getDockManager() {
return dockManager;
}
public DockSplitPaneW getRootComponent() {
if(dockManager == null) {
return null;
}
return dockManager.getRoot();
}
}