src/Tools/Graphview/mutator_dialog.scala
changeset 59218 eadd82d440b0
parent 59202 711c2446dc9d
child 59221 f779f83ef4ec
equal deleted inserted replaced
59212:ecf64bc69778 59218:eadd82d440b0
    26     reverse_caption: String = "Inverse",
    26     reverse_caption: String = "Inverse",
    27     show_color_chooser: Boolean = true)
    27     show_color_chooser: Boolean = true)
    28   extends Dialog
    28   extends Dialog
    29 {
    29 {
    30   type Mutator_Markup = (Boolean, Color, Mutator)
    30   type Mutator_Markup = (Boolean, Color, Mutator)
    31   
    31 
    32   title = caption
    32   title = caption
    33   
    33 
    34   private var _panels: List[Mutator_Panel] = Nil
    34   private var _panels: List[Mutator_Panel] = Nil
    35   private def panels = _panels
    35   private def panels = _panels
    36   private def panels_= (panels: List[Mutator_Panel]) {
    36   private def panels_=(panels: List[Mutator_Panel])
       
    37   {
    37     _panels = panels
    38     _panels = panels
    38     paintPanels
    39     paintPanels
    39   }
    40   }
    40 
    41 
    41   container.events += {
    42   container.events +=
       
    43   {
    42     case Mutator_Event.Add(m) => addPanel(new Mutator_Panel(m))
    44     case Mutator_Event.Add(m) => addPanel(new Mutator_Panel(m))
    43     case Mutator_Event.NewList(ms) => panels = getPanels(ms)
    45     case Mutator_Event.NewList(ms) => panels = getPanels(ms)
    44   }
    46   }
    45 
    47 
    46   override def open() {
    48   override def open()
    47     if (!visible)
    49   {
    48       panels = getPanels(container())
    50     if (!visible) panels = getPanels(container())
    49 
       
    50     super.open
    51     super.open
    51   }
    52   }
    52 
    53 
    53   minimumSize = new Dimension(700, 200)
    54   minimumSize = new Dimension(700, 200)
    54   preferredSize = new Dimension(1000, 300)
    55   preferredSize = new Dimension(1000, 300)
    55   peer.setFocusTraversalPolicy(focusTraversal)
    56   peer.setFocusTraversalPolicy(focusTraversal)
    56 
    57 
    57   private def getPanels(m: List[Mutator_Markup]): List[Mutator_Panel] =
    58   private def getPanels(m: List[Mutator_Markup]): List[Mutator_Panel] =
    58     m.filter(_ match {case (_, _, Identity()) => false; case _ => true})
    59     m.filter(_ match { case (_, _, Identity()) => false; case _ => true })
    59     .map(m => new Mutator_Panel(m))
    60     .map(m => new Mutator_Panel(m))
    60 
    61 
    61   private def getMutators(panels: List[Mutator_Panel]): List[Mutator_Markup] = 
    62   private def getMutators(panels: List[Mutator_Panel]): List[Mutator_Markup] =
    62     panels.map(panel => panel.get_Mutator_Markup)
    63     panels.map(panel => panel.get_Mutator_Markup)
    63 
    64 
    64   private def movePanelUp(m: Mutator_Panel) = {
    65   private def movePanelUp(m: Mutator_Panel) =
    65     def moveUp(l: List[Mutator_Panel]): List[Mutator_Panel] = l match {
    66   {
    66       case x :: y :: xs => if (y == m) y :: x :: xs else x :: moveUp(y :: xs)
    67     def moveUp(l: List[Mutator_Panel]): List[Mutator_Panel] =
    67       case _ => l
    68       l match {
    68     }
    69         case x :: y :: xs => if (y == m) y :: x :: xs else x :: moveUp(y :: xs)
       
    70         case _ => l
       
    71       }
    69 
    72 
    70     panels = moveUp(panels)
    73     panels = moveUp(panels)
    71   }
    74   }
    72 
    75 
    73   private def movePanelDown(m: Mutator_Panel) = {
    76   private def movePanelDown(m: Mutator_Panel) =
    74     def moveDown(l: List[Mutator_Panel]): List[Mutator_Panel] = l match {
    77   {
    75       case x :: y :: xs => if (x == m) y :: x :: xs else x :: moveDown(y :: xs)
    78     def moveDown(l: List[Mutator_Panel]): List[Mutator_Panel] =
    76       case _ => l
    79       l match {
    77     }
    80         case x :: y :: xs => if (x == m) y :: x :: xs else x :: moveDown(y :: xs)
       
    81         case _ => l
       
    82       }
    78 
    83 
    79     panels = moveDown(panels)
    84     panels = moveDown(panels)
    80   }
    85   }
    81 
    86 
    82   private def removePanel(m: Mutator_Panel) = {
    87   private def removePanel(m: Mutator_Panel)
       
    88   {
    83     panels = panels.filter(_ != m).toList
    89     panels = panels.filter(_ != m).toList
    84   }
    90   }
    85 
    91 
    86   private def addPanel(m: Mutator_Panel) = {
    92   private def addPanel(m: Mutator_Panel)
       
    93   {
    87     panels = panels ::: List(m)
    94     panels = panels ::: List(m)
    88   }
    95   }
    89 
    96 
    90   def paintPanels = {
    97   def paintPanels
       
    98   {
    91     focusTraversal.clear
    99     focusTraversal.clear
    92     filterPanel.contents.clear
   100     filterPanel.contents.clear
    93     panels.map(x => {
   101     panels.map(x => {
    94         filterPanel.contents += x
   102         filterPanel.contents += x
    95         focusTraversal.addAll(x.focusList)
   103         focusTraversal.addAll(x.focusList)
   106 
   114 
   107   val filterPanel = new BoxPanel(Orientation.Vertical) {}
   115   val filterPanel = new BoxPanel(Orientation.Vertical) {}
   108 
   116 
   109   private val mutatorBox = new ComboBox[Mutator](container.available)
   117   private val mutatorBox = new ComboBox[Mutator](container.available)
   110 
   118 
   111   private val addButton: Button = new Button{
   119   private val addButton: Button = new Button {
   112     action = Action("Add") {
   120     action = Action("Add") {
   113       addPanel(
   121       addPanel(new Mutator_Panel((true, visualizer.Colors.next, mutatorBox.selection.item)))
   114         new Mutator_Panel((true, visualizer.Colors.next,
   122     }
   115                            mutatorBox.selection.item))
   123   }
   116       )
   124 
   117     }
   125   private val applyButton = new Button {
   118   }
       
   119 
       
   120   private val applyButton = new Button{
       
   121     action = Action("Apply") {
   126     action = Action("Apply") {
   122       container(getMutators(panels))
   127       container(getMutators(panels))
   123     }
   128     }
   124   }
   129   }
   125 
   130 
   127     action = Action("Reset") {
   132     action = Action("Reset") {
   128       panels = getPanels(container())
   133       panels = getPanels(container())
   129     }
   134     }
   130   }
   135   }
   131 
   136 
   132   private val cancelButton = new Button{
   137   private val cancelButton = new Button {
   133       action = Action("Close") {
   138     action = Action("Close") {
   134         close
   139       close
   135       }
   140     }
   136     }
   141   }
   137   defaultButton = cancelButton
   142   defaultButton = cancelButton
   138 
   143 
   139   private val botPanel = new BoxPanel(Orientation.Horizontal) {
   144   private val botPanel = new BoxPanel(Orientation.Horizontal) {
   140     border = new EmptyBorder(10, 0, 0, 0)
   145     border = new EmptyBorder(10, 0, 0, 0)
   141 
   146 
   151     contents += resetButton
   156     contents += resetButton
   152 
   157 
   153     contents += Swing.RigidBox(new Dimension(5, 0))
   158     contents += Swing.RigidBox(new Dimension(5, 0))
   154     contents += cancelButton
   159     contents += cancelButton
   155   }
   160   }
   156   
   161 
   157   contents = new BorderPanel {
   162   contents = new BorderPanel {
   158     border = new EmptyBorder(5, 5, 5, 5)
   163     border = new EmptyBorder(5, 5, 5, 5)
   159 
   164 
   160     add(new ScrollPane(filterPanel), BorderPanel.Position.Center)
   165     add(new ScrollPane(filterPanel), BorderPanel.Position.Center)
   161     add(botPanel, BorderPanel.Position.South)
   166     add(botPanel, BorderPanel.Position.South)
   163 
   168 
   164   private class Mutator_Panel(initials: Mutator_Markup)
   169   private class Mutator_Panel(initials: Mutator_Markup)
   165     extends BoxPanel(Orientation.Horizontal)
   170     extends BoxPanel(Orientation.Horizontal)
   166   {
   171   {
   167     private val (_enabled, _color, _mutator) = initials
   172     private val (_enabled, _color, _mutator) = initials
   168     
   173 
   169     private val inputs: List[(String, Mutator_Input_Value)] = get_Inputs()
   174     private val inputs: List[(String, Mutator_Input_Value)] = get_Inputs()
   170     var focusList = List.empty[java.awt.Component]
   175     var focusList = List.empty[java.awt.Component]
   171     private val enabledBox = new iCheckBox("Enabled", _enabled)
   176     private val enabledBox = new iCheckBox("Enabled", _enabled)
   172 
   177 
   173     border = new EmptyBorder(5, 5, 5, 5)
   178     border = new EmptyBorder(5, 5, 5, 5)
   181     }
   186     }
   182     contents += Swing.RigidBox(new Dimension(10, 0))
   187     contents += Swing.RigidBox(new Dimension(10, 0))
   183     contents += enabledBox
   188     contents += enabledBox
   184     contents += Swing.RigidBox(new Dimension(5, 0))
   189     contents += Swing.RigidBox(new Dimension(5, 0))
   185     focusList = enabledBox.peer :: focusList
   190     focusList = enabledBox.peer :: focusList
   186     inputs.map( _ match {
   191     inputs.map(_ match {
   187       case (n, c) => {
   192       case (n, c) =>
   188           contents += Swing.RigidBox(new Dimension(10, 0))
   193         contents += Swing.RigidBox(new Dimension(10, 0))
   189         if (n != "") {
   194         if (n != "") {
   190           contents += new Label(n)
   195           contents += new Label(n)
   191           contents += Swing.RigidBox(new Dimension(5, 0))
   196           contents += Swing.RigidBox(new Dimension(5, 0))
   192         }
   197         }
   193         contents += c.asInstanceOf[Component]
   198         contents += c.asInstanceOf[Component]
   194         
   199 
   195         focusList = c.asInstanceOf[Component].peer :: focusList
   200         focusList = c.asInstanceOf[Component].peer :: focusList
   196       }
       
   197       case _ =>
   201       case _ =>
   198     })
   202     })
   199 
   203 
   200     {
   204     {
   201       val t = this
   205       val t = this
   247       }
   251       }
   248     }
   252     }
   249 
   253 
   250     focusList = focusList.reverse
   254     focusList = focusList.reverse
   251 
   255 
   252     private def isRegex(regex: String): Boolean = {
   256     private def isRegex(regex: String): Boolean =
   253       try {
   257     {
   254         regex.r
   258       try { regex.r; true }
   255 
   259       catch { case _: java.util.regex.PatternSyntaxException =>  false }
   256         true
   260     }
   257       } catch {
   261 
   258         case _: java.util.regex.PatternSyntaxException =>  false
   262     def get_Mutator_Markup: Mutator_Markup =
   259       }
   263     {
   260     }
   264       def regexOrElse(regex: String, orElse: String): String =
   261    
   265       {
   262     def get_Mutator_Markup: Mutator_Markup = {
       
   263       def regexOrElse(regex: String, orElse: String): String = {
       
   264         if (isRegex(regex)) regex
   266         if (isRegex(regex)) regex
   265         else orElse
   267         else orElse
   266       }
   268       }
   267       
   269 
   268       val m = _mutator match {
   270       val m = _mutator match
       
   271       {
   269         case Identity() =>
   272         case Identity() =>
   270           Identity()
   273           Identity()
   271         case Node_Expression(r, _, _, _) =>
   274         case Node_Expression(r, _, _, _) =>
   272           Node_Expression(
   275           Node_Expression(
   273             regexOrElse(inputs(2)._2.getString, r),
   276             regexOrElse(inputs(2)._2.getString, r),
   274             inputs(3)._2.getBool,
   277             inputs(3)._2.getBool,
   275             // "Parents" means "Show parents" or "Matching Children"
   278             // "Parents" means "Show parents" or "Matching Children"
   276             inputs(1)._2.getBool,
   279             inputs(1)._2.getBool,
   277             inputs(0)._2.getBool
   280             inputs(0)._2.getBool)
   278           )
       
   279         case Node_List(_, _, _, _) =>
   281         case Node_List(_, _, _, _) =>
   280           Node_List(
   282           Node_List(
   281             inputs(2)._2.getString.split(',').filter(_ != "").toList,
   283             inputs(2)._2.getString.split(',').filter(_ != "").toList,
   282             inputs(3)._2.getBool,
   284             inputs(3)._2.getBool,
   283             // "Parents" means "Show parents" or "Matching Children"
   285             // "Parents" means "Show parents" or "Matching Children"
   284             inputs(1)._2.getBool,
   286             inputs(1)._2.getBool,
   285             inputs(0)._2.getBool
   287             inputs(0)._2.getBool)
   286           )
       
   287         case Edge_Endpoints(_, _) =>
   288         case Edge_Endpoints(_, _) =>
   288           Edge_Endpoints(
   289           Edge_Endpoints(
   289             inputs(0)._2.getString,
   290             inputs(0)._2.getString,
   290             inputs(1)._2.getString
   291             inputs(1)._2.getString)
   291           )
       
   292         case Add_Node_Expression(r) =>
   292         case Add_Node_Expression(r) =>
   293           Add_Node_Expression(
   293           Add_Node_Expression(regexOrElse(inputs(0)._2.getString, r))
   294             regexOrElse(inputs(0)._2.getString, r)
       
   295           )
       
   296         case Add_Transitive_Closure(_, _) =>
   294         case Add_Transitive_Closure(_, _) =>
   297           Add_Transitive_Closure(
   295           Add_Transitive_Closure(
   298             inputs(0)._2.getBool,
   296             inputs(0)._2.getBool,
   299             inputs(1)._2.getBool
   297             inputs(1)._2.getBool)
   300           )
       
   301         case _ =>
   298         case _ =>
   302           Identity()
   299           Identity()
   303       }
   300       }
   304       
   301 
   305       (enabledBox.selected, background, m)
   302       (enabledBox.selected, background, m)
   306     }
   303     }
   307     
   304 
   308     private def get_Inputs(): List[(String, Mutator_Input_Value)] = _mutator match {
   305     private def get_Inputs(): List[(String, Mutator_Input_Value)] =
   309       case Node_Expression(regex, reverse, check_parents, check_children) =>
   306       _mutator match {
   310         List(
   307         case Node_Expression(regex, reverse, check_parents, check_children) =>
   311           ("", new iCheckBox("Parents", check_children)),
   308           List(
   312           ("", new iCheckBox("Children", check_parents)),
   309             ("", new iCheckBox("Parents", check_children)),
   313           ("Regex", new iTextField(regex, x => !isRegex(x))),
   310             ("", new iCheckBox("Children", check_parents)),
   314           ("", new iCheckBox(reverse_caption, reverse))
   311             ("Regex", new iTextField(regex, x => !isRegex(x))),
   315         )
   312             ("", new iCheckBox(reverse_caption, reverse)))
   316       case Node_List(list, reverse, check_parents, check_children) =>
   313         case Node_List(list, reverse, check_parents, check_children) =>
   317         List(
   314           List(
   318           ("", new iCheckBox("Parents", check_children)),
   315             ("", new iCheckBox("Parents", check_children)),
   319           ("", new iCheckBox("Children", check_parents)),
   316             ("", new iCheckBox("Children", check_parents)),
   320           ("Names", new iTextField(list.mkString(","))),
   317             ("Names", new iTextField(list.mkString(","))),
   321           ("", new iCheckBox(reverse_caption, reverse))
   318             ("", new iCheckBox(reverse_caption, reverse)))
   322         )
   319         case Edge_Endpoints(source, dest) =>
   323       case Edge_Endpoints(source, dest) =>
   320           List(
   324         List(
   321             ("Source", new iTextField(source)),
   325           ("Source", new iTextField(source)),
   322             ("Destination", new iTextField(dest)))
   326           ("Destination", new iTextField(dest))
   323         case Add_Node_Expression(regex) =>
   327         )
   324           List(("Regex", new iTextField(regex, x => !isRegex(x))))
   328       case Add_Node_Expression(regex) =>
   325         case Add_Transitive_Closure(parents, children) =>
   329         List(
   326           List(
   330           ("Regex", new iTextField(regex, x => !isRegex(x)))
   327             ("", new iCheckBox("Parents", parents)),
   331         )
   328             ("", new iCheckBox("Children", children)))
   332       case Add_Transitive_Closure(parents, children) =>
   329         case _ => Nil
   333         List(
   330       }
   334           ("", new iCheckBox("Parents", parents)),
       
   335           ("", new iCheckBox("Children", children))
       
   336         )
       
   337       case _ => Nil
       
   338     }
       
   339   }
   331   }
   340 
   332 
   341   private trait Mutator_Input_Value
   333   private trait Mutator_Input_Value
   342   {
   334   {
   343     def getString: String
   335     def getString: String
   349   {
   341   {
   350     def this(t: String) = this(t, x => false)
   342     def this(t: String) = this(t, x => false)
   351 
   343 
   352     preferredSize = new Dimension(125, 18)
   344     preferredSize = new Dimension(125, 18)
   353 
   345 
   354     reactions += {
   346     reactions +=
       
   347     {
   355       case ValueChanged(_) =>
   348       case ValueChanged(_) =>
   356           if (colorator(text))
   349         if (colorator(text)) background = Color.RED
   357             background = Color.RED
   350         else background = Color.WHITE
   358           else
       
   359             background = Color.WHITE
       
   360     }
   351     }
   361 
   352 
   362     def getString = text
   353     def getString = text
   363     def getBool = true
   354     def getBool = true
   364   }
   355   }
   370 
   361 
   371     def getString = ""
   362     def getString = ""
   372     def getBool = selected
   363     def getBool = selected
   373   }
   364   }
   374 
   365 
   375   private object focusTraversal
   366   private object focusTraversal extends FocusTraversalPolicy
   376     extends FocusTraversalPolicy
       
   377   {
   367   {
   378     private var items = Vector[java.awt.Component]()
   368     private var items = Vector[java.awt.Component]()
   379 
   369 
   380     def add(c: java.awt.Component) {
   370     def add(c: java.awt.Component) { items = items :+ c }
   381       items = items :+ c
   371     def addAll(cs: TraversableOnce[java.awt.Component]) { items = items ++ cs }
   382     }
   372     def clear() { items = Vector[java.awt.Component]() }
   383     def addAll(cs: TraversableOnce[java.awt.Component]) {
   373 
   384       items = items ++ cs
   374     def getComponentAfter(root: java.awt.Container, c: java.awt.Component): java.awt.Component =
   385     }
   375     {
   386     def clear() {
       
   387       items = Vector[java.awt.Component]()
       
   388     }
       
   389 
       
   390     def getComponentAfter(root: java.awt.Container,
       
   391                           c: java.awt.Component): java.awt.Component = {
       
   392       val i = items.indexOf(c)
   376       val i = items.indexOf(c)
   393       if (i < 0) {
   377       if (i < 0) getDefaultComponent(root)
   394         getDefaultComponent(root)
   378       else items((i + 1) % items.length)
   395       } else {
   379     }
   396         items((i + 1) % items.length)
   380 
   397       }
   381     def getComponentBefore(root: java.awt.Container, c: java.awt.Component): java.awt.Component =
   398     }
   382     {
   399 
       
   400     def getComponentBefore(root: java.awt.Container,
       
   401                            c: java.awt.Component): java.awt.Component = {
       
   402       val i = items.indexOf(c)
   383       val i = items.indexOf(c)
   403       if (i < 0) {
   384       if (i < 0) getDefaultComponent(root)
   404         getDefaultComponent(root)
   385       else items((i - 1) % items.length)
   405       } else {
   386     }
   406         items((i - 1) % items.length)
   387 
   407       }
   388     def getFirstComponent(root: java.awt.Container): java.awt.Component =
   408     }
   389       if (items.length > 0) items(0) else null
   409 
   390 
   410     def getFirstComponent(root: java.awt.Container): java.awt.Component = {
   391     def getDefaultComponent(root: java.awt.Container): java.awt.Component =
   411       if (items.length > 0)
   392       getFirstComponent(root)
   412         items(0)
   393 
   413       else
   394     def getLastComponent(root: java.awt.Container): java.awt.Component =
   414         null
   395       if (items.length > 0) items.last else null
   415     }
       
   416 
       
   417     def getDefaultComponent(root: java.awt.Container)
       
   418       : java.awt.Component = getFirstComponent(root)
       
   419 
       
   420     def getLastComponent(root: java.awt.Container): java.awt.Component = {
       
   421       if (items.length > 0)
       
   422         items.last
       
   423       else
       
   424         null
       
   425     }
       
   426   }
   396   }
   427 }
   397 }