src/Tools/Graphview/graph_panel.scala
author wenzelm
Sat, 03 Jan 2015 20:22:27 +0100
changeset 59245 be4180f3c236
parent 59243 21ef04bd4e17
child 59250 abe4c7cdac0e
permissions -rw-r--r--
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge; misc tuning; tuned signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
59202
711c2446dc9d clarified source location;
wenzelm
parents: 57044
diff changeset
     1
/*  Title:      Tools/Graphview/graph_panel.scala
49557
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
59240
e411afcfaa29 tuned headers;
wenzelm
parents: 59239
diff changeset
     3
    Author:     Makarius
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     4
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     5
Graphview Java2D drawing panel.
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
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     8
package isabelle.graphview
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
     9
55618
995162143ef4 tuned imports;
wenzelm
parents: 51616
diff changeset
    10
49558
af7b652180d5 minimal component and build setup for graphview;
wenzelm
parents: 49557
diff changeset
    11
import isabelle._
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    12
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
    13
import java.awt.{Dimension, Graphics2D, Point}
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.geom.{AffineTransform, Point2D}
49732
ad362eec19c3 more direct tooltip content;
wenzelm
parents: 49731
diff changeset
    15
import java.awt.image.BufferedImage
59225
d0edf67253d3 tuned imports;
wenzelm
parents: 59219
diff changeset
    16
import javax.swing.{JScrollPane, JComponent, SwingUtilities}
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    17
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    18
import scala.swing.{Panel, ScrollPane}
59239
d20cdab3bfeb less excessive event handling;
wenzelm
parents: 59238
diff changeset
    19
import scala.swing.event.{Event, Key, KeyTyped, MousePressed, MouseDragged, MouseClicked, MouseEvent}
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    20
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    21
59233
876a81f5788b tuned signature;
wenzelm
parents: 59231
diff changeset
    22
class Graph_Panel(val visualizer: Visualizer) extends ScrollPane
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    23
{
49731
wenzelm
parents: 49730
diff changeset
    24
  panel =>
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    25
59243
21ef04bd4e17 recovered tooltip from 6e77ddb1e3fb: non-null default is required as prerequisite;
wenzelm
parents: 59241
diff changeset
    26
  tooltip = ""
21ef04bd4e17 recovered tooltip from 6e77ddb1e3fb: non-null default is required as prerequisite;
wenzelm
parents: 59241
diff changeset
    27
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    28
  override lazy val peer: JScrollPane = new JScrollPane with SuperMixin {
49730
e0d98ff3c0db use Pretty_Tooltip for Graphview_Panel;
wenzelm
parents: 49729
diff changeset
    29
    override def getToolTipText(event: java.awt.event.MouseEvent): String =
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
    30
      find_node(Transform.pane_to_graph_coordinates(event.getPoint)) match {
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
    31
        case Some(node) =>
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
    32
          visualizer.model.complete_graph.get_node(node) match {
49732
ad362eec19c3 more direct tooltip content;
wenzelm
parents: 49731
diff changeset
    33
            case Nil => null
59233
876a81f5788b tuned signature;
wenzelm
parents: 59231
diff changeset
    34
            case content => visualizer.make_tooltip(panel.peer, event.getX, event.getY, content)
49732
ad362eec19c3 more direct tooltip content;
wenzelm
parents: 49731
diff changeset
    35
          }
ad362eec19c3 more direct tooltip content;
wenzelm
parents: 49731
diff changeset
    36
        case None => null
ad362eec19c3 more direct tooltip content;
wenzelm
parents: 49731
diff changeset
    37
      }
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    38
  }
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    39
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    40
  focusable = true
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    41
  requestFocus()
50470
wenzelm
parents: 50469
diff changeset
    42
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    43
  horizontalScrollBarPolicy = ScrollPane.BarPolicy.Always
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    44
  verticalScrollBarPolicy = ScrollPane.BarPolicy.Always
49729
f53a8f73b40f more basic tooltips;
wenzelm
parents: 49569
diff changeset
    45
59237
ac135eff1ffb clarified mouse wheel: conventional scrolling, not scaling;
wenzelm
parents: 59234
diff changeset
    46
  peer.getVerticalScrollBar.setUnitIncrement(10)
ac135eff1ffb clarified mouse wheel: conventional scrolling, not scaling;
wenzelm
parents: 59234
diff changeset
    47
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
    48
  def find_node(at: Point2D): Option[Graph_Display.Node] =
59231
6dea47cf6c6b more dynamic visualizer -- re-use jEdit font info;
wenzelm
parents: 59228
diff changeset
    49
  {
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
    50
    val m = visualizer.metrics()
56372
fadb0fef09d7 more explicit iterator terminology, in accordance to Scala 2.8 library;
wenzelm
parents: 55618
diff changeset
    51
    visualizer.model.visible_nodes_iterator
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
    52
      .find(node => visualizer.Drawer.shape(m, node).contains(at))
59231
6dea47cf6c6b more dynamic visualizer -- re-use jEdit font info;
wenzelm
parents: 59228
diff changeset
    53
  }
49732
ad362eec19c3 more direct tooltip content;
wenzelm
parents: 49731
diff changeset
    54
49735
30e2f3f1c623 more precise repaint and revalidate -- the latter is important to keep in sync with content update;
wenzelm
parents: 49733
diff changeset
    55
  def refresh()
30e2f3f1c623 more precise repaint and revalidate -- the latter is important to keep in sync with content update;
wenzelm
parents: 49733
diff changeset
    56
  {
50491
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
    57
    if (paint_panel != null) {
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
    58
      paint_panel.set_preferred_size()
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
    59
      paint_panel.repaint()
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
    60
    }
49735
30e2f3f1c623 more precise repaint and revalidate -- the latter is important to keep in sync with content update;
wenzelm
parents: 49733
diff changeset
    61
  }
30e2f3f1c623 more precise repaint and revalidate -- the latter is important to keep in sync with content update;
wenzelm
parents: 49733
diff changeset
    62
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    63
  def fit_to_window() = {
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    64
    Transform.fit_to_window()
49735
30e2f3f1c623 more precise repaint and revalidate -- the latter is important to keep in sync with content update;
wenzelm
parents: 49733
diff changeset
    65
    refresh()
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    66
  }
50470
wenzelm
parents: 50469
diff changeset
    67
57044
042d6e58cb40 more uniform Font_Info.Zoom_Box;
wenzelm
parents: 56372
diff changeset
    68
  val zoom = new GUI.Zoom_Box { def changed = rescale(0.01 * factor) }
50491
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
    69
50478
ccfdd1f6cf10 added explicit zoom box;
wenzelm
parents: 50477
diff changeset
    70
  def rescale(s: Double)
ccfdd1f6cf10 added explicit zoom box;
wenzelm
parents: 50477
diff changeset
    71
  {
ccfdd1f6cf10 added explicit zoom box;
wenzelm
parents: 50477
diff changeset
    72
    Transform.scale = s
57044
042d6e58cb40 more uniform Font_Info.Zoom_Box;
wenzelm
parents: 56372
diff changeset
    73
    if (zoom != null) zoom.set_item((Transform.scale_discrete * 100).round.toInt)
50478
ccfdd1f6cf10 added explicit zoom box;
wenzelm
parents: 50477
diff changeset
    74
    refresh()
ccfdd1f6cf10 added explicit zoom box;
wenzelm
parents: 50477
diff changeset
    75
  }
ccfdd1f6cf10 added explicit zoom box;
wenzelm
parents: 50477
diff changeset
    76
50470
wenzelm
parents: 50469
diff changeset
    77
  def apply_layout() = visualizer.Coordinates.update_layout()
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    78
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    79
  private class Paint_Panel extends Panel
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    80
  {
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    81
    def set_preferred_size()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    82
    {
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
    83
      val box = visualizer.Coordinates.bounding_box()
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    84
      val s = Transform.scale_discrete
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    85
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    86
      preferredSize =
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
    87
        new Dimension((box.width * s).ceil.toInt, (box.height * s).ceil.toInt)
50470
wenzelm
parents: 50469
diff changeset
    88
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    89
      revalidate()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    90
    }
50470
wenzelm
parents: 50469
diff changeset
    91
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    92
    override def paint(g: Graphics2D)
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
    93
    {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    94
      super.paintComponent(g)
59234
ef8104d6deb6 tuned color;
wenzelm
parents: 59233
diff changeset
    95
      g.setColor(visualizer.background_color)
ef8104d6deb6 tuned color;
wenzelm
parents: 59233
diff changeset
    96
      g.fillRect(0, 0, peer.getWidth, peer.getHeight)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
    97
      g.transform(Transform())
50470
wenzelm
parents: 50469
diff changeset
    98
49731
wenzelm
parents: 49730
diff changeset
    99
      visualizer.Drawer.paint_all_visible(g, true)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   100
    }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   101
  }
49954
44658062d822 more explicit auxiliary classes to avoid warning "reflective access of structural type member method" of scala-2.10.0-RC1;
wenzelm
parents: 49745
diff changeset
   102
  private val paint_panel = new Paint_Panel
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   103
  contents = paint_panel
50470
wenzelm
parents: 50469
diff changeset
   104
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   105
  listenTo(keys)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   106
  listenTo(mouse.moves)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   107
  listenTo(mouse.clicks)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   108
  reactions += Interaction.Mouse.react
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   109
  reactions += Interaction.Keyboard.react
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   110
  reactions +=
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   111
  {
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   112
    case KeyTyped(_, _, _, _) => repaint(); requestFocus()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   113
    case MousePressed(_, _, _, _, _) => repaint(); requestFocus()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   114
    case MouseDragged(_, _, _) => repaint(); requestFocus()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   115
    case MouseClicked(_, _, _, _, _) => repaint(); requestFocus()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   116
  }
49733
38a68e6593be prefer synchronous Mutator_Event.Bus on Swing_Thread;
wenzelm
parents: 49732
diff changeset
   117
38a68e6593be prefer synchronous Mutator_Event.Bus on Swing_Thread;
wenzelm
parents: 49732
diff changeset
   118
  visualizer.model.Colors.events += { case _ => repaint() }
38a68e6593be prefer synchronous Mutator_Event.Bus on Swing_Thread;
wenzelm
parents: 49732
diff changeset
   119
  visualizer.model.Mutators.events += { case _ => repaint() }
50470
wenzelm
parents: 50469
diff changeset
   120
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   121
  apply_layout()
50491
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
   122
  rescale(1.0)
50470
wenzelm
parents: 50469
diff changeset
   123
50469
wenzelm
parents: 50468
diff changeset
   124
  private object Transform
wenzelm
parents: 50468
diff changeset
   125
  {
50474
6ee044e2d1a7 initial layout coordinates more like old browser;
wenzelm
parents: 50470
diff changeset
   126
    private var _scale: Double = 1.0
50477
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   127
    def scale: Double = _scale
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   128
    def scale_=(s: Double)
50468
7a2a4b84c5ee tuned min/max;
wenzelm
parents: 50465
diff changeset
   129
    {
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
   130
      _scale = (s min 10.0) max 0.1
50468
7a2a4b84c5ee tuned min/max;
wenzelm
parents: 50465
diff changeset
   131
    }
50477
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   132
    def scale_discrete: Double =
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   133
      (_scale * visualizer.font_size).round.toDouble / visualizer.font_size
50470
wenzelm
parents: 50469
diff changeset
   134
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   135
    def apply() =
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   136
    {
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
   137
      val box = visualizer.Coordinates.bounding_box()
50477
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   138
      val at = AffineTransform.getScaleInstance(scale_discrete, scale_discrete)
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
   139
      at.translate(- box.x, - box.y)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   140
      at
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   141
    }
50470
wenzelm
parents: 50469
diff changeset
   142
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   143
    def fit_to_window()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   144
    {
56372
fadb0fef09d7 more explicit iterator terminology, in accordance to Scala 2.8 library;
wenzelm
parents: 55618
diff changeset
   145
      if (visualizer.model.visible_nodes_iterator.isEmpty)
50491
0faaa279faee improved coupling of zoom_box and scale;
wenzelm
parents: 50478
diff changeset
   146
        rescale(1.0)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   147
      else {
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
   148
        val box = visualizer.Coordinates.bounding_box()
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
   149
        rescale((size.width / box.width) min (size.height / box.height))
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   150
      }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   151
    }
50470
wenzelm
parents: 50469
diff changeset
   152
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   153
    def pane_to_graph_coordinates(at: Point2D): Point2D =
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   154
    {
50477
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   155
      val s = Transform.scale_discrete
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   156
      val p = Transform().inverseTransform(peer.getViewport.getViewPosition, null)
50470
wenzelm
parents: 50469
diff changeset
   157
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   158
      p.setLocation(p.getX + at.getX / s, p.getY + at.getY / s)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   159
      p
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   160
    }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   161
  }
50470
wenzelm
parents: 50469
diff changeset
   162
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   163
  object Interaction
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   164
  {
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   165
    object Keyboard
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   166
    {
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   167
      val react: PartialFunction[Event, Unit] =
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   168
      {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   169
        case KeyTyped(_, c, m, _) => typed(c, m)
50470
wenzelm
parents: 50469
diff changeset
   170
      }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   171
59225
d0edf67253d3 tuned imports;
wenzelm
parents: 59219
diff changeset
   172
      def typed(c: Char, m: Key.Modifiers) =
59226
wenzelm
parents: 59225
diff changeset
   173
        c match {
wenzelm
parents: 59225
diff changeset
   174
          case '+' => rescale(Transform.scale * 5.0/4)
wenzelm
parents: 59225
diff changeset
   175
          case '-' => rescale(Transform.scale * 4.0/5)
wenzelm
parents: 59225
diff changeset
   176
          case '0' => Transform.fit_to_window()
59238
wenzelm
parents: 59237
diff changeset
   177
          case '1' => apply_layout()
50470
wenzelm
parents: 50469
diff changeset
   178
          case _ =>
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   179
        }
50470
wenzelm
parents: 50469
diff changeset
   180
    }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   181
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   182
    object Mouse
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   183
    {
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   184
      type Dummy = (Graph_Display.Edge, Int)
50470
wenzelm
parents: 50469
diff changeset
   185
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   186
      private var draginfo: (Point, List[Graph_Display.Node], List[Dummy]) = null
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   187
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   188
      val react: PartialFunction[Event, Unit] =
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   189
      {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   190
        case MousePressed(_, p, _, _, _) => pressed(p)
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   191
        case MouseDragged(_, to, _) =>
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   192
          drag(draginfo, to)
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   193
          val (_, p, d) = draginfo
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   194
          draginfo = (to, p, d)
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   195
        case e @ MouseClicked(_, p, m, n, _) => click(p, m, n, e)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   196
      }
50470
wenzelm
parents: 50469
diff changeset
   197
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   198
      def dummy(at: Point2D): Option[Dummy] =
59231
6dea47cf6c6b more dynamic visualizer -- re-use jEdit font info;
wenzelm
parents: 59228
diff changeset
   199
      {
59241
541b95e94dc7 clarified bounding box, similar to old graph browser;
wenzelm
parents: 59240
diff changeset
   200
        val m = visualizer.metrics()
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   201
        visualizer.model.visible_edges_iterator.map(
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   202
          edge => visualizer.Coordinates(edge).zipWithIndex.map((edge, _))).flatten.find(
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   203
            {
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   204
              case (_, ((x, y), _)) =>
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   205
                visualizer.Drawer.shape(m, Graph_Display.Node.dummy).
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   206
                  contains(at.getX() - x, at.getY() - y)
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   207
            }) match {
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   208
              case None => None
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   209
              case Some((edge, (_, index))) => Some((edge, index))
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   210
            }
59231
6dea47cf6c6b more dynamic visualizer -- re-use jEdit font info;
wenzelm
parents: 59228
diff changeset
   211
      }
50470
wenzelm
parents: 50469
diff changeset
   212
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   213
      def pressed(at: Point)
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   214
      {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   215
        val c = Transform.pane_to_graph_coordinates(at)
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   216
        val l =
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   217
          find_node(c) match {
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   218
            case Some(node) =>
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   219
              if (visualizer.Selection.contains(node)) visualizer.Selection.get()
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   220
              else List(node)
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   221
            case None => Nil
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   222
          }
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   223
        val d =
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   224
          l match {
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   225
            case Nil =>
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   226
              dummy(c) match {
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   227
                case Some(d) => List(d)
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   228
                case None => Nil
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   229
              }
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   230
            case _ => Nil
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   231
          }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   232
        draginfo = (at, l, d)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   233
      }
50470
wenzelm
parents: 50469
diff changeset
   234
59225
d0edf67253d3 tuned imports;
wenzelm
parents: 59219
diff changeset
   235
      def click(at: Point, m: Key.Modifiers, clicks: Int, e: MouseEvent)
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   236
      {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   237
        val c = Transform.pane_to_graph_coordinates(at)
50470
wenzelm
parents: 50469
diff changeset
   238
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   239
        def left_click()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   240
        {
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   241
          (find_node(c), m) match {
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   242
            case (Some(node), Key.Modifier.Control) => visualizer.Selection.add(node)
59225
d0edf67253d3 tuned imports;
wenzelm
parents: 59219
diff changeset
   243
            case (None, Key.Modifier.Control) =>
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   244
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   245
            case (Some(node), Key.Modifier.Shift) => visualizer.Selection.add(node)
59225
d0edf67253d3 tuned imports;
wenzelm
parents: 59219
diff changeset
   246
            case (None, Key.Modifier.Shift) =>
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   247
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   248
            case (Some(node), _) =>
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   249
              visualizer.Selection.clear()
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   250
              visualizer.Selection.add(node)
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   251
            case (None, _) =>
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   252
              visualizer.Selection.clear()
50470
wenzelm
parents: 50469
diff changeset
   253
          }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   254
        }
50470
wenzelm
parents: 50469
diff changeset
   255
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   256
        def right_click()
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   257
        {
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   258
          val menu = Popups(panel, find_node(c), visualizer.Selection.get())
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   259
          menu.show(panel.peer, at.x, at.y)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   260
        }
50470
wenzelm
parents: 50469
diff changeset
   261
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   262
        if (clicks < 2) {
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   263
          if (SwingUtilities.isRightMouseButton(e.peer)) right_click()
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   264
          else left_click()
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   265
        }
50470
wenzelm
parents: 50469
diff changeset
   266
      }
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   267
59245
be4180f3c236 more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
wenzelm
parents: 59243
diff changeset
   268
      def drag(draginfo: (Point, List[Graph_Display.Node], List[Dummy]), to: Point)
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   269
      {
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   270
        val (from, p, d) = draginfo
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   271
50477
ffa18243a4e3 some attempts at more discrete scale factor;
wenzelm
parents: 50476
diff changeset
   272
        val s = Transform.scale_discrete
50470
wenzelm
parents: 50469
diff changeset
   273
        val (dx, dy) = (to.x - from.x, to.y - from.y)
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   274
        (p, d) match {
59218
eadd82d440b0 tuned whitespace;
wenzelm
parents: 59202
diff changeset
   275
          case (Nil, Nil) =>
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   276
            val r = panel.peer.getViewport.getViewRect
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   277
            r.translate(-dx, -dy)
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   278
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   279
            paint_panel.peer.scrollRectToVisible(r)
50470
wenzelm
parents: 50469
diff changeset
   280
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   281
          case (Nil, ds) =>
49731
wenzelm
parents: 49730
diff changeset
   282
            ds.foreach(d => visualizer.Coordinates.translate(d, (dx / s, dy / s)))
50470
wenzelm
parents: 50469
diff changeset
   283
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   284
          case (ls, _) =>
49731
wenzelm
parents: 49730
diff changeset
   285
            ls.foreach(l => visualizer.Coordinates.translate(l, (dx / s, dy / s)))
49557
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   286
        }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   287
      }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   288
    }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   289
  }
61988f9df94d added Graphview tool, based on Isabelle/Scala and Swing/Graphics2D;
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
   290
}