/* 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. */ /* * DrawPoint.java * * Created on 11. Oktober 2001, 23:59 */ package org.geogebra.common.euclidian.draw; import org.geogebra.common.awt.GGraphics2D; import org.geogebra.common.awt.GRectangle; import org.geogebra.common.euclidian.BoundingBox; import org.geogebra.common.euclidian.Drawable; import org.geogebra.common.euclidian.EuclidianView; import org.geogebra.common.euclidian.RemoveNeeded; import org.geogebra.common.factories.AwtFactory; import org.geogebra.common.kernel.arithmetic.FunctionalNVar; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoList; /** * Draw a GeoList containing drawable objects * * @author Markus Hohenwarter */ public final class DrawList extends Drawable implements RemoveNeeded { /** coresponding list as geo */ GeoList geoList; private DrawListArray drawables; /** whether this is visible */ boolean isVisible; /** * Creates new drawable list * * @param view * view * @param geoList * list */ public DrawList(EuclidianView view, GeoList geoList) { this.view = view; this.geoList = geoList; geo = geoList; reset(); update(); } private void reset() { if (drawables == null) { drawables = new DrawListArray(view); } } @Override final public void update() { isVisible = geoList.isEuclidianVisible(); if (!isVisible) { return; } // go through list elements and create and/or update drawables int size = geoList.size(); drawables.ensureCapacity(size); int oldDrawableSize = drawables.size(); int drawablePos = 0; for (int i = 0; i < size; i++) { GeoElement listElement = geoList.get(i); if (!listElement.isDrawable()) { continue; } // add drawable for listElement // if (addToDrawableList(listElement, drawablePos, // oldDrawableSize)) if (drawables.addToDrawableList(listElement, drawablePos, oldDrawableSize, this)) { drawablePos++; } } // remove end of list for (int i = drawables.size() - 1; i >= drawablePos; i--) { view.remove(drawables.get(i).getGeoElement()); drawables.remove(i); } // draw trace if (geoList.getTrace()) { isTracing = true; GGraphics2D g2 = view.getBackgroundGraphics(); if (g2 != null) { drawTrace(g2); } } else { if (isTracing) { isTracing = false; // view.updateBackground(); } } } /** * This method is necessary, for example when we set another construction * step, and the sub-drawables of this list should be removed as well */ @Override final public void remove() { for (int i = drawables.size() - 1; i >= 0; i--) { GeoElement currentGeo = drawables.get(i).getGeoElement(); if (!currentGeo.isLabelSet()) { view.remove(currentGeo); } } drawables.clear(); } @Override protected final void drawTrace(GGraphics2D g2) { g2.setPaint(geo.getObjectColor()); g2.setStroke(objStroke); if (isVisible) { int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable d = (Drawable) drawables.get(i); // draw only those drawables that have been created by this // list; // if d belongs to another object, we don't want to mess // with it // here if (createdByDrawList() || !d.getGeoElement().isLabelSet()) { d.draw(g2); } } } } @Override final public void draw(GGraphics2D g2) { if (isVisible) { boolean doHighlight = geoList.doHighlighting(); int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable d = (Drawable) drawables.get(i); // draw only those drawables that have been created by this // list; // if d belongs to another object, we don't want to mess // with it // here if (createdByDrawList() || !d.getGeoElement().isLabelSet()) { d.getGeoElement().setHighlighted(doHighlight); d.draw(g2); } } } } /** * Returns whether any one of the list items is at the given screen * position. */ @Override final public boolean hit(int x, int y, int hitThreshold) { int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable d = (Drawable) drawables.get(i); if (d.hit(x, y, hitThreshold)) { return true; } } return false; } @Override public boolean isInside(GRectangle rect) { int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable d = (Drawable) drawables.get(i); if (!d.isInside(rect)) { return false; } } return size > 0; } @Override public boolean intersectsRectangle(GRectangle rect) { int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable d = (Drawable) drawables.get(i); if (d.intersectsRectangle(rect)) { return true; } } return false; } /** * Returns the bounding box of this DrawPoint in screen coordinates. */ @Override final public GRectangle getBounds() { if (!geo.isEuclidianVisible()) { return null; } GRectangle result = null; int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable d = (Drawable) drawables.get(i); GRectangle bb = d.getBounds(); if (bb != null) { if (result == null) { result = AwtFactory.getPrototype().newRectangle(bb); } // changed () to (bb) bugfix, // otherwise top-left of screen // is always included // add bounding box of list element result.add(bb); } } return result; } /** * @param geoItem * geo * @return whether it should be painted in LaTeX */ static boolean needsLatex(GeoElement geoItem) { return geoItem instanceof FunctionalNVar || (geoItem.isGeoText() && geoItem.isLaTeXDrawableGeo()); } /** * * @return if list when draw as combo, is selected. */ public boolean isSelected() { return geo.doHighlighting(); } @Override public void setGeoElement(GeoElement geo) { this.geo = geo; } @Override public BoundingBox getBoundingBox() { // TODO Auto-generated method stub return null; } @Override public void updateBoundingBox() { // TODO Auto-generated method stub } @Override public GeoElement getGeoElement() { return geo; } }