src/Tools/Graphview/src/visualizer.scala
author wenzelm
Mon, 10 Dec 2012 19:42:58 +0100
changeset 50467 4b0e69dc9db8
parent 50465 0afb01666df2
child 50470 cb73e91bb019
permissions -rw-r--r--
tuned;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     1
/*  Title:      Tools/Graphview/src/visualizer.scala
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     2
    Author:     Markus Kaiser, TU Muenchen
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     3
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     4
Graph visualization interface.
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     5
*/
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     6
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     7
package isabelle.graphview
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     8
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
     9
49565
ea4308b7ef0f ML support for generic graph display, with browser and graphview backends (via print modes);
wenzelm
parents: 49557
diff changeset
    10
import isabelle._
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    11
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
    12
50465
wenzelm
parents: 50464
diff changeset
    13
import java.awt.{Font, Color => JColor, Shape}
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    14
import java.awt.{RenderingHints, Graphics2D}
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49573
diff changeset
    15
import javax.swing.JComponent
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    16
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    17
50465
wenzelm
parents: 50464
diff changeset
    18
class Visualizer(val model: Model)
wenzelm
parents: 50464
diff changeset
    19
{
wenzelm
parents: 50464
diff changeset
    20
  object Coordinates
wenzelm
parents: 50464
diff changeset
    21
  {
wenzelm
parents: 50464
diff changeset
    22
    private var nodes = Map.empty[String, (Double, Double)]
wenzelm
parents: 50464
diff changeset
    23
    private var dummies = Map.empty[(String, String), List[(Double, Double)]]
wenzelm
parents: 50464
diff changeset
    24
wenzelm
parents: 50464
diff changeset
    25
    def apply(k: String): (Double, Double) =
wenzelm
parents: 50464
diff changeset
    26
      nodes.get(k) match {
wenzelm
parents: 50464
diff changeset
    27
        case Some(c) => c
wenzelm
parents: 50464
diff changeset
    28
        case None => (0, 0)
wenzelm
parents: 50464
diff changeset
    29
      }
wenzelm
parents: 50464
diff changeset
    30
wenzelm
parents: 50464
diff changeset
    31
    def apply(e: (String, String)): List[(Double, Double)] =
wenzelm
parents: 50464
diff changeset
    32
      dummies.get(e) match {
wenzelm
parents: 50464
diff changeset
    33
        case Some(ds) => ds
wenzelm
parents: 50464
diff changeset
    34
        case None => Nil
wenzelm
parents: 50464
diff changeset
    35
      }
wenzelm
parents: 50464
diff changeset
    36
wenzelm
parents: 50464
diff changeset
    37
    def reposition(k: String, to: (Double, Double))
wenzelm
parents: 50464
diff changeset
    38
    {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    39
      nodes += (k -> to)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    40
    }
50465
wenzelm
parents: 50464
diff changeset
    41
wenzelm
parents: 50464
diff changeset
    42
    def reposition(d: ((String, String), Int), to: (Double, Double))
wenzelm
parents: 50464
diff changeset
    43
    {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    44
      val (e, index) = d
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    45
      dummies.get(e) match {
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    46
        case None =>
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    47
        case Some(ds) =>
50465
wenzelm
parents: 50464
diff changeset
    48
          dummies += (e ->
50467
wenzelm
parents: 50465
diff changeset
    49
            (ds.zipWithIndex :\ List.empty[(Double, Double)]) {
50465
wenzelm
parents: 50464
diff changeset
    50
              case ((t, i), n) => if (index == i) to :: n else t :: n
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    51
            }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    52
          )
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    53
      }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    54
    }
50465
wenzelm
parents: 50464
diff changeset
    55
wenzelm
parents: 50464
diff changeset
    56
    def translate(k: String, by: (Double, Double))
wenzelm
parents: 50464
diff changeset
    57
    {
wenzelm
parents: 50464
diff changeset
    58
      val ((x, y), (dx, dy)) = (Coordinates(k), by)
wenzelm
parents: 50464
diff changeset
    59
      reposition(k, (x + dx, y + dy))
wenzelm
parents: 50464
diff changeset
    60
    }
wenzelm
parents: 50464
diff changeset
    61
wenzelm
parents: 50464
diff changeset
    62
    def translate(d: ((String, String), Int), by: (Double, Double))
wenzelm
parents: 50464
diff changeset
    63
    {
wenzelm
parents: 50464
diff changeset
    64
      val ((e, i),(dx, dy)) = (d, by)
wenzelm
parents: 50464
diff changeset
    65
      val (x, y) = apply(e)(i)
wenzelm
parents: 50464
diff changeset
    66
      reposition(d, (x + dx, y + dy))
wenzelm
parents: 50464
diff changeset
    67
    }
wenzelm
parents: 50464
diff changeset
    68
wenzelm
parents: 50464
diff changeset
    69
    def layout()
wenzelm
parents: 50464
diff changeset
    70
    {
50467
wenzelm
parents: 50465
diff changeset
    71
      val (l, d) = Layout_Pendulum(model.current)  // FIXME avoid computation on Swing thread
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    72
      nodes = l
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    73
      dummies = d
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    74
    }
50465
wenzelm
parents: 50464
diff changeset
    75
wenzelm
parents: 50464
diff changeset
    76
    def bounds(): (Double, Double, Double, Double) =
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    77
      model.visible_nodes().toList match {
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    78
        case Nil => (0, 0, 0, 0)
50465
wenzelm
parents: 50464
diff changeset
    79
        case nodes =>
wenzelm
parents: 50464
diff changeset
    80
          val X: (String => Double) = (n => apply(n)._1)
wenzelm
parents: 50464
diff changeset
    81
          val Y: (String => Double) = (n => apply(n)._2)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    82
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    83
          (X(nodes.minBy(X)), Y(nodes.minBy(Y)),
50465
wenzelm
parents: 50464
diff changeset
    84
           X(nodes.maxBy(X)), Y(nodes.maxBy(Y)))
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    85
      }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    86
  }
50465
wenzelm
parents: 50464
diff changeset
    87
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    88
  private val visualizer = this
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
    89
  object Drawer
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
    90
  {
50465
wenzelm
parents: 50464
diff changeset
    91
    def apply(g: Graphics2D, n: Option[String])
wenzelm
parents: 50464
diff changeset
    92
    {
wenzelm
parents: 50464
diff changeset
    93
      n match {
wenzelm
parents: 50464
diff changeset
    94
        case None =>
wenzelm
parents: 50464
diff changeset
    95
        case Some(_) => Shapes.Growing_Node.paint(g, visualizer, n)
wenzelm
parents: 50464
diff changeset
    96
      }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    97
    }
50465
wenzelm
parents: 50464
diff changeset
    98
wenzelm
parents: 50464
diff changeset
    99
    def apply(g: Graphics2D, e: (String, String), head: Boolean, dummies: Boolean)
wenzelm
parents: 50464
diff changeset
   100
    {
wenzelm
parents: 50464
diff changeset
   101
      Shapes.Cardinal_Spline_Edge.paint(g, visualizer, e, head, dummies)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   102
    }
50465
wenzelm
parents: 50464
diff changeset
   103
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   104
    def paint_all_visible(g: Graphics2D, dummies: Boolean)
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   105
    {
50465
wenzelm
parents: 50464
diff changeset
   106
      g.setFont(font)
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   107
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   108
      g.setRenderingHints(rendering_hints)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   109
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   110
      model.visible_edges().foreach(e => {
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   111
          apply(g, e, Parameters.arrow_heads, dummies)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   112
        })
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   113
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   114
      model.visible_nodes().foreach(l => {
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   115
          apply(g, Some(l))
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   116
        })
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   117
    }
50465
wenzelm
parents: 50464
diff changeset
   118
wenzelm
parents: 50464
diff changeset
   119
    def shape(g: Graphics2D, n: Option[String]): Shape =
wenzelm
parents: 50464
diff changeset
   120
      n match {
wenzelm
parents: 50464
diff changeset
   121
        case None => Shapes.Dummy.shape(g, visualizer, None)
wenzelm
parents: 50464
diff changeset
   122
        case Some(_) => Shapes.Growing_Node.shape(g, visualizer, n)
wenzelm
parents: 50464
diff changeset
   123
      }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   124
  }
50465
wenzelm
parents: 50464
diff changeset
   125
wenzelm
parents: 50464
diff changeset
   126
  object Selection
wenzelm
parents: 50464
diff changeset
   127
  {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   128
    private var selected: List[String] = Nil
50465
wenzelm
parents: 50464
diff changeset
   129
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   130
    def apply() = selected
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   131
    def apply(s: String) = selected.contains(s)
50465
wenzelm
parents: 50464
diff changeset
   132
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   133
    def add(s: String) { selected = s :: selected }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   134
    def set(ss: List[String]) { selected = ss }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   135
    def clear() { selected = Nil }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   136
  }
50465
wenzelm
parents: 50464
diff changeset
   137
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   138
  object Color
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   139
  {
50465
wenzelm
parents: 50464
diff changeset
   140
    def apply(l: Option[String]): (JColor, JColor, JColor) =
wenzelm
parents: 50464
diff changeset
   141
      l match {
wenzelm
parents: 50464
diff changeset
   142
        case None => (JColor.GRAY, JColor.WHITE, JColor.BLACK)
wenzelm
parents: 50464
diff changeset
   143
        case Some(c) => {
wenzelm
parents: 50464
diff changeset
   144
            if (Selection(c))
wenzelm
parents: 50464
diff changeset
   145
              (JColor.BLUE, JColor.GREEN, JColor.BLACK)
wenzelm
parents: 50464
diff changeset
   146
            else
wenzelm
parents: 50464
diff changeset
   147
              (JColor.BLACK, model.colors.getOrElse(c, JColor.WHITE), JColor.BLACK)
wenzelm
parents: 50464
diff changeset
   148
        }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   149
      }
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   150
50465
wenzelm
parents: 50464
diff changeset
   151
    def apply(e: (String, String)): JColor = JColor.BLACK
wenzelm
parents: 50464
diff changeset
   152
  }
wenzelm
parents: 50464
diff changeset
   153
wenzelm
parents: 50464
diff changeset
   154
  object Caption
50464
37b53813426f tuned signature;
wenzelm
parents: 49736
diff changeset
   155
  {
49736
dfa100466d2e clarified long_names -- conform to usual Isabelle practice of not analysing internal names;
wenzelm
parents: 49732
diff changeset
   156
    def apply(key: String) =
dfa100466d2e clarified long_names -- conform to usual Isabelle practice of not analysing internal names;
wenzelm
parents: 49732
diff changeset
   157
      if (Parameters.long_names) key
dfa100466d2e clarified long_names -- conform to usual Isabelle practice of not analysing internal names;
wenzelm
parents: 49732
diff changeset
   158
      else model.complete.get_node(key).name
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   159
  }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   160
50465
wenzelm
parents: 50464
diff changeset
   161
  val font = new Font(Parameters.font_family, Font.BOLD, Parameters.font_size)
wenzelm
parents: 50464
diff changeset
   162
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   163
  val rendering_hints =
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   164
    new RenderingHints(
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   165
      RenderingHints.KEY_ANTIALIASING,
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   166
      RenderingHints.VALUE_ANTIALIAS_ON)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   167
}