s1520454056@5025
|
1 |
package isac.gui.mawen.editor
|
s1520454056@5025
|
2 |
|
wneuper@5199
|
3 |
import isac.gui.mawen.editor.Box.DrawBox
|
wneuper@5199
|
4 |
import isac.gui.mawen.syntax.Ast._
|
wneuper@5199
|
5 |
import isac.interfaces.IEditor
|
walther@5239
|
6 |
import edu.tum.cs.isabelle.api.Implementation
|
wneuper@5199
|
7 |
|
s1520454056@5025
|
8 |
import javax.swing._
|
s1520454056@5025
|
9 |
import java.awt._
|
s1520454056@5025
|
10 |
import java.awt.geom._
|
s1520454056@5025
|
11 |
import java.awt.font._
|
s1520454056@5029
|
12 |
import java.awt.event._
|
s1520454056@5029
|
13 |
import java.awt.font._
|
s1520454056@5057
|
14 |
import org.drools.xml.ExtensibleXmlParser.Null
|
s1520454056@5093
|
15 |
import scala.collection.immutable.List
|
s1520454056@5162
|
16 |
|
wneuper@5165
|
17 |
/**
|
wneuper@5165
|
18 |
* The Java Swing component for a formula
|
wneuper@5165
|
19 |
* represented by an <code>Ast</code>
|
wneuper@5165
|
20 |
*/
|
s1520454056@5160
|
21 |
class AstComponent(var ast: Ast) extends JComponent with AstContainer with MouseListener with MouseMotionListener {
|
s1520454056@5057
|
22 |
|
s1520454056@5057
|
23 |
addMouseListener(this)
|
s1520454056@5057
|
24 |
addMouseMotionListener(this)
|
s1520454056@5057
|
25 |
var pressedMousePoint : Point = null
|
s1520454056@5144
|
26 |
var marker : Rectangle = new Rectangle()
|
wneuper@5214
|
27 |
// list of boxes touched by mouse while drawing a rectangle; the outmost is relevant
|
s1520454056@5162
|
28 |
var markedBoxes : List[DrawBox] = List.empty[DrawBox]
|
s1520454056@5162
|
29 |
var box : DrawBox = null
|
s1520454056@5144
|
30 |
setFocusable(true)
|
s1520454056@5144
|
31 |
addKeyListener(EventUtil.CreateKeyEventHandler(this))
|
s1520454056@5160
|
32 |
addMouseWheelListener(EventUtil.CreateMouseWheelHandler(this))
|
s1520454056@5112
|
33 |
setSize(50,150)
|
s1520454056@5025
|
34 |
|
s1520454056@5171
|
35 |
new Thread(new Runnable() {
|
s1520454056@5171
|
36 |
def run() {
|
s1520454056@5171
|
37 |
while (true) {
|
s1520454056@5212
|
38 |
Thread.sleep(250);
|
s1520454056@5177
|
39 |
repaint()
|
s1520454056@5171
|
40 |
}
|
s1520454056@5171
|
41 |
}
|
s1520454056@5171
|
42 |
}).start()
|
s1520454056@5171
|
43 |
|
s1520454056@5091
|
44 |
def setAst(ast: Ast) = {
|
s1520454056@5091
|
45 |
this.ast = ast
|
s1520454056@5091
|
46 |
repaint()
|
s1520454056@5091
|
47 |
}
|
s1520454056@5129
|
48 |
def getAst() : Ast = this.ast
|
wneuper@5199
|
49 |
|
s1520454056@5057
|
50 |
override def paint(g: Graphics) = {
|
s1520454056@5168
|
51 |
Settings.g = g
|
s1520454056@5057
|
52 |
val g2 = g.asInstanceOf[Graphics2D]
|
s1520454056@5057
|
53 |
// enable antialiasing for Text
|
s1520454056@5057
|
54 |
val rh = new RenderingHints(
|
s1520454056@5057
|
55 |
RenderingHints.KEY_TEXT_ANTIALIASING,
|
s1520454056@5057
|
56 |
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
s1520454056@5057
|
57 |
g2.setRenderingHints(rh);
|
s1520454056@5057
|
58 |
// white background
|
s1520454056@5057
|
59 |
g.setColor(Color.WHITE)
|
s1520454056@5057
|
60 |
g.fillRect(0, 0, getWidth, getHeight)
|
s1520454056@5057
|
61 |
g.setColor(Color.BLACK)
|
s1520454056@5057
|
62 |
g.translate(Settings.translateX, Settings.translateY)
|
s1520454056@5057
|
63 |
g2.scale(Settings.zoom, Settings.zoom)
|
s1520454056@5164
|
64 |
Settings.fillStringbounds(ast, g2)
|
s1520454056@5164
|
65 |
box = CalcUtil.assembleBoxes(ast, (box: DrawBox) =>
|
s1520454056@5093
|
66 |
{
|
s1520454056@5101
|
67 |
if (EventUtil.foreachBoxFunction != null) {
|
s1520454056@5101
|
68 |
EventUtil.foreachBoxFunction(g2, box)
|
s1520454056@5093
|
69 |
}
|
s1520454056@5057
|
70 |
}
|
s1520454056@5101
|
71 |
)
|
s1520454056@5213
|
72 |
BoxUtil.draw(box , g)
|
s1520454056@5108
|
73 |
setSize((box.width * Settings.zoom).round + 50 + Settings.translateX, Math.max((box.height * Settings.zoom).round, 50) + Settings.translateY)
|
s1520454056@5108
|
74 |
setPreferredSize(getSize)
|
s1520454056@5218
|
75 |
|
s1520454056@5144
|
76 |
g.drawRect(marker.x, marker.y, marker.width, marker.height)
|
s1520454056@5057
|
77 |
}
|
wneuper@5199
|
78 |
|
wneuper@5185
|
79 |
// /--- enforced by trait MouseListener --------------------------------------\
|
wneuper@5199
|
80 |
def mouseEntered(e: MouseEvent) {}
|
wneuper@5199
|
81 |
def mouseExited(e: MouseEvent ) {}
|
s1520454056@5029
|
82 |
def mousePressed(e: MouseEvent ) {
|
s1520454056@5213
|
83 |
AstInfoUtil.FindBox(ast) match {
|
s1520454056@5213
|
84 |
case Some(boxAst) => {
|
s1520454056@5213
|
85 |
ast =TransformAstUtil.Update(ast, boxAst, TransformAstUtil.UnBox)
|
s1520454056@5213
|
86 |
}
|
s1520454056@5213
|
87 |
case None => {}
|
s1520454056@5144
|
88 |
}
|
s1520454056@5213
|
89 |
|
s1520454056@5175
|
90 |
val cursorAst : Ast = AstInfoUtil.FindCursor(ast)
|
s1520454056@5175
|
91 |
if (cursorAst != null) {
|
s1520454056@5175
|
92 |
ast =TransformAstUtil.Update(ast, cursorAst , TransformAstUtil.CursorToAst)
|
s1520454056@5175
|
93 |
}
|
s1520454056@5057
|
94 |
pressedMousePoint = new Point ( Settings.translateX - e.getX , Settings.translateY - e.getY)
|
s1520454056@5144
|
95 |
marker.setLocation((e.getX / Settings.zoom ).round - (Settings.translateX / Settings.zoom).round,
|
s1520454056@5144
|
96 |
(e.getY / Settings.zoom ).round - (Settings.translateY / Settings.zoom).round)
|
s1520454056@5029
|
97 |
}
|
s1520454056@5029
|
98 |
def mouseReleased(e: MouseEvent ) {
|
s1520454056@5057
|
99 |
pressedMousePoint = null
|
s1520454056@5144
|
100 |
marker.setSize(0, 0)
|
s1520454056@5187
|
101 |
findHighestBoxOf(box, markedBoxes) match {
|
s1520454056@5187
|
102 |
case Some(highest) => {
|
s1520454056@5187
|
103 |
this.ast = TransformAstUtil.Update(ast, highest.ast, TransformAstUtil.Box)
|
s1520454056@5187
|
104 |
}
|
s1520454056@5187
|
105 |
case None => {}
|
s1520454056@5187
|
106 |
}
|
s1520454056@5162
|
107 |
markedBoxes = List.empty[DrawBox]
|
s1520454056@5144
|
108 |
repaint()
|
s1520454056@5029
|
109 |
}
|
s1520454056@5029
|
110 |
def mouseClicked(e: MouseEvent ) {
|
s1520454056@5206
|
111 |
if (e.isControlDown()) {
|
s1520454056@5213
|
112 |
AstInfoUtil.FindBox(ast) match {
|
s1520454056@5213
|
113 |
case Some(boxAst) => ast =TransformAstUtil.Update(ast, boxAst, TransformAstUtil.UnBox)
|
s1520454056@5213
|
114 |
case None => {}
|
s1520454056@5213
|
115 |
}
|
s1520454056@5101
|
116 |
EventUtil.foreachBoxFunction = EventUtil.doInBox(e.getPoint,
|
s1520454056@5093
|
117 |
(g, box) => {
|
s1520454056@5093
|
118 |
ast = TransformAstUtil.Update(ast, box.ast, TransformAstUtil.AstToCursor)
|
s1520454056@5218
|
119 |
EventUtil.foreachBoxFunction = null;
|
s1520454056@5093
|
120 |
repaint()
|
s1520454056@5093
|
121 |
}
|
s1520454056@5093
|
122 |
);
|
s1520454056@5057
|
123 |
}
|
s1520454056@5057
|
124 |
repaint()
|
s1520454056@5029
|
125 |
}
|
s1520454056@5057
|
126 |
def mouseDragged(e:MouseEvent) {
|
s1520454056@5144
|
127 |
if (e.isControlDown() && Settings.isdraggingAllowed) {
|
s1520454056@5108
|
128 |
if (pressedMousePoint != null) {
|
s1520454056@5108
|
129 |
Settings.translateX = e.getX + pressedMousePoint.x
|
s1520454056@5108
|
130 |
Settings.translateY = e.getY + pressedMousePoint.y
|
s1520454056@5108
|
131 |
|
s1520454056@5108
|
132 |
repaint()
|
s1520454056@5108
|
133 |
}
|
s1520454056@5108
|
134 |
}
|
s1520454056@5144
|
135 |
else {
|
s1520454056@5144
|
136 |
marker.setSize(((e.getX / Settings.zoom).round - marker.x ) - (Settings.translateX / Settings.zoom).round,
|
s1520454056@5144
|
137 |
((e.getY / Settings.zoom).round - marker.y ) - (Settings.translateY / Settings.zoom).round)
|
s1520454056@5144
|
138 |
EventUtil.foreachBoxFunction = (g, b) => {
|
s1520454056@5162
|
139 |
if (Box.BoxIn(b, marker) && Box.isLeaf(b)) {
|
s1520454056@5162
|
140 |
Box.draw(b, g, false)
|
s1520454056@5144
|
141 |
if (!markedBoxes.contains(b))
|
s1520454056@5144
|
142 |
markedBoxes = b :: markedBoxes
|
s1520454056@5144
|
143 |
}
|
s1520454056@5144
|
144 |
}
|
s1520454056@5144
|
145 |
repaint()
|
s1520454056@5144
|
146 |
}
|
s1520454056@5057
|
147 |
}
|
s1520454056@5057
|
148 |
def mouseMoved(e: MouseEvent ) {
|
s1520454056@5218
|
149 |
if (Settings.drawBoxesOnMouseMove) {
|
s1520454056@5218
|
150 |
EventUtil.drawBoxAt(e.getPoint())
|
s1520454056@5218
|
151 |
}
|
s1520454056@5218
|
152 |
repaint()
|
s1520454056@5057
|
153 |
}
|
wneuper@5185
|
154 |
// \--- enforced by trait MouseMotionListener --------------------------------/
|
s1520454056@5187
|
155 |
|
s1520454056@5187
|
156 |
def findHighestBoxOf(rootbox: DrawBox, markedBoxes : List[DrawBox]) : Option[DrawBox] = {
|
s1520454056@5178
|
157 |
if (markedBoxes != null && rootbox != null && rootbox.children != null) {
|
s1520454056@5178
|
158 |
if (markedBoxes.forall(x => Box.Contains(rootbox,x)) &&
|
s1520454056@5178
|
159 |
! rootbox.children.exists(x => markedBoxes.forall(y => Box.Contains(x, y)))
|
s1520454056@5178
|
160 |
) {
|
s1520454056@5187
|
161 |
return Some(rootbox)
|
s1520454056@5178
|
162 |
|
s1520454056@5178
|
163 |
} else if (markedBoxes.forall(x => Box.Contains(rootbox, x)) &&
|
s1520454056@5178
|
164 |
rootbox.children.exists(x => markedBoxes.forall(y => Box.Contains(x, y)))) {
|
s1520454056@5178
|
165 |
|
s1520454056@5178
|
166 |
for( box <- rootbox.children) {
|
s1520454056@5187
|
167 |
findHighestBoxOf(box, markedBoxes) match {
|
s1520454056@5187
|
168 |
case Some(box) => return Some(box)
|
s1520454056@5187
|
169 |
case None => {}
|
s1520454056@5187
|
170 |
}
|
s1520454056@5144
|
171 |
}
|
s1520454056@5144
|
172 |
}
|
s1520454056@5144
|
173 |
}
|
s1520454056@5187
|
174 |
return None
|
s1520454056@5144
|
175 |
}
|
wneuper@5199
|
176 |
|
s1520454056@5029
|
177 |
}
|