Java tutorial
/* * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt */ package edu.caltech.ipac.firefly.visualize; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; 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.TouchMoveEvent; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.DeckPanel; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import edu.caltech.ipac.firefly.resbundle.images.VisIconCreator; import edu.caltech.ipac.firefly.ui.GwtUtil; import edu.caltech.ipac.firefly.ui.PopupPane; import edu.caltech.ipac.firefly.ui.PopupType; import edu.caltech.ipac.firefly.ui.input.SimpleInputField; import edu.caltech.ipac.firefly.util.BrowserUtil; import edu.caltech.ipac.firefly.util.PropertyChangeEvent; import edu.caltech.ipac.firefly.util.PropertyChangeListener; import edu.caltech.ipac.firefly.util.WebAssert; import edu.caltech.ipac.firefly.util.event.Name; import edu.caltech.ipac.firefly.util.event.WebEvent; import edu.caltech.ipac.firefly.util.event.WebEventListener; import edu.caltech.ipac.firefly.util.event.WebEventManager; import edu.caltech.ipac.firefly.visualize.draw.DrawObj; import edu.caltech.ipac.firefly.visualize.draw.DrawSymbol; import edu.caltech.ipac.firefly.visualize.draw.DrawingDef; import edu.caltech.ipac.firefly.visualize.draw.DrawingManager; import edu.caltech.ipac.firefly.visualize.draw.PointDataObj; import edu.caltech.ipac.firefly.visualize.draw.SimpleDataConnection; import edu.caltech.ipac.visualize.plot.ImagePt; import edu.caltech.ipac.visualize.plot.ImageWorkSpacePt; import edu.caltech.ipac.visualize.plot.WorldPt; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * User: roby * Date: May 20, 2008 * Time: 1:43:46 PM */ /** * @author Trey Roby * @version $Id: WebMouseReadout.java,v 1.65 2012/11/21 21:12:43 roby Exp $ */ public class WebMouseReadout implements PropertyChangeListener, Readout { public enum DisplayMode { Quick, Group } public enum Choice { Good, OK, Bad } public enum Side { Left, Right, Top, Bottom, IRSA_LOGO } private static final int IRSA_LOGO_X = 139; private static final int WIDE_MAX_ROWS = 4; private static WebDefaultMouseReadoutHandler _defaultHandler = new WebDefaultMouseReadoutHandler(); private static final boolean INTELLIGENT_CHOICE = false; private WebMouseReadoutHandler _currentHandler = _defaultHandler; private Map<Widget, String> _styleMap = new HashMap<Widget, String>(30); private WebPlot _currentPlot = null; private int _currentRows = 0; private int _currentCols = 0; private WebPlotView _plotView; private final PopupPane _popupPanel; private Grid _grid = new Grid(); private Grid gridWide = new Grid(); private boolean _showing = false; private Side _displaySide = Side.Left; private Image _lockIcon; private Image _unlockIcon; private static final NumberFormat _nfPix = NumberFormat.getFormat("#.##"); private HTML _filePix = new HTML(); private HTML _screenPix = new HTML(); private HTML _zoomLevel = new HTML(); private final DeckPanel _thumbDeck = new DeckPanel(); private final DeckPanel _magDeck = new DeckPanel(); private final List<WebPlotView> _pvList = new ArrayList<WebPlotView>(3); private int _laterX; private int _laterY; private ShowReadoutTimer _showReadoutTimer = null; private HideReadoutTimer _hideReadoutTimer = null; private GwtUtil.ImageButton _lockButton; private boolean _dialogLockedUp = false; private boolean _enabled = true; private DisplayMode _mode = DisplayMode.Quick; private final WebPlotView.MouseInfo _mi = new WebPlotView.MouseInfo(new ReadOut(), "Move mouse to see plot information"); private boolean _mayLockOnce = false; private boolean _pixelClickLock = false; private MarkedPointDisplay _dataConnect = new MarkedPointDisplay(); private DrawingManager _lockPointDrawMan = null; private CheckBox _lockMouCheckBox = new CheckBox("Lock By Click"); private final boolean wide; private final Label titleLabel = new Label(); private final MouseHandlers mouseHandlers = new MouseHandlers(); private ScreenPt lastPt = null; private HTML arrowDesc = new HTML("Arrow: Eq. North & East"); public WebMouseReadout() { this(false); } public WebMouseReadout(boolean wide) { super(); this.wide = wide; HorizontalPanel hp = new HorizontalPanel(); _popupPanel = new PopupPane(null, hp, PopupType.STANDARD, false, false, false, PopupPane.HeaderType.NONE); _popupPanel.alignTo(null, PopupPane.Align.DISABLE); _popupPanel.setRolldownAnimation(true); _popupPanel.setAnimateDown(true); _popupPanel.setAnimationEnabled(true); _lockIcon = new Image(VisIconCreator.Creator.getInstance().getLocked()); _unlockIcon = new Image(VisIconCreator.Creator.getInstance().getUnlocked()); hp.addDomHandler(new TouchStartHandler() { public void onTouchStart(TouchStartEvent event) { lockDialogOnce(); } }, TouchStartEvent.getType()); _lockButton = GwtUtil.makeImageButton(_unlockIcon, "Lock readout area to stay showing", new ClickHandler() { public void onClick(ClickEvent event) { if (_dialogLockedUp) unlockDialog(); else lockDialog(); } }); _lockButton.setSize("20px", "20px"); _lockMouCheckBox.setTitle("Click on an image to lock the display at that point."); _lockMouCheckBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() { public void onValueChange(ValueChangeEvent<Boolean> lock) { setClickLock(lock.getValue()); } }); VerticalPanel fixedDisplay = new VerticalPanel(); fixedDisplay.setSpacing(2); GwtUtil.setStyle(titleLabel, "whiteSpace", "nowrap"); VerticalPanel wideControlArea = null; addMouseHandlers(_popupPanel.getPopupPanel(), true); addMouseHandlers(hp, true); addMouseHandlers(_grid, true); addMouseHandlers(gridWide, true); addMouseHandlers(fixedDisplay, true); if (wide) { wideControlArea = new VerticalPanel(); wideControlArea.add(_lockButton); wideControlArea.add(titleLabel); GwtUtil.setStyles(titleLabel, "padding", "13px 0 10px 0", "width", "160px"); if (!BrowserUtil.isTouchInput()) { wideControlArea.add(_lockMouCheckBox); GwtUtil.setStyles(_lockMouCheckBox, "paddingTop", "15px"); } fixedDisplay.add(_filePix); fixedDisplay.add(_screenPix); fixedDisplay.add(_zoomLevel); GwtUtil.setStyles(fixedDisplay, "width", "100px"); } else { fixedDisplay.add(_lockButton); fixedDisplay.add(_filePix); fixedDisplay.add(_screenPix); fixedDisplay.add(_zoomLevel); if (!BrowserUtil.isTouchInput()) fixedDisplay.add(_lockMouCheckBox); GwtUtil.setStyles(_lockMouCheckBox, "paddingRight", "10px"); } if (wide) { GwtUtil.setStyles(_filePix, "marginTop", "3px", "paddingLeft", "1px", "fontSize", "10px", "textAlign", "left"); GwtUtil.setStyles(_screenPix, "padding", "1px 12px 0px 1px", "fontSize", "10px", "textAlign", "left"); GwtUtil.setStyles(_zoomLevel, "padding", "12px 0 3px 0", "textAlign", "center", "color", "green", "fontSize", "9pt"); } else { GwtUtil.setStyles(_filePix, "marginTop", "-7px", "fontSize", "10px", "textAlign", "center"); GwtUtil.setStyles(_screenPix, "paddingTop", "5px", "fontSize", "10px", "textAlign", "center"); GwtUtil.setStyles(_zoomLevel, "padding", "2px 0 3px 0", "textAlign", "center", "color", "green", "fontSize", "9pt"); } _lockMouCheckBox.addStyleName("lock-click"); _filePix.addStyleName("title-font-family"); _screenPix.addStyleName("title-font-family"); _zoomLevel.addStyleName("title-font-family"); GwtUtil.setStyles(_grid, "lineHeight", "1", "marginLeft", "-8px"); if (wide) { GwtUtil.setStyles(gridWide, "lineHeight", "1"); } VerticalPanel imagePanel = new VerticalPanel(); if (wide) hp.add(wideControlArea); hp.add(fixedDisplay); hp.add(_grid); hp.add(imagePanel); HorizontalPanel decPanel = new HorizontalPanel(); decPanel.add(_thumbDeck); decPanel.setSpacing(2); decPanel.add(_magDeck); imagePanel.add(decPanel); if (wide) { hp.add(gridWide); } else { arrowDesc.addStyleName("title-font-family"); GwtUtil.setStyles(arrowDesc, "fontSize", "10px", "padding", "0 0 0 35px"); imagePanel.add(arrowDesc); } GwtUtil.setStyle(_magDeck, "paddingLeft", "5px"); if (wide) { _magDeck.setSize("70px", "70px"); } else { _magDeck.setSize("100px", "100px"); } WebEventManager.getAppEvManager().addListener(Name.REGION_CHANGE, new WebEventListener() { public void eventNotify(WebEvent ev) { hideMouseReadout(); } }); Window.addResizeHandler(new ResizeHandler() { public void onResize(ResizeEvent event) { if (BrowserUtil.isTouchInput()) hideMouseReadout(); // tablet resizing only } }); } DrawingManager getLockPointDrawing() { if (_lockPointDrawMan == null) { _lockPointDrawMan = new DrawingManager("Clicked Point", _dataConnect); } return _lockPointDrawMan; } private void lockDialogOnce() { if (_mayLockOnce) { lockDialog(); _mayLockOnce = false; } } private void lockDialog() { if (!_dialogLockedUp) { _lockButton.setImage(_lockIcon); cancelHideTimer(); _dialogLockedUp = true; } } private void unlockDialog() { _lockButton.setImage(_unlockIcon); _dialogLockedUp = false; if (BrowserUtil.isTouchInput()) hideMouseReadoutLater(1000); } public void setDisplayMode(DisplayMode mode) { _mode = mode; } public void addPlotView(WebPlotView pv) { if (!_pvList.contains(pv)) { _plotView = pv; _pvList.add(pv); int i = _pvList.indexOf(pv); if (wide) { _magDeck.insert(new MagnifiedView(pv, 70), i); _thumbDeck.insert(new ThumbnailView(pv, 70), i); } else { _magDeck.insert(new MagnifiedView(pv, 100), i); _thumbDeck.insert(new ThumbnailView(pv, 100), i); } ((ThumbnailView) _thumbDeck.getWidget(i)).setParentShowingHint(false); pv.addPersistentMouseInfo(_mi); adjustGrid(); // todo turn off click lock _lockMouCheckBox.setValue(false); setClickLock(false); } } public void removePlotView(WebPlotView pv) { if (_pvList.contains(pv)) { if (pv == _plotView) _plotView = null; int i = _pvList.indexOf(pv); pv.removePersistentMouseInfo(_mi); _magDeck.remove(i); _thumbDeck.remove(i); _pvList.remove(pv); } } public void setEnabled(boolean enabled) { _enabled = enabled; if (!_enabled) { hideMouseReadout(); } } public void clear() { showReadout(null, null, true); } // public static WebDefaultMouseReadoutHandler getDefaultHandler() { // return _defaultHandler; // } public void updateReadout(ScreenPt pt) { ImagePt ipt; lastPt = pt; ipt = _currentPlot.getImageCoords(pt); showReadout(pt, ipt, false); WebMouseReadoutPerm.notifyExternal(pt, ipt, Band.NO_BAND, 0, null, false, false); } public void updateReadout(ImagePt ipt) { ImageWorkSpacePt iwspt = new ImageWorkSpacePt(ipt.getX(), ipt.getY()); ScreenPt pt = _currentPlot.getScreenCoords(iwspt); showReadout(pt, ipt, false); } public void updateReadout(WebPlot plot, ImagePt ipt) { ImageWorkSpacePt iwspt = new ImageWorkSpacePt(ipt.getX(), ipt.getY()); ScreenPt pt = _currentPlot.getScreenCoords(iwspt); _currentPlot = plot; adjustGrid(); showReadout(pt, ipt, false); } public void setValue(int row, String labelText, String valueText) { setValue(row, labelText, valueText, null, false, false); } public void setValue(int row, String labelText, String valueText, boolean valueIsHtml) { setValue(row, labelText, valueText, null, valueIsHtml, false); } public void setValue(int row, String labelText, String valueText, String valueStyle) { setValue(row, labelText, valueText, valueStyle, false, false); } public void setValue(int row, String labelText, String valueText, String valueStyle, boolean valueIsHtml, boolean setOnlyIfActive) { int rowMin = 1; final int rowFinal = row; if (wide) { row--; rowMin = 0; } int labelIdx = 0; int valueIdx = labelIdx + 1; int gridRowCount = _grid.getRowCount() + (wide ? gridWide.getRowCount() : 0); if (gridRowCount > row) { Grid workingGrid = _grid; int workingRow = row; if (wide && row >= WIDE_MAX_ROWS) { workingGrid = gridWide; workingRow = row - WIDE_MAX_ROWS; if ((gridRowCount - WIDE_MAX_ROWS) < (WIDE_MAX_ROWS)) workingRow++; } Label label = (Label) workingGrid.getWidget(workingRow, labelIdx); Label value = (Label) workingGrid.getWidget(workingRow, valueIdx); if (workingRow >= rowMin && label == null) { label = new Label(labelText); label.addStyleName("readout-label"); workingGrid.setWidget(workingRow, labelIdx, label); List<Integer> rowWithOps = incrementAll(_currentHandler.getRowsWithOptions()); if (rowWithOps != null && rowWithOps.contains(row)) { GwtUtil.makeIntoLinkButton(label); label.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { showRowOps(rowFinal); } }); } } if (value == null) { value = new Label(valueText); value.addStyleName("readout-value"); workingGrid.setWidget(workingRow, valueIdx, value); } label.setText(labelText); if (valueIsHtml) { DOM.setInnerHTML(value.getElement(), valueText); } else { value.setText(valueText); } String oldStyle = _styleMap.get(value); if (oldStyle != null) value.removeStyleName(oldStyle); if (valueStyle != null) { value.addStyleName(valueStyle); _styleMap.put(value, valueStyle); } } } private List<Integer> incrementAll(List<Integer> inList) { List<Integer> retList = new ArrayList(inList); for (int i = 0; (i < retList.size()); i++) { retList.set(i, retList.get(i) + 1); } return retList; } private void showRowOps(final int row) { List<String> opList = _currentHandler.getRowOptions(row); final SimpleInputField field = GwtUtil.createRadioBox("options", opList, _currentHandler.getRowOption(row)); final PopupPane popup = new PopupPane("Choose Option", field, true, true); popup.addCloseHandler(new CloseHandler<PopupPane>() { public void onClose(CloseEvent<PopupPane> event) { String s = field.getValue(); _currentHandler.setRowOption(row, s); } }); field.getField().addValueChangeHandler(new ValueChangeHandler<String>() { public void onValueChange(ValueChangeEvent<String> event) { popup.hide(); String s = field.getValue(); _currentHandler.setRowOption(row, s); if (_currentPlot != null && lastPt != null && _pixelClickLock) { try { _currentHandler.computeMouseValue(_currentPlot, WebMouseReadout.this, row, _currentPlot.getImageCoords(lastPt), lastPt, new Date().getTime()); } catch (Exception e) { _currentHandler.computeMouseExitValue(_currentPlot, WebMouseReadout.this, row); } } else { _currentHandler.computeMouseExitValue(_currentPlot, WebMouseReadout.this, row); } } }); // popup.alignTo(gridPanel, PopupPane.Align.BOTTOM_CENTER); popup.show(); } public void setTitle(String valueText, boolean valueIsHtml) { if (valueIsHtml) { DOM.setInnerHTML(titleLabel.getElement(), valueText); } else { titleLabel.setText(valueText); } if (!wide) { _grid.setWidget(0, 1, titleLabel); } } //========================================================================= //--------------------- Methods from PlotViewStatusListener --------------- //========================================================================= //========================================================================= //--------------------- Methods from PropertyChangeListener --------------- //========================================================================= public void propertyChange(PropertyChangeEvent ev) { introduceNewReadout(); } //=================================================================== //------------ Private Methods -------------------------------------- //=================================================================== private void introduceNewReadout() { _currentPlot = _plotView.getPrimaryPlot(); if (_currentPlot != null) adjustGrid(); clear(); } private void adjustGrid() { if (_plotView != null && _currentPlot != null) { if (_currentPlot.containsAttributeKey(WebPlot.READOUT_ATTR)) { Object o = _currentPlot.getAttribute(WebPlot.READOUT_ATTR); if (o instanceof WebMouseReadoutHandler) { _currentHandler = (WebMouseReadoutHandler) o; } else { _currentHandler = _defaultHandler; } } else { _currentHandler = _defaultHandler; } } int rows = _currentHandler.getRows(_currentPlot); int col = 1; if (_currentRows != rows || _currentCols != col) { reinitGridSize(rows, col); } } private void reinitGridSize(int rows, int col) { _currentRows = rows + 1; _currentCols = col; int rowMin = wide ? 0 : 1; int rowMax = wide ? WIDE_MAX_ROWS : (rows + 1); _grid.resize(rowMax, col * 2); for (int i = rowMin; (i < rowMax); i++) { for (int j = 0; (j < col * 2); j += 2) { _grid.getCellFormatter().setHorizontalAlignment(i, j, HasHorizontalAlignment.ALIGN_RIGHT); } } if (wide) { if (rows - WIDE_MAX_ROWS > 0) { gridWide.resize(rows - WIDE_MAX_ROWS, col * 2); for (int i = 0; (i < rows - WIDE_MAX_ROWS); i++) { for (int j = 0; (j < col * 2); j += 2) { gridWide.getCellFormatter().setHorizontalAlignment(i, j, HasHorizontalAlignment.ALIGN_RIGHT); } } } } } private void update(int x, int y) { int i = _pvList.indexOf(_plotView); ((ThumbnailView) _thumbDeck.getWidget(i)).setParentShowingHint(true); _currentPlot = _plotView.getPrimaryPlot(); if (_currentPlot != null) { adjustGrid(); updateReadout(new ScreenPt(x, y)); } } private void showReadout(ScreenPt pt, ImagePt ipt, boolean doClear) { if (pt == null || ipt == null) return; long callID = new Date().getTime(); boolean minimal = isMinimal(_currentPlot); _thumbDeck.setVisible(!minimal); _magDeck.setVisible(!minimal); arrowDesc.setVisible(!minimal); _filePix.setVisible(!minimal); _screenPix.setVisible(!minimal); _zoomLevel.setVisible(!minimal); for (int col = 0; col < _currentCols; col++) { for (int row = 0; row < _currentRows; row++) { if (doClear) { _currentHandler.computeMouseExitValue(_currentPlot, this, row); } else { _currentHandler.computeMouseValue(_currentPlot, this, row, ipt, pt, callID); // updateScaleDisplay(); } } } } // private void updateScaleDisplay() { // if (!_currentPlot.isBlankImage()) { // String ipStr= _nfPix.format(_currentPlot.getImagePixelScaleInArcSec()); // if (wide) _filePix.setHTML( ipStr+ "\"/ file pix"); // else _filePix.setHTML( ipStr+ "\"/<br>file pix"); // } // else { // _filePix.setHTML(""); // } // float size = (float) _currentPlot.getImagePixelScaleInArcSec() / _currentPlot.getZoomFact(); // // // String pStr= _nfPix.format(size); // // if (wide) _screenPix.setHTML(pStr + "\"/ screen pix"); // else _screenPix.setHTML(pStr + "\"/<br>screen pix"); // // _zoomLevel.setHTML(ZoomUtil.convertZoomToString(_currentPlot.getZoomFact())); // } /* public Side getDisplaySide() { return _displaySide; }*/ public void setDisplaySide(Side side) { _displaySide = side; if (_showing) displayMouseReadout(); } public void suggestHideMouseReadout() { if (!_dialogLockedUp) hideMouseReadout(false); } public void hideMouseReadoutLater(int millsToHide) { cancelShowTimer(); if (_hideReadoutTimer == null && !_dialogLockedUp) { _hideReadoutTimer = new HideReadoutTimer(); _hideReadoutTimer.schedule(millsToHide); } } public void hideMouseReadout() { hideMouseReadout(true); } public void hideMouseReadout(boolean animation) { cancelTimers(); _popupPanel.setAnimationEnabled(animation); _popupPanel.hide(); _showing = false; int i = _pvList.indexOf(_plotView); if (i > 0 && i < _thumbDeck.getWidgetCount()) { ThumbnailView thumb = (ThumbnailView) _thumbDeck.getWidget(i); thumb.setParentShowingHint(false); } } public void displayMouseReadout() { displayMouseReadout(0, 0); } public void displayMouseReadoutLater(int mouseX, int mouseY) { _laterX = mouseX; _laterY = mouseY; if (_showReadoutTimer == null) { _showReadoutTimer = new ShowReadoutTimer(); _showReadoutTimer.schedule(300); } } public void displayMouseReadout(int mouseX, int mouseY) { boolean alreadyUp = _showing; cancelShowTimer(); mouseX = mouseX - _plotView.getScrollX(); mouseY = mouseY - _plotView.getScrollY(); if (!alreadyUp) _popupPanel.getPopupPanel().setVisible(false); _popupPanel.setAnimationEnabled(false); if (!alreadyUp) _popupPanel.show(); ScreenPt pt; switch (_displaySide) { case Left: case Right: case IRSA_LOGO: pt = computeLeftRight(mouseX, mouseY, _displaySide, true); break; case Top: case Bottom: pt = computeTopBottom(mouseX, mouseY, _displaySide, true); break; default: WebAssert.fail("unknown case"); return; } _popupPanel.setPopupPosition(pt.getIX(), pt.getIY()); if (alreadyUp) { _popupPanel.setAnimationEnabled(false); } else { _popupPanel.hide(); _popupPanel.getPopupPanel().setVisible(true); _popupPanel.setAnimationEnabled(true); } _popupPanel.show(); _showing = true; _mayLockOnce = BrowserUtil.isTouchInput(); _popupPanel.setAnimationEnabled(true); // _thumbnail.setParentShowingHint(true); } int getContentHeight() { int retval = 0; if (_popupPanel.isVisible()) { retval = _popupPanel.getWidget().getOffsetHeight(); } else { _popupPanel.getPopupPanel().setVisible(false); _popupPanel.setAnimationEnabled(false); _popupPanel.show(); retval = _popupPanel.getWidget().getOffsetHeight(); _popupPanel.hide(); _popupPanel.setAnimationEnabled(true); _popupPanel.getPopupPanel().setVisible(true); } return retval; } private ScreenPt computeLeftRight(int mouseX, int mouseY, Side side, boolean choose) { WebAssert.argTst((side == Side.Left || side == Side.Right || side == Side.IRSA_LOGO), "Side must be left, right, or IRSA_LOGO"); int x = 0; Side otherSide; int popWidth = _popupPanel.getPopupPanel().getOffsetWidth(); int popHeight = _popupPanel.getPopupPanel().getOffsetHeight(); if (side == Side.Left) { otherSide = Side.Right; switch (_mode) { case Quick: x = _plotView.getAbsoluteLeft() - popWidth; break; case Group: x = 3; break; default: WebAssert.argTst(false, "not a supported mode"); break; } } else { otherSide = Side.Left; switch (_mode) { case Quick: x = _plotView.getAbsoluteLeft() + _plotView.getOffsetWidth(); break; case Group: x = Window.getClientWidth() - popWidth; if (side == Side.IRSA_LOGO && x > IRSA_LOGO_X) { x = IRSA_LOGO_X; } break; default: WebAssert.argTst(false, "not a supported mode"); break; } } int y = 0; switch (_mode) { case Quick: y = _plotView.getAbsoluteTop(); break; // case Group : y= Window.getClientWidth()- popHeight-3; break; case Group: y = 0; break; default: WebAssert.argTst(false, "not a supported mode"); break; } ScreenPt op1Pt = adjustXY(x, y); x = op1Pt.getIX(); ScreenPt retval = op1Pt; if (INTELLIGENT_CHOICE) { ScreenPt op2Pt = null; ScreenPt op3Pt = null; Choice op2Choice = Choice.Bad; Choice op3Choice = Choice.Bad; Choice op1Choice = computeChoice(op1Pt, mouseX, mouseY); if (op1Choice != Choice.Good) { y = _plotView.getAbsoluteTop() + _plotView.getOffsetHeight(); op2Pt = adjustXY(x, y); op2Choice = computeChoice(op2Pt, mouseX, mouseY); } if (op1Choice != Choice.Good && op2Choice != Choice.Good) { y = _plotView.getAbsoluteTop() - popHeight; op3Pt = adjustXY(x, y); op3Choice = computeChoice(op3Pt, mouseX, mouseY); } retval = chooseBest(op1Choice, op1Pt, op2Choice, op2Pt, op3Choice, op3Pt); if (retval == null && choose) { retval = computeLeftRight(mouseX, mouseY, otherSide, false); if (retval == null) retval = op1Pt; } } return retval; } private ScreenPt computeTopBottom(int mouseX, int mouseY, Side side, boolean choose) { WebAssert.argTst((side == Side.Top || side == Side.Bottom), "Side must be Top or Bottom"); Side otherSide; int y = 0; int popHeight = _popupPanel.getPopupPanel().getOffsetHeight(); if (side == Side.Top) { otherSide = Side.Bottom; switch (_mode) { case Quick: y = _plotView.getAbsoluteTop() - popHeight; break; case Group: y = 3; break; default: WebAssert.argTst(false, "not a supported mode"); break; } } else { otherSide = Side.Top; switch (_mode) { case Quick: y = _plotView.getAbsoluteTop() + _plotView.getOffsetHeight(); break; case Group: y = Window.getClientHeight() - popHeight - 3; break; default: WebAssert.argTst(false, "not a supported mode"); break; } } int x = 0; switch (_mode) { case Quick: x = _plotView.getAbsoluteLeft(); break; case Group: x = 3; break; default: WebAssert.argTst(false, "not a supported mode"); break; } ScreenPt op1Pt = adjustXY(x, y); ScreenPt op2Pt = null; ScreenPt op3Pt = null; Choice op2Choice = Choice.Bad; Choice op3Choice = Choice.Bad; Choice op1Choice = computeChoice(op1Pt, mouseX, mouseY); if (op1Choice != Choice.Good) { x = _plotView.getAbsoluteLeft() + _plotView.getOffsetWidth(); op2Pt = adjustXY(x, y); op2Choice = computeChoice(op2Pt, mouseX, mouseY); } if (op1Choice != Choice.Good && op2Choice != Choice.Good) { int popWidth = _popupPanel.getPopupPanel().getOffsetWidth(); x = _plotView.getAbsoluteLeft() - popWidth; op3Pt = adjustXY(x, y); op3Choice = computeChoice(op3Pt, mouseX, mouseY); } ScreenPt retval = chooseBest(op1Choice, op1Pt, op2Choice, op2Pt, op3Choice, op3Pt); if (retval == null && choose) { retval = computeLeftRight(mouseX, mouseY, otherSide, false); if (retval == null) retval = op1Pt; } return retval; } private ScreenPt chooseBest(Choice op1Choice, ScreenPt op1Pt, Choice op2Choice, ScreenPt op2Pt, Choice op3Choice, ScreenPt op3Pt) { ScreenPt retval = null; switch (op1Choice) { case Good: retval = op1Pt; break; case OK: switch (op2Choice) { case Good: retval = op2Pt; break; case OK: retval = (op3Choice == Choice.Good) ? op3Pt : op2Pt; break; case Bad: retval = (op3Choice == Choice.Good) ? op3Pt : op1Pt; break; } break; case Bad: switch (op2Choice) { case Good: retval = op2Pt; break; case OK: retval = (op3Choice == Choice.Good) ? op3Pt : op2Pt; break; case Bad: retval = (op3Choice == Choice.Good) ? op3Pt : null; break; } break; } return retval; } private Choice computeChoice(ScreenPt pt, int mouseX, int mouseY) { return computeChoice(isCoveringPlot(pt.getIX(), pt.getIY()), isOverMouse(pt.getIX(), pt.getIY(), mouseX, mouseY)); } private Choice computeChoice(boolean coversPlot, boolean overMouse) { Choice retval = Choice.Good; if (overMouse) retval = Choice.Bad; else if (coversPlot) retval = Choice.OK; return retval; } private ScreenPt adjustXY(int x, int y) { int popWidth = _popupPanel.getPopupPanel().getOffsetWidth(); int popHeight = _popupPanel.getPopupPanel().getOffsetHeight(); int bWidth = Window.getClientWidth(); int bHeight = Window.getClientHeight(); int sx = Window.getScrollLeft(); int sy = Window.getScrollTop(); if (x + popWidth > bWidth) x = (bWidth - popWidth) + sx; if (y + popHeight > bHeight) y = (bHeight - popHeight) + sy; if (x < sx) x = sx; if (y < sy) y = sy; return new ScreenPt(x, y); } private boolean isCoveringPlot(int x, int y) { int width = _popupPanel.getPopupPanel().getOffsetWidth(); int height = _popupPanel.getPopupPanel().getOffsetHeight(); int px = _plotView.getAbsoluteLeft(); int py = _plotView.getAbsoluteTop(); int pw = Math.min(_plotView.getScrollWidth(), _plotView.getPrimaryPlot().getScreenWidth()); int ph = Math.min(_plotView.getScrollHeight(), _plotView.getPrimaryPlot().getScreenHeight()); return VisUtil.intersects(x, y, width, height, px, py, pw, ph); } private boolean isOverMouse(int x, int y, int mouseX, int mouseY) { int width = _popupPanel.getPopupPanel().getOffsetWidth(); int height = _popupPanel.getPopupPanel().getOffsetHeight(); int mx = _plotView.getAbsoluteLeft() + mouseX; int my = _plotView.getAbsoluteTop() + mouseY; return (mx >= x && mx <= x + width && my >= y && my <= y + height); } private boolean isOverPlot(int x, int y) { ScreenPt wcsMargin = _plotView.getWcsMargins(); int mx = wcsMargin.getIX(); int my = wcsMargin.getIY(); x += mx; y += my; int sx = _plotView.getScrollX(); int sy = _plotView.getScrollY(); int ex = sx + _plotView.getScrollWidth(); int ey = sy + _plotView.getScrollHeight(); return (x >= sx && x <= ex && y >= sy && y <= ey); } private void cancelTimers() { cancelShowTimer(); cancelHideTimer(); } private void cancelHideTimer() { if (_hideReadoutTimer != null) { // GwtUtil.showDebugMsg("cancel",5,90); _hideReadoutTimer.cancel(); _hideReadoutTimer = null; } } private void cancelShowTimer() { if (_showReadoutTimer != null) { _showReadoutTimer.cancel(); _showReadoutTimer = null; } } // static int cnt = 1; private void move(WebPlotView pv, ScreenPt spt, boolean fromTouch, boolean updateDisplay) { int i = _pvList.indexOf(pv); if (i > -1) { _thumbDeck.showWidget(i); _magDeck.showWidget(i); WebPlotView oldPV = _plotView; _plotView = pv; // int x= ev.getX(); // int y= ev.getY(); int x = spt.getIX(); int y = spt.getIY(); if (_enabled && isOverPlot(x, y)) { cancelHideTimer(); if (updateDisplay) { update(x, y); if (_pixelClickLock) { MagnifiedView mv = (MagnifiedView) _magDeck.getWidget(_pvList.indexOf(pv)); if (mv != null) mv.update(spt); } } if (!_showing || oldPV != _plotView) { switch (_mode) { case Quick: displayMouseReadout(x, y); break; case Group: if (fromTouch || _showing) { displayMouseReadout(x, y); } else { displayMouseReadoutLater(x, y); } break; default: WebAssert.argTst(false, "not a supported mode"); break; } } } } } private class ReadOut extends WebPlotView.DefMouseAll { @Override public void onMouseOut(WebPlotView pv) { switch (_mode) { case Quick: hideMouseReadout(); break; case Group: hideMouseReadoutLater(2000); break; default: WebAssert.argTst(false, "not a supported mode"); break; } } @Override public void onMouseMove(WebPlotView pv, ScreenPt spt, MouseMoveEvent ev) { move(pv, spt, false, !_pixelClickLock); } @Override public void onTouchStart(WebPlotView pv, ScreenPt spt, TouchStartEvent ev) { move(pv, spt, true, true); } @Override public void onTouchMove(WebPlotView pv, ScreenPt spt, TouchMoveEvent ev) { move(pv, spt, true, true); } @Override public void onClick(WebPlotView pv, ScreenPt spt) { move(pv, spt, false, true); if (_pixelClickLock) { _dataConnect.setPoint(pv.getPrimaryPlot().getWorldCoords(spt), pv.getPrimaryPlot()); getLockPointDrawing().redraw(); } } @Override public void onTouchEnd(WebPlotView pv) { hideMouseReadoutLater(2000); } } private class ShowReadoutTimer extends Timer { @Override public void run() { _showReadoutTimer.cancel(); _showReadoutTimer = null; displayMouseReadout(_laterX, _laterY); } } private class HideReadoutTimer extends Timer { @Override public void run() { _hideReadoutTimer.cancel(); _hideReadoutTimer = null; hideMouseReadout(); } } private void setClickLock(boolean clickLock) { if (_pixelClickLock == clickLock) return; _pixelClickLock = clickLock; int tot = _magDeck.getWidgetCount(); for (int i = 0; (i < tot); i++) { Widget w = _magDeck.getWidget(i); ((MagnifiedView) w).setFreezeView(_pixelClickLock); } DrawingManager dm = getLockPointDrawing(); if (_pixelClickLock) { _dataConnect.setPoint(null, null); dm.redraw(); for (WebPlotView pv : _pvList) { dm.addPlotView(pv); } } else { for (WebPlotView pv : _pvList) { dm.removePlotView(pv); } } } private void addMouseHandlers(Widget w, boolean includeHide) { w.addDomHandler(mouseHandlers, MouseOverEvent.getType()); w.addDomHandler(mouseHandlers, MouseMoveEvent.getType()); if (includeHide) { w.addDomHandler(new MouseOutHandler() { public void onMouseOut(MouseOutEvent ev) { int x = ev.getScreenX(); int y = ev.getScreenY(); int py = _popupPanel.getPopupPanel().getAbsoluteTop(); int px = _popupPanel.getPopupPanel().getAbsoluteLeft(); int w = _popupPanel.getPopupPanel().getOffsetWidth(); int h = _popupPanel.getPopupPanel().getOffsetHeight(); if (x < px || x > px + w - 1 || y < py || y > py + h - 1) { hideMouseReadoutLater(700); // GwtUtil.showDebugMsg("hiding: x="+x+",y="+y+",px="+px+",py="+py+",w="+w+",h="+h,5,90); } else { // GwtUtil.showDebugMsg("x="+x+",y="+y+",px="+px+",py="+py+",w="+w+",h="+h,5,90); } } }, MouseOutEvent.getType()); } } private static class MarkedPointDisplay extends SimpleDataConnection { private final List<DrawObj> list = new ArrayList<DrawObj>(1); private WebPlot markedPlot = null; MarkedPointDisplay() { super("Clicked Point", "Point lock to your click", DrawingDef.COLOR_PT_3); } public void setPoint(WorldPt wp, WebPlot plot) { list.clear(); if (wp != null && plot != null) { PointDataObj obj = new PointDataObj(wp, DrawSymbol.CIRCLE); list.add(obj); markedPlot = plot; } } @Override public List<DrawObj> getData(boolean rebuild, WebPlot plot) { List<DrawObj> retList = list; if (list.size() > 0 && plot != null && markedPlot != null && plot == markedPlot) { PointDataObj obj = new PointDataObj(list.get(0).getCenterPt(), DrawSymbol.SQUARE); retList = new ArrayList<DrawObj>(2); retList.addAll(list); retList.add(obj); } return retList; } @Override public boolean getSupportsMouse() { return false; } } private class MouseHandlers implements MouseOverHandler, MouseMoveHandler { public void onMouseOver(MouseOverEvent ev) { cancelHideTimer(); } public void onMouseMove(MouseMoveEvent ev) { cancelHideTimer(); } } public static boolean isMinimal(WebPlot plot) { boolean minimal = false; if (plot != null && plot.containsAttributeKey(WebPlot.MINIMAL_READOUT)) { minimal = Boolean.valueOf(plot.getAttribute(WebPlot.MINIMAL_READOUT).toString()); } return minimal; } }