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