package org.geogebra.web.html5.euclidian; import java.util.ArrayList; import org.geogebra.common.euclidian.EuclidianConstants; import org.geogebra.common.euclidian.EuclidianController; import org.geogebra.common.euclidian.EuclidianView; import org.geogebra.common.euclidian.EuclidianViewInterfaceCommon; import org.geogebra.common.euclidian.Hits; import org.geogebra.common.euclidian.event.AbstractEvent; import org.geogebra.common.euclidian.event.PointerEventType; import org.geogebra.common.euclidianForPlane.EuclidianViewForPlaneInterface; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.ModeSetter; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.arithmetic.TextValue; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoText; import org.geogebra.common.kernel.kernelND.GeoElementND; import org.geogebra.common.main.App; import org.geogebra.common.main.Feature; import org.geogebra.web.html5.event.PointerEvent; import org.geogebra.web.html5.gui.GuiManagerInterfaceW; import org.geogebra.web.html5.gui.util.LongTouchManager; import org.geogebra.web.html5.main.AppW; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.DropEvent; import com.google.gwt.event.dom.client.DropHandler; import com.google.gwt.event.dom.client.GestureChangeEvent; import com.google.gwt.event.dom.client.GestureChangeHandler; import com.google.gwt.event.dom.client.GestureEndEvent; import com.google.gwt.event.dom.client.GestureEndHandler; import com.google.gwt.event.dom.client.GestureStartEvent; import com.google.gwt.event.dom.client.GestureStartHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.dom.client.MouseWheelEvent; import com.google.gwt.event.dom.client.MouseWheelHandler; import com.google.gwt.event.dom.client.TouchCancelEvent; import com.google.gwt.event.dom.client.TouchCancelHandler; import com.google.gwt.event.dom.client.TouchEndEvent; import com.google.gwt.event.dom.client.TouchEndHandler; import com.google.gwt.event.dom.client.TouchMoveEvent; import com.google.gwt.event.dom.client.TouchMoveHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.user.client.Event; /** * Web version of Euclidian controller * */ public class EuclidianControllerW extends EuclidianController implements MouseDownHandler, MouseUpHandler, MouseMoveHandler, MouseOutHandler, MouseOverHandler, MouseWheelHandler, TouchStartHandler, TouchEndHandler, TouchMoveHandler, TouchCancelHandler, GestureStartHandler, GestureEndHandler, GestureChangeHandler, IsEuclidianController, DropHandler { @Override public EnvironmentStyleW getEnvironmentStyle() { return mtg.getEnvironmentStyle(); } /** * recalculates cached styles concerning browser environment */ @Override public void calculateEnvironment() { mtg.calculateEnvironment(); } @Override public void moveIfWaiting() { mtg.moveIfWaiting(); } private MouseTouchGestureControllerW mtg; @Override protected void createCompanions() { super.createCompanions(); mtg = new MouseTouchGestureControllerW((AppW) app, this); } /** * Creates a new controller * * @param kernel * kernel */ public EuclidianControllerW(Kernel kernel) { super(kernel.getApplication()); setKernel(kernel); } @Override public void handleLongTouch(int x, int y) { mtg.handleLongTouch(x, y); } @Override public void onGestureChange(GestureChangeEvent event) { mtg.onGestureChange(event); } @Override public void onGestureEnd(GestureEndEvent event) { mtg.onGestureEnd(event); } @Override public void onGestureStart(GestureStartEvent event) { mtg.onGestureStart(event); } @Override public void onTouchCancel(TouchCancelEvent event) { mtg.onTouchCancel(event); } @Override public void onTouchMove(TouchMoveEvent event) { mtg.onTouchMove(event); } /** * @param touch * first finger * @param touch2 * second finger */ public void twoTouchMove(Touch touch, Touch touch2) { mtg.twoTouchMove(touch, touch2); } @Override public void onTouchEnd(TouchEndEvent event) { mtg.onTouchEnd(event); } @Override public void onTouchStart(TouchStartEvent event) { if ((app.getGuiManager() != null) && (getEvNo() != EuclidianView.EVNO_GENERAL || (getView() instanceof EuclidianViewForPlaneInterface))) { // Probability calculator plot panel view should not set active // toolbar ID // this is used by DataDisplayPanelW and PlotPanelEuclidianViewW, // #plotpanelevno // probably both are Okay not changing the toolbar to full Graphics // view toolbar ((GuiManagerInterfaceW) app.getGuiManager()) .setActivePanelAndToolbar(App.VIEW_EUCLIDIAN); } else { setMode(EuclidianConstants.MODE_MOVE, ModeSetter.TOOLBAR); // app.setMode(EuclidianConstants.MODE_MOVE); // app.getGuiManager().updateToolbar(); } mtg.onTouchStart(event); } /** * @param event * touch event */ public void preventTouchIfNeeded(TouchStartEvent event) { mtg.preventTouchIfNeeded(event); } /** * @param touch * first finger * @param touch2 * second finger */ public void twoTouchStart(Touch touch, Touch touch2) { mtg.twoTouchStart(touch, touch2); } @Override public void onMouseWheel(MouseWheelEvent event) { mtg.onMouseWheel(event); } @Override public void onMouseOver(MouseOverEvent event) { mtg.onMouseOver(event); } @Override public void onMouseOut(MouseOutEvent event) { mtg.onMouseOut(event); } @Override public void onMouseMove(MouseMoveEvent event) { mtg.onMouseMove(event); } @Override public void onMouseUp(MouseUpEvent event) { mtg.onMouseUp(event); } @Override public void onMouseDown(MouseDownEvent event) { mtg.onMouseDown(event); } @Override public void onPointerEventStart(AbstractEvent event) { if (temporaryMode) { mtg.setComboboxFocused(false); } if ((app.getGuiManager() != null) && (getEvNo() != EuclidianView.EVNO_GENERAL || (getView() instanceof EuclidianViewForPlaneInterface))) { // Probability calculator plot panel view should not set active // toolbar ID // this is used by DataDisplayPanelW and PlotPanelEuclidianViewW, // #plotpanelevno // probably both are Okay not changing the toolbar to full Graphics // view toolbar ((GuiManagerInterfaceW) app.getGuiManager()) .setActivePanelAndToolbar(App.VIEW_EUCLIDIAN); } else { if (mode == EuclidianConstants.MODE_MOVE || mode == EuclidianConstants.MODE_TRANSLATEVIEW || mode == EuclidianConstants.MODE_SELECTION_LISTENER) { setMode(mode, ModeSetter.TOOLBAR); } // app.setMode(EuclidianConstants.MODE_MOVE); // app.getGuiManager().updateToolbar(); } mtg.onPointerEventStart(event); } @Override protected void initToolTipManager() { mtg.initToolTipManager(); } @Override protected void resetToolTipManager() { mtg.resetToolTipManager(); } @Override protected boolean hitResetIcon() { return mtg.hitResetIcon(); } @Override public boolean textfieldJustFocused(int x, int y, PointerEventType type) { if (isComboboxFocused()) { // Log.info("isComboboxFocused!"); this.draggingOccured = false; getView().setHits(mouseLoc, type); Hits hits = getView().getHits().getTopHits(); if (!hits.isEmpty()) { GeoElement hit = hits.get(0); if (hit != null && !hit.isGeoButton() && !hit.isGeoInputBox() && !hit.isGeoBoolean()) { GeoElement geo = chooseGeo(hits, true); if (geo != null) { runScriptsIfNeeded(geo); } } } return true; } // return view.textfieldClicked(x, y, type) || isComboboxFocused(); return getView().textfieldClicked(x, y, type); } @Override public boolean isComboboxFocused() { return mtg.isComboboxFocused(); } /** * @param flag * whether a combobox has focus */ public void setComboboxFocused(boolean flag) { mtg.setComboboxFocused(flag); } /** * @return the multiplier that must be used to multiply the native event * coordinates */ public double getScaleXMultiplier() { return mtg.getScaleXMultiplier(); } /** * @return the multiplier that must be used to multiply the native event * coordinates */ public double getScaleYMultiplier() { return mtg.getScaleYMultiplier(); } /* * @Override public int getEvID() { return view.getViewID(); } */ @Override public void twoTouchMove(double x1d, double y1d, double x2d, double y2d) { mtg.twoTouchMove(x1d, y1d, x2d, y2d); } @Override public void twoTouchStart(double x1, double y1, double x2, double y2) { mtg.twoTouchStart(x1, y1, x2, y2); } @Override protected void startCapture(AbstractEvent event) { if (app != null && !app.has(Feature.PEN_EVENTS)) { Event.setCapture(((PointerEvent) event).getRelativeElement()); } } @Override protected boolean processZoomRectangle() { boolean processed = super.processZoomRectangle(); if (processed) { selectionStartPoint.setLocation(mouseLoc); } return processed; } @Override protected void showPopupMenuChooseGeo(ArrayList<GeoElement> selectedGeos1, Hits hits) { ArrayList<GeoElement> geos = selectedGeos1 != null && selectedGeos1.isEmpty() ? getAppSelectedGeos() : selectedGeos1; app.getGuiManager().showPopupMenu(geos, getView(), mouseLoc); } /** * set whether the actual tool should be kept after the element was * constructed or not * * @param sticky * keep the tool iff true */ @Override public void setActualSticky(boolean sticky) { // TODO decide if we ever want to do this } @Override public void onDrop(DropEvent event) { app.setActiveView(App.VIEW_EUCLIDIAN); app.setActiveView(App.VIEW_EUCLIDIAN2); EuclidianViewInterfaceCommon ev = app.getActiveEuclidianView(); GeoElement geo = app.getAlgebraView().getDraggedGeo(); if (geo == null) { return; } ArrayList<String> list = new ArrayList<String>(); list.add(geo.isLabelSet() ? geo.getLabelSimple() : "\"" + geo.getLaTeXAlgebraDescription(true, StringTemplate.latexTemplate) + "\""); String text = EuclidianView.getDraggedLabels(list); GeoElementND[] ret = app.getKernel().getAlgebraProcessor() .processAlgebraCommand(text, true); if (ret != null && ret[0] instanceof TextValue) { GeoText geo0 = (GeoText) ret[0]; geo0.setLaTeX(true, false); // TODO: h should equal the geo height, this is just an // estimate int x = event.getNativeEvent().getClientX(); //double h = 2 * app.getFontSize(); int y = event.getNativeEvent().getClientY(); geo0.setRealWorldLoc(ev.toRealWorldCoordX(mtg.touchEventX(x)), ev.toRealWorldCoordY(mtg.touchEventY(y))); geo0.updateRepaint(); } } @Override public LongTouchManager getLongTouchManager() { return mtg.getLongTouchManager(); } @Override public void closePopups(int x, int y, PointerEventType type) { PointerEvent wrap = new PointerEvent(x, y, type, mtg); ((AppW) app).closePopups(wrap.getX(), wrap.getY()); } @Override public void setDynamicStylebarVisible(boolean visible) { if (!app.has(Feature.DYNAMIC_STYLEBAR) || !((AppW) app).allowStylebar()) { return; } this.getView().getDynamicStyleBar().setVisible(visible); } @Override protected void addDynamicStylebar() { getView().getDynamicStyleBar().setVisible(true); getView().getDynamicStyleBar().updateStyleBar(); } public void onPointerEventMove(PointerEvent event) { mtg.onMouseMoveNow(event, System.currentTimeMillis(), true); } public void onPointerEventEnd(PointerEvent event) { mtg.onPointerEventEnd(event); } public MouseTouchGestureControllerW getOffsets() { return mtg; } }