src/Tools/jEdit/src/jedit/ScrollerDockable.scala
author wenzelm
Sat, 27 Dec 2008 14:13:05 +0100
changeset 34440 561a6d19bd95
parent 34438 2faedc70b52d
child 34456 14367c0715e8
permissions -rw-r--r--
renamed object Plugin to Isabelle; renamed Plugin.self to Isabelle.plugin; renamed Isabelle.plugin.symbols to Isabelle.symbols;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
     1
/*
34408
ad7b6c4813c8 added some headers and comments;
wenzelm
parents: 34406
diff changeset
     2
 * Dockable window with scrollable messages
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
     3
 *
34408
ad7b6c4813c8 added some headers and comments;
wenzelm
parents: 34406
diff changeset
     4
 * @author Fabian Immler, TU Munich
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
     5
 */
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
     6
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
     7
package isabelle.jedit
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
     8
34424
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
     9
34376
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
    10
import isabelle.IsabelleProcess.Result
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
    11
import isabelle.YXML.parse_failsafe
34431
wenzelm
parents: 34424
diff changeset
    12
import isabelle.utils.EventSource
34438
2faedc70b52d proper import isabelle.renderer.UserAgent;
wenzelm
parents: 34434
diff changeset
    13
import isabelle.renderer.UserAgent
2faedc70b52d proper import isabelle.renderer.UserAgent;
wenzelm
parents: 34434
diff changeset
    14
34370
e0679b361a0e register to buffer all messages
immler@in.tum.de
parents: 34369
diff changeset
    15
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    16
import scala.collection.mutable.{ArrayBuffer, HashMap}
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    17
34424
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
    18
import java.awt.{BorderLayout, Adjustable, Dimension}
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
    19
import java.awt.event.{ActionListener, ActionEvent, AdjustmentListener, AdjustmentEvent, ComponentListener, ComponentEvent}
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
    20
import javax.swing.{JFrame, JPanel, JRadioButton, JScrollBar, JTextArea, Timer}
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    21
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    22
import org.w3c.dom.Document
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    23
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    24
import org.xhtmlrenderer.simple.XHTMLPanel
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    25
import org.xhtmlrenderer.context.AWTFontResolver
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    26
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    27
import org.gjt.sp.jedit.View
34424
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
    28
