src/Tools/jEdit/src/rich_text_area.scala
author wenzelm
Sun, 13 Apr 2014 16:06:55 +0200
changeset 56558 05c833d402bc
parent 56551 d4da2b11c729
child 56560 ac916ea744e4
permissions -rw-r--r--
tuned signature -- explicit Spell_Checker_Variable;
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
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
    13
import java.awt.{Graphics2D, Shape, Color, Point, Toolkit, Cursor, MouseInfo}
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    14
import java.awt.event.{MouseMotionAdapter, MouseAdapter, MouseEvent,
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    15
  FocusAdapter, FocusEvent, WindowEvent, WindowAdapter}
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
import java.util.ArrayList
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    20
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    21
import org.gjt.sp.util.Log
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    22
import org.gjt.sp.jedit.{OperatingSystem, Debug, View}
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    23
import org.gjt.sp.jedit.syntax.{DisplayTokenHandler, Chunk}
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    24
import org.gjt.sp.jedit.textarea.{TextAreaExtension, TextAreaPainter, TextArea}
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    25
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    26
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
    27
class Rich_Text_Area(
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
    28
  view: View,
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
    29
  text_area: TextArea,
50199
6d04e2422769 quasi-abstract module Rendering, with Isabelle-specific implementation;
wenzelm
parents: 50165
diff changeset
    30
  get_rendering: () => 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
    31
  close_action: () => Unit,
50306
b655d2d0406d updated to jedit-5.0.0;
wenzelm
parents: 50216
diff changeset
    32
  caret_visible: Boolean,
53179
336cd976698c tuned signature;
wenzelm
parents: 52980
diff changeset
    33
  enable_hovering: Boolean)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    34
{
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    35
  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
    36
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    37
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    38
  /* robust extension body */
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    39
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    40
  def robust_body[A](default: A)(body: => A): A =
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    41
  {
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    42
    try {
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    43
      Swing_Thread.require()
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    44
      if (buffer == text_area.getBuffer) body
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    45
      else {
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    46
        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
    47
        default
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    48
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    49
    }
50641
wenzelm
parents: 50553
diff changeset
    50
    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
    51
  }
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
    52
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    53
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    54
  /* original painters */
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    55
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    56
  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
    57
  {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    58
    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
    59
    match {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    60
      case List(x) => x
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    61
      case _ => error("Expected exactly one " + name)
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    62
    }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    63
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    64
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    65
  private val orig_text_painter =
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    66
    pick_extension("org.gjt.sp.jedit.textarea.TextAreaPainter$PaintText")
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    67
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
    68
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
    69
  /* common painter state */
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    70
50199
6d04e2422769 quasi-abstract module Rendering, with Isabelle-specific implementation;
wenzelm
parents: 50165
diff changeset
    71
  @volatile private var painter_rendering: Rendering = null
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
    72
  @volatile private var painter_clip: Shape = null
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    73
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
    74
  private val set_state = new TextAreaExtension
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    75
  {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    76
    override def paintScreenLineRange(gfx: Graphics2D,
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    77
      first_line: Int, last_line: Int, physical_lines: Array[Int],
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    78
      start: Array[Int], end: Array[Int], y: Int, line_height: Int)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    79
    {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    80
      painter_rendering = get_rendering()
46220
663251a395c2 more explicit/robust treatment of common snapshot;
wenzelm
parents: 46205
diff changeset
    81
      painter_clip = gfx.getClip
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    82
    }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    83
  }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    84
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
    85
  private val reset_state = new TextAreaExtension
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
    86
  {
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    87
    override def paintScreenLineRange(gfx: Graphics2D,
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    88
      first_line: Int, last_line: Int, physical_lines: Array[Int],
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    89
      start: Array[Int], end: Array[Int], y: Int, line_height: Int)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    90
    {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
    91
      painter_rendering = null
46220
663251a395c2 more explicit/robust treatment of common snapshot;
wenzelm
parents: 46205
diff changeset
    92
      painter_clip = null
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    93
    }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    94
  }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
    95
50199
6d04e2422769 quasi-abstract module Rendering, with Isabelle-specific implementation;
wenzelm
parents: 50165
diff changeset
    96
  def robust_rendering(body: Rendering => Unit)
46220
663251a395c2 more explicit/robust treatment of common snapshot;
wenzelm
parents: 46205
diff changeset
    97
  {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    98
    robust_body(()) { body(painter_rendering) }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
    99
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   100
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   101
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   102
  /* active areas within the text */
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   103
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   104
  private class Active_Area[A](
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   105
    rendering: Rendering => Text.Range => Option[Text.Info[A]],
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   106
    cursor: Option[Int])
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   107
  {
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   108
    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
   109
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   110
    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
   111
    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
   112
    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
   113
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   114
    def update(new_info: Option[Text.Info[A]])
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   115
    {
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   116
      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
   117
      val new_text_info =
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   118
        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
   119
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   120
      if (new_text_info != old_text_info) {
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   121
        if (cursor.isDefined) {
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   122
          if (new_text_info.isDefined)
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   123
            text_area.getPainter.setCursor(Cursor.getPredefinedCursor(cursor.get))
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   124
          else
56406
0e21270952c3 revert ce37fcb30cf2 for the sake of Mac OS X -- let some event listeners of jEdit reset the cursor;
wenzelm
parents: 56373
diff changeset
   125
            text_area.getPainter.resetCursor()
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   126
        }
49493
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   127
        for {
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   128
          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
   129
          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
   130
          (_, Text.Info(r1, _)) <- opt
db58490a68ac more realistic sendback: pick exec_id from message position and text from buffer;
wenzelm
parents: 49492
diff changeset
   131
          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
   132
        } 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
   133
        the_text_info = new_text_info
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   134
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   135
    }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   136
50199
6d04e2422769 quasi-abstract module Rendering, with Isabelle-specific implementation;
wenzelm
parents: 50165
diff changeset
   137
    def update_rendering(r: Rendering, range: Text.Range)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   138
    { update(rendering(r)(range)) }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   139
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   140
    def reset { update(None) }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   141
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   142
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   143
  // owned by Swing thread
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   144
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   145
  private val highlight_area =
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   146
    new Active_Area[Color]((r: Rendering) => r.highlight _, None)
52980
28f59ca8ce78 manage hyperlinks via PIDE editor interface;
wenzelm
parents: 52867
diff changeset
   147
  private val hyperlink_area =
56317
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   148
    new Active_Area[PIDE.editor.Hyperlink](
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   149
      (r: Rendering) => r.hyperlink _, Some(Cursor.HAND_CURSOR))
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   150
  private val active_area =
1147854080b4 tuned rendering -- change mouse pointer for active areas;
wenzelm
parents: 56172
diff changeset
   151
    new Active_Area[XML.Elem]((r: Rendering) => r.active _, Some(Cursor.DEFAULT_CURSOR))
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   152
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   153
  private val active_areas =
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   154
    List((highlight_area, true), (hyperlink_area, true), (active_area, false))
50216
de77cde57376 reset active areas on content update;
wenzelm
parents: 50215
diff changeset
   155
  def active_reset(): Unit = active_areas.foreach(_._1.reset)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   156
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   157
  private val focus_listener = new FocusAdapter {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   158
    override def focusLost(e: FocusEvent) { robust_body(()) { active_reset() } }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   159
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   160
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   161
  private val window_listener = new WindowAdapter {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   162
    override def windowIconified(e: WindowEvent) { robust_body(()) { active_reset() } }
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   163
    override def windowDeactivated(e: WindowEvent) { robust_body(()) { active_reset() } }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   164
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   165
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   166
  private val mouse_listener = new MouseAdapter {
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   167
    override def mouseClicked(e: MouseEvent) {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   168
      robust_body(()) {
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   169
        hyperlink_area.info match {
56433
db69cb14f7ed prepare "back" position for Navigator, before following hyperlink;
wenzelm
parents: 56406
diff changeset
   170
          case Some(Text.Info(range, link)) =>
56494
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   171
            if (!link.external) {
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   172
              try { text_area.moveCaretPosition(range.start) }
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   173
              catch {
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   174
                case _: ArrayIndexOutOfBoundsException =>
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   175
                case _: IllegalArgumentException =>
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   176
              }
1b74abf064e1 avoid confusion about pointless cursor movement with external links;
wenzelm
parents: 56433
diff changeset
   177
              text_area.requestFocus
56433
db69cb14f7ed prepare "back" position for Navigator, before following hyperlink;
wenzelm
parents: 56406
diff changeset
   178
            }
52482
5b7c4fb41511 explicit Pretty_Tooltip.dismiss_all due to slightly changed focus mechanics;
wenzelm
parents: 52480
diff changeset
   179
            link.follow(view)
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   180
          case None =>
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   181
        }
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   182
        active_area.text_info match {
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
   183
          case Some((text, Text.Info(_, markup))) =>
12de8ea66f54 close tooltip after Active.action, to make it look more interactive (notably due to lack of dynamic update);
wenzelm
parents: 50849
diff changeset
   184
            Active.action(view, text, markup)
12de8ea66f54 close tooltip after Active.action, to make it look more interactive (notably due to lack of dynamic update);
wenzelm
parents: 50849
diff changeset
   185
            close_action()
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   186
          case None =>
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   187
        }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   188
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   189
    }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   190
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   191
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
   192
  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
   193
    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
   194
      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
   195
      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
   196
        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
   197
        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
   198
        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
   199
        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
   200
    }
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
   201
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   202
  private val mouse_motion_listener = new MouseMotionAdapter {
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
   203
    override def mouseDragged(evt: MouseEvent) {
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
   204
      robust_body(()) {
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
   205
        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
   206
        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
   207
      }
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
   208
    }
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
   209
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   210
    override def mouseMoved(evt: MouseEvent) {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   211
      robust_body(()) {
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   212
        val x = evt.getX
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   213
        val y = evt.getY
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   214
        val control = (evt.getModifiers & Toolkit.getDefaultToolkit.getMenuShortcutKeyMask) != 0
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   215
53179
336cd976698c tuned signature;
wenzelm
parents: 52980
diff changeset
   216
        if ((control || enable_hovering) && !buffer.isLoading) {
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   217
          JEdit_Lib.buffer_lock(buffer) {
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   218
            JEdit_Lib.pixel_range(text_area, x, y) match {
50211
2a3d6d760629 always reset active areas;
wenzelm
parents: 50199
diff changeset
   219
              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
   220
              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
   221
                val rendering = get_rendering()
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   222
                for ((area, require_control) <- active_areas)
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   223
                {
50165
24d47733975f reset active area for outdated snapshot (again?);
wenzelm
parents: 50164
diff changeset
   224
                  if (control == require_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
   225
                    area.update_rendering(rendering, range)
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   226
                  else area.reset
f2db0596bd61 more precise pixel_range: avoid popup when pointing into empty space after actual end-of-line;
wenzelm
parents: 49843
diff changeset
   227
                }
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   228
            }
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   229
          }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   230
        }
49424
491363c6feb4 more robust GUI component handlers;
wenzelm
parents: 49411
diff changeset
   231
        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
   232
53182
61b983193dc1 more static values;
wenzelm
parents: 53180
diff changeset
   233
        if (evt.getSource == text_area.getPainter) {
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52483
diff changeset
   234
          Pretty_Tooltip.invoke(() =>
52495
bf45606912e3 more robust delayed invocation;
wenzelm
parents: 52494
diff changeset
   235
            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
   236
              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
   237
                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
   238
                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
   239
                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
   240
                  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
   241
                    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
   242
                    case Some(range) =>
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
   243
                      val result =
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
   244
                        if (control) rendering.tooltip(range)
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
   245
                        else rendering.tooltip_message(range)
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
   246
                      result 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
   247
                        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
   248
                        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
   249
                          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
   250
                          val loc = new Point(x, y + painter.getFontMetrics.getHeight / 2)
56496
46b29bb1c627 clarifed results range;
wenzelm
parents: 56494
diff changeset
   251
                          val results = rendering.command_results(tip.range)
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
   252
                          Pretty_Tooltip(view, painter, loc, rendering, results, 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
   253
                      }
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
                  }
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52483
diff changeset
   255
                }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52483
diff changeset
   256
              }
52495
bf45606912e3 more robust delayed invocation;
wenzelm
parents: 52494
diff changeset
   257
          })
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51449
diff changeset
   258
        }
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   259
      }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   260
    }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   261
  }
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   262
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   263
55713
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   264
  /* text background */
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   265
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   266
  private val background_painter = new TextAreaExtension
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   267
  {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   268
    override def paintScreenLineRange(gfx: Graphics2D,
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   269
      first_line: Int, last_line: Int, physical_lines: Array[Int],
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   270
      start: Array[Int], end: Array[Int], y: Int, line_height: Int)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   271
    {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   272
      robust_rendering { rendering =>
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   273
        val fm = text_area.getPainter.getFontMetrics
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   274
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   275
        for (i <- 0 until physical_lines.length) {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   276
          if (physical_lines(i) != -1) {
49843
afddf4e26fac further refinement of jEdit line range, avoiding lack of final \n;
wenzelm
parents: 49730
diff changeset
   277
            val line_range = Text.Range(start(i), end(i))
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   278
49473
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   279
            // line background color
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   280
            for { (color, separator) <- rendering.line_background(line_range) }
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   281
            {
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   282
              gfx.setColor(color)
49475
8f3a3adadd5a tuned painter;
wenzelm
parents: 49473
diff changeset
   283
              val sep = if (separator) (2 min (line_height / 2)) else 0
8f3a3adadd5a tuned painter;
wenzelm
parents: 49473
diff changeset
   284
              gfx.fillRect(0, y + i * line_height, text_area.getWidth, line_height - sep)
49473
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   285
            }
ca7e2c21b104 tuned rendering;
wenzelm
parents: 49424
diff changeset
   286
55790
4670f18baba5 simplified rendering -- no need to over-emphasize "token_range";
wenzelm
parents: 55766
diff changeset
   287
            // background color
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   288
            for {
55790
4670f18baba5 simplified rendering -- no need to over-emphasize "token_range";
wenzelm
parents: 55766
diff changeset
   289
              Text.Info(range, color) <- rendering.background(line_range)
49409
7140a738aa49 tuned signature;
wenzelm
parents: 49408
diff changeset
   290
              r <- JEdit_Lib.gfx_range(text_area, range)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   291
            } {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   292
              gfx.setColor(color)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   293
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   294
            }
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   295
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   296
            // active area -- potentially from other snapshot
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   297
            for {
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   298
              info <- active_area.info
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   299
              Text.Info(range, _) <- info.try_restrict(line_range)
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   300
              r <- JEdit_Lib.gfx_range(text_area, range)
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   301
            } {
50450
358b6020f8b6 generalized notion of active area, where sendback is just one application;
wenzelm
parents: 50306
diff changeset
   302
              gfx.setColor(rendering.active_hover_color)
49492
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   303
              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
   304
            }
2e3e7ea5ce8e some support for hovering and sendback area;
wenzelm
parents: 49475
diff changeset
   305
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   306
            // squiggly underline
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   307
            for {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   308
              Text.Info(range, color) <- rendering.squiggly_underline(line_range)
49409
7140a738aa49 tuned signature;
wenzelm
parents: 49408
diff changeset
   309
              r <- JEdit_Lib.gfx_range(text_area, range)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   310
            } {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   311
              gfx.setColor(color)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   312
              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
   313
              val y0 = r.y + fm.getAscent + 1
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   314
              for (x1 <- Range(x0, x0 + r.length, 2)) {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   315
                val y1 = if (x1 % 4 < 2) y0 else y0 + 1
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   316
                gfx.drawLine(x1, y1, x1 + 1, y1)
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   317
              }
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   318
            }
56550
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   319
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   320
            // spell-checker
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   321
            for {
56558
05c833d402bc tuned signature -- explicit Spell_Checker_Variable;
wenzelm
parents: 56551
diff changeset
   322
              spell_checker <- PIDE.spell_checker.get
56551
d4da2b11c729 more general spell_checker_elements;
wenzelm
parents: 56550
diff changeset
   323
              range0 <- rendering.spell_checker_ranges(line_range)
56550
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   324
              text <- JEdit_Lib.try_get_text(buffer, range0)
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   325
              range <- spell_checker.bad_words(text)
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   326
              r <- JEdit_Lib.gfx_range(text_area, range + range0.start)
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   327
            } {
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   328
              gfx.setColor(rendering.spell_checker_color)
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   329
              val y0 = r.y + fm.getAscent + 2
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   330
              gfx.drawLine(r.x, y0, r.x + r.length, y0)
b26bdc1f96e5 added spell-checker options;
wenzelm
parents: 56497
diff changeset
   331
            }
43376
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   332
          }
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   333
        }
0f6880c1c759 some direct text foreground painting, instead of token marking;
wenzelm
parents: 43375
diff changeset
   334
      }
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   335
    }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   336
  }
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   337
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   338
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   339
  /* text */
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   340
55766
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   341
  private def caret_enabled: Boolean =
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   342
    caret_visible && (!text_area.hasFocus || text_area.isCaretVisible)
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   343
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   344
  private def caret_color(rendering: Rendering): Color =
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   345
  {
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   346
    if (text_area.isCaretVisible)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   347
      text_area.getPainter.getCaretColor
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   348
    else rendering.caret_invisible_color
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   349
  }
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   350
50199
6d04e2422769 quasi-abstract module Rendering, with Isabelle-specific implementation;
wenzelm
parents: 50165
diff changeset
   351
  private def paint_chunk_list(rendering: Rendering,
43505
0aca4edbfa99 clarified chunk.offset, chunk.length;
wenzelm
parents: 43451
diff changeset
   352
    gfx: Graphics2D, line_start: Text.Offset, head: Chunk, x: Float, y: Float): Float =
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   353
  {
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   354
    val clip_rect = gfx.getClipBounds
43392
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
   355
    val painter = text_area.getPainter
fe4b8c52b1cc paint caret according to precise font metrics;
wenzelm
parents: 43383
diff changeset
   356
    val font_context = painter.getFontRenderContext
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   357
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   358
    val caret_range =
55766
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   359
      if (caret_enabled) JEdit_Lib.point_range(buffer, text_area.getCaretPosition)
56172
31289387fdf8 tuned signature;
wenzelm
parents: 55790
diff changeset
   360
      else Text.Range.offside
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   361
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   362
    var w = 0.0f
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   363
    var chunk = head
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   364
    while (chunk != null) {
43505
0aca4edbfa99 clarified chunk.offset, chunk.length;
wenzelm
parents: 43451
diff changeset
   365
      val chunk_offset = line_start + chunk.offset
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   366
      if (x + w + chunk.width > clip_rect.x &&
50306
b655d2d0406d updated to jedit-5.0.0;
wenzelm
parents: 50216
diff changeset
   367
          x + w < clip_rect.x + clip_rect.width && chunk.length > 0)
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   368
      {
43505
0aca4edbfa99 clarified chunk.offset, chunk.length;
wenzelm
parents: 43451
diff changeset
   369
        val chunk_range = Text.Range(chunk_offset, chunk_offset + chunk.length)
44662
c8f1d943bfc5 more robust chunk painting wrt. hard tabs, when chunk.str == null;
wenzelm
parents: 44545
diff changeset
   370
        val chunk_str = if (chunk.str == null) " " * chunk.length else chunk.str
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   371
        val chunk_font = chunk.style.getFont
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   372
        val chunk_color = chunk.style.getForegroundColor
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   373
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   374
        def string_width(s: String): Float =
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   375
          if (s.isEmpty) 0.0f
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   376
          else chunk_font.getStringBounds(s, font_context).getWidth.toFloat
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   377
43426
24e2e2f0032b more explicit treatment of ranges after revert/convert, which may well distort the overall start/end positions;
wenzelm
parents: 43419
diff changeset
   378
        val markup =
43428
b41dea5772c6 more robust treatment of partial range restriction;
wenzelm
parents: 43426
diff changeset
   379
          for {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   380
            r1 <- rendering.text_color(chunk_range, chunk_color)
43450
b6b09fc8d671 proper x1;
wenzelm
parents: 43448
diff changeset
   381
            r2 <- r1.try_restrict(chunk_range)
b6b09fc8d671 proper x1;
wenzelm
parents: 43448
diff changeset
   382
          } yield r2
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   383
56373
0605d90be6fc tuned signature -- more explicit iterator terminology;
wenzelm
parents: 56358
diff changeset
   384
        val padded_markup_iterator =
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   385
          if (markup.isEmpty)
46197
e4da482283ef tuned text_color: cumulate with explicit default color;
wenzelm
parents: 46178
diff changeset
   386
            Iterator(Text.Info(chunk_range, chunk_color))
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   387
          else
46197
e4da482283ef tuned text_color: cumulate with explicit default color;
wenzelm
parents: 46178
diff changeset
   388
            Iterator(
e4da482283ef tuned text_color: cumulate with explicit default color;
wenzelm
parents: 46178
diff changeset
   389
              Text.Info(Text.Range(chunk_range.start, markup.head.range.start), chunk_color)) ++
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   390
            markup.iterator ++
46197
e4da482283ef tuned text_color: cumulate with explicit default color;
wenzelm
parents: 46178
diff changeset
   391
            Iterator(Text.Info(Text.Range(markup.last.range.stop, chunk_range.stop), chunk_color))
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   392
43450
b6b09fc8d671 proper x1;
wenzelm
parents: 43448
diff changeset
   393
        var x1 = x + w
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   394
        gfx.setFont(chunk_font)
56373
0605d90be6fc tuned signature -- more explicit iterator terminology;
wenzelm
parents: 56358
diff changeset
   395
        for (Text.Info(range, color) <- padded_markup_iterator if !range.is_singularity) {
44662
c8f1d943bfc5 more robust chunk painting wrt. hard tabs, when chunk.str == null;
wenzelm
parents: 44545
diff changeset
   396
          val str = chunk_str.substring(range.start - chunk_offset, range.stop - chunk_offset)
46197
e4da482283ef tuned text_color: cumulate with explicit default color;
wenzelm
parents: 46178
diff changeset
   397
          gfx.setColor(color)
43448
90aec5043461 more robust caret painting wrt. surrogate characters;
wenzelm
parents: 43435
diff changeset
   398
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   399
          range.try_restrict(caret_range) match {
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   400
            case Some(r) if !r.is_singularity =>
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   401
              val i = r.start - range.start
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   402
              val j = r.stop - range.start
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   403
              val s1 = str.substring(0, i)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   404
              val s2 = str.substring(i, j)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   405
              val s3 = str.substring(j)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   406
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   407
              if (!s1.isEmpty) gfx.drawString(s1, x1, y)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   408
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   409
              val astr = new AttributedString(s2)
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   410
              astr.addAttribute(TextAttribute.FONT, chunk_font)
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   411
              astr.addAttribute(TextAttribute.FOREGROUND, caret_color(rendering))
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   412
              astr.addAttribute(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   413
              gfx.drawString(astr.getIterator, x1 + string_width(s1), y)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   414
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   415
              if (!s3.isEmpty)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   416
                gfx.drawString(s3, x1 + string_width(str.substring(0, j)), y)
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   417
43759
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   418
            case _ =>
d93a69672362 more uniform padded_markup, which is important for caret visibility despite absence of markup;
wenzelm
parents: 43506
diff changeset
   419
              gfx.drawString(str, x1, y)
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   420
          }
44056
be825a69fc67 less ambitious use of AttributedString, for proper caret painting within \<^sup>\<foobar>;
wenzelm
parents: 43759
diff changeset
   421
          x1 += string_width(str)
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   422
        }
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   423
      }
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   424
      w += chunk.width
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   425
      chunk = chunk.next.asInstanceOf[Chunk]
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   426
    }
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   427
    w
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   428
  }
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   429
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   430
  private val text_painter = new TextAreaExtension
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   431
  {
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   432
    override def paintScreenLineRange(gfx: Graphics2D,
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   433
      first_line: Int, last_line: Int, physical_lines: Array[Int],
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   434
      start: Array[Int], end: Array[Int], y: Int, line_height: Int)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   435
    {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   436
      robust_rendering { rendering =>
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   437
        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
   438
        val fm = painter.getFontMetrics
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   439
        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
   440
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   441
        val clip = gfx.getClip
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   442
        val x0 = text_area.getHorizontalOffset
43382
5d9d34bdec25 misc tuning and simplification;
wenzelm
parents: 43381
diff changeset
   443
        var y0 = y + fm.getHeight - (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
   444
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   445
        val (bullet_x, bullet_y, bullet_w, bullet_h) =
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   446
        {
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   447
          val w = fm.charWidth(' ')
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   448
          val b = (w / 2) max 1
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   449
          val c = (lm.getAscent + lm.getStrikethroughOffset).round.toInt
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   450
          ((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
   451
        }
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   452
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   453
        for (i <- 0 until physical_lines.length) {
49097
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   454
          val line = physical_lines(i)
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   455
          if (line != -1) {
51581
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   456
            val line_range = Text.Range(start(i), end(i))
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   457
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   458
            // bullet bar
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   459
            for {
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   460
              Text.Info(range, color) <- rendering.bullet(line_range)
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   461
              r <- JEdit_Lib.gfx_range(text_area, range)
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   462
            } {
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   463
              gfx.setColor(color)
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   464
              gfx.fillRect(r.x + bullet_x, y + i * line_height + bullet_y,
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   465
                r.length - bullet_w, line_height - bullet_h)
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   466
            }
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   467
587c917e8d36 paint bullet bar within text layer -- thus it remains visible with active selection etc.;
wenzelm
parents: 51577
diff changeset
   468
            // text chunks
49097
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   469
            val screen_line = first_line + i
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   470
            val chunks = text_area.getChunksOfScreenLine(screen_line)
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   471
            if (chunks != null) {
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   472
              try {
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   473
                val line_start = buffer.getLineStartOffset(line)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   474
                gfx.clipRect(x0, y + line_height * i, Integer.MAX_VALUE, line_height)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   475
                val w = paint_chunk_list(rendering, gfx, line_start, chunks, x0, y0).toInt
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   476
                gfx.clipRect(x0 + w.toInt, 0, Integer.MAX_VALUE, Integer.MAX_VALUE)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   477
                orig_text_painter.paintValidLine(gfx,
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   478
                  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
   479
              } finally { gfx.setClip(clip) }
49097
4e5e48c589ea more direct access to all-important chunks for text painting;
wenzelm
parents: 48921
diff changeset
   480
            }
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   481
          }
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   482
          y0 += line_height
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   483
        }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   484
      }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   485
    }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   486
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   487
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   488
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   489
  /* foreground */
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   490
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   491
  private val foreground_painter = new TextAreaExtension
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   492
  {
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   493
    override def paintScreenLineRange(gfx: Graphics2D,
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   494
      first_line: Int, last_line: Int, physical_lines: Array[Int],
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   495
      start: Array[Int], end: Array[Int], y: Int, line_height: Int)
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   496
    {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   497
      robust_rendering { rendering =>
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   498
        for (i <- 0 until physical_lines.length) {
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   499
          if (physical_lines(i) != -1) {
49843
afddf4e26fac further refinement of jEdit line range, avoiding lack of final \n;
wenzelm
parents: 49730
diff changeset
   500
            val line_range = Text.Range(start(i), end(i))
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   501
44545
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   502
            // foreground color
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   503
            for {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   504
              Text.Info(range, color) <- rendering.foreground(line_range)
49409
7140a738aa49 tuned signature;
wenzelm
parents: 49408
diff changeset
   505
              r <- JEdit_Lib.gfx_range(text_area, range)
44545
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   506
            } {
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   507
              gfx.setColor(color)
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   508
              gfx.fillRect(r.x, y + i * line_height, r.length, line_height)
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   509
            }
3c40007aa031 transparent foreground color for quoted entities;
wenzelm
parents: 44056
diff changeset
   510
49357
34ac36642a31 more general Document_Model.point_range;
wenzelm
parents: 49356
diff changeset
   511
            // highlight range -- potentially from other snapshot
46205
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   512
            for {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   513
              info <- highlight_area.info
46205
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   514
              Text.Info(range, color) <- info.try_restrict(line_range)
49409
7140a738aa49 tuned signature;
wenzelm
parents: 49408
diff changeset
   515
              r <- JEdit_Lib.gfx_range(text_area, range)
46205
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   516
            } {
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   517
              gfx.setColor(color)
07e334ad2e2a ignore empty gfx_range;
wenzelm
parents: 46204
diff changeset
   518
              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
   519
            }
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   520
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   521
            // hyperlink range -- potentially from other snapshot
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   522
            for {
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   523
              info <- hyperlink_area.info
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   524
              Text.Info(range, _) <- info.try_restrict(line_range)
49409
7140a738aa49 tuned signature;
wenzelm
parents: 49408
diff changeset
   525
              r <- JEdit_Lib.gfx_range(text_area, range)
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   526
            } {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   527
              gfx.setColor(rendering.hyperlink_color)
48921
5d8d409b897e support for direct hyperlinks, without the Hyperlinks plugin;
wenzelm
parents: 47471
diff changeset
   528
              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
   529
            }
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   530
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   531
            // completion range
55747
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   532
            if (!hyperlink_area.is_active && caret_visible) {
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   533
              for {
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   534
                completion <- Completion_Popup.Text_Area(text_area)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   535
                Text.Info(range, color) <- completion.rendering(rendering, line_range)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   536
                r <- JEdit_Lib.gfx_range(text_area, range)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   537
              } {
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   538
                gfx.setColor(color)
bef19c929ba5 more completion rendering: active, semantic, syntactic;
wenzelm
parents: 55726
diff changeset
   539
                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
   540
              }
55688
767edb2c1e4e some rendering of completion range;
wenzelm
parents: 53247
diff changeset
   541
            }
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   542
          }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   543
        }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   544
      }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   545
    }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   546
  }
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   547
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   548
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   549
  /* 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
   550
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   551
  private class Caret_Painter(before: Boolean) extends TextAreaExtension
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   552
  {
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   553
    override def paintValidLine(gfx: Graphics2D,
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   554
      screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   555
    {
49356
6e0c0ffb6ec7 more static handling of rendering options;
wenzelm
parents: 49355
diff changeset
   556
      robust_rendering { _ =>
43404
c8369f3d88a1 uniform use of Document_View.robust_body;
wenzelm
parents: 43398
diff changeset
   557
        if (before) gfx.clipRect(0, 0, 0, 0)
c8369f3d88a1 uniform use of Document_View.robust_body;
wenzelm
parents: 43398
diff changeset
   558
        else gfx.setClip(painter_clip)
c8369f3d88a1 uniform use of Document_View.robust_body;
wenzelm
parents: 43398
diff changeset
   559
      }
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   560
    }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   561
  }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   562
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   563
  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
   564
  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
   565
  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
   566
  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
   567
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   568
  private val caret_painter = new TextAreaExtension
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   569
  {
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   570
    override def paintValidLine(gfx: Graphics2D,
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   571
      screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   572
    {
55713
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   573
      robust_rendering { rendering =>
734ac5709fbe clarified painting of invisible caret, e.g. focus change due to popup;
wenzelm
parents: 55711
diff changeset
   574
        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
   575
          val caret = text_area.getCaretPosition
55766
6a16443e520e improved rendering of blinking cursor;
wenzelm
parents: 55747
diff changeset
   576
          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
   577
            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
   578
            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
   579
43398
c3e2a361b418 more robust painter_body wrt. EBP races and spurious exceptions (which causes jEdit to remove the extension);
wenzelm
parents: 43396
diff changeset
   580
            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
   581
            val x = text_area.offsetToXY(physical_line, offset).x
56358
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   582
            val y1 = y + fm.getHeight - (fm.getLeading + 1) - fm.getDescent
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   583
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   584
            val astr = new AttributedString(" ")
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   585
            astr.addAttribute(TextAttribute.FONT, painter.getFont)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   586
            astr.addAttribute(TextAttribute.FOREGROUND, caret_color(rendering))
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   587
            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
   588
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   589
            val clip = gfx.getClip
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   590
            try {
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   591
              gfx.clipRect(x, y, Integer.MAX_VALUE, painter.getLineHeight)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   592
              gfx.drawString(astr.getIterator, x, y1)
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   593
            }
ed09e5f3aedf more uniform painting of caret, which also improves visibility in invisible state;
wenzelm
parents: 56340
diff changeset
   594
            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
   595
          }
43393
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   596
        }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   597
      }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   598
    }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   599
  }
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   600
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   601
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   602
  /* activation */
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   603
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   604
  def activate()
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   605
  {
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   606
    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
   607
    painter.addExtension(TextAreaPainter.LOWEST_LAYER, set_state)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   608
    painter.addExtension(TextAreaPainter.LINE_BACKGROUND_LAYER + 1, background_painter)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   609
    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
   610
    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
   611
    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
   612
    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
   613
    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
   614
    painter.addExtension(TextAreaPainter.BLOCK_CARET_LAYER + 2, caret_painter)
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   615
    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
   616
    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
   617
    painter.removeExtension(orig_text_painter)
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   618
    painter.addMouseListener(mouse_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   619
    painter.addMouseMotionListener(mouse_motion_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   620
    text_area.addFocusListener(focus_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   621
    view.addWindowListener(window_listener)
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   622
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   623
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   624
  def deactivate()
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   625
  {
56340
af8cb60b55eb clear active areas (notably mouse pointer) before changing context (e.g. via hyperlink);
wenzelm
parents: 56339
diff changeset
   626
    active_reset()
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   627
    val painter = text_area.getPainter
49410
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   628
    view.removeWindowListener(window_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   629
    text_area.removeFocusListener(focus_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   630
    painter.removeMouseMotionListener(mouse_motion_listener)
34acbcc33adf tuned signature -- more general Text_Area_Painter operations;
wenzelm
parents: 49409
diff changeset
   631
    painter.removeMouseListener(mouse_listener)
43396
548a68eafaea recovered orig_text_painter from f4141da52e92;
wenzelm
parents: 43393
diff changeset
   632
    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
   633
    painter.removeExtension(reset_state)
43435
ae6b0c3e58a8 highlight via foreground painter, using alpha channel;
wenzelm
parents: 43434
diff changeset
   634
    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
   635
    painter.removeExtension(caret_painter)
f4141da52e92 more precise caret painting, working around existing painter (which is reinstalled by jEdit occasionally);
wenzelm
parents: 43392
diff changeset
   636
    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
   637
    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
   638
    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
   639
    painter.removeExtension(before_caret_painter1)
43381
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   640
    painter.removeExtension(text_painter)
806878ae2219 separate module for text area painting;
wenzelm
parents: 43376
diff changeset
   641
    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
   642
    painter.removeExtension(set_state)
43369
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   643
  }
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   644
}
4c86b3405010 separate isabelle.jedit.Text_Painter, which actually replaces the original TextAreaPainter$PaintText instance;
wenzelm
parents:
diff changeset
   645