src/Tools/jEdit/src/pretty_tooltip.scala
author wenzelm
Mon, 01 Jul 2013 15:08:29 +0200
changeset 52498 d802431fe356
parent 52497 2dd4e4a368e3
child 52548 a1a8248a4677
permissions -rw-r--r--
clarified focus after dismiss;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     1
/*  Title:      Tools/jEdit/src/pretty_tooltip.scala
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     3
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     4
Enhanced tooltip window based on Pretty_Text_Area.
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     5
*/
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     6
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     7
package isabelle.jedit
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     8
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
     9
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    10
import isabelle._
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    11
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    12
import java.awt.{Color, Point, BorderLayout, Dimension}
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    13
import java.awt.event.{FocusAdapter, FocusEvent}
52483
478ef4fa3d5a more direct use of screen location: avoid misplacement if parent component has already disappeared asynchronously;
wenzelm
parents: 52481
diff changeset
    14
import javax.swing.{JWindow, JPanel, JComponent, PopupFactory}
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    15
import javax.swing.border.LineBorder
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    16
49725
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
    17
import scala.swing.{FlowPanel, Label}
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
    18
import scala.swing.event.MouseClicked
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
    19
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    20
import org.gjt.sp.jedit.View
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    21
import org.gjt.sp.jedit.textarea.TextArea
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    22
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
    23
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    24
object Pretty_Tooltip
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    25
{
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    26
  /* tooltip hierarchy */
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    27
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    28
  // owned by Swing thread
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    29
  private var stack: List[Pretty_Tooltip] = Nil
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    30
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    31
  private def hierarchy(tip: Pretty_Tooltip): Option[(List[Pretty_Tooltip], List[Pretty_Tooltip])] =
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    32
  {
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    33
    Swing_Thread.require()
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    34
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    35
    if (stack.contains(tip)) Some(stack.span(_ != tip))
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
    36
    else None
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    37
  }
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    38
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    39
  def apply(
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    40
    view: View,
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    41
    parent: JComponent,
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    42
    rendering: Rendering,
52483
478ef4fa3d5a more direct use of screen location: avoid misplacement if parent component has already disappeared asynchronously;
wenzelm
parents: 52481
diff changeset
    43
    screen_point: Point,
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    44
    results: Command.Results,
52497
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    45
    info: Text.Info[XML.Body]): Pretty_Tooltip =
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    46
  {
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    47
    Swing_Thread.require()
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    48
52497
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    49
    stack match {
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    50
      case top :: _ if top.results == results && top.info == info => top
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    51
      case _ =>
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    52
        val (old, rest) =
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    53
          JEdit_Lib.ancestors(parent).collectFirst({ case x: Pretty_Tooltip => x }) match {
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    54
            case Some(tip) => hierarchy(tip).getOrElse((stack, Nil))
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    55
            case None => (stack, Nil)
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    56
          }
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    57
        old.foreach(_.hide_popup)
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    58
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    59
        val tip = new Pretty_Tooltip(view, rendering, parent, screen_point, results, info)
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    60
        stack = tip :: rest
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    61
        tip.show_popup
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    62
        tip
52496
8188e5286662 avoid repeated window popup when the mouse is moved over the same content (again, see also cb677987b7e3 and 0a1db0d02628);
wenzelm
parents: 52494
diff changeset
    63
    }
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
    64
  }
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    65
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    66
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    67
  /* pending event and active state */  // owned by Swing thread
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    68
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    69
  private var pending: Option[() => Unit] = None
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    70
  private var active = true
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    71
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    72
  private val pending_delay =
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    73
    Swing_Thread.delay_last(PIDE.options.seconds("jedit_tooltip_delay")) {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    74
      pending match {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    75
        case Some(body) => pending = None; body()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    76
        case None =>
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    77
      }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    78
    }
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    79
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    80
  def invoke(body: () => Unit): Unit =
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    81
    Swing_Thread.required {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    82
      if (active) {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    83
        pending = Some(body)
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    84
        pending_delay.invoke()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    85
      }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    86
    }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    87
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    88
  private lazy val reactivate_delay =
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    89
    Swing_Thread.delay_last(PIDE.options.seconds("jedit_tooltip_delay")) {
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    90
      active = true
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    91
    }
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    92
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    93
  private def deactivate(): Unit =
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    94
    Swing_Thread.required {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    95
      pending = None
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    96
      active = false
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    97
      pending_delay.revoke()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    98
      reactivate_delay.invoke()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    99
    }
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   100
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   101
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   102
  /* dismiss */
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   103
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   104
  def dismiss(tip: Pretty_Tooltip)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   105
  {
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   106
    deactivate()
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   107
    hierarchy(tip) match {
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   108
      case Some((old, _ :: rest)) =>
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   109
        old.foreach(_.hide_popup)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   110
        tip.hide_popup
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   111
        stack = rest
52498
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   112
        rest match {
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   113
          case top :: _ => top.request_focus
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   114
          case Nil =>
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   115
        }
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   116
      case _ =>
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   117
    }
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   118
  }
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   119
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   120
  def dismiss_all()
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   121
  {
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   122
    deactivate()
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   123
    stack.foreach(_.hide_popup)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   124
    stack = Nil
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   125
  }
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   126
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   127
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   128
  /* auxiliary geometry measurement */
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   129
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   130
  private lazy val dummy_window = new JWindow
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   131
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   132
  private def decoration_size(tip: Pretty_Tooltip): (Int, Int) =
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   133
  {
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   134
    val old_content = dummy_window.getContentPane
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   135
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   136
    dummy_window.setContentPane(tip)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   137
    dummy_window.pack
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   138
    dummy_window.revalidate
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   139
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   140
    val painter = tip.pretty_text_area.getPainter
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   141
    val w = dummy_window.getWidth - painter.getWidth
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   142
    val h = dummy_window.getHeight - painter.getHeight
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   143
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   144
    dummy_window.setContentPane(old_content)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   145
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   146
    (w, h)
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   147
  }
51449
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
   148
}
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
   149
8d6e478934dc explicit handling of tooltip window stack -- avoid memory leak due to not-so-weak references to disposed windows (via event handlers and other aux. components);
wenzelm
parents: 51440
diff changeset
   150
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   151
class Pretty_Tooltip private(
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   152
  view: View,
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   153
  rendering: Rendering,
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   154
  parent: JComponent,
52483
478ef4fa3d5a more direct use of screen location: avoid misplacement if parent component has already disappeared asynchronously;
wenzelm
parents: 52481
diff changeset
   155
  screen_point: Point,
52496
8188e5286662 avoid repeated window popup when the mouse is moved over the same content (again, see also cb677987b7e3 and 0a1db0d02628);
wenzelm
parents: 52494
diff changeset
   156
  private val results: Command.Results,
8188e5286662 avoid repeated window popup when the mouse is moved over the same content (again, see also cb677987b7e3 and 0a1db0d02628);
wenzelm
parents: 52494
diff changeset
   157
  private val info: Text.Info[XML.Body]) extends JPanel(new BorderLayout)
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
   158
{
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   159
  tip =>
49705
036c9a028dbd close tooltip window on escape;
wenzelm
parents: 49703
diff changeset
   160
49725
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   161
  Swing_Thread.require()
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   162
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   163
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   164
  /* controls */
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   165
49727
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   166
  private val close = new Label {
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   167
    icon = rendering.tooltip_close_icon
49727
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   168
    tooltip = "Close tooltip window"
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   169
    listenTo(mouse.clicks)
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   170
    reactions += { case _: MouseClicked => Pretty_Tooltip.dismiss(tip) }
49727
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   171
  }
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   172
49726
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   173
  private val detach = new Label {
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   174
    icon = rendering.tooltip_detach_icon
49726
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   175
    tooltip = "Detach tooltip window"
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   176
    listenTo(mouse.clicks)
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   177
    reactions += {
50501
6f41f1646617 more careful handling of Dialog_Result, with active area and color feedback;
wenzelm
parents: 50206
diff changeset
   178
      case _: MouseClicked =>
52496
8188e5286662 avoid repeated window popup when the mouse is moved over the same content (again, see also cb677987b7e3 and 0a1db0d02628);
wenzelm
parents: 52494
diff changeset
   179
        Info_Dockable(view, rendering.snapshot, results, info.info)
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   180
        Pretty_Tooltip.dismiss(tip)
49726
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   181
    }
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   182
  }
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   183
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   184
  private val controls = new FlowPanel(FlowPanel.Alignment.Left)(close, detach) {
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   185
    background = rendering.tooltip_color
49709
3062937b45b3 tuned window position to fit on screen;
wenzelm
parents: 49708
diff changeset
   186
  }
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   187
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   188
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   189
  /* text area */
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   190
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   191
  val pretty_text_area =
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   192
    new Pretty_Text_Area(view, () => Pretty_Tooltip.dismiss(tip), true) {
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   193
      override def get_background() = Some(rendering.tooltip_color)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   194
    }
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   195
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   196
  pretty_text_area.addFocusListener(new FocusAdapter {
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   197
    override def focusGained(e: FocusEvent)
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   198
    {
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   199
      tip_border(true)
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   200
    }
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   201
    override def focusLost(e: FocusEvent)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   202
    {
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   203
      Pretty_Tooltip.hierarchy(tip) match {
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   204
        case Some((Nil, _)) => Pretty_Tooltip.dismiss(tip)
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   205
        case _ => tip_border(false)
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   206
      }
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   207
    }
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   208
  })
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   209
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   210
  pretty_text_area.resize(Rendering.font_family(),
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   211
    Rendering.font_size("jedit_tooltip_font_scale").round)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   212
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   213
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   214
  /* main content */
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   215
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   216
  def tip_border(has_focus: Boolean)
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   217
  {
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   218
    tip.setBorder(new LineBorder(if (has_focus) Color.BLACK else Color.GRAY))
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   219
    tip.repaint()
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   220
  }
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   221
  tip_border(true)
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   222
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   223
  override def getFocusTraversalKeysEnabled = false
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   224
  tip.setBackground(rendering.tooltip_color)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   225
  tip.add(controls.peer, BorderLayout.NORTH)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   226
  tip.add(pretty_text_area)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   227
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   228
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   229
  /* popup */
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   230
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   231
  private val popup =
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   232
  {
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   233
    val screen_bounds = JEdit_Lib.screen_bounds(screen_point)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   234
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   235
    val (w, h) =
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   236
    {
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   237
      val painter = pretty_text_area.getPainter
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   238
      val metric = JEdit_Lib.pretty_metric(painter)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   239
      val margin = rendering.tooltip_margin * metric.average
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   240
52496
8188e5286662 avoid repeated window popup when the mouse is moved over the same content (again, see also cb677987b7e3 and 0a1db0d02628);
wenzelm
parents: 52494
diff changeset
   241
      val formatted = Pretty.formatted(info.info, margin, metric)
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   242
      val lines =
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   243
        XML.traverse_text(formatted)(0)(
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   244
          (n: Int, s: String) => n + s.iterator.filter(_ == '\n').length)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   245
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   246
      val (deco_width, deco_height) = Pretty_Tooltip.decoration_size(tip)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   247
      val bounds = rendering.tooltip_bounds
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   248
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   249
      val h1 = painter.getFontMetrics.getHeight * (lines + 1) + deco_height
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   250
      val h2 = (screen_bounds.height * bounds).toInt
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   251
      val h = h1 min h2
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   252
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   253
      val margin1 =
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   254
        if (h1 <= h2)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   255
          (0.0 /: split_lines(XML.content(formatted)))({ case (m, line) => m max metric(line) })
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   256
        else margin
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   257
      val w =
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   258
        ((metric.unit * (margin1 + metric.average)).round.toInt + deco_width) min
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   259
        (screen_bounds.width * bounds).toInt
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   260
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   261
      (w, h)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   262
    }
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   263
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   264
    tip.setSize(new Dimension(w, h))
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   265
    tip.setPreferredSize(new Dimension(w, h))
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   266
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   267
    val x = screen_point.x min (screen_bounds.x + screen_bounds.width - tip.getWidth)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   268
    val y = screen_point.y min (screen_bounds.y + screen_bounds.height - tip.getHeight)
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   269
    PopupFactory.getSharedInstance.getPopup(parent, tip, x, y)
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   270
  }
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   271
52484
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   272
  private def show_popup
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   273
  {
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   274
    popup.show
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   275
    pretty_text_area.requestFocus
52496
8188e5286662 avoid repeated window popup when the mouse is moved over the same content (again, see also cb677987b7e3 and 0a1db0d02628);
wenzelm
parents: 52494
diff changeset
   276
    pretty_text_area.update(rendering.snapshot, results, info.info)
52484
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   277
  }
52478
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   278
0a1db0d02628 manage popup windows via PopupFactory, which prefers light-weight JComponent, but might fall back on JWindow (despite JPanel of 0f88591478e6);
wenzelm
parents: 52472
diff changeset
   279
  private def hide_popup: Unit = popup.hide
52498
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   280
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   281
  private def request_focus: Unit = pretty_text_area.requestFocus
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
   282
}
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
   283