import org.gjt.sp.jedit.gui.DockableWindowManager
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
    29
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    30
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    31
trait Renderer[U, R] {
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    32
  def render (u: U): R
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    33
  //relayout a rendered element using argument a
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    34
  def relayout (r: R, a: Int)
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    35
}
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    36
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    37
trait Unrendered[U] {
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    38
  def addUnrendered (id: Int, u: U) : Unit
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    39
  def getUnrendered (id: Int) : Option[U]
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    40
  def size : Int
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    41
}
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
    42
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    43
trait Rendered[U, R] {
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    44
  def getRendered (id: Int) : Option[R]
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    45
  val renderer : Renderer[U, R]
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    46
}
34360
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
    47
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    48
class MessagePanel(cache: Rendered[_, XHTMLPanel]) extends JPanel {
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    49
  // defining the current view
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
    50
  var offset = 0 //what percentage of the lowest message is hidden
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    51
  var no = -1  //index of the lowest message
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    52
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    53
  // preferences
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    54
  val scrollunit = 5
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    55
  setLayout(null)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    56
  
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    57
  // place the bottom of the message at y-coordinate and return the rendered panel
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    58
  def place_message (message_no: Int, y: Int) = {
34354
110f5f6902dc cleaned up a bit, scrolling arbitrary heights (incremental rendering)
immler@in.tum.de
parents: 34353
diff changeset
    59
    //add panel to cache if necessary and possible
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    60
    cache.getRendered(message_no) match {
34353
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    61
      case Some(panel) => {
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    62
        //panel has to be displayable before calculating preferred size!
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    63
        add(panel)
34354
110f5f6902dc cleaned up a bit, scrolling arbitrary heights (incremental rendering)
immler@in.tum.de
parents: 34353
diff changeset
    64
        // recalculate preferred size after resizing the message_view
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    65
        if(panel.getPreferredSize.getWidth.toInt != getWidth){
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
    66
          cache.renderer.relayout (panel, getWidth)
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    67
        }
34353
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    68
        val width = panel.getPreferredSize.getWidth.toInt
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    69
        val height = panel.getPreferredSize.getHeight.toInt
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    70
        panel.setBounds(0, y - height, width, height)
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    71
        panel
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    72
      }
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    73
      case None => null
aa0d2f0bde83 UserAgent as seperate class, moved stylesheets, baseURL to UserAgent
immler@in.tum.de
parents: 34351
diff changeset
    74
    }
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
    75
  }
34351
1c919f65c296 fine scrolling principally possible
immler@in.tum.de
parents: 34350
diff changeset
    76
  
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    77
  override def doLayout = {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    78
    removeAll()
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
    79
    //calculate offset in pixel
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
    80
    val panel = place_message(no, 0)
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
    81
    val pixeloffset = if(panel != null) panel.getHeight*offset/100 else 0
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    82
    var n = no
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
    83
    var y:Int = getHeight + pixeloffset
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
    84
    while (y >= 0 && n >= 0){
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    85
      val panel = place_message (n, y)
34370
e0679b361a0e register to buffer all messages
immler@in.tum.de
parents: 34369
diff changeset
    86
      if(panel != null) {
e0679b361a0e register to buffer all messages
immler@in.tum.de
parents: 34369
diff changeset
    87
        panel.setBorder(javax.swing.border.LineBorder.createBlackLineBorder)
e0679b361a0e register to buffer all messages
immler@in.tum.de
parents: 34369
diff changeset
    88
        y = y - panel.getHeight
e0679b361a0e register to buffer all messages
immler@in.tum.de
parents: 34369
diff changeset
    89
      }
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
    90
      n = n - 1
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
    91
    }
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    92
  }  
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    93
}
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    94
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    95
class InfoPanel extends JPanel {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    96
  val auto_scroll = new JRadioButton("Auto Scroll", false)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    97
  val message_ind = new JTextArea("0")
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    98
  add(message_ind)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
    99
  add(auto_scroll)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   100
  
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   101
  def isAutoScroll = auto_scroll.isSelected
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   102
  def setIndicator(b: Boolean) = {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   103
    message_ind.setBackground(if (b) java.awt.Color.red else java.awt.Color.white)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   104
  }
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   105
  def setText(s: String) {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   106
    message_ind.setText(s)
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
   107
  }
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   108
}
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
   109
34424
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
   110
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   111
class ScrollerDockable(view : View, position : String) extends JPanel with AdjustmentListener {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   112
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   113
  val renderer:Renderer[Result, XHTMLPanel] = new ResultToPanelRenderer
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   114
  val buffer:Unrendered[Result] = new MessageBuffer
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   115
  val cache:Rendered[Result, XHTMLPanel] = new PanelCache(buffer, renderer)
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   116
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   117
  val subunits = 100
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   118
  // set up view
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   119
  val message_panel = new MessagePanel(cache)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   120
  val infopanel = new InfoPanel
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   121
  val vscroll = new JScrollBar(Adjustable.VERTICAL, 0, 1, 0, 1)
34384
00276ab4f1d5 adj scrolling
immler@in.tum.de
parents: 34383
diff changeset
   122
  vscroll.setUnitIncrement(subunits / 3)
00276ab4f1d5 adj scrolling
immler@in.tum.de
parents: 34383
diff changeset
   123
  vscroll.setBlockIncrement(subunits)
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   124
  vscroll.addAdjustmentListener(this)
34424
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
   125
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
   126
  if (position == DockableWindowManager.FLOATING)
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
   127
    setPreferredSize(new Dimension(500, 250))
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
   128
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   129
  setLayout(new BorderLayout())
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   130
  add (vscroll, BorderLayout.EAST)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   131
  add (message_panel, BorderLayout.CENTER)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   132
  add (infopanel, BorderLayout.SOUTH)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   133
  
34365
5691af1d34cd renamed to message_panel
immler@in.tum.de
parents: 34361
diff changeset
   134
  // do not show every new message, wait a certain amount of time
5691af1d34cd renamed to message_panel
immler@in.tum.de
parents: 34361
diff changeset
   135
  val message_ind_timer : Timer = new Timer(250, new ActionListener {
34360
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
   136
      // this method is called to indicate a new message
34357
61674cd653f9 scroll to first message immediately; potential later messages periodically
immler@in.tum.de
parents: 34356
diff changeset
   137
      override def actionPerformed(e:ActionEvent){
34360
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
   138
        //fire scroll-event if necessary and wanted
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   139
        if(message_panel.no != buffer.size*subunits - 1 && infopanel.isAutoScroll) {
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   140
          vscroll.setValue(buffer.size*subunits - 1)
34360
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
   141
        }
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   142
        infopanel.setIndicator(false)
34357
61674cd653f9 scroll to first message immediately; potential later messages periodically
immler@in.tum.de
parents: 34356
diff changeset
   143
      }
61674cd653f9 scroll to first message immediately; potential later messages periodically
immler@in.tum.de
parents: 34356
diff changeset
   144
    })
61674cd653f9 scroll to first message immediately; potential later messages periodically
immler@in.tum.de
parents: 34356
diff changeset
   145
34376
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
   146
  def add_result (result: Result) = {
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
   147
    buffer.addUnrendered(buffer.size, result)
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   148
    vscroll.setMaximum (Math.max(1, buffer.size * subunits))
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   149
    infopanel.setIndicator(true)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   150
    infopanel.setText(buffer.size.toString)
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   151
34360
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
   152
    if (! message_ind_timer.isRunning()){
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   153
      if(infopanel.isAutoScroll){
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   154
        vscroll.setValue(buffer.size*subunits - 1)
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   155
      }
34360
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
   156
      message_ind_timer.setRepeats(false)
b7af69a030a1 worked over autoscrolling
immler@in.tum.de
parents: 34359
diff changeset
   157
      message_ind_timer.start()
34351
1c919f65c296 fine scrolling principally possible
immler@in.tum.de
parents: 34350
diff changeset
   158
    }
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   159
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   160
    if(message_panel.no == -1) {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   161
      message_panel.no = 0
34386
b295fe78294a revalidate for repainting
immler@in.tum.de
parents: 34384
diff changeset
   162
      message_panel.revalidate
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   163
    }
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
   164
  }
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   165
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
   166
  override def adjustmentValueChanged (e : AdjustmentEvent) = {
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
   167
    //event-handling has to be so general (without UNIT_INCR,...)
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
   168
    // because all events could be sent as TRACK e.g. on my mac
34355
3ae10f5d40aa prepared for automatic scrolling
immler@in.tum.de
parents: 34354
diff changeset
   169
    if (e.getSource == vscroll){
34368
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   170
      message_panel.no = e.getValue / subunits
8ba358ac69a8 fine grained scrolling
immler@in.tum.de
parents: 34367
diff changeset
   171
      message_panel.offset = 100 - 100 * (e.getValue % subunits) / subunits
34386
b295fe78294a revalidate for repainting
immler@in.tum.de
parents: 34384
diff changeset
   172
      message_panel.revalidate
34355
3ae10f5d40aa prepared for automatic scrolling
immler@in.tum.de
parents: 34354
diff changeset
   173
    }
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
   174
  }
34346
634024f57c18 faster resizing, unlimited caching(but cache is cleared on resize)
immler@in.tum.de
parents: 34344
diff changeset
   175
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
   176
  
34370
e0679b361a0e register to buffer all messages
immler@in.tum.de
parents: 34369
diff changeset
   177
  // TODO: register
34440
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   178
  //Isabelle.plugin.prover.allInfo.add(add_result(_))
34344
3775958051c5 absolute positioning according to preferred size of panels,
immler@in.tum.de
parents: 34343
diff changeset
   179
}
34342
b2781f2cd80a LazyScroller: rendering messages only when needed
immler@in.tum.de
parents:
diff changeset
   180
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   181
//Concrete Implementations
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   182
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   183
//containing the unrendered messages
34376
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
   184
class MessageBuffer extends HashMap[Int,Result] with Unrendered[Result]{
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
   185
  override def addUnrendered (id: Int, m: Result) {
34375
71e86ec7e159 replacing xsymbols *after* inserting text
immler@in.tum.de
parents: 34374
diff changeset
   186
    update(id, m)
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   187
  }
34376
76435dd5183d pass results to Scroller
immler@in.tum.de
parents: 34375
diff changeset
   188
  override def getUnrendered (id: Int): Option[Result] = {
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   189
    if(id < size && id >= 0 && apply(id) != null) Some (apply(id))
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   190
    else None
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   191
  }
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   192
  override def size = super.size
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   193
}
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   194
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   195
//containing the rendered messages
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   196
class PanelCache (buffer: Unrendered[Result], val renderer: Renderer[Result, XHTMLPanel])
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   197
  extends HashMap[Int, XHTMLPanel] with Rendered[Result, XHTMLPanel]{
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   198
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   199
  override def getRendered (id: Int): Option[XHTMLPanel] = {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   200
    //get message from buffer and render it if necessary
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   201
    if(!isDefinedAt(id)){
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   202
      buffer.getUnrendered(id) match {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   203
        case Some (message) =>
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   204
          update (id, renderer.render (message))
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   205
        case None =>
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   206
      }
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   207
    }
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   208
    val result = try {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   209
      Some (apply(id))
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   210
    } catch {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   211
      case _ => {
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   212
          None
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   213
      }
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   214
    }
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   215
    return result
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   216
  }
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   217
}
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   218
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   219
class ResultToPanelRenderer extends Renderer[Result, XHTMLPanel]{
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   220
  
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   221
  def render (r: Result): XHTMLPanel = {
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   222
    val panel = new XHTMLPanel(new UserAgent())
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   223
    val fontResolver =
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   224
      panel.getSharedContext.getFontResolver.asInstanceOf[AWTFontResolver]
34440
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   225
    if (Isabelle.plugin.font != null)
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   226
      fontResolver.setFontMapping("Isabelle", Isabelle.plugin.font)
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   227
34440
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   228
    Isabelle.plugin.font_changed.add(font => {
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   229
      if (Isabelle.plugin.font != null)
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   230
        fontResolver.setFontMapping("Isabelle", Isabelle.plugin.font)
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   231
      panel.relayout()
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   232
    })
34440
561a6d19bd95 renamed object Plugin to Isabelle;
wenzelm
parents: 34438
diff changeset
   233
    val tree = parse_failsafe(Isabelle.symbols.decode(r.result))
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   234
    val document = XML.document(tree)
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   235
    panel.setDocument(document, UserAgent.baseURL)
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   236
    val sa = new SelectionActions
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   237
    sa.install(panel)
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   238
    panel
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   239
  }
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   240
  
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   241
  def relayout (panel: XHTMLPanel, width : Int) {
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   242
    // ATTENTION:
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   243
    // panel has to be displayable in a frame/container message_view for doDocumentLayout to have
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   244
    // an effect, especially returning correct preferredSize
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   245
    panel.setBounds (0, 0, width, 1) // document has to fit into width
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   246
    panel.doDocumentLayout (panel.getGraphics) //lay out, preferred size is set then
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   247
    // if there are thousands of empty panels, all have to be rendered -
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   248
    // but this takes time (even for empty panels); therefore minimum size
34424
c880492754d0 setPreferredSize for floating dockables;
wenzelm
parents: 34408
diff changeset
   249
    panel.setPreferredSize(new java.awt.Dimension(width, Math.max(25, panel.getPreferredSize.getHeight.toInt)))
34383
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   250
  }
e5c34d6809dd abstract buffers and renderer
immler@in.tum.de
parents: 34376
diff changeset
   251
34366
2f6e50fa7ac4 restructured scroller
immler@in.tum.de
parents: 34365
diff changeset
   252
}