TODOWN finished
authorWalther Neuper <wneuper@ist.tugraz.at>
Tue, 12 Sep 2017 15:39:03 +0200
changeset 5216a23bca3a94bd
parent 5215 bf7d431b06ee
child 5217 812150bbcc9d
TODOWN finished
isac-java/src/java/isac/gui/mawen/editor/AstInfoUtil.scala
isac-java/src/java/isac/gui/mawen/editor/CalcUtil.scala
isac-java/src/java/isac/gui/mawen/editor/EditingUtil.scala
isac-java/src/java/isac/gui/mawen/editor/EditorListenerHandler.scala
isac-java/src/java/isac/gui/mawen/editor/EventUtil.scala
isac-java/src/java/isac/gui/mawen/editor/Settings.scala
     1.1 --- a/isac-java/src/java/isac/gui/mawen/editor/AstInfoUtil.scala	Tue Sep 12 14:46:07 2017 +0200
     1.2 +++ b/isac-java/src/java/isac/gui/mawen/editor/AstInfoUtil.scala	Tue Sep 12 15:39:03 2017 +0200
     1.3 @@ -108,6 +108,7 @@
     1.4       }
     1.5       case ast                                                   => None
     1.6    }
     1.7 +  // precondition: there is only ONE "CURSOR" in a formula.
     1.8    // introducing Option[Ast] would cause delicate changes
     1.9    def FindCursor(ast: Ast) : Ast = ast match {
    1.10       case Appl(List(Constant("CURSOR"), a))                               => ast
     2.1 --- a/isac-java/src/java/isac/gui/mawen/editor/CalcUtil.scala	Tue Sep 12 14:46:07 2017 +0200
     2.2 +++ b/isac-java/src/java/isac/gui/mawen/editor/CalcUtil.scala	Tue Sep 12 15:39:03 2017 +0200
     2.3 @@ -25,43 +25,50 @@
     2.4    def assembleBoxes (ast: Ast, f: (DrawBox) => Unit ) =
     2.5      assembleBoxesRec(new EmptyBox(0,0,0,ast), f)
     2.6  
     2.7 -  def assembleBoxesRec(emptyBox: EmptyBox, f:(DrawBox) => Unit) : DrawBox = emptyBox.ast match {
     2.8 +  /*
     2.9 +   * Recursively assemble boxes, i.e. sub-terms of a formula while scanning the Ast.
    2.10 +   * 
    2.11 +   * For the call back see  $4.3.1 p.53/54 and $4.3.2 p.56.
    2.12 +   */
    2.13 +  def assembleBoxesRec(emptyBox: EmptyBox, callback_calc:(DrawBox) => Unit) : DrawBox = emptyBox.ast match {
    2.14      case Appl(operator :: param :: Nil)
    2.15 -      => assembleUniopBoxes(EmptyUniOpBox(emptyBox.level, emptyBox.x0, emptyBox.y0, param, emptyBox.ast), f)
    2.16 +      => assembleUniopBoxes(EmptyUniOpBox(emptyBox.level, emptyBox.x0, emptyBox.y0, param, emptyBox.ast), callback_calc)
    2.17      case Appl(operator :: paraml :: paramr :: Nil)
    2.18 -      => assembleBinopBoxes(AstInfoUtil.OperatorString(operator), EmptyBinOpBox(emptyBox.level,emptyBox.x0, emptyBox.y0, operator, paraml, paramr,emptyBox.ast), f)
    2.19 +      => assembleBinopBoxes(AstInfoUtil.OperatorString(operator), EmptyBinOpBox(emptyBox.level,emptyBox.x0, emptyBox.y0, operator, paraml, paramr,emptyBox.ast), callback_calc)
    2.20      case Appl(Constant(str) :: param)
    2.21 -      => calcDefault(str,param, emptyBox.x0, emptyBox.y0, emptyBox.level, emptyBox.ast, f)
    2.22 +      => calcDefault(str,param, emptyBox.x0, emptyBox.y0, emptyBox.level, emptyBox.ast, callback_calc)
    2.23      case a
    2.24 -      => assembleLeafBoxes(EmptyLeafOpBox(emptyBox.level, emptyBox.x0, emptyBox.y0, emptyBox.ast), f)
    2.25 +      => assembleLeafBoxes(EmptyLeafOpBox(emptyBox.level, emptyBox.x0, emptyBox.y0, emptyBox.ast), callback_calc)
    2.26    }
    2.27 -  def assembleLeafBoxes(emptyBox: EmptyLeafOpBox, f:(DrawBox) => Unit) : DrawBox = emptyBox.ast match {
    2.28 -    case Variable("GAP") => calcGAP( emptyBox, f)
    2.29 -    case Constant("GAP") => calcGAP( emptyBox, f)
    2.30 -    case Constant(str)   => calcConstant( emptyBox, f)
    2.31 -    case Variable(str)   => calcVariable( emptyBox, f)
    2.32 +  def assembleLeafBoxes(emptyBox: EmptyLeafOpBox, callback_calc:(DrawBox) => Unit) : DrawBox = emptyBox.ast match {
    2.33 +    case Variable("GAP") => calcGAP( emptyBox, callback_calc)
    2.34 +    case Constant("GAP") => calcGAP( emptyBox, callback_calc)
    2.35 +    case Constant(str)   => calcConstant( emptyBox, callback_calc)
    2.36 +    case Variable(str)   => calcVariable( emptyBox, callback_calc)
    2.37      case ast => throw new AstException("assembleBoxesRec, uncovered match: " + raw_string_of(ast))
    2.38    }
    2.39 -  def assembleUniopBoxes(emptyBox: EmptyUniOpBox, f:(DrawBox) => Unit) : DrawBox = emptyBox.ast match {
    2.40 +  def assembleUniopBoxes(emptyBox: EmptyUniOpBox, callback_calc:(DrawBox) => Unit) : DrawBox = emptyBox.ast match {
    2.41      case Appl(Constant(str) ::  ast :: Nil) if str.startsWith("BOX")
    2.42 -      => CalcBox( str.replace("BOX.", ""), emptyBox, f)
    2.43 +      => CalcBox( str.replace("BOX.", ""), emptyBox, callback_calc)
    2.44      case Appl(Constant("CURSOR") :: param :: Nil)
    2.45 -      => calcCursor( EmptyUniOpBox(emptyBox.level,emptyBox.x0,emptyBox.y0, param, emptyBox.ast), f)
    2.46 +      => calcCursor( EmptyUniOpBox(emptyBox.level,emptyBox.x0,emptyBox.y0, param, emptyBox.ast), callback_calc)
    2.47      case Appl(param :: Constant("CURSOR") :: Nil)
    2.48 -      => calcCursor( EmptyUniOpBox(emptyBox.level,emptyBox.x0,emptyBox.y0, param, emptyBox.ast), f)
    2.49 +      => calcCursor( EmptyUniOpBox(emptyBox.level,emptyBox.x0,emptyBox.y0, param, emptyBox.ast), callback_calc)
    2.50      case Appl(op :: param :: Nil)
    2.51 -      => calcDefault( AstInfoUtil.OperatorString(op), List(param), emptyBox.x0, emptyBox.y0, emptyBox.level, emptyBox.ast, f)
    2.52 +      => calcDefault( AstInfoUtil.OperatorString(op), List(param), emptyBox.x0, emptyBox.y0, emptyBox.level, emptyBox.ast, callback_calc)
    2.53      case ast
    2.54        => throw new AstException("assembleBoxesRec, uncovered match: " + raw_string_of(ast))
    2.55    }
    2.56 -  def assembleBinopBoxes( operatorString: String, emptyBox: EmptyBinOpBox, f:(DrawBox) => Unit) : DrawBox = Settings.layoutName(XSyntax.isa_ast(operatorString) ) match {
    2.57 -    case "binOp" => calcDefaultBinOp( emptyBox, f)
    2.58 -    case "Pow"   => calcPow( emptyBox, f)
    2.59 -    case "Frac"  => calcFrac( emptyBox, f)
    2.60 -    case _       => calcDefault( operatorString, List(emptyBox.paramr, emptyBox.paraml), emptyBox.x0, emptyBox.y0, emptyBox.level, emptyBox.ast, f)
    2.61 +  def assembleBinopBoxes( operatorString: String, emptyBox: EmptyBinOpBox, callback_calc:(DrawBox) => Unit) : DrawBox = Settings.layoutName(XSyntax.isa_ast(operatorString) ) match {
    2.62 +    case "binOp" => calcDefaultBinOp( emptyBox, callback_calc)
    2.63 +    case "Pow"   => calcPow( emptyBox, callback_calc)
    2.64 +    case "Frac"  => calcFrac( emptyBox, callback_calc)
    2.65 +    case _       => calcDefault( operatorString, List(emptyBox.paramr, emptyBox.paraml), emptyBox.x0, emptyBox.y0, emptyBox.level, emptyBox.ast, callback_calc)
    2.66    }
    2.67    /*
    2.68 -   * calc* calculates the size of a fram around <code>DrawBox</code> for
    2.69 +   * calc* calculates the size of a frame around <code>DrawBox</code>.
    2.70 +   * 
    2.71 +   * For the call back see  $4.3.1 p.53/54 and $4.3.2 p.56.
    2.72     */
    2.73    def calcVariable( emptybox: EmptyLeafOpBox, callback_calc:(DrawBox) => Unit): DrawBox = {
    2.74      val level = emptybox.level
    2.75 @@ -71,7 +78,7 @@
    2.76      val str = AstInfoUtil.VariableString(emptybox.ast)
    2.77      val box : Rectangle =  Settings.getStringBoundOf(str, level, x0, y0) //  getStringBounds(g.asInstanceOf[Graphics2D], str, x0, y0) // TODO: Why does this work without x0,y0?
    2.78      val b = DrawBox(str, level, box.x, box.y + box.height, box.width, box.height, x0, y0, ast)
    2.79 -    callback_calc(b) // see mmahringer $4.3.1 p.53/54 and $4.3.2 p.56
    2.80 +    callback_calc(b)
    2.81      b
    2.82    }
    2.83    def calcConstant( emptyBox: EmptyLeafOpBox, callback_calc:(DrawBox) => Unit) = {
    2.84 @@ -84,7 +91,7 @@
    2.85      val midline = y0 - (fontsizeOf(level) * (2f / 3f)*(1f / 3f)).round
    2.86      val newY = ((box.y - y0) * -1) - box.height /2 + midline
    2.87      val b = DrawBox(op, level, box.x, y0, box.width, fontWidthOf(fontsizeOf(level)),x0, newY, ast)
    2.88 -    callback_calc(b) // see mmahringer $4.3.1 p.53/54 and $4.3.2 p.56
    2.89 +    callback_calc(b)
    2.90      b
    2.91    }
    2.92    def calcGAP( emptyBox: EmptyLeafOpBox, callback_calc:(DrawBox) => Unit) = {
    2.93 @@ -94,7 +101,7 @@
    2.94      val ast =  emptyBox.ast
    2.95      val box : Rectangle = Settings.getStringBoundOf("xx", level, x0, y0) //getStringBounds(g.asInstanceOf[Graphics2D], "xx", x0, y0)
    2.96      val b = new DrawBox("GAP", level, box.x, y0, box.width, fontWidthOf(fontsizeOf(level)),x0, y0, ast)
    2.97 -    callback_calc(b) // see callback mmahringer $4.3.1 p.53/54 and $4.3.2 p.56
    2.98 +    callback_calc(b)
    2.99      b
   2.100    }
   2.101    // NO callback_calc, because a frame does NOT accept a mouse interaction
   2.102 @@ -118,7 +125,7 @@
   2.103      val param = emptyBox.param
   2.104      val childBox = assembleBoxesRec( new EmptyBox(level, x0, y0, param), callback_calc)
   2.105      val b = new DrawBox("CURSOR", level, childBox.x - 1, childBox.y + 1, childBox.width + 2,  childBox.height + 2, x0, y0, ast)
   2.106 -    callback_calc(b) // see mmahringer $4.3.1 p.53/54 and $4.3.2 p.56
   2.107 +    callback_calc(b)
   2.108      b.children = List(childBox)
   2.109      b
   2.110    }
   2.111 @@ -349,8 +356,7 @@
   2.112    }
   2.113    def fontWidthOf(fontsize: Int) = ((fontsize * 2f) / 3f).round
   2.114  
   2.115 -  //TODOWN rename to decreaseFontOfLevel
   2.116 -  def decreseFontOfLevel(fontsize: Int, level: Int) = level match {
   2.117 +  def decreaseFontOfLevel(fontsize: Int, level: Int) = level match {
   2.118      case 1 => (fontsize * 0.7f).round
   2.119      case 2 => (fontsize * 0.7f).round
   2.120      case _ => fontsize // higher levels stay with the same
     3.1 --- a/isac-java/src/java/isac/gui/mawen/editor/EditingUtil.scala	Tue Sep 12 14:46:07 2017 +0200
     3.2 +++ b/isac-java/src/java/isac/gui/mawen/editor/EditingUtil.scala	Tue Sep 12 15:39:03 2017 +0200
     3.3 @@ -5,16 +5,15 @@
     3.4  import java.awt.event.KeyEvent
     3.5  
     3.6  /**
     3.7 - * Edit a formulas listening to key events
     3.8 + * Edit a formula listening to key events
     3.9   * according to a state-transition-system
    3.10 - * described in mmahringer Fig.TODO.TODOWN.
    3.11 + * described in mmahringer Fig.4.12. p.58
    3.12   * 
    3.13   * "State" in identifiers refer to this system.
    3.14   */
    3.15  object EditingUtil {
    3.16    
    3.17 -  // TODOWN rename
    3.18 -  def parse(c: AstContainer, inputCode: Int) : Unit =  {
    3.19 +  def startKeyInput(c: AstContainer, inputCode: Int) : Unit =  {
    3.20      val cursorAst = AstInfoUtil.FindCursor(c.getAst()) 
    3.21      val cursorAstElem = AstInfoUtil.AstOfCursor(cursorAst)
    3.22      findState(c, cursorAst, inputCode) match {
    3.23 @@ -22,6 +21,7 @@
    3.24        case None => {}
    3.25      }
    3.26    }
    3.27 +  // find state according to Fig.4.12.
    3.28    def findState(c: AstContainer, cursorAst: Ast, inputCode: Int) : Option[Ast] = cursorAst match {
    3.29      case Appl(List(Variable(str), Constant("CURSOR"))) if str forall Character.isDigit  => numberState(AstInfoUtil.AstOfCursor(cursorAst), inputCode) match {
    3.30        case Some(ast) => Some(ast)
    3.31 @@ -82,24 +82,24 @@
    3.32    def delimerState(c: AstContainer, input: Character, cursorAst: Ast) : Option[Ast] =  AstInfoUtil.AstOfCursor(cursorAst) match {
    3.33      case Variable(str)   if input == '(' && isLongDelim(str)
    3.34        => Some(ReplaceFirstGap(
    3.35 -           Settings.OperatorToAst(str),
    3.36 +           Settings.shortOpToIsaOp(str),
    3.37             Appl(List(Constant("CURSOR"), Constant("GAP")))))
    3.38      case Variable(str)
    3.39        => Some(ReplaceFirstGap(
    3.40             ReplaceFirstGap(
    3.41 -             Settings.OperatorToAst(input.toString()),
    3.42 +             Settings.shortOpToIsaOp(input.toString()),
    3.43               Variable(str)),
    3.44             Appl(List(Constant("CURSOR"), Constant("GAP")))))
    3.45      case Appl(asts)
    3.46        => Some(ReplaceFirstGap(
    3.47             ReplaceFirstGap(
    3.48 -             Settings.OperatorToAst(input.toString()),
    3.49 +             Settings.shortOpToIsaOp(input.toString()),
    3.50               Appl(asts)),
    3.51             Appl(List(Constant("CURSOR"), Constant("GAP")))))
    3.52 -    case Constant("GAP") => Some(Settings.OperatorToAst(input.toString()))
    3.53 +    case Constant("GAP") => Some(Settings.shortOpToIsaOp(input.toString()))
    3.54      case Constant(str) => {
    3.55        val operatorParams = AstInfoUtil.Parent(c.getAst(), cursorAst).asInstanceOf[Appl].name.tail
    3.56 -      var newOperatorAst = Settings.OperatorToAst(input.toString())
    3.57 +      var newOperatorAst = Settings.shortOpToIsaOp(input.toString())
    3.58        for(a <- operatorParams) {
    3.59          newOperatorAst = ReplaceFirstGap(newOperatorAst, a)
    3.60        }
    3.61 @@ -126,11 +126,10 @@
    3.62      code == -KeyEvent.VK_DOWN || 
    3.63      code == -KeyEvent.VK_DELETE ||
    3.64      code == -KeyEvent.VK_F2
    3.65 -  //TODOWN rename to isLongOp
    3.66 +  // TODO reconsider edge to state "Operator" in Fig.4.12
    3.67    def isLongDelim(ch: String) : Boolean=  Settings.layout.keys.filter(x => x.length() > 1).toList.contains(ch)
    3.68 -  //TODOWN ???
    3.69 -  def OperatorToAst(ch: Character) : Ast = Settings.OperatorToAst(ch.toString())
    3.70 -  // TODOWN why only first ?
    3.71 +  def OperatorToAst(ch: Character) : Ast = Settings.shortOpToIsaOp(ch.toString())
    3.72 +  // recursive replacement of arguments in case the respective operator is changed
    3.73    def ReplaceFirstGap(ast: Ast, replace: Ast) : Ast = ast match {
    3.74      case Appl(Constant("GAP") :: asts)      => Appl(replace :: asts)
    3.75      case Appl(a :: Constant("GAP") :: asts) => Appl(a :: replace :: asts)
     4.1 --- a/isac-java/src/java/isac/gui/mawen/editor/EditorListenerHandler.scala	Tue Sep 12 14:46:07 2017 +0200
     4.2 +++ b/isac-java/src/java/isac/gui/mawen/editor/EditorListenerHandler.scala	Tue Sep 12 15:39:03 2017 +0200
     4.3 @@ -4,7 +4,7 @@
     4.4  import isac.interfaces.IEditor
     4.5  
     4.6  /**
     4.7 - * TODOWN
     4.8 + * Notifies (the Worksheet) about key actions.
     4.9   */
    4.10  object EditorListenerHandler {
    4.11    
     5.1 --- a/isac-java/src/java/isac/gui/mawen/editor/EventUtil.scala	Tue Sep 12 14:46:07 2017 +0200
     5.2 +++ b/isac-java/src/java/isac/gui/mawen/editor/EventUtil.scala	Tue Sep 12 15:39:03 2017 +0200
     5.3 @@ -65,7 +65,7 @@
     5.4    def CreateKeyEventHandler(c: AstContainer) : KeyListener = new KeyListener () {
     5.5      def keyPressed(event: KeyEvent): Unit = {
     5.6        if (event.getKeyCode == KeyEvent.VK_BACK_SPACE) { 
     5.7 -        EditingUtil.parse(c, -event.getKeyCode)
     5.8 +        EditingUtil.startKeyInput(c, -event.getKeyCode)
     5.9        }
    5.10      }
    5.11      def keyReleased(event: KeyEvent): Unit = {
    5.12 @@ -85,7 +85,7 @@
    5.13             case None => {}
    5.14           }
    5.15        } else if (AstInfoUtil.hasCursor(c.getAst())) {
    5.16 -        EditingUtil.parse(c, -event.getKeyCode)
    5.17 +        EditingUtil.startKeyInput(c, -event.getKeyCode)
    5.18        }
    5.19        if (event.getKeyCode == KeyEvent.VK_DOWN) {
    5.20          TransformAstUtil.CursorChild(c)
    5.21 @@ -122,13 +122,13 @@
    5.22            || (event.getKeyChar >= 'a' && event.getKeyChar <= 'z')
    5.23            || (event.getKeyChar >= 'A' && event.getKeyChar <= 'Z')
    5.24            || List('+', '-', '*', '/', '(', '=').contains(event.getKeyChar)) {
    5.25 -        EditingUtil.parse(c, event.getKeyChar.toInt)
    5.26 +        EditingUtil.startKeyInput(c, event.getKeyChar.toInt)
    5.27          //EditorListenerHandler.fireNotifysBraille(c, AstInfoUtil.FindBox(c.getAst()))
    5.28        } else if (
    5.29            event.getKeyCode == KeyEvent.VK_ENTER || 
    5.30            event.getKeyCode == KeyEvent.VK_DELETE || 
    5.31            event.getKeyCode == KeyEvent.VK_F2) {
    5.32 -        EditingUtil.parse(c, -event.getKeyCode)
    5.33 +        EditingUtil.startKeyInput(c, -event.getKeyCode)
    5.34        }
    5.35        if (event.getKeyCode == KeyEvent.VK_ENTER)
    5.36          println(c.getAst()) // Output ast on key enter
     6.1 --- a/isac-java/src/java/isac/gui/mawen/editor/Settings.scala	Tue Sep 12 14:46:07 2017 +0200
     6.2 +++ b/isac-java/src/java/isac/gui/mawen/editor/Settings.scala	Tue Sep 12 15:39:03 2017 +0200
     6.3 @@ -166,8 +166,7 @@
     6.4        case None => str
     6.5      }
     6.6    }
     6.7 -  // TODOWN ??
     6.8 -  def OperatorToAst(o: String) : Ast = layout.get(o) match {
     6.9 +  def shortOpToIsaOp(o: String) : Ast = layout.get(o) match {
    6.10      case Some((_, _,a)) => a 
    6.11      case None => Appl(List(Constant(o), Constant("GAP")))
    6.12    }