src/Tools/jEdit/src/rich_text_area.scala
author wenzelm
Sat, 16 Nov 2024 19:54:30 +0100
changeset 81462 dc35aa7d5311
parent 81461 b82ee80baa05
child 82013 82f47e645c0a
permissions -rw-r--r--
minor performance tuning: avoided repeated metric initialization;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49411
1da54e9bda68 renamed Text_Area_Painter to Rich_Text_Area;
wenzelm
parents: 49410
diff changeset
     1
/*  Title:      Tools/jEdit/src/rich_text_area.scala
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     3
49411
1da54e9bda68 renamed Text_Area_Painter to Rich_Text_Area;
wenzelm
parents: 49410
diff changeset
     4
Enhanced version of jEdit text area, with rich text rendering,
1da54e9bda68 renamed Text_Area_Painter to Rich_Text_Area;
wenzelm
parents: 49410
diff changeset
     5
tooltips, hyperlinks etc.
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     6
*/
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     7
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     8
package isabelle.jedit
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
     9
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    10
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    11
import isabelle._
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    12
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
    13
import java.awt.{Graphics2D, Shape, Color, Point, Cursor, MouseInfo, Font}
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    14
import java.awt.event.{MouseMotionAdapter, MouseAdapter, MouseEvent,
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    15
  FocusAdapter, FocusEvent, WindowEvent, WindowAdapter, KeyEvent}
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    16
import java.awt.font.TextAttribute
56322
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
    17
import javax.swing.SwingUtilities
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    18
import java.text.AttributedString
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    19
56883
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
    20
import scala.util.matching.Regex
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
    21
import scala.collection.mutable
56883
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
    22
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    23
import org.gjt.sp.util.Log
72898
4e4b4298f1e7 tuned imports;
wenzelm
parents: 71932
diff changeset
    24
import org.gjt.sp.jedit.View
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
    25
import org.gjt.sp.jedit.syntax.{Chunk => JEditChunk, SyntaxStyle}
81437
8d2d68c8c051 more ambitious mouse handler: double-click selects highlight_area;
wenzelm
parents: 81436
diff changeset
    26
import org.gjt.sp.jedit.textarea.{TextAreaExtension, TextAreaPainter, TextArea, Selection}
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    27
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    28
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
    29
class Rich_Text_Area(
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
    30
  view: View,
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
    31
  text_area: TextArea,
64621
7116f2634e32 clarified module name;
wenzelm
parents: 63044
diff changeset
    32
  get_rendering: () => JEdit_Rendering,
50915
12de8ea66f54 close tooltip after Active.action, to make it look more interactive (notably due to lack of dynamic update);
wenzelm
parents: 50849
diff changeset
    33
  close_action: () => Unit,
56883
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
    34
  get_search_pattern: () => Option[Regex],
63028
5fb352275db3 more thorough update;
wenzelm
parents: 62991
diff changeset
    35
  caret_update: () => Unit,
50306
b655d2d0406d updated to jedit-5.0.0;
wenzelm
parents: 50216
diff changeset
    36
  caret_visible: Boolean,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
    37
  enable_hovering: Boolean
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
    38
) {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    39
  private val buffer = text_area.getBuffer
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    40
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    41
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    42
  /* robust extension body */
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    43
64884
b2e78c0ce537 more robust: delay switches thread context from timer to GUI and may get out of sync with revoke operation;
wenzelm
parents: 64621
diff changeset
    44
  def check_robust_body: Boolean =
b2e78c0ce537 more robust: delay switches thread context from timer to GUI and may get out of sync with revoke operation;
wenzelm
parents: 64621
diff changeset
    45
    GUI_Thread.require { buffer == text_area.getBuffer }
b2e78c0ce537 more robust: delay switches thread context from timer to GUI and may get out of sync with revoke operation;
wenzelm
parents: 64621
diff changeset
    46
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
    47
  def robust_body[A](default: A)(body: => A): A = {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    48
    try {
64884
b2e78c0ce537 more robust: delay switches thread context from timer to GUI and may get out of sync with revoke operation;
wenzelm
parents: 64621
diff changeset
    49
      if (check_robust_body) body
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    50
      else {
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    51
        Log.log(Log.ERROR, this, ERROR("Implicit change of text area buffer"))
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    52
        default
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    53
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    54
    }
50641
wenzelm
parents: 50553
diff changeset
    55
    catch { case exn: Throwable => Log.log(Log.ERROR, this, exn); default }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    56
  }
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
    57
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    58
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    59
  /* original painters */
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    60
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
    61
  private def pick_extension(name: String): TextAreaExtension = {
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    62
    text_area.getPainter.getExtensions.iterator.filter(x => x.getClass.getName == name).toList
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    63
    match {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    64
      case List(x) => x
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    65
      case _ => error("Expected exactly one " + name)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    66
    }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    67
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    68
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    69
  private val orig_text_painter =
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    70
    pick_extension("org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText")
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    71
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    72
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    73
  /* caret focus modifier */
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    74
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    75
  @volatile private var caret_focus_modifier = false
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    76
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    77
  def caret_focus_range: Text.Range =
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    78
    if (caret_focus_modifier) Text.Range.full
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    79
    else JEdit_Lib.visible_range(text_area) getOrElse Text.Range.offside
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    80
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    81
  private val key_listener =
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    82
    JEdit_Lib.key_listener(
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
    83
      key_pressed = { (evt: KeyEvent) =>
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    84
        val mod = PIDE.options.string("jedit_focus_modifier")
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    85
        val old = caret_focus_modifier
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    86
        caret_focus_modifier = (mod.nonEmpty && mod == JEdit_Lib.modifier_string(evt))
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    87
        if (caret_focus_modifier != old) caret_update()
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    88
      },
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
    89
      key_released = { _ =>
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    90
        if (caret_focus_modifier) {
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    91
          caret_focus_modifier = false
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    92
          caret_update()
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    93
        }
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    94
      })
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    95
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
    96
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
    97
  /* common painter state */
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    98
64621
7116f2634e32 clarified module name;
wenzelm
parents: 63044
diff changeset
    99
  @volatile private var painter_rendering: JEdit_Rendering = null
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   100
  @volatile private var painter_clip: Shape = null
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   101
  @volatile private var painter_gfx_range: Text.Range => Option[JEdit_Lib.Gfx_Range] = null
72900
c9813630cca4 clarified signature: more explicit types;
wenzelm
parents: 72899
diff changeset
   102
  @volatile private var caret_focus = Rendering.Focus.empty
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   103
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   104
  private val set_state = new TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   105
    override def paintScreenLineRange(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   106
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   107
      first_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   108
      last_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   109
      physical_lines: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   110
      start: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   111
      end: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   112
      y: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   113
      line_height: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   114
    ): Unit = {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   115
      painter_rendering = get_rendering()
46220
663251a395c2 more explicit/robust treatment of common snapshot;
wenzelm
parents: 46205
diff changeset
   116
      painter_clip = gfx.getClip
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   117
      painter_gfx_range = JEdit_Lib.gfx_range(text_area)
62988
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   118
      caret_focus =
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
   119
        if (caret_enabled && !painter_rendering.snapshot.is_outdated) {
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
   120
          painter_rendering.caret_focus(JEdit_Lib.caret_range(text_area), caret_focus_range)
62988
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   121
        }
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
   122
        else Rendering.Focus.empty
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   123
    }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   124
  }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   125
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   126
  private val reset_state = new TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   127
    override def paintScreenLineRange(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   128
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   129
      first_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   130
      last_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   131
      physical_lines: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   132
      start: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   133
      end: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   134
      y: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   135
      line_height: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   136
    ): Unit = {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   137
      painter_rendering = null
46220
663251a395c2 more explicit/robust treatment of common snapshot;
wenzelm
parents: 46205
diff changeset
   138
      painter_clip = null
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   139
      painter_gfx_range = null
72900
c9813630cca4 clarified signature: more explicit types;
wenzelm
parents: 72899
diff changeset
   140
      caret_focus = Rendering.Focus.empty
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   141
    }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   142
  }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   143
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   144
  def robust_rendering(body: JEdit_Rendering => Unit): Unit = {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   145
    robust_body(()) { body(painter_rendering) }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   146
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   147
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   148
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   149
  /* active areas within the text */
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   150
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   151
  private class Active_Area[A](
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   152
    render: JEdit_Rendering => Text.Range => Option[Text.Info[A]],
81296
59994f7feace GUI option "editor_auto_hovering" for Output panel;
wenzelm
parents: 81180
diff changeset
   153
    require_control: => Boolean = false,
59994f7feace GUI option "editor_auto_hovering" for Output panel;
wenzelm
parents: 81180
diff changeset
   154
    ignore_control: => Boolean = false,
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   155
    cursor: Int = -1
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   156
  ) {
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   157
    private var the_text_info: Option[(String, Text.Info[A])] = None
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   158
81180
264f043c5da1 more ambitious rendering: highlight active area for mouse hovering without modifier;
wenzelm
parents: 80558
diff changeset
   159
    def check_control(control: Boolean): Boolean =
264f043c5da1 more ambitious rendering: highlight active area for mouse hovering without modifier;
wenzelm
parents: 80558
diff changeset
   160
      control == require_control || ignore_control
264f043c5da1 more ambitious rendering: highlight active area for mouse hovering without modifier;
wenzelm
parents: 80558
diff changeset
   161
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   162
    def is_active: Boolean = the_text_info.isDefined
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   163
    def text_info: Option[(String, Text.Info[A])] = the_text_info
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   164
    def info: Option[Text.Info[A]] = the_text_info.map(_._2)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   165
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   166
    def update(new_info: Option[Text.Info[A]]): Unit = {
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   167
      val old_text_info = the_text_info
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   168
      val new_text_info =
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   169
        new_info.map(info => (text_area.getText(info.range.start, info.range.length), info))
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   170
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   171
      if (new_text_info != old_text_info) {
63028
5fb352275db3 more thorough update;
wenzelm
parents: 62991
diff changeset
   172
        caret_update()
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   173
        if (cursor >= 0) {
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   174
          if (new_text_info.isDefined) {
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   175
            text_area.getPainter.setCursor(Cursor.getPredefinedCursor(cursor))
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   176
          }
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   177
          else text_area.getPainter.resetCursor()
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   178
        }
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   179
        for {
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   180
          r0 <- JEdit_Lib.visible_range(text_area)
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   181
          opt <- List(old_text_info, new_text_info)
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   182
          (_, Text.Info(r1, _)) <- opt
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   183
          r2 <- r1.try_restrict(r0)  // FIXME more precise?!
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   184
        } JEdit_Lib.invalidate_range(text_area, r2)
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   185
        the_text_info = new_text_info
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   186
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   187
    }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   188
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   189
    def update_rendering(rendering: JEdit_Rendering, range: Text.Range): Unit =
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   190
      update(render(rendering)(range))
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   191
73881
b1272ec71568 tuned signature;
wenzelm
parents: 73880
diff changeset
   192
    def reset(): Unit = update(None)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   193
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   194
57612
990ffb84489b clarified module name: facilitate alternative GUI frameworks;
wenzelm
parents: 56884
diff changeset
   195
  // owned by GUI thread
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   196
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   197
  private val highlight_area =
81296
59994f7feace GUI option "editor_auto_hovering" for Output panel;
wenzelm
parents: 81180
diff changeset
   198
    new Active_Area[Color](_.highlight, require_control = true,
59994f7feace GUI option "editor_auto_hovering" for Output panel;
wenzelm
parents: 81180
diff changeset
   199
      ignore_control = JEdit_Options.auto_hovering())
60892
wenzelm
parents: 60215
diff changeset
   200
52980
28f59ca8ce78 manage hyperlinks via PIDE editor interface;
wenzelm
parents: 52867
diff changeset
   201
  private val hyperlink_area =
66082
2d12a730a380 clarified modules;
wenzelm
parents: 65332
diff changeset
   202
    new Active_Area[PIDE.editor.Hyperlink](
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   203
      _.hyperlink, require_control = true, cursor = Cursor.HAND_CURSOR)
60892
wenzelm
parents: 60215
diff changeset
   204
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   205
  private val active_area =
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   206
    new Active_Area[XML.Elem](_.active, cursor = Cursor.DEFAULT_CURSOR)
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   207
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   208
  private val active_areas = List(highlight_area, hyperlink_area, active_area)
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   209
  private def active_exists(): Boolean = active_areas.exists(_.is_active)
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   210
  def active_reset(): Unit = active_areas.foreach(_.reset())
62988
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   211
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   212
  private val focus_listener = new FocusAdapter {
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72927
diff changeset
   213
    override def focusLost(e: FocusEvent): Unit = { robust_body(()) { active_reset() } }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   214
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   215
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   216
  private val window_listener = new WindowAdapter {
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72927
diff changeset
   217
    override def windowIconified(e: WindowEvent): Unit = { robust_body(()) { active_reset() } }
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72927
diff changeset
   218
    override def windowDeactivated(e: WindowEvent): Unit = { robust_body(()) { active_reset() } }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   219
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   220
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   221
  private val mouse_listener = new MouseAdapter {
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   222
    override def mouseClicked(e: MouseEvent): Unit = {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   223
      robust_body(()) {
81444
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   224
        if (!e.isConsumed() && e.getClickCount == 1) {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   225
          hyperlink_area.info match {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   226
            case Some(Text.Info(range, link)) =>
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   227
              if (!link.external) {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   228
                try { text_area.moveCaretPosition(range.start) }
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   229
                catch {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   230
                  case _: ArrayIndexOutOfBoundsException =>
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   231
                  case _: IllegalArgumentException =>
81436
7436cdef0f14 more accurate mouse handler: only for single clicks, consume accepted event;
wenzelm
parents: 81404
diff changeset
   232
                }
81444
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   233
                text_area.requestFocus()
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   234
              }
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   235
              link.follow(view)
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   236
              e.consume()
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   237
            case None =>
81436
7436cdef0f14 more accurate mouse handler: only for single clicks, consume accepted event;
wenzelm
parents: 81404
diff changeset
   238
          }
81444
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   239
          active_area.text_info match {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   240
            case Some((text, Text.Info(_, markup))) =>
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   241
              Active.action(view, text, markup)
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   242
              close_action()
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   243
              e.consume()
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   244
            case None =>
81437
8d2d68c8c051 more ambitious mouse handler: double-click selects highlight_area;
wenzelm
parents: 81436
diff changeset
   245
          }
8d2d68c8c051 more ambitious mouse handler: double-click selects highlight_area;
wenzelm
parents: 81436
diff changeset
   246
        }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   247
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   248
    }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   249
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   250
56322
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   251
  private def mouse_inside_painter(): Boolean =
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   252
    MouseInfo.getPointerInfo match {
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   253
      case null => false
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   254
      case info =>
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   255
        val point = info.getLocation
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   256
        val painter = text_area.getPainter
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   257
        SwingUtilities.convertPointFromScreen(point, painter)
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   258
        painter.contains(point)
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   259
    }
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   260
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   261
  private val mouse_motion_listener = new MouseMotionAdapter {
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   262
    override def mouseDragged(evt: MouseEvent): Unit = {
56321
7e8c11011fdf dismiss all popups on mouse drags, e.g. to avoid conflict of C-hover of Isabelle/jEdit and C-selection of jEdit;
wenzelm
parents: 56317
diff changeset
   263
      robust_body(()) {
57857
4d86378e635f even more thorough reset on mouse drag (see also 0c63f3538639, 7e8c11011fdf);
wenzelm
parents: 57612
diff changeset
   264
        active_reset()
56497
0c63f3538639 dismiss popups more carefully (amending 7e8c11011fdf), notably allow mouse dragging within some tooltip, e.g. for text selection;
wenzelm
parents: 56496
diff changeset
   265
        Completion_Popup.Text_Area.dismissed(text_area)
0c63f3538639 dismiss popups more carefully (amending 7e8c11011fdf), notably allow mouse dragging within some tooltip, e.g. for text selection;
wenzelm
parents: 56496
diff changeset
   266
        Pretty_Tooltip.dismiss_descendant(text_area.getPainter)
56321
7e8c11011fdf dismiss all popups on mouse drags, e.g. to avoid conflict of C-hover of Isabelle/jEdit and C-selection of jEdit;
wenzelm
parents: 56317
diff changeset
   267
      }
7e8c11011fdf dismiss all popups on mouse drags, e.g. to avoid conflict of C-hover of Isabelle/jEdit and C-selection of jEdit;
wenzelm
parents: 56317
diff changeset
   268
    }
7e8c11011fdf dismiss all popups on mouse drags, e.g. to avoid conflict of C-hover of Isabelle/jEdit and C-selection of jEdit;
wenzelm
parents: 56317
diff changeset
   269
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   270
    override def mouseMoved(evt: MouseEvent): Unit = {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   271
      robust_body(()) {
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   272
        val x = evt.getX
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   273
        val y = evt.getY
72899
8732315dfafa tuned signature;
wenzelm
parents: 72898
diff changeset
   274
        val control = JEdit_Lib.command_modifier(evt)
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   275
53179
336cd976698c tuned signature;
wenzelm
parents: 52980
diff changeset
   276
        if ((control || enable_hovering) && !buffer.isLoading) {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   277
          JEdit_Lib.buffer_lock(buffer) {
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   278
            JEdit_Lib.pixel_range(text_area, x, y) match {
50211
2a3d6d760629 always reset active areas;
wenzelm
parents: 50199
diff changeset
   279
              case None => active_reset()
49941
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   280
              case Some(range) =>
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   281
                val rendering = get_rendering()
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   282
                for (area <- active_areas) {
81180
264f043c5da1 more ambitious rendering: highlight active area for mouse hovering without modifier;
wenzelm
parents: 80558
diff changeset
   283
                  if (area.check_control(control) && !rendering.snapshot.is_outdated) {
49941
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   284
                    area.update_rendering(rendering, range)
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   285
                  }
73881
b1272ec71568 tuned signature;
wenzelm
parents: 73880
diff changeset
   286
                  else area.reset()
49941
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   287
                }
81444
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   288
                if (JEdit_Lib.alt_modifier(evt)) {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   289
                  highlight_area.info.map(_.range) match {
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   290
                    case Some(range) =>
81451
cc9fc6f375b2 proper focus to support subsequent copy-paste via keyboard;
wenzelm
parents: 81447
diff changeset
   291
                      text_area.requestFocus()
81447
7a7ad99212b1 less ambitious selection;
wenzelm
parents: 81444
diff changeset
   292
                      text_area.selectNone()
81444
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   293
                      text_area.addToSelection(new Selection.Range(range.start, range.stop))
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   294
                    case None =>
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   295
                  }
cd685e2291fa clarified mouse selection, avoid conflict of double-click with single-click (follow hyperlink);
wenzelm
parents: 81443
diff changeset
   296
                }
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   297
            }
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   298
          }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   299
        }
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   300
        else active_reset()
51441
37f699750430 more elementary tooltips via mouse events (imitating parts of javax.swing.ToolTipManager) -- avoid abuse of getToolTipText to produce window as side-effect;
wenzelm
parents: 50915
diff changeset
   301
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   302
        if (evt.getSource == text_area.getPainter) {
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52483
diff changeset
   303
          Pretty_Tooltip.invoke(() =>
52495
bf45606912e3 more robust delayed invocation;
wenzelm
parents: 52494
diff changeset
   304
            robust_body(()) {
56322
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   305
              if (mouse_inside_painter()) {
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   306
                val rendering = get_rendering()
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   307
                val snapshot = rendering.snapshot
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   308
                if (!snapshot.is_outdated) {
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   309
                  JEdit_Lib.pixel_range(text_area, x, y) match {
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   310
                    case None =>
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   311
                    case Some(range) =>
71496
5d62f797e40c tuned signature;
wenzelm
parents: 67395
diff changeset
   312
                      rendering.tooltip(range, control) match {
56322
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   313
                        case None =>
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   314
                        case Some(tip) =>
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   315
                          val painter = text_area.getPainter
58767
30766b5fd0e1 proper line height and text base line, like regular TextAreaPainter.PaintText;
wenzelm
parents: 57857
diff changeset
   316
                          val loc = new Point(x, y + painter.getLineHeight / 2)
65332
7dbb780f24a9 tuned signature;
wenzelm
parents: 65247
diff changeset
   317
                          val results = snapshot.command_results(tip.range)
81398
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81338
diff changeset
   318
                          Pretty_Tooltip(view, painter, loc, rendering, results, tip.info)
56322
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   319
                      }
f9ad26836516 check global mouse status before opening tooltip, e.g. relevant when the mouse has moved outside the window and mouse events are no longer seen by this component;
wenzelm
parents: 56321
diff changeset
   320
                  }
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52483
diff changeset
   321
                }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52483
diff changeset
   322
              }
52495
bf45606912e3 more robust delayed invocation;
wenzelm
parents: 52494
diff changeset
   323
          })
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51449
diff changeset
   324
        }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   325
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   326
    }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   327
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   328
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   329
55713
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   330
  /* text background */
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   331
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   332
  private val background_painter = new TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   333
    override def paintScreenLineRange(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   334
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   335
      first_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   336
      last_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   337
      physical_lines: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   338
      start: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   339
      end: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   340
      y: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   341
      line_height: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   342
    ): Unit = {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   343
      robust_rendering { rendering =>
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   344
        val fm = text_area.getPainter.getFontMetrics
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   345
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71496
diff changeset
   346
        for (i <- physical_lines.indices) {
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   347
          if (physical_lines(i) != -1) {
56884
7de69b35bdaf more robust line_range, according to usual jEdit confusion at end of last line (see also 71c5d1f516c0);
wenzelm
parents: 56883
diff changeset
   348
            val line_range = Text.Range(start(i), end(i) min buffer.getLength)
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   349
49473
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   350
            // line background color
81404
7acc6fabca6a clarified signature;
wenzelm
parents: 81398
diff changeset
   351
            for (c <- rendering.line_background(line_range)) {
7acc6fabca6a clarified signature;
wenzelm
parents: 81398
diff changeset
   352
              val separator = rendering.line_separator(line_range)
7acc6fabca6a clarified signature;
wenzelm
parents: 81398
diff changeset
   353
              val sep = if (separator) (2 min (line_height / 2)) max (line_height / 8) else 0
65124
759c64c39a6f more generic colors;
wenzelm
parents: 65121
diff changeset
   354
              gfx.setColor(rendering.color(c))
49475
8f3a3adadd5a tuned painter;
wenzelm
parents: 49473
diff changeset
   355
              gfx.fillRect(0, y + i * line_height, text_area.getWidth, line_height - sep)
49473
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   356
            }
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   357
55790
4670f18baba5 simplified rendering -- no need to over-emphasize "token_range";
wenzelm
parents: 55766
diff changeset
   358
            // background color
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   359
            for {
65176
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65124
diff changeset
   360
              Text.Info(range, c) <-
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65124
diff changeset
   361
                rendering.background(Rendering.background_elements, line_range, caret_focus)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   362
              r <- painter_gfx_range(range)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   363
            } {
65101
4263b2a201b3 symbolic Rendering.Color;
wenzelm
parents: 64884
diff changeset
   364
              gfx.setColor(rendering.color(c))
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   365
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   366
            }
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   367
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   368
            // active area -- potentially from other snapshot
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   369
            for {
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   370
              info <- active_area.info
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   371
              Text.Info(range, _) <- info.try_restrict(line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   372
              r <- painter_gfx_range(range)
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   373
            } {
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   374
              gfx.setColor(rendering.active_hover_color)
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   375
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   376
            }
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   377
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   378
            // squiggly underline
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   379
            for {
65121
12c6774a8f65 more generic rendering;
wenzelm
parents: 65101
diff changeset
   380
              Text.Info(range, c) <- rendering.squiggly_underline(line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   381
              r <- painter_gfx_range(range)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   382
            } {
65121
12c6774a8f65 more generic rendering;
wenzelm
parents: 65101
diff changeset
   383
              gfx.setColor(rendering.color(c))
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   384
              val x0 = (r.x / 2) * 2
51574
2b58d7b139d6 ghost bullet via markup, which is painted as bar under text (normally space);
wenzelm
parents: 51496
diff changeset
   385
              val y0 = r.y + fm.getAscent + 1
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   386
              for (x1 <- Range(x0, x0 + r.length, 2)) {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   387
                val y1 = if (x1 % 4 < 2) y0 else y0 + 1
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   388
                gfx.drawLine(x1, y1, x1 + 1, y1)
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   389
              }
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   390
            }
56550
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   391
56560
ac916ea744e4 tuned rendering -- avoid overlap with squiggly underline;
wenzelm
parents: 56558
diff changeset
   392
            // spell checker
56550
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   393
            for {
65239
509a9b0ad02e avoid global variables with implicit initialization;
wenzelm
parents: 65213
diff changeset
   394
              spell_checker <- PIDE.plugin.spell_checker.get
67395
b39d596b77ce more accurate spell-checking for nested quotations / antiquotations, notably in formal comments;
wenzelm
parents: 67014
diff changeset
   395
              spell <- rendering.spell_checker(line_range)
b39d596b77ce more accurate spell-checking for nested quotations / antiquotations, notably in formal comments;
wenzelm
parents: 67014
diff changeset
   396
              text <- JEdit_Lib.get_text(buffer, spell.range)
b39d596b77ce more accurate spell-checking for nested quotations / antiquotations, notably in formal comments;
wenzelm
parents: 67014
diff changeset
   397
              info <- spell_checker.marked_words(spell.range.start, text)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   398
              r <- painter_gfx_range(info.range)
56550
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   399
            } {
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   400
              gfx.setColor(rendering.spell_checker_color)
56560
ac916ea744e4 tuned rendering -- avoid overlap with squiggly underline;
wenzelm
parents: 56558
diff changeset
   401
              val y0 = r.y + ((fm.getAscent + 4) min (line_height - 2))
56550
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   402
              gfx.drawLine(r.x, y0, r.x + r.length, y0)
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   403
            }
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   404
          }
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   405
        }
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   406
      }
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   407
    }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   408
  }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   409
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   410
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   411
  /* text */
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   412
55766
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   413
  private def caret_enabled: Boolean =
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   414
    caret_visible && (!text_area.hasFocus || text_area.isCaretVisible)
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   415
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   416
  private def caret_color(rendering: JEdit_Rendering, offset: Text.Offset): Color = {
61011
018b0c996b54 more explicit debugger caret rendering;
wenzelm
parents: 60913
diff changeset
   417
    if (text_area.isCaretVisible) text_area.getPainter.getCaretColor
61014
39f67bb4e609 maintain per-thread focus context;
wenzelm
parents: 61011
diff changeset
   418
    else {
39f67bb4e609 maintain per-thread focus context;
wenzelm
parents: 61011
diff changeset
   419
      val debug_positions =
61017
wenzelm
parents: 61014
diff changeset
   420
        (for {
65247
63d91d5de121 tuned signature;
wenzelm
parents: 65246
diff changeset
   421
          c <- PIDE.session.debugger.focus().iterator
61017
wenzelm
parents: 61014
diff changeset
   422
          pos <- c.debug_position.iterator
wenzelm
parents: 61014
diff changeset
   423
        } yield pos).toList
66082
2d12a730a380 clarified modules;
wenzelm
parents: 65332
diff changeset
   424
      if (debug_positions.exists(PIDE.editor.is_hyperlink_position(rendering.snapshot, offset, _)))
61011
018b0c996b54 more explicit debugger caret rendering;
wenzelm
parents: 60913
diff changeset
   425
        rendering.caret_debugger_color
018b0c996b54 more explicit debugger caret rendering;
wenzelm
parents: 60913
diff changeset
   426
      else rendering.caret_invisible_color
61014
39f67bb4e609 maintain per-thread focus context;
wenzelm
parents: 61011
diff changeset
   427
    }
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   428
  }
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   429
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   430
  private class Font_Subst {
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   431
    private var cache = Map.empty[Int, Option[Font]]
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   432
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   433
    def get(codepoint: Int): Option[Font] =
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   434
      cache.getOrElse(codepoint,
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   435
        {
80557
08034bb75ee8 tuned signature;
wenzelm
parents: 80556
diff changeset
   436
          val field = classOf[JEditChunk].getDeclaredField("lastSubstFont")
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   437
          field.setAccessible(true)
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   438
          field.set(null, null)
80557
08034bb75ee8 tuned signature;
wenzelm
parents: 80556
diff changeset
   439
          val res = Option(JEditChunk.getSubstFont(codepoint))
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   440
          cache += (codepoint -> res)
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   441
          res
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   442
        })
73883
994c9dacd2f9 more predictable result, avoid slightly odd "lastSubstFont" by jEdit;
wenzelm
parents: 73881
diff changeset
   443
  }
994c9dacd2f9 more predictable result, avoid slightly odd "lastSubstFont" by jEdit;
wenzelm
parents: 73881
diff changeset
   444
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   445
  sealed case class Chunk(
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   446
    id: Byte,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   447
    style: SyntaxStyle,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   448
    offset: Int,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   449
    length: Int,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   450
    width: Float,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   451
    font_subst: Boolean,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   452
    str: String
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   453
  )
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   454
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   455
  private def make_chunk_list(chunk_head: JEditChunk): List[Chunk] = {
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   456
    val buf = new mutable.ListBuffer[Chunk]
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   457
    var chunk = chunk_head
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   458
    while (chunk != null) {
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   459
      val str =
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   460
        if (chunk.chars == null) Symbol.spaces(chunk.length)
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   461
        else {
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   462
          if (chunk.str == null) { chunk.str = new String(chunk.chars) }
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   463
          chunk.str
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   464
        }
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   465
      buf += Chunk(chunk.id, chunk.style, chunk.offset, chunk.length, chunk.width,
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   466
        chunk.usedFontSubstitution, str)
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   467
      chunk = chunk.next.asInstanceOf[JEditChunk]
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   468
    }
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   469
    buf.toList
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   470
  }
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   471
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   472
  private def paint_chunk_list(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   473
    rendering: JEdit_Rendering,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   474
    font_subst: Font_Subst,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   475
    gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   476
    line_start: Text.Offset,
80555
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   477
    caret_range: Text.Range,
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   478
    chunk_list: List[Chunk],
80555
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   479
    x0: Int,
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   480
    y0: Int
80556
6be239aa5cdb tuned signature (again);
wenzelm
parents: 80555
diff changeset
   481
  ): Float = {
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   482
    val clip_rect = gfx.getClipBounds
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   483
80555
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   484
    val x = x0.toFloat
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   485
    val y = y0.toFloat
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   486
    chunk_list.foldLeft(0.0f) { case (w, chunk) =>
43505
0aca4edbfa99 clarified chunk.offset, chunk.length;
wenzelm
parents: 43451
diff changeset
   487
      val chunk_offset = line_start + chunk.offset
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   488
      if (x + w + chunk.width > clip_rect.x &&
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   489
          x + w < clip_rect.x + clip_rect.width && chunk.length > 0) {
43505
0aca4edbfa99 clarified chunk.offset, chunk.length;
wenzelm
parents: 43451
diff changeset
   490
        val chunk_range = Text.Range(chunk_offset, chunk_offset + chunk.length)
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   491
        val chunk_font = chunk.style.getFont
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   492
        val chunk_color = chunk.style.getForegroundColor
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   493
        val chunk_text = new AttributedString(chunk.str)
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   494
73875
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   495
        def chunk_attrib(attrib: TextAttribute, value: AnyRef, r: Text.Range): Unit =
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   496
          chunk_text.addAttribute(attrib, value, r.start - chunk_offset, r.stop - chunk_offset)
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   497
73875
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   498
        // font
73877
wenzelm
parents: 73876
diff changeset
   499
        chunk_text.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_LTR)
73875
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   500
        chunk_text.addAttribute(TextAttribute.FONT, chunk_font)
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   501
        if (chunk.font_subst) {
73876
e6c9c1c3f580 support for jEdit font substitution;
wenzelm
parents: 73875
diff changeset
   502
          for {
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   503
            (c, i) <- Codepoint.iterator_offset(chunk.str) if !chunk_font.canDisplay(c)
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   504
            subst_font <- font_subst.get(c)
73876
e6c9c1c3f580 support for jEdit font substitution;
wenzelm
parents: 73875
diff changeset
   505
          } {
e6c9c1c3f580 support for jEdit font substitution;
wenzelm
parents: 73875
diff changeset
   506
            val r = Text.Range(i, i + Character.charCount(c)) + chunk_offset
80557
08034bb75ee8 tuned signature;
wenzelm
parents: 80556
diff changeset
   507
            val font = JEditChunk.deriveSubstFont(chunk_font, subst_font)
73876
e6c9c1c3f580 support for jEdit font substitution;
wenzelm
parents: 73875
diff changeset
   508
            chunk_attrib(TextAttribute.FONT, font, r)
e6c9c1c3f580 support for jEdit font substitution;
wenzelm
parents: 73875
diff changeset
   509
          }
e6c9c1c3f580 support for jEdit font substitution;
wenzelm
parents: 73875
diff changeset
   510
        }
43448
90aec5043461 more robust caret painting wrt. surrogate characters;
wenzelm
parents: 43435
diff changeset
   511
73875
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   512
        // color
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   513
        chunk_text.addAttribute(TextAttribute.FOREGROUND, chunk_color)
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   514
        for {
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   515
          Text.Info(r1, color) <- rendering.text_color(chunk_range, chunk_color).iterator
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   516
          r2 <- r1.try_restrict(chunk_range) if !r2.is_singularity
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   517
        } chunk_attrib(TextAttribute.FOREGROUND, color, r2)
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   518
73875
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   519
        // caret
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   520
        for { r <- caret_range.try_restrict(chunk_range) if !r.is_singularity } {
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   521
          chunk_attrib(TextAttribute.FOREGROUND, caret_color(rendering, r.start), r)
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   522
          chunk_attrib(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON, r)
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   523
        }
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   524
73875
6e43936f2111 more ambitious use of AttributedString (despite be825a69fc67, which was for much older Java);
wenzelm
parents: 73367
diff changeset
   525
        gfx.drawString(chunk_text.getIterator, x + w, y)
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   526
      }
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   527
      w + chunk.width
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   528
    }
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   529
  }
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   530
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   531
  private val text_painter = new TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   532
    override def paintScreenLineRange(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   533
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   534
      first_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   535
      last_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   536
      physical_lines: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   537
      start: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   538
      end: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   539
      y: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   540
      line_height: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   541
    ): Unit = {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   542
      robust_rendering { rendering =>
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   543
        val painter = text_area.getPainter
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   544
        val fm = painter.getFontMetrics
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   545
        val lm = painter.getFont.getLineMetrics(" ", painter.getFontRenderContext)
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   546
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   547
        val clip = gfx.getClip
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   548
        val x0 = text_area.getHorizontalOffset
58767
30766b5fd0e1 proper line height and text base line, like regular TextAreaPainter.PaintText;
wenzelm
parents: 57857
diff changeset
   549
        var y0 = y + painter.getLineHeight - (fm.getLeading + 1) - fm.getDescent
43372
2df2144b0910 use orig_text_painter for extras outside main text (also required to update internal line infos);
wenzelm
parents: 43371
diff changeset
   550
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   551
        val (bullet_x, bullet_y, bullet_w, bullet_h) = {
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   552
          val w = fm.charWidth(' ')
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   553
          val b = (w / 2) max 1
73880
wenzelm
parents: 73877
diff changeset
   554
          val c = (lm.getAscent + lm.getStrikethroughOffset).round
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   555
          ((w - b + 1) / 2, c - b / 2, w - b, line_height - b)
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   556
        }
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   557
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   558
        val font_subst = new Font_Subst
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   559
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71496
diff changeset
   560
        for (i <- physical_lines.indices) {
49097
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   561
          val line = physical_lines(i)
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   562
          if (line != -1) {
56884
7de69b35bdaf more robust line_range, according to usual jEdit confusion at end of last line (see also 71c5d1f516c0);
wenzelm
parents: 56883
diff changeset
   563
            val line_range = Text.Range(start(i), end(i) min buffer.getLength)
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   564
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   565
            // text chunks
49097
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   566
            val screen_line = first_line + i
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   567
            val chunk_list = make_chunk_list(text_area.getChunksOfScreenLine(screen_line))
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   568
            if (chunk_list.nonEmpty) {
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   569
              try {
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   570
                val line_start = buffer.getLineStartOffset(line)
80555
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   571
                val caret_range =
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   572
                  if (caret_enabled) JEdit_Lib.caret_range(text_area)
a66a962b015b clarified signature: more self-contained paint_chunk_list;
wenzelm
parents: 80550
diff changeset
   573
                  else Text.Range.offside
78243
0e221a8128e4 tuned: prefer Scala over Java;
wenzelm
parents: 75394
diff changeset
   574
                gfx.clipRect(x0, y + line_height * i, Int.MaxValue, line_height)
73884
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   575
                val w =
0a12ca4f3e8d proper Font_Subst.cache for paintScreenLineRange;
wenzelm
parents: 73883
diff changeset
   576
                  paint_chunk_list(rendering, font_subst, gfx,
80558
69e21910febc clarified signature: afford explicit Scala data types;
wenzelm
parents: 80557
diff changeset
   577
                    line_start, caret_range, chunk_list, x0, y0)
80556
6be239aa5cdb tuned signature (again);
wenzelm
parents: 80555
diff changeset
   578
                gfx.clipRect(x0 + w.toInt, 0, Int.MaxValue, Int.MaxValue)
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   579
                orig_text_painter.paintValidLine(gfx,
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   580
                  screen_line, line, start(i), end(i), y + line_height * i)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   581
              } finally { gfx.setClip(clip) }
49097
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   582
            }
60913
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   583
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   584
            // bullet bar
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   585
            for {
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   586
              Text.Info(range, color) <- rendering.bullet(line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   587
              r <- painter_gfx_range(range)
60913
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   588
            } {
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   589
              gfx.setColor(color)
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   590
              gfx.fillRect(r.x + bullet_x, y + i * line_height + bullet_y,
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   591
                r.length - bullet_w, line_height - bullet_h)
7432d6bb4195 clarified breakpoint rendering;
wenzelm
parents: 60892
diff changeset
   592
            }
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   593
          }
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   594
          y0 += line_height
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   595
        }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   596
      }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   597
    }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   598
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   599
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   600
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   601
  /* foreground */
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   602
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   603
  private val foreground_painter = new TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   604
    override def paintScreenLineRange(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   605
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   606
      first_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   607
      last_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   608
      physical_lines: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   609
      start: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   610
      end: Array[Int],
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   611
      y: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   612
      line_height: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   613
    ): Unit = {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   614
      robust_rendering { rendering =>
56883
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   615
        val search_pattern = get_search_pattern()
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71496
diff changeset
   616
        for (i <- physical_lines.indices) {
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   617
          if (physical_lines(i) != -1) {
56884
7de69b35bdaf more robust line_range, according to usual jEdit confusion at end of last line (see also 71c5d1f516c0);
wenzelm
parents: 56883
diff changeset
   618
            val line_range = Text.Range(start(i), end(i) min buffer.getLength)
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   619
44545
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   620
            // foreground color
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   621
            for {
65101
4263b2a201b3 symbolic Rendering.Color;
wenzelm
parents: 64884
diff changeset
   622
              Text.Info(range, c) <- rendering.foreground(line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   623
              r <- painter_gfx_range(range)
44545
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   624
            } {
65101
4263b2a201b3 symbolic Rendering.Color;
wenzelm
parents: 64884
diff changeset
   625
              gfx.setColor(rendering.color(c))
44545
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   626
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   627
            }
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   628
56883
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   629
            // search pattern
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   630
            for {
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   631
              regex <- search_pattern
81461
b82ee80baa05 tuned signature: more operations;
wenzelm
parents: 81451
diff changeset
   632
              range <- JEdit_Lib.search_text(buffer, line_range, regex)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   633
              r <- painter_gfx_range(range)
56883
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   634
            } {
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   635
              gfx.setColor(rendering.search_color)
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   636
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   637
            }
38c6b70e5e53 common support for search field, which is actually a light-weight Highlighter;
wenzelm
parents: 56662
diff changeset
   638
49357
34ac36642a31 more general Document_Model.point_range;
wenzelm
parents: 49356
diff changeset
   639
            // highlight range -- potentially from other snapshot
46205
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   640
            for {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   641
              info <- highlight_area.info
46205
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   642
              Text.Info(range, color) <- info.try_restrict(line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   643
              r <- painter_gfx_range(range)
46205
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   644
            } {
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   645
              gfx.setColor(color)
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   646
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   647
            }
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   648
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   649
            // hyperlink range -- potentially from other snapshot
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   650
            for {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   651
              info <- hyperlink_area.info
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   652
              Text.Info(range, _) <- info.try_restrict(line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   653
              r <- painter_gfx_range(range)
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   654
            } {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   655
              gfx.setColor(rendering.hyperlink_color)
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   656
              gfx.drawRect(r.x, y + i * line_height, r.length - 1, line_height - 1)
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   657
            }
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   658
62988
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   659
            // entity def range
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   660
            if (!active_exists() && caret_visible) {
62988
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   661
              for {
62991
35f1475e9ced clarified rendering wrt. hyperlinks;
wenzelm
parents: 62988
diff changeset
   662
                Text.Info(range, color) <- rendering.entity_ref(line_range, caret_focus)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   663
                r <- painter_gfx_range(range)
62988
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   664
              } {
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   665
                gfx.setColor(color)
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   666
                gfx.drawRect(r.x, y + i * line_height, r.length - 1, line_height - 1)
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   667
              }
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   668
            }
224e8d8a4fb8 tuned rendering;
wenzelm
parents: 62986
diff changeset
   669
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   670
            // completion range
80550
642e2de19d95 misc tuning and clarification;
wenzelm
parents: 78243
diff changeset
   671
            if (!active_exists() && caret_visible) {
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   672
              for {
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   673
                completion <- Completion_Popup.Text_Area(text_area)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   674
                Text.Info(range, color) <- completion.rendering(rendering, line_range)
81462
dc35aa7d5311 minor performance tuning: avoided repeated metric initialization;
wenzelm
parents: 81461
diff changeset
   675
                r <- painter_gfx_range(range)
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   676
              } {
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   677
                gfx.setColor(color)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   678
                gfx.drawRect(r.x, y + i * line_height, r.length - 1, line_height - 1)
55711
9e3d64e5919a paint completion range of active popup;
wenzelm
parents: 55690
diff changeset
   679
              }
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   680
            }
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   681
          }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   682
        }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   683
      }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   684
    }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   685
  }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   686
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   687
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   688
  /* caret -- outside of text range */
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   689
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   690
  private class Caret_Painter(before: Boolean) extends TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   691
    override def paintValidLine(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   692
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   693
      screen_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   694
      physical_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   695
      start: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   696
      end: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   697
      y: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   698
    ): Unit = {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   699
      robust_rendering { _ =>
43404
c8369f3d88a1 uniform use of Document_View.robust_body;
wenzelm
parents: 43398
diff changeset
   700
        if (before) gfx.clipRect(0, 0, 0, 0)
c8369f3d88a1 uniform use of Document_View.robust_body;
wenzelm
parents: 43398
diff changeset
   701
        else gfx.setClip(painter_clip)
c8369f3d88a1 uniform use of Document_View.robust_body;
wenzelm
parents: 43398
diff changeset
   702
      }
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   703
    }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   704
  }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   705
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   706
  private val before_caret_painter1 = new Caret_Painter(true)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   707
  private val after_caret_painter1 = new Caret_Painter(false)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   708
  private val before_caret_painter2 = new Caret_Painter(true)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   709
  private val after_caret_painter2 = new Caret_Painter(false)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   710
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   711
  private val caret_painter = new TextAreaExtension {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   712
    override def paintValidLine(
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   713
      gfx: Graphics2D,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   714
      screen_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   715
      physical_line: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   716
      start: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   717
      end: Int,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   718
      y: Int
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   719
    ): Unit = {
55713
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   720
      robust_rendering { rendering =>
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   721
        if (caret_visible) {
43398
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   722
          val caret = text_area.getCaretPosition
55766
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   723
          if (caret_enabled && start <= caret && caret == end - 1) {
43398
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   724
            val painter = text_area.getPainter
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   725
            val fm = painter.getFontMetrics
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   726
43398
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   727
            val offset = caret - text_area.getLineStartOffset(physical_line)
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   728
            val x = text_area.offsetToXY(physical_line, offset).x
58767
30766b5fd0e1 proper line height and text base line, like regular TextAreaPainter.PaintText;
wenzelm
parents: 57857
diff changeset
   729
            val y1 = y + painter.getLineHeight - (fm.getLeading + 1) - fm.getDescent
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   730
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   731
            val astr = new AttributedString(" ")
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   732
            astr.addAttribute(TextAttribute.FONT, painter.getFont)
61011
018b0c996b54 more explicit debugger caret rendering;
wenzelm
parents: 60913
diff changeset
   733
            astr.addAttribute(TextAttribute.FOREGROUND, caret_color(rendering, caret))
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   734
            astr.addAttribute(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   735
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   736
            val clip = gfx.getClip
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   737
            try {
78243
0e221a8128e4 tuned: prefer Scala over Java;
wenzelm
parents: 75394
diff changeset
   738
              gfx.clipRect(x, y, Int.MaxValue, painter.getLineHeight)
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   739
              gfx.drawString(astr.getIterator, x, y1)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   740
            }
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   741
            finally { gfx.setClip(clip) }
43398
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   742
          }
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   743
        }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   744
      }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   745
    }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   746
  }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   747
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   748
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   749
  /* activation */
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   750
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   751
  def activate(): Unit = {
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   752
    val painter = text_area.getPainter
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   753
    painter.addExtension(TextAreaPainter.LOWEST_LAYER, set_state)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   754
    painter.addExtension(TextAreaPainter.LINE_BACKGROUND_LAYER + 1, background_painter)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   755
    painter.addExtension(TextAreaPainter.TEXT_LAYER, text_painter)
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   756
    painter.addExtension(TextAreaPainter.CARET_LAYER - 1, before_caret_painter1)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   757
    painter.addExtension(TextAreaPainter.CARET_LAYER + 1, after_caret_painter1)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   758
    painter.addExtension(TextAreaPainter.BLOCK_CARET_LAYER - 1, before_caret_painter2)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   759
    painter.addExtension(TextAreaPainter.BLOCK_CARET_LAYER + 1, after_caret_painter2)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   760
    painter.addExtension(TextAreaPainter.BLOCK_CARET_LAYER + 2, caret_painter)
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   761
    painter.addExtension(500, foreground_painter)
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   762
    painter.addExtension(TextAreaPainter.HIGHEST_LAYER, reset_state)
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   763
    painter.removeExtension(orig_text_painter)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   764
    painter.addMouseListener(mouse_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   765
    painter.addMouseMotionListener(mouse_motion_listener)
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
   766
    text_area.addKeyListener(key_listener)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   767
    text_area.addFocusListener(focus_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   768
    view.addWindowListener(window_listener)
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   769
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   770
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73884
diff changeset
   771
  def deactivate(): Unit = {
56340
af8cb60b55eb clear active areas (notably mouse pointer) before changing context (e.g. via hyperlink);
wenzelm
parents: 56339
diff changeset
   772
    active_reset()
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   773
    val painter = text_area.getPainter
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   774
    view.removeWindowListener(window_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   775
    text_area.removeFocusListener(focus_listener)
72927
69f768aff611 clarified caret focus modifier, depending on option "jedit_focus_modifier";
wenzelm
parents: 72900
diff changeset
   776
    text_area.removeKeyListener(key_listener)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   777
    painter.removeMouseMotionListener(mouse_motion_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   778
    painter.removeMouseListener(mouse_listener)
43396
548a68eafaea recovered orig_text_painter from f4141da52e92;
wenzelm
parents: 43393
diff changeset
   779
    painter.addExtension(TextAreaPainter.TEXT_LAYER, orig_text_painter)
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   780
    painter.removeExtension(reset_state)
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   781
    painter.removeExtension(foreground_painter)
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   782
    painter.removeExtension(caret_painter)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   783
    painter.removeExtension(after_caret_painter2)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   784
    painter.removeExtension(before_caret_painter2)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   785
    painter.removeExtension(after_caret_painter1)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   786
    painter.removeExtension(before_caret_painter1)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   787
    painter.removeExtension(text_painter)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   788
    painter.removeExtension(background_painter)
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   789
    painter.removeExtension(set_state)
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   790
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   791
}