1 package isac.gui.mawen.editor
3 import isac.gui.mawen.editor.Box.DrawBox
4 import isac.gui.mawen.syntax.Ast._
5 import isac.interfaces.IEditor
6 import edu.tum.cs.isabelle.api.Implementation
10 import java.awt.geom._
11 import java.awt.font._
12 import java.awt.event._
13 import java.awt.font._
14 import org.drools.xml.ExtensibleXmlParser.Null
15 import scala.collection.immutable.List
18 * The Java Swing component for a formula
19 * represented by an <code>Ast</code>
21 class AstComponent(var ast: Ast) extends JComponent with AstContainer with MouseListener with MouseMotionListener {
23 addMouseListener(this)
24 addMouseMotionListener(this)
25 var pressedMousePoint : Point = null
26 var marker : Rectangle = new Rectangle()
27 // list of boxes touched by mouse while drawing a rectangle; the outmost is relevant
28 var markedBoxes : List[DrawBox] = List.empty[DrawBox]
29 var box : DrawBox = null
31 addKeyListener(EventUtil.CreateKeyEventHandler(this))
32 addMouseWheelListener(EventUtil.CreateMouseWheelHandler(this))
35 new Thread(new Runnable() {
44 def setAst(ast: Ast) = {
48 def getAst() : Ast = this.ast
50 override def paint(g: Graphics) = {
52 val g2 = g.asInstanceOf[Graphics2D]
53 // enable antialiasing for Text
54 val rh = new RenderingHints(
55 RenderingHints.KEY_TEXT_ANTIALIASING,
56 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
57 g2.setRenderingHints(rh);
59 g.setColor(Color.WHITE)
60 g.fillRect(0, 0, getWidth, getHeight)
61 g.setColor(Color.BLACK)
62 g.translate(Settings.translateX, Settings.translateY)
63 g2.scale(Settings.zoom, Settings.zoom)
64 Settings.fillStringbounds(ast, g2)
65 box = CalcUtil.assembleBoxes(ast, (box: DrawBox) =>
67 if (EventUtil.foreachBoxFunction != null) {
68 EventUtil.foreachBoxFunction(g2, box)
73 setSize((box.width * Settings.zoom).round + 50 + Settings.translateX, Math.max((box.height * Settings.zoom).round, 50) + Settings.translateY)
74 setPreferredSize(getSize)
76 g.drawRect(marker.x, marker.y, marker.width, marker.height)
79 // /--- enforced by trait MouseListener --------------------------------------\
80 def mouseEntered(e: MouseEvent) {}
81 def mouseExited(e: MouseEvent ) {}
82 def mousePressed(e: MouseEvent ) {
83 AstInfoUtil.FindBox(ast) match {
84 case Some(boxAst) => {
85 ast =TransformAstUtil.Update(ast, boxAst, TransformAstUtil.UnBox)
90 val cursorAst : Ast = AstInfoUtil.FindCursor(ast)
91 if (cursorAst != null) {
92 ast =TransformAstUtil.Update(ast, cursorAst , TransformAstUtil.CursorToAst)
94 pressedMousePoint = new Point ( Settings.translateX - e.getX , Settings.translateY - e.getY)
95 marker.setLocation((e.getX / Settings.zoom ).round - (Settings.translateX / Settings.zoom).round,
96 (e.getY / Settings.zoom ).round - (Settings.translateY / Settings.zoom).round)
98 def mouseReleased(e: MouseEvent ) {
99 pressedMousePoint = null
101 findHighestBoxOf(box, markedBoxes) match {
102 case Some(highest) => {
103 this.ast = TransformAstUtil.Update(ast, highest.ast, TransformAstUtil.Box)
107 markedBoxes = List.empty[DrawBox]
110 def mouseClicked(e: MouseEvent ) {
111 if (e.isControlDown()) {
112 AstInfoUtil.FindBox(ast) match {
113 case Some(boxAst) => ast =TransformAstUtil.Update(ast, boxAst, TransformAstUtil.UnBox)
116 EventUtil.foreachBoxFunction = EventUtil.doInBox(e.getPoint,
118 ast = TransformAstUtil.Update(ast, box.ast, TransformAstUtil.AstToCursor)
119 EventUtil.foreachBoxFunction = null;
126 def mouseDragged(e:MouseEvent) {
127 if (e.isControlDown() && Settings.isdraggingAllowed) {
128 if (pressedMousePoint != null) {
129 Settings.translateX = e.getX + pressedMousePoint.x
130 Settings.translateY = e.getY + pressedMousePoint.y
136 marker.setSize(((e.getX / Settings.zoom).round - marker.x ) - (Settings.translateX / Settings.zoom).round,
137 ((e.getY / Settings.zoom).round - marker.y ) - (Settings.translateY / Settings.zoom).round)
138 EventUtil.foreachBoxFunction = (g, b) => {
139 if (Box.BoxIn(b, marker) && Box.isLeaf(b)) {
140 Box.draw(b, g, false)
141 if (!markedBoxes.contains(b))
142 markedBoxes = b :: markedBoxes
148 def mouseMoved(e: MouseEvent ) {
149 if (Settings.drawBoxesOnMouseMove) {
150 EventUtil.drawBoxAt(e.getPoint())
154 // \--- enforced by trait MouseMotionListener --------------------------------/
156 def findHighestBoxOf(rootbox: DrawBox, markedBoxes : List[DrawBox]) : Option[DrawBox] = {
157 if (markedBoxes != null && rootbox != null && rootbox.children != null) {
158 if (markedBoxes.forall(x => Box.Contains(rootbox,x)) &&
159 ! rootbox.children.exists(x => markedBoxes.forall(y => Box.Contains(x, y)))
163 } else if (markedBoxes.forall(x => Box.Contains(rootbox, x)) &&
164 rootbox.children.exists(x => markedBoxes.forall(y => Box.Contains(x, y)))) {
166 for( box <- rootbox.children) {
167 findHighestBoxOf(box, markedBoxes) match {
168 case Some(box) => return Some(box)