src/Tools/jEdit/src/document_view.scala
changeset 75393 87ebf5a50283
parent 73340 0ffcad1f6130
child 75394 42267c650205
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
    17 import org.gjt.sp.jedit.jEdit
    17 import org.gjt.sp.jedit.jEdit
    18 import org.gjt.sp.jedit.options.GutterOptionPane
    18 import org.gjt.sp.jedit.options.GutterOptionPane
    19 import org.gjt.sp.jedit.textarea.{JEditTextArea, TextArea, TextAreaExtension, TextAreaPainter}
    19 import org.gjt.sp.jedit.textarea.{JEditTextArea, TextArea, TextAreaExtension, TextAreaPainter}
    20 
    20 
    21 
    21 
    22 object Document_View
    22 object Document_View {
    23 {
       
    24   /* document view of text area */
    23   /* document view of text area */
    25 
    24 
    26   private val key = new Object
    25   private val key = new Object
    27 
    26 
    28   def get(text_area: TextArea): Option[Document_View] =
    27   def get(text_area: TextArea): Option[Document_View] = {
    29   {
       
    30     GUI_Thread.require {}
    28     GUI_Thread.require {}
    31     text_area.getClientProperty(key) match {
    29     text_area.getClientProperty(key) match {
    32       case doc_view: Document_View => Some(doc_view)
    30       case doc_view: Document_View => Some(doc_view)
    33       case _ => None
    31       case _ => None
    34     }
    32     }
    35   }
    33   }
    36 
    34 
    37   def exit(text_area: JEditTextArea): Unit =
    35   def exit(text_area: JEditTextArea): Unit = {
    38   {
       
    39     GUI_Thread.require {}
    36     GUI_Thread.require {}
    40     get(text_area) match {
    37     get(text_area) match {
    41       case None =>
    38       case None =>
    42       case Some(doc_view) =>
    39       case Some(doc_view) =>
    43         doc_view.deactivate()
    40         doc_view.deactivate()
    44         text_area.putClientProperty(key, null)
    41         text_area.putClientProperty(key, null)
    45     }
    42     }
    46   }
    43   }
    47 
    44 
    48   def init(model: Buffer_Model, text_area: JEditTextArea): Document_View =
    45   def init(model: Buffer_Model, text_area: JEditTextArea): Document_View = {
    49   {
       
    50     exit(text_area)
    46     exit(text_area)
    51     val doc_view = new Document_View(model, text_area)
    47     val doc_view = new Document_View(model, text_area)
    52     text_area.putClientProperty(key, doc_view)
    48     text_area.putClientProperty(key, doc_view)
    53     doc_view.activate()
    49     doc_view.activate()
    54     doc_view
    50     doc_view
    55   }
    51   }
    56 }
    52 }
    57 
    53 
    58 
    54 
    59 class Document_View(val model: Buffer_Model, val text_area: JEditTextArea)
    55 class Document_View(val model: Buffer_Model, val text_area: JEditTextArea) {
    60 {
       
    61   private val session = model.session
    56   private val session = model.session
    62 
    57 
    63   def get_rendering(): JEdit_Rendering =
    58   def get_rendering(): JEdit_Rendering =
    64     JEdit_Rendering(model.snapshot(), model, PIDE.options.value)
    59     JEdit_Rendering(model.snapshot(), model, PIDE.options.value)
    65 
    60 
    68       () => delay_caret_update.invoke(), caret_visible = true, enable_hovering = false)
    63       () => delay_caret_update.invoke(), caret_visible = true, enable_hovering = false)
    69 
    64 
    70 
    65 
    71   /* perspective */
    66   /* perspective */
    72 
    67 
    73   def perspective(snapshot: Document.Snapshot): Text.Perspective =
    68   def perspective(snapshot: Document.Snapshot): Text.Perspective = {
    74   {
       
    75     GUI_Thread.require {}
    69     GUI_Thread.require {}
    76 
    70 
    77     val active_command =
    71     val active_command = {
    78     {
       
    79       val view = text_area.getView
    72       val view = text_area.getView
    80       if (view != null && view.getTextArea == text_area) {
    73       if (view != null && view.getTextArea == text_area) {
    81         PIDE.editor.current_command(view, snapshot) match {
    74         PIDE.editor.current_command(view, snapshot) match {
    82           case Some(command) =>
    75           case Some(command) =>
    83             snapshot.node.command_start(command) match {
    76             snapshot.node.command_start(command) match {
   103       yield range).toList
    96       yield range).toList
   104 
    97 
   105     Text.Perspective(active_command ::: visible_lines)
    98     Text.Perspective(active_command ::: visible_lines)
   106   }
    99   }
   107 
   100 
   108   private def update_view = new TextAreaExtension
   101   private def update_view = new TextAreaExtension {
   109   {
   102     override def paintScreenLineRange(
   110     override def paintScreenLineRange(gfx: Graphics2D,
   103       gfx: Graphics2D,
   111       first_line: Int, last_line: Int, physical_lines: Array[Int],
   104       first_line: Int,
   112       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   105       last_line: Int,
   113     {
   106       physical_lines: Array[Int],
       
   107       start: Array[Int],
       
   108       end: Array[Int],
       
   109       y: Int,
       
   110       line_height: Int
       
   111     ): Unit = {
   114       // no robust_body
   112       // no robust_body
   115       PIDE.editor.invoke_generated()
   113       PIDE.editor.invoke_generated()
   116     }
   114     }
   117   }
   115   }
   118 
   116 
   119 
   117 
   120   /* gutter */
   118   /* gutter */
   121 
   119 
   122   private val gutter_painter = new TextAreaExtension
   120   private val gutter_painter = new TextAreaExtension {
   123   {
   121     override def paintScreenLineRange(
   124     override def paintScreenLineRange(gfx: Graphics2D,
   122       gfx: Graphics2D,
   125       first_line: Int, last_line: Int, physical_lines: Array[Int],
   123       first_line: Int,
   126       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   124       last_line: Int,
   127     {
   125       physical_lines: Array[Int],
       
   126       start: Array[Int],
       
   127       end: Array[Int],
       
   128       y: Int,
       
   129       line_height: Int
       
   130     ): Unit = {
   128       rich_text_area.robust_body(()) {
   131       rich_text_area.robust_body(()) {
   129         GUI_Thread.assert {}
   132         GUI_Thread.assert {}
   130 
   133 
   131         val gutter = text_area.getGutter
   134         val gutter = text_area.getGutter
   132         val sel_width = GutterOptionPane.getSelectionAreaWidth
   135         val sel_width = GutterOptionPane.getSelectionAreaWidth
   143 
   146 
   144               rendering.gutter_content(line_range) match {
   147               rendering.gutter_content(line_range) match {
   145                 case Some((icon, color)) =>
   148                 case Some((icon, color)) =>
   146                   // icons within selection area
   149                   // icons within selection area
   147                   if (!gutter.isExpanded &&
   150                   if (!gutter.isExpanded &&
   148                       gutter.isSelectionAreaEnabled && sel_width >= 12 && line_height >= 12)
   151                       gutter.isSelectionAreaEnabled && sel_width >= 12 && line_height >= 12) {
   149                   {
       
   150                     val x0 =
   152                     val x0 =
   151                       (FOLD_MARKER_SIZE + sel_width - border_width - icon.getIconWidth) max 10
   153                       (FOLD_MARKER_SIZE + sel_width - border_width - icon.getIconWidth) max 10
   152                     val y0 =
   154                     val y0 =
   153                       y + i * line_height + (((line_height - icon.getIconHeight) / 2) max 0)
   155                       y + i * line_height + (((line_height - icon.getIconHeight) / 2) max 0)
   154                     icon.paintIcon(gutter, gfx, x0, y0)
   156                     icon.paintIcon(gutter, gfx, x0, y0)
   171 
   173 
   172   /* key listener */
   174   /* key listener */
   173 
   175 
   174   private val key_listener =
   176   private val key_listener =
   175     JEdit_Lib.key_listener(
   177     JEdit_Lib.key_listener(
   176       key_pressed = (evt: KeyEvent) =>
   178       key_pressed = (evt: KeyEvent) => {
   177         {
   179         if (evt.getKeyCode == KeyEvent.VK_ESCAPE && Isabelle.dismissed_popups(text_area.getView))
   178           if (evt.getKeyCode == KeyEvent.VK_ESCAPE && Isabelle.dismissed_popups(text_area.getView))
   180           evt.consume
   179             evt.consume
   181       }
   180         }
       
   181     )
   182     )
   182 
   183 
   183 
   184 
   184   /* caret handling */
   185   /* caret handling */
   185 
   186 
   226     }
   227     }
   227 
   228 
   228 
   229 
   229   /* activation */
   230   /* activation */
   230 
   231 
   231   private def activate(): Unit =
   232   private def activate(): Unit = {
   232   {
       
   233     val painter = text_area.getPainter
   233     val painter = text_area.getPainter
   234 
   234 
   235     painter.addExtension(TextAreaPainter.LOWEST_LAYER, update_view)
   235     painter.addExtension(TextAreaPainter.LOWEST_LAYER, update_view)
   236     rich_text_area.activate()
   236     rich_text_area.activate()
   237     text_area.getGutter.addExtension(gutter_painter)
   237     text_area.getGutter.addExtension(gutter_painter)
   244       foreach(text_area.addStructureMatcher)
   244       foreach(text_area.addStructureMatcher)
   245     session.raw_edits += main
   245     session.raw_edits += main
   246     session.commands_changed += main
   246     session.commands_changed += main
   247   }
   247   }
   248 
   248 
   249   private def deactivate(): Unit =
   249   private def deactivate(): Unit = {
   250   {
       
   251     val painter = text_area.getPainter
   250     val painter = text_area.getPainter
   252 
   251 
   253     session.raw_edits -= main
   252     session.raw_edits -= main
   254     session.commands_changed -= main
   253     session.commands_changed -= main
   255     Isabelle.structure_matchers(JEdit_Lib.buffer_mode(text_area.getBuffer)).
   254     Isabelle.structure_matchers(JEdit_Lib.buffer_mode(text_area.getBuffer)).