A group of related toolbar items.
A group of related toolbar items. The compoentns in this group should be visually distanced from components in other groups with a small amount of empty space.
An experiment to see if I can't set up a visualization that combines the data from two fields into a single visualization.
An experiment to see if I can't set up a visualization that combines the data from two fields into a single visualization.
The idea stems from Matthew + Ben's tracker app, where they had to render a circular target on top of a webcam feed. Originally, that required a lot of hacking and pixel twiddling; but with the right probe framework, it should be simple to define a viewer that does the same sort of thing, e.g. by interpreting the contents of fieldA as an image and the contents of fieldB as the coordinates of a target that needs to be overlaid on top.
---
Sudden realization - how do we actually build one of these in response to user input? They can only click on one field at a time...
A field viewer that can be subscribed to an event source so as to reacively update its visualizaion in response to new data becoming available.
A field viewer that can be subscribed to an event source so as to reacively update its visualizaion in response to new data becoming available.
While you can call the viewer's update
method directly, in the typical
usage scenario an EventDrivenViewer will be subscribed to a
cogdebugger.Probe that has been registered with the debugger's
cogdebugger.ProbeManager. The probe manager will read out the data
from any probed fields at regular intervals, raise NewProbeData events,
and the viewers will then update themselves. Note however, that the viewer
is NOT guaranteed to respond to all NewProbeData events, see more below.
The task of visualizing a field can be an expensive operation. Updating
and rendering all viewers on a single thread makes for an unresponsive
debugger. For this reaon, each EventDrivenViewer contains a Scala Actor
that performs the update
operation in response to probe date events
(calling update
directly on this class does NOT use the actor). Because
there is no way of knowing in advance how long an update will take or the
rate at which NewProbeData events will be raised, the actor only ever
operates on the most recently received probe data, discarding any older
messages that may have enqueued in its mailbox. While the actor is busy
in the update
method, the volatile busy
variable will be set to true;
a Probe implemenation may take advantage of this to perform additional
flow control.
---
The intent was to allow for a single viewer to listen to multiple probes, so that it could compose their data in some way. The original motivation for this was Ben+Matthew's Virage tracker, in which they overlayed a moving target on a color image. The target's size, position and color was determined by one field, and the background by another. I don't know exactly what sort of hackery the resorted to go get that to work, but I know it took more effort than it ought to have.
I'd really like this to be an abstract class taking the visualization targets as arguments, but then subclasses can't extend the different Panel classes.
A mixin for DoubleBufferedImagePanel that enables dynamic tooltips.
A mixin for DoubleBufferedImagePanel that enables dynamic tooltips.
You can set a static tooltip for a Swing component that will be displayed any time the mouse comes to rest somewhere over that component. This mixin does things slightly different - the tooltip String that pops up can vary depending on the coordinates of the mouse relative to the component.
Created by gonztobi on 4/22/2014.
Interface for a subpanel within a larger panel.
Created with IntelliJ IDEA.
Created with IntelliJ IDEA. User: gonzatob Date: 9/6/12 Time: 2:22 PM
This abstract class takes care of much of the drawing logic needed to render fields that can be visualized as a grid of distinct elements (such as vector fields or dyad fields). It supports pan, zoom, and save/restore functionality, and can handle 0D, 1D, 2D, and 3D fields.
Concrete viewer implementations will need to define three methods. The first is update, which runs before any drawing is done to allow a client to do such things as compute min/max values for normalization. The second is drawElement, where the client must supply the code to draw a single element of the field. Lastly is getXmlTagName, which just defines a name unique to this viewer type for use in the workspace configuration XML files.
A trait for subpanels that define controls or labels that a parent/container panel can place in a toolbar or similar.
A trait for subpanels that define controls or labels that a parent/container panel can place in a toolbar or similar.
Created by gonztobi on 3/21/2014.
An exception indicating that some operation is invalid for fields or tensors of a certain dimension.
Base trait for classes that visualize field data.
Base trait for classes that visualize field data.
One of the design goals for Viewers is to have any of their user configurable options persist across invocations of the debugger. To this end, all Viewers maintain a list of properties that wrap the values they need to save across debugger sessions. Each cogdebugger.Property is capable of generating an XML tag describing the state of that property, and Viewers are capable of collecting those tags and nesting them inside another tag specific to the Viewer instance.
A high-level visualization container that lets a user choose switch between available visualization options for a particular field.
A high-level visualization container that lets a user choose switch between available visualization options for a particular field.
Besides a target field, this class also requires as arguments a list of user-friendly visualization names and a factory that uses those names as keys to produce an actual Viewer instance. The superpanel itself is presented as a BorderPanel with a toolbar at the top and the visualization in the center. The selectable viewer's names are presented to the user in a ComboBox installed in the toolbar after any visualiztion specific controls (which are installed if a given Viewer implements the ToolbarItems trait). This combobox will only appear if there is more than one available visualization.
The first visualization named in the options
argument is used as the
default and will be immediately installed in the superpanel as part of
initialization.
While viewerFactory
can be any map from Strings to Viewers, consider
making it some sort of lazy or memoized map, particularly if any of the
Viewer instances has substantial startup time. cogdebugger.Memoize#apply
cogdebugger.Memoize
This class was designed with the expectation that we'll wish to implement a subclass specific to each particualar type of field. A companion object with a straightforward factory method can make the instantiation of the subclass cleaner. E.g., for ColorFields (which currently only have one visualization):
class ColorFieldSuperPanel protected (target: ProbedField, options: List[String], factory: (String) => Viewer) extends ViewerSuperPanel2(target, options, factory) object ColorFieldSuperPanel { val ColorPanelName = "Color Image" val viewerNames = List(ColorPanelName) def apply(target: ProbedField) = { //require( // Check for ColorField //, "Not a ColorField") val fieldShape = target.fieldType.fieldShape val tensorShape = target.fieldType.tensorShape val memoizer = Memoize[String, EventDrivenViewer] { case ColorPanelName => new ColorFieldMemoryView(target, fieldShape) with MouseDragZoom } new ColorFieldSuperPanel(target, viewerNames, memoizer) } }
Created by gonztobi on 4/10/2014.
A mixin for GUI classes that support zoom operations.
A mixin for GUI classes that support zoom operations. This trait defines a
cogdebugger.FloatProperty ZoomLevel
that clients can make use of to
track and save zoom level.
There are two ways to make something happen in response to ZoomLevel
changing: one is to listenTo
the property and add a reaction for
cogdebugger.PropertyValueChanged events. The other is to install a
Swing action on the property itself.
A trait for viewers that support zoom operations, but that don't or can't track their own zoom level.
A trait for viewers that support zoom operations, but that don't or can't track their own zoom level. This is mostly intended for higher-level panels that have one or more Zoomable children, which individually track their own magnification level. Case-in-point: cogdebugger.ui.fieldvisualizations.ViewerSuperPanel has one of any number of subpanels installed at a time, but each subpanel can respond to zoom changes in its own way and/or maintain its own level of magnification.