Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUI tree construction integrated into ornl/elision/core #12

Merged
merged 1 commit into from
May 15, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 50 additions & 22 deletions Elision/src/ElisionGUI/TreeSprite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ object TreeSprite {


/**
*
* Factory method builds a fabricated tree structure with a friendly
* welcome message and some basic instructions.
*/

def buildWelcomeTree : TreeSprite = {
Expand All @@ -270,12 +271,13 @@ object TreeSprite {

new TreeSprite(0,0,realroot)
}


/**
* Factory method builds a fabricated tree structure for testing purposes.
* The Touhou Project and its characters are copyright (c) ZUN, Team Shanghai Alice.
*/

/*
def buildTouhouTree : TreeSprite = {
val root = new NodeSprite("Touhou Characters")
var parent : NodeSprite = root
Expand Down Expand Up @@ -565,12 +567,7 @@ object TreeSprite {
parent = ts.pop
parent = ts.pop

/*
ts.push(parent)
parent = addChild("A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name...A very long term name... ",parent)
addChild("A small term",parent)
parent = ts.pop
*/


parent = ts.pop

Expand All @@ -579,6 +576,7 @@ object TreeSprite {

new TreeSprite(0,0,root)
}
*/

/**
* Used by some of the TreeSprite factory methods.
Expand Down Expand Up @@ -620,6 +618,8 @@ object TreeSprite {
node.properties = rwNode.properties
parent.addChild(node)

node.isComment = rwNode.isComment

for(child <- rwNode.children) {
buildRWTreeRec(child, node)
}
Expand Down Expand Up @@ -691,6 +691,9 @@ class NodeSprite(var term : String = "Unnamed Node", val parent : NodeSprite = n
/** The node's properties describing the Elision atom it represents */
var properties : String = ""

/** flag indicates that this node is just a documentation string and doesn't actually represent an atom */
var isComment = true

//////////////////// Rendering methods


Expand All @@ -713,6 +716,8 @@ class NodeSprite(var term : String = "Unnamed Node", val parent : NodeSprite = n
if(!children.isEmpty) {
if(this.isSelected)
NodeSprite.selectedBoxColor
else if(this.isComment)
NodeSprite.comBoxColor
else
NodeSprite.boxColor
}
Expand All @@ -723,20 +728,26 @@ class NodeSprite(var term : String = "Unnamed Node", val parent : NodeSprite = n
NodeSprite.leafBoxColor
}
))

g.fill(box)

val startPt = g.getTransform.transform(new geom.Point2D.Double(0,box.y), null)
val endPt = g.getTransform.transform(new geom.Point2D.Double(box.width,box.y+box.height), null)
val isOnScreen = (startPt.getX <= NodeSprite.camera.pWidth && endPt.getX >= 0 && startPt.getY <= NodeSprite.camera.pHeight && endPt.getY >= 0)

if(isOnScreen) g.fill(box)

if(this.isSelected)
g.setColor(alphaColor(NodeSprite.selectedBorderColor))
else
else if(this.isComment)
g.setColor(alphaColor(NodeSprite.comBorderColor))
else
g.setColor(alphaColor(NodeSprite.borderColor))

g.draw(box)
if(isOnScreen) g.draw(box)

// draw the label

g.setColor(alphaColor(NodeSprite.textColor))
g.drawString(term, 3, NodeSprite.font.getSize/2)
if(isOnScreen && NodeSprite.camera.zoom > 0.2) g.drawString(term, 3, NodeSprite.font.getSize/2)

// restore the graphics context's font

Expand Down Expand Up @@ -803,7 +814,7 @@ class NodeSprite(var term : String = "Unnamed Node", val parent : NodeSprite = n
val origTrans = g.getTransform

// use the unselected border color as the color for the edges
g.setColor(alphaColor(NodeSprite.borderColor))
g.setColor(alphaColor(NodeSprite.comBorderColor))

// iterate over the children and obtain their relative positions to determine how to draw the edges.
for(i <- 0 to children.size - 1) {
Expand All @@ -815,12 +826,16 @@ class NodeSprite(var term : String = "Unnamed Node", val parent : NodeSprite = n
val endY = childPos.getY
val ctrlX = math.max(endX/2,endX - 50)

// create the cubic curve shape for the edge.
val edge = new CubicCurve2D.Double(0, 0, ctrlX, 0, ctrlX, endY, endX, endY)

// scale the current graphics transform according to how compressed/decompressed this node's children are. Then draw the edge.
// scale the current graphics transform according to how compressed/decompressed this node's children are.
g.scale(child.expansion,child.expansion)
if(child.expansion > 0.01) g.draw(edge)
val startPt = g.getTransform.transform(new geom.Point2D.Double(0,0), null)
val endPt = g.getTransform.transform(new geom.Point2D.Double(endX,0), null)

if(startPt.getX <= NodeSprite.camera.pWidth && endPt.getX >= 0) {
// create the cubic curve shape for the edge. // Then draw the edge.
val edge = new CubicCurve2D.Double(0, 0, ctrlX, 0, ctrlX, endY, endX, endY)
if(child.expansion > 0.01) g.draw(edge)
}

// restore the original transform for the next edge drawing.
g.setTransform(origTrans)
Expand Down Expand Up @@ -910,14 +925,27 @@ object NodeSprite {
val font = new Font("Lucida Console", java.awt.Font.PLAIN, 12)

val textColor = new Color(0x000000)
val boxColor = new Color(0xddddff)
val borderColor = new Color(0x5555aa)

// comment color: Twilight lavender
val comBoxColor = new Color(0xddddff)
val comBorderColor = new Color(0x5555aa)

// rewritten atom colors: Dash blue
val boxColor = new Color(0xd7e9ff)
val borderColor = new Color(0x77a9dd)

// selected colors : Flutter yellow
val selectedBoxColor = new Color(0xffffcc)
val selectedBorderColor = new Color(0xaaaa55)
val leafBoxColor = new Color(0xffffff)

// leaf colors: Rare grey
val leafBoxColor = new Color(0xf8f8ff)
// val leafBorderColor = new Color(0x8888aa)
val selectedLeafBoxColor = new Color(0xffffee)

val maxTermLength = 50

var camera : Camera = null
}


Expand Down
10 changes: 9 additions & 1 deletion Elision/src/ElisionGUI/mainGUI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ class TreeVisPanel extends GamePanel {

/** The panel's camera for panning around and zooming in the visualization */
val camera = new Camera(0,0,640,480)
NodeSprite.camera = camera

/** The mouse input interface for the panel */
val mouseIn = new MouseInput(this)
Expand Down Expand Up @@ -339,6 +340,12 @@ class TreeVisPanel extends GamePanel {
//testPaint(g)
treeSprite.render(g)

// draw the panel's border (used for testing clipping techniques)
/*
g.setColor(new Color(0xffaaaa))
g.drawRect(camera.xLeftEdge.toInt, camera.yTopEdge.toInt, camera.xRightEdge.toInt - camera.xLeftEdge.toInt, camera.yBottomEdge.toInt - camera.yTopEdge.toInt)
*/

// restore the original transform
g.setTransform(origTrans)

Expand Down Expand Up @@ -430,7 +437,8 @@ class TreeVisPanel extends GamePanel {
camera.zoomAtScreen(0.8, mouseIn.position)

// update the camera's transform based on its new state.

camera.pWidth = this.size.width
camera.pHeight = this.size.height
camera.updateTransform

// update the mouse's current world coordinates
Expand Down
93 changes: 83 additions & 10 deletions Elision/src/ornl/elision/core/AlgProp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,33 @@ class AlgProp(
case Some(atom) => atom
case _ => default
}


//////////////////// GUI changes
/**
* Apply this to the given atom. If the provided atom is an atom sequence,
* then this will override the properties of the atom sequence.
*/
def doApply(rhs: BasicAtom, bypass: Boolean) = rhs match {
/* A Note to Maintainers
* Remember that the "and" has the properties of the second override those
* of the first.
*/
case ap: AlgProp => (ap and this)
case as: AtomSeq => AtomSeq(as.props and this, as.atoms)
case _ => SimpleApply(this, rhs)
def doApply(rhs: BasicAtom, bypass: Boolean) = {
// get the node representing this atom that is being rewritten
val rwNode = RWTree.current.addChild("AlgProp doApply: ")

rhs match {
/* A Note to Maintainers
* Remember that the "and" has the properties of the second override those
* of the first.
*/
case ap: AlgProp => (ap and this)
case as: AtomSeq =>
val newAS = AtomSeq(as.props and this, as.atoms)
rwNode.addChild(newAS)
newAS
case _ =>
val newSA = SimpleApply(this, rhs)
rwNode.addChild(newSA)
newSA
}
}
//////////////////// end GUI changes

/**
* Rewrite an optional atom.
Expand All @@ -288,14 +301,44 @@ class AlgProp(
* @param binds The bindings.
* @return The rewritten optional atom.
*/
private def _rewrite(opt: Option[BasicAtom], binds: Bindings) = opt match {
/* private def _rewrite(opt: Option[BasicAtom], binds: Bindings) = opt match {
case None => (None, false)
case Some(atom) => {
val newatom = atom.rewrite(binds)
(Some(newatom._1), newatom._2)
}
}*/

//////////////////// GUI changes

/**
* Rewrite an optional atom.
*
* @param opt The optional atom.
* @param binds The bindings.
* @return The rewritten optional atom.
*/

private def _rewrite(opt: Option[BasicAtom], binds: Bindings) = {
// get the node representing this atom that is being rewritten
val rwNode = RWTree.current

opt match {
case None =>
rwNode.addChild("n/a")
(None, false)
case Some(atom) => {
val atomNode = rwNode.addChild(atom)
RWTree.current = atomNode

val newatom = atom.rewrite(binds)
(Some(newatom._1), newatom._2)
}
}
}

//////////////////// end GUI changes
/*
def rewrite(binds: Bindings): (AlgProp, Boolean) = {
val assoc = _rewrite(associative, binds)
val commu = _rewrite(commutative, binds)
Expand All @@ -306,6 +349,36 @@ class AlgProp(
(AlgProp(assoc._1, commu._1, idemp._1, absor._1, ident._1), true)
else (this, false)
}
*/
//////////////////// GUI changes

def rewrite(binds: Bindings): (AlgProp, Boolean) = {
// get the node representing this atom that is being rewritten
val rwNode = RWTree.current.addChild("AlgProp rewrite: ")

RWTree.current = rwNode.addChild("associative: ")
val assoc = _rewrite(associative, binds)

RWTree.current = rwNode.addChild("commutative: ")
val commu = _rewrite(commutative, binds)

RWTree.current = rwNode.addChild("idempotent: ")
val idemp = _rewrite(idempotent, binds)

RWTree.current = rwNode.addChild("absorber: ")
val absor = _rewrite(absorber, binds)

RWTree.current = rwNode.addChild("identity: ")
val ident = _rewrite(identity, binds)

if (assoc._2 || commu._2 || idemp._2 || absor._2 || ident._2) {
val newAlgProp = AlgProp(assoc._1, commu._1, idemp._1, absor._1, ident._1)
rwNode.addChild(newAlgProp)
(newAlgProp, true)
} else (this, false)
}

//////////////////// end GUI changes

/**
* Match two optional atoms against one another. A match is really only
Expand Down
Loading