src/Tools/jEdit/src/jedit/LazyScroller.scala
changeset 34346 634024f57c18
parent 34344 3775958051c5
equal deleted inserted replaced
34345:bec7e6e25a4b 34346:634024f57c18
     1 /*
     1 /*
     2  * LazyScroller.scala
     2  * LazyScroller.scala
     3  *
     3  *
     4  *
     4  * TODO: clearer seperation of tasks: layout message_view, layout panel (with preferredsize), repaint, relayout, ...
       
     5  * + relayout on ValueIsAdjusting while scrolling
       
     6  * + scrolling *one* panel 
     5  */
     7  */
     6 
     8 
     7 package isabelle.jedit
     9 package isabelle.jedit
     8 
    10 
     9 import java.io.{ ByteArrayInputStream, FileInputStream, InputStream }
    11 import java.io.{ ByteArrayInputStream, FileInputStream, InputStream }
    86 
    88 
    87     panel.setDocument(message, LazyScroller.baseURL)
    89     panel.setDocument(message, LazyScroller.baseURL)
    88     panel
    90     panel
    89   }
    91   }
    90   
    92   
    91   //calculates preferred size of panel and add it to the cache and view
    93   //calculates preferred size of panel
    92   def add_to_cache (message_no: Int, panel: XHTMLPanel) = {
    94   def calculate_preferred_size(panel: XHTMLPanel){
    93     message_cache = message_cache.update (message_no, panel)
       
    94     //necessary for calculating preferred size of panel
       
    95     message_view.add (panel)
    95     message_view.add (panel)
    96     panel.setBounds (0, 0, message_view.getWidth, 1) // document has to fit into width
    96     panel.setBounds (0, 0, message_view.getWidth, 1) // document has to fit into width
    97     panel.doLayout (panel.getGraphics) //lay out, preferred size is set then
    97     panel.doLayout (panel.getGraphics) //lay out, preferred size is set then
       
    98   }
       
    99   
       
   100   //add panel to the cache
       
   101   def add_to_cache (message_no: Int, panel: XHTMLPanel) = {
       
   102     message_cache = message_cache.update (message_no, panel)
       
   103     calculate_preferred_size(panel)
    98     System.err.println("Added " + message_no + " with preferred Size " + panel.getPreferredSize + " to cache")
   104     System.err.println("Added " + message_no + " with preferred Size " + panel.getPreferredSize + " to cache")
    99   }
   105   }
   100   
   106   
   101   //render and load a message into cache, place its bottom at y-coordinate;
   107   //render and load a message into cache, place its bottom at y-coordinate;
   102   def set_message (message_no: Int, y: Int) = {
   108   def set_message (message_no: Int, y: Int) = {
   119     while (y >= 0 && n >= 0){
   125     while (y >= 0 && n >= 0){
   120       val panel = set_message (n, y)
   126       val panel = set_message (n, y)
   121       y = y - panel.getHeight
   127       y = y - panel.getHeight
   122       n = n - 1
   128       n = n - 1
   123     }
   129     }
   124     //clean cache (except for some elements on top and bottom, if existent)
       
   125     //TODO: find appropriate values
       
   126     //larger cache makes e.g. resizing slower
       
   127     if(message_cache.size > 20){
       
   128       val min = n - 5
       
   129       val max = message_no + 5
       
   130       message_cache = message_cache filter (t => t match{case (no, _) => no >= min && no <= max})
       
   131     }
       
   132     repaint()
   130     repaint()
   133   }
   131   }
   134 
   132 
   135   def add_message (message: Document) = {
   133   def add_message (message: Document) = {
   136     message_buffer += message
   134     message_buffer += message
   141     //event-handling has to be so general (without UNIT_INCR,...)
   139     //event-handling has to be so general (without UNIT_INCR,...)
   142     // because all events could be sent as TRACK e.g. on my mac
   140     // because all events could be sent as TRACK e.g. on my mac
   143     message_no = e.getValue
   141     message_no = e.getValue
   144     update_view
   142     update_view
   145   }
   143   }
   146   
   144 
       
   145   // handle Component-Events
       
   146   override def componentShown(e: ComponentEvent){}
   147   override def componentHidden(e: ComponentEvent){}
   147   override def componentHidden(e: ComponentEvent){}
   148   override def componentMoved(e: ComponentEvent){}
   148   override def componentMoved(e: ComponentEvent){}
   149   override def componentResized(e: ComponentEvent){
   149   override def componentResized(e: ComponentEvent){
   150     // update_cache: insert panels into new cache -> preferred size is calculated
   150     // remove all hidden messages from cache
   151     val panels = message_cache.elements
   151     // TODO: move to unlayouted cache
   152     message_cache = message_cache.empty
   152     message_cache = message_cache filter ( pair => pair match {case (no, _) =>
   153     panels foreach (pair => pair match{case (no, pa) => add_to_cache (no, pa)})
   153       no <= message_no && no >= message_no - message_view.getComponents.length})
   154     vscroll.setMaximum (Math.max(1, message_buffer.length))    
   154     //calculate preferred size for each panel
       
   155     message_cache foreach (pair => pair match { case (_, pa) =>
       
   156       calculate_preferred_size (pa)
       
   157     })
   155     update_view
   158     update_view
   156   }
   159   }
   157   override def componentShown(e: ComponentEvent){}
       
   158   
   160   
   159   //register somewhere
   161   //register somewhere
       
   162   // TODO: only testing atm
   160   Plugin.plugin.stateUpdate.add(state => {
   163   Plugin.plugin.stateUpdate.add(state => {
   161     var i = 0
   164     var i = 0
   162     if(state != null) while (i < 500) {
   165     if(state != null) while (i < 500) {
   163       add_message(state.document)
   166       add_message(state.document)
   164       i += 1
   167       i += 1