
org.graphstream.ui.j2dviewer.renderer.StyleRenderer.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gs-ui Show documentation
Show all versions of gs-ui Show documentation
The GraphStream library. With GraphStream you deal with
graphs. Static and Dynamic. You create them from scratch, from a file
or any source. You display and render them.
The newest version!
/*
* Copyright 2006 - 2015
* Stefan Balev
* Julien Baudry
* Antoine Dutot
* Yoann Pigné
* Guilhelm Savin
*
* This file is part of GraphStream .
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
package org.graphstream.ui.j2dviewer.renderer
import org.graphstream.graph.Element
import org.graphstream.ui.graphicGraph.{GraphicElement, GraphicNode, GraphicEdge, GraphicSprite, GraphicGraph, StyleGroup}
import org.graphstream.ui.graphicGraph.GraphicElement.SwingElementRenderer
import org.graphstream.ui.graphicGraph.StyleGroup.ElementEvents
import org.graphstream.ui.j2dviewer.{Backend, Camera, J2DGraphRenderer}
import scala.collection.JavaConversions._
/** Style renderer companion object, acts as a factory for renderers. */
object StyleRenderer {
import org.graphstream.ui.graphicGraph.stylesheet.Selector.Type._
def apply(style:StyleGroup, mainRenderer:J2DGraphRenderer):StyleRenderer = {
style.getType match {
case NODE => NodeRenderer(style, mainRenderer)
case EDGE => EdgeRenderer(style, mainRenderer)
case SPRITE => SpriteRenderer(style, mainRenderer)
case GRAPH => printf("we got a graph%n"); null
case _ => throw new RuntimeException("WTF?")
}
}
}
/** Base class for style renderers.
*
* The main rendering loop is defined here.
*/
abstract class StyleRenderer(val group:StyleGroup) extends GraphicElement.SwingElementRenderer {
// Attribute
/** True if some event is taking place actually. */
protected var hadEvents:Boolean = false;
// Command
/** Render the shadow of all (visible) elements of the group. */
def renderShadow(bck:Backend, camera:Camera) { render(bck, camera, true, renderShadow _) }
/** Render all the (visible) elements of the group. */
def render(bck:Backend, camera:Camera) { render(bck, camera, false, renderElement _) }
/** Main rendering method.
*
* This works in three phases:
* - draw all "bulk" elements using renderElement()
* - draw all "dynamic" elements using renderElement().
* - draw all "event" elements using renderElement().
*
* Before drawing, the setupRenderingPass() and pushStyle() methods are called. The phase 1 is
* run. Then for each dynamic element in phase 2, before calling renderElement, for each element
* the pushDynStyle() method is called.
* Then for each element modified by an event, in phase 3, the before drawing the element, the
* event is enabled, then pushStyle() is called, then the element is drawn, and finally the
* event is disabled.
*
* This rendering pass is made both for shadows and for regular drawing. The shadow and render
* arguments allow to specify that we are rendering for shadow, and what element rendering
* method to use (renderElement() or renderShadow()). */
protected def render(bck:Backend, camera:Camera, shadow:Boolean, render:(Backend,Camera,GraphicElement)=>Unit ) {
setupRenderingPass(bck, camera, shadow)
pushStyle(bck, camera, shadow)
//var T1 = System.currentTimeMillis
group.bulkElements.foreach { e =>
val ge = e.asInstanceOf[GraphicElement]
if(camera.isVisible(ge))
render(bck, camera, ge)
else elementInvisible(bck, camera, ge);
}
//var T2 = System.currentTimeMillis
if(group.hasDynamicElements) {
group.dynamicElements.foreach { e =>
val ge = e.asInstanceOf[GraphicElement]
if(camera.isVisible(ge)) {
if(! group.elementHasEvents(ge)) {
pushDynStyle(bck, camera, ge)
render(bck, camera, ge)
}
} else {
elementInvisible(bck, camera, ge)
}
}
}
if(group.hasEventElements) {
group.elementsEvents.foreach { event =>
val ge = event.getElement.asInstanceOf[GraphicElement]
if(camera.isVisible(ge)) {
event.activate
pushStyle(bck, camera, shadow)
render(bck, camera, ge)
event.deactivate
} else {
elementInvisible(bck, camera, ge)
}
}
hadEvents = true;
}
else
{
hadEvents = false;
}
endRenderingPass(bck, camera, shadow)
}
// Methods to implement in each renderer
/** Called before the whole rendering pass for all elements.
* @param bck The rendering back-end.
* @param camera The camera.
* @param forShadow true if we are in the shadow rendering pass. */
protected def setupRenderingPass(bck:Backend, camera:Camera, forShadow:Boolean)
/** Called before the rendering of bulk and event elements.
* @param bck The rendering back-end.
* @param camera The camera.
* @param forShadow true if we are in the shadow rendering pass. */
protected def pushStyle(bck:Backend, camera:Camera, forShadow:Boolean)
/** Called before the rendering of elements on dynamic styles. This must only change the style
* properties that can change dynamically.
* @param bck The rendering back-end.
* @param camera The camera.
* @param element The graphic element concerned by the dynamic style change. */
protected def pushDynStyle(bck:Backend, camera:Camera, element:GraphicElement)
/** Render a single element knowing the style is already prepared. Elements that are not visible
* are not drawn.
* @param bck The rendering back-end.
* @param camera The camera.
* @param element The element to render. */
protected def renderElement(bck:Backend, camera:Camera, element:GraphicElement)
/** Render the shadow of the element.
* @param bck The rendering back-end.
* @param camera The camera.
* @param element The element to render. */
protected def renderShadow(bck:Backend, camera:Camera, element:GraphicElement)
/** Called during rendering in place of {@link #renderElement(Graphics2D, Camera, GraphicElement)}
* to signal that the given element is not inside the view. The renderElement() method will be
* called as soon as the element becomes visible anew.
* @param bck The rendering back-end.
* @param camera The camera.
* @param element The element to render. */
protected def elementInvisible(bck:Backend, camera:Camera, element:GraphicElement)
/** Called at the end of the rendering pass.
* @param bck The rendering back-end.
* @param camera The camera.
* @param forShadow true if we are in the shadow rendering pass. */
protected def endRenderingPass(bck:Backend, camera:Camera, forShadow:Boolean) {
// NOP by default.
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy