isac-java/src/java/isac/gui/mawen/editor/AstComponent.scala
author Walther Neuper <walther.neuper@jku.at>
Fri, 26 Mar 2021 10:45:05 +0100
changeset 5239 b4e3883d7b66
parent 5229 6bf0e95981e3
permissions -rw-r--r--
reset mathematics-engine to Isabelle2015

note: for this version libisabelle was available,
which connects front-end (Java) and back-end (Isabelle/ML)
     1 package isac.gui.mawen.editor
     2 
     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
     7 
     8 import javax.swing._
     9 import java.awt._
    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
    16 
    17 /**
    18  * The Java Swing component for a formula
    19  * represented by an <code>Ast</code>
    20  */
    21 class AstComponent(var ast: Ast) extends JComponent with AstContainer with MouseListener with MouseMotionListener {
    22 
    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
    30   setFocusable(true)
    31   addKeyListener(EventUtil.CreateKeyEventHandler(this))
    32   addMouseWheelListener(EventUtil.CreateMouseWheelHandler(this))
    33   setSize(50,150)
    34   
    35   new Thread(new Runnable() {
    36     def run() {
    37       while (true) {
    38         Thread.sleep(250);
    39         repaint()
    40       }
    41     }
    42   }).start()
    43   
    44   def setAst(ast: Ast) = {
    45     this.ast = ast
    46     repaint()
    47   }
    48   def getAst() : Ast = this.ast
    49 
    50   override def paint(g: Graphics) = {
    51     Settings.g = g
    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);
    58     // white background
    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) => 
    66         {
    67           if (EventUtil.foreachBoxFunction != null) {
    68             EventUtil.foreachBoxFunction(g2, box)
    69           }
    70         }
    71       )
    72       BoxUtil.draw(box , g)
    73       setSize((box.width * Settings.zoom).round + 50 + Settings.translateX, Math.max((box.height * Settings.zoom).round, 50)  + Settings.translateY)
    74       setPreferredSize(getSize)
    75       
    76       g.drawRect(marker.x, marker.y, marker.width, marker.height)
    77   }
    78 
    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)    
    86 	    }
    87 	    case None => {}
    88 	  }
    89 	 
    90 	  val cursorAst : Ast = AstInfoUtil.FindCursor(ast)
    91 	  if (cursorAst != null) {
    92   	  ast =TransformAstUtil.Update(ast, cursorAst , TransformAstUtil.CursorToAst)    
    93 	  }
    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)
    97 	}
    98 	def mouseReleased(e: MouseEvent ) {
    99 		pressedMousePoint = null
   100 		marker.setSize(0, 0)
   101 		findHighestBoxOf(box, markedBoxes) match {
   102 		  case Some(highest) => {
   103 		    this.ast = TransformAstUtil.Update(ast, highest.ast, TransformAstUtil.Box)
   104 		  }
   105 		  case None => {}
   106 		}
   107 		markedBoxes = List.empty[DrawBox]
   108 		repaint()
   109 	}
   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)
   114 	      case None => {}
   115 	    }
   116 		  EventUtil.foreachBoxFunction = EventUtil.doInBox(e.getPoint,
   117 		      (g, box) => {
   118   	        ast = TransformAstUtil.Update(ast, box.ast, TransformAstUtil.AstToCursor)
   119   	        EventUtil.foreachBoxFunction = null;
   120   	        repaint()
   121 		      }
   122 		    );
   123 		}
   124 		repaint()
   125 	}
   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 
   131     	  
   132     	  repaint()
   133   	  }
   134     }
   135     else {
   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 
   143         }
   144       }
   145       repaint()
   146     }
   147 	}
   148 	def mouseMoved(e: MouseEvent ) {
   149 	  if (Settings.drawBoxesOnMouseMove) {
   150 	    EventUtil.drawBoxAt(e.getPoint())
   151 	  }
   152 	  repaint()
   153 	}
   154   // \--- enforced by trait MouseMotionListener --------------------------------/
   155 
   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)))
   160         ) {
   161         return Some(rootbox)
   162         
   163       } else if (markedBoxes.forall(x => Box.Contains(rootbox, x)) && 
   164           rootbox.children.exists(x => markedBoxes.forall(y => Box.Contains(x, y)))) {
   165         
   166         for( box <- rootbox.children) {
   167           findHighestBoxOf(box, markedBoxes) match {
   168             case Some(box) => return Some(box)
   169             case None => {}
   170           }          
   171         }
   172       }
   173     }
   174     return None
   175   }
   176   
   177 }