/************************************************************************** * Copyright (c) 2007, 2008 Gregory Jordan * * This file is part of PhyloWidget. * * PhyloWidget 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, either version 2 of the License, or * (at your option) any later version. * * PhyloWidget is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PhyloWidget. If not, see <http://www.gnu.org/licenses/>. */ package org.phylowidget.ui; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.geom.Rectangle2D; import org.andrewberman.ui.AbstractUIObject; import org.andrewberman.ui.Point; import org.andrewberman.ui.UIUtils; import org.andrewberman.ui.tween.Tween; import org.andrewberman.ui.tween.TweenListener; import org.andrewberman.ui.tween.TweenQuad; import org.phylowidget.PWContext; import org.phylowidget.PWPlatform; import org.phylowidget.render.NodeRange; import org.phylowidget.render.RenderConstants; import processing.core.PApplet; public final class HoverHalo extends AbstractUIObject implements TweenListener { private PApplet p; private PWContext context; final int type = ELLIPSE; static final int FRAMES = 30; Rectangle2D.Float rect; Point tempPt; NodeRange prevNearest; NodeRange curNode; Tween aTween; Tween wTween; Tween hTween; public static final int RECTANGLE = 0; public static final int ELLIPSE = 1; public boolean hidden = true; public boolean solid = false; public static float hoverMult; public HoverHalo(PApplet p) { this.p = p; this.context = PWPlatform.getInstance().getThisAppContext(); context.event().add(this); // UIGlobals.g.event().add(this); rect = new Rectangle2D.Float(0, 0, 0, 0); tempPt = new Point(0, 0); aTween = new Tween(this, TweenQuad.tween, Tween.INOUT, 1f, .25f, FRAMES); wTween = new Tween(this, TweenQuad.tween, Tween.INOUT, 1.5f, 1.1f, FRAMES); hTween = new Tween(this, TweenQuad.tween, Tween.INOUT, 1.5f, 1.1f, FRAMES); } public void draw() { if (hidden) return; if (context.focus().getFocusedObject() != null) return; NodeRange r = curNode; // if (r == null) // r = PhyloWidget.ui.nearest.nearest; if (r != prevNearest) { prevNearest = r; restart(); } if (r == null) return; float maxD = 100; tempPt.setLocation(r.node.getLayoutX(),r.node.getLayoutY()); // r.render.getNodePosition(r.node, tempPt); UIUtils.modelToScreen(tempPt); float dist = (float) tempPt.distance(p.mouseX, p.mouseY); dist = (dist > maxD ? maxD : dist); float alpha = (maxD - dist) / maxD * 255; // float rad = r.render.getNodeRadius() * 2; float rad = 50; rect.setFrameFromCenter(r.node.getLayoutX(), r.node.getLayoutY(), r.node.getLayoutX() - rad, r.node.getLayoutY() - rad); // rect.x = r.node.x; // rect.y = r.node.y; // rect.width = r.render.getNodeRadius(); // rect.height = r.render.getNodeRadius(); aTween.update(); wTween.update(); hTween.update(); hoverMult = wTween.getPosition(); int color = RenderConstants.hoverColor.getRGB(); p.stroke(color * aTween.getPosition()); if (solid) { // p.noStroke(); // p.fill(color,255); p.stroke(40, 120, 240, 255); p.strokeWeight(Math.max(rect.width / 20, 3)); } else { p.noFill(); p.stroke(40, 120, 240, 255); p.strokeWeight(Math.max(rect.width / 20, 3)); } float w = wTween.getPosition() * rect.width; float h = hTween.getPosition()* rect.height; float x = (float) rect.getCenterX(); float y = (float) rect.getCenterY(); switch (type) { case (RECTANGLE): p.rect(x - w / 2, y - h / 2, w, h); // p.rect(rect.x,rect.y,rect.width,rect.height); break; case (ELLIPSE): p.ellipse(x, y, w, h); break; } } public void hide() { hidden = true; UIUtils.releaseCursor(this, p); } public void show() { hidden = false; restart(); } public void restart() { solid = false; aTween.restart(.75f, .25f, FRAMES); hTween.restart(1.5f, 1.1f, FRAMES); wTween.restart(1.5f, 1.1f, FRAMES); } public void becomeSolid() { hTween.continueTo(1.1f); hTween.fforward(); hTween.stop(); wTween.continueTo(1.1f); wTween.fforward(); wTween.stop(); solid = true; } public void tweenEvent(Tween source, int eventType) { if (eventType == Tween.FINISHED) source.yoyo(); } public void keyEvent(KeyEvent e) { } public void mouseEvent(MouseEvent e, Point screen, Point model) { if (hidden) return; if (context.focus().getFocusedObject() != null) return; // System.out.println("Hover event!"); Point pt = model; // NodeRange r = PhyloWidget.ui.nearest.nearest; // if (r == null) // return; // // switch (e.getID()) // { // case (MouseEvent.MOUSE_MOVED): // if (containsPoint(r, pt)) // { // UIUtils.setCursor(this, p, Cursor.HAND_CURSOR); // r.node.hovered = true; // } else // { // UIUtils.releaseCursor(this, p); // r.node.hovered = false; // } // break; // case (MouseEvent.MOUSE_PRESSED): // if (containsPoint(r, pt)) // { // PhyloWidget.ui.context.open(r); // } // break; // } } public void focusEvent(FocusEvent e) { } public boolean containsPoint(NodeRange r, Point pt) { if (r == null) return false; // r.render.getNodePosition(r.node, tempPt); tempPt.setLocation(r.node.getLayoutX(),r.node.getLayoutY()); // float radius = r.render.getNodeRadius(); float radius = r.render.getTextSize()/2 * wTween.getPosition(); radius = Math.max(radius,5); float x = pt.x - tempPt.x; float y = pt.y - tempPt.y; return (x * x + y * y < radius * radius); } }