/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
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.
*/
package org.geogebra.common.gui.view.functioninspector;
import org.geogebra.common.gui.SetLabels;
import org.geogebra.common.gui.UpdateFonts;
import org.geogebra.common.gui.view.functioninspector.FunctionInspectorModel.IFunctionInspectorListener;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.ModeSetter;
import org.geogebra.common.kernel.View;
import org.geogebra.common.kernel.geos.GProperty;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoFunction;
import org.geogebra.common.main.App;
import org.geogebra.common.main.GeoElementSelectionListener;
import org.geogebra.common.util.debug.Log;
/**
* View for inspecting selected GeoFunctions
*
* @author G. Sturr, 2011-2-12
*
*/
public abstract class FunctionInspector
implements View, UpdateFonts, SetLabels, IFunctionInspectorListener {
private FunctionInspectorModel model;
// ggb fields
private Kernel kernel;
private boolean isIniting;
private boolean isChangingValue;
protected App app;
private GeoElementSelectionListener sl;
/***************************************************************
* Constructs a FunctionInspecor
*
* @param app
* @param selectedGeo
*/
public FunctionInspector(App app, GeoFunction selectedGeo) {
this.setApp(app);
setKernel(app.getKernel());
app.getKernel().attach(this);
setModel(new FunctionInspectorModel(app, selectedGeo, this));
// create the GUI
createGeoElementSelectionListener();
createGUI();
// load selected function
insertGeoElement(selectedGeo);
isIniting = false;
}
// ======================================================
// GUI
// ======================================================
protected void createGUI() {
// create the GUI components
createGUIElements();
createHeaderPanel();
createTabPanel();
}
protected void createTabPanel() {
createTabPointPanel();
createTabIntervalPanel();
buildTabPanel();
}
protected abstract void buildTabPanel();
protected abstract void buildHelpPanel();
protected abstract void buildHeaderPanel();
protected void createHeaderPanel() {
createHelpPanel();
buildHeaderPanel();
}
private void createHelpPanel() {
createOptionsButton();
buildHelpPanel();
}
protected abstract void createTabIntervalPanel();
protected abstract void createTabPointPanel();
protected abstract void createGUIElements();
protected void updateIntervalTab() {
updateIntervalTable();
getModel().updateIntervalGeoVisiblity();
}
protected abstract void updatePointsTab();
protected abstract boolean isIntervalTabSelected();
// =====================================
// Update
// =====================================
public void updateGUI() {
if (isIntervalTabSelected()) {
updateIntervalTab();
} else {
updatePointsTab();
}
setLabels();
}
/**
* Updates the tab panels and thus the entire GUI. Also updates the active
* EV to hide/show temporary GeoElements associated with the
* FunctionInspector (e.g. points, integral)
*/
public void updateTabPanels() {
if (isIntervalTabSelected()) {
updateIntervalFields();
} else {
updatePointsTab();
}
getModel().updateGeos(isIntervalTabSelected());
updateGUI();
}
protected abstract void updateIntervalFields();
/**
* Updates the interval table. The max, min, roots, area etc. for the
* current interval are calculated and put into the IntervalTable model.
*/
protected void updateIntervalTable() {
isChangingValue = true;
getModel().updateIntervalTable();
isChangingValue = false;
}
/**
* Updates the XYTable with the coordinates of the current sample points and
* any related values (e.g. derivative, difference)
*/
protected abstract void updateXYTable();
protected abstract void removeColumn();
public void setInspectorVisible(boolean isVisible) {
if (isVisible) {
Log.debug("setInspectorVisible(true)");
app.getKernel().attach(this);
} else {
Log.debug("setInspectorVisible(false)");
app.getKernel().detach(this);
app.getSelectionManager().removeSelectionListener(sl);
getModel().clearGeoList();
}
}
// ====================================================
// View Implementation
// ====================================================
@Override
public void update(GeoElement geo) {
if (!getModel().isValid() || isChangingValue || isIniting) {
return;
}
getModel().update(geo, !isIntervalTabSelected());
}
@Override
final public void updateVisualStyle(GeoElement geo, GProperty prop) {
update(geo);
}
@Override
public void add(GeoElement geo) {
// not needed in this view
}
@Override
public void updatePreviewFromInputBar(GeoElement[] geos) {
// not needed in this view
}
@Override
public void remove(GeoElement geo) {
// not needed in this view
}
@Override
public void rename(GeoElement geo) {
// not needed in this view
}
@Override
public void updateAuxiliaryObject(GeoElement geo) {
// not needed in this view
}
@Override
public void repaintView() {
// not needed in this view
}
@Override
public void clearView() {
// not needed in this view
}
@Override
public void setMode(int mode, ModeSetter m) {
// not needed in this view
}
// ====================================================
// Geo Selection Listener
// ====================================================
private void createGeoElementSelectionListener() {
if (sl == null) {
sl = new GeoElementSelectionListener() {
@Override
public void geoElementSelected(GeoElement geo,
boolean addToSelection) {
insertGeoElement(geo);
}
};
}
app.getSelectionManager().addSelectionListener(sl);
}
/**
* Sets the function to be inspected and updates the entire GUI
*
* @param geo
* The function to be inspected
*/
public void insertGeoElement(GeoElement geo) {
if (geo == null || !geo.isGeoFunction()) {
return;
}
getModel().insertGeoElement(geo);
updateTabPanels();
}
protected void updateTestPoint() {
if (isIniting) {
return;
}
isChangingValue = true;
getModel().updateTestPoint();
isChangingValue = false;
}
protected void setStart(double x) {
try {
getModel().setStart(x);
// Application.debug("" + start);
updateXYTable();
updateTestPoint();
} catch (Exception e1) {
e1.printStackTrace();
}
}
protected abstract void changeStart(double x);
@Override
public void changedNumberFormat() {
this.updateGUI();
this.updateIntervalFields();
this.updateTestPoint();
}
protected abstract void createOptionsButton();
protected abstract void doCopyToSpreadsheet();
@Override
public int getViewID() {
return App.VIEW_FUNCTION_INSPECTOR;
}
public void repaint() {
//
}
@Override
public boolean isShowing() {
//
return false;
}
@Override
public void startBatchUpdate() {
//
}
@Override
public void endBatchUpdate() {
//
}
public void setApp(App app) {
this.app = app;
}
public FunctionInspectorModel getModel() {
return model;
}
public void setModel(FunctionInspectorModel model) {
this.model = model;
}
public Kernel getKernel() {
return kernel;
}
public void setKernel(Kernel kernel) {
this.kernel = kernel;
}
}