src/Tools/jEdit/src/pretty_tooltip.scala
author wenzelm
Mon, 31 Mar 2014 20:45:30 +0200
changeset 56341 bfd13102eb54
parent 55825 694833e3e4a0
child 56497 0c63f3538639
permissions -rw-r--r--
observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
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
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
     4
Tooltip based on Pretty_Text_Area.
49702
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}
53778
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    14
import javax.swing.{JPanel, JComponent, SwingUtilities, JLayeredPane}
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,
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
    42
    location: 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
    43
    rendering: Rendering,
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,
53778
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    45
    info: Text.Info[XML.Body])
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 {
53779
wenzelm
parents: 53778
diff changeset
    50
      case top :: _ if top.results == results && top.info == info =>
52497
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    51
      case _ =>
53778
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    52
        GUI.layered_pane(parent) match {
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    53
          case None =>
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    54
          case Some(layered) =>
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    55
            val (old, rest) =
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    56
              GUI.ancestors(parent).collectFirst({ case x: Pretty_Tooltip => x }) match {
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    57
                case Some(tip) => hierarchy(tip).getOrElse((stack, Nil))
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    58
                case None => (stack, Nil)
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    59
              }
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    60
            old.foreach(_.hide_popup)
52497
2dd4e4a368e3 tuned signature;
wenzelm
parents: 52496
diff changeset
    61
53778
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    62
            val loc = SwingUtilities.convertPoint(parent, location, layered)
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    63
            val tip = new Pretty_Tooltip(view, layered, loc, rendering, results, info)
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    64
            stack = tip :: rest
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    65
            tip.show_popup
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
    66
        }
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
    67
    }
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
    68
  }
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    69
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    70
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    71
  /* 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
    72
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    73
  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
    74
  private var active = true
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    75
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    76
  private val pending_delay =
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    77
    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
    78
      pending match {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    79
        case Some(body) => pending = None; body()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    80
        case None =>
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    81
      }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    82
    }
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    83
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    84
  def invoke(body: () => Unit): Unit =
52859
f31624cc4467 tuned signature;
wenzelm
parents: 52664
diff changeset
    85
    Swing_Thread.require {
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    86
      if (active) {
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    87
        pending = Some(body)
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    88
        pending_delay.invoke()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    89
      }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    90
    }
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
    91
52664
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
    92
  def revoke(): Unit =
52859
f31624cc4467 tuned signature;
wenzelm
parents: 52664
diff changeset
    93
    Swing_Thread.require {
52664
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
    94
      pending = None
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
    95
      pending_delay.revoke()
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
    96
    }
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
    97
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    98
  private lazy val reactivate_delay =
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
    99
    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
   100
      active = true
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   101
    }
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   102
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   103
  private def deactivate(): Unit =
52859
f31624cc4467 tuned signature;
wenzelm
parents: 52664
diff changeset
   104
    Swing_Thread.require {
52664
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
   105
      revoke()
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   106
      active = false
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   107
      reactivate_delay.invoke()
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   108
    }
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
   109
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   110
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   111
  /* dismiss */
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   112
56341
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   113
  private lazy val focus_delay = Swing_Thread.delay_last(PIDE.options.seconds("editor_input_delay"))
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   114
  {
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   115
    dismiss_unfocused()
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   116
  }
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   117
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   118
  def dismiss_unfocused()
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   119
  {
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   120
    stack.span(tip => !tip.pretty_text_area.isFocusOwner) match {
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   121
      case (Nil, _) =>
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   122
      case (unfocused, rest) =>
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   123
        deactivate()
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   124
        unfocused.foreach(_.hide_popup)
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   125
        stack = rest
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   126
    }
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   127
  }
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   128
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
   129
  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
   130
  {
52494
a1e09340c0f4 clarified tooltip timing of pending event and active state;
wenzelm
parents: 52493
diff changeset
   131
    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
   132
    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
   133
      case Some((old, _ :: rest)) =>
52498
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   134
        rest match {
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   135
          case top :: _ => top.request_focus
53003
39da27fc6101 attempt to transfer focus back to main window after closing popups, which is potentially relevant for heavy-weight windows (cf. workaround in org/gjt/sp/jedit/gui/CompletionPopup.java);
wenzelm
parents: 52859
diff changeset
   136
          case Nil => JEdit_Lib.request_focus_view
52498
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   137
        }
54376
3eb84b6b0353 transfer focus before closing old component -- avoid intermediate focus switch to root component, which is actually visible e.g. on Windows;
wenzelm
parents: 53779
diff changeset
   138
        old.foreach(_.hide_popup)
3eb84b6b0353 transfer focus before closing old component -- avoid intermediate focus switch to root component, which is actually visible e.g. on Windows;
wenzelm
parents: 53779
diff changeset
   139
        tip.hide_popup
3eb84b6b0353 transfer focus before closing old component -- avoid intermediate focus switch to root component, which is actually visible e.g. on Windows;
wenzelm
parents: 53779
diff changeset
   140
        stack = rest
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
   141
      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
   142
    }
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
52548
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   145
  def dismissed_all(): Boolean =
52664
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
   146
  {
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
   147
    deactivate()
52548
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   148
    if (stack.isEmpty) false
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   149
    else {
54376
3eb84b6b0353 transfer focus before closing old component -- avoid intermediate focus switch to root component, which is actually visible e.g. on Windows;
wenzelm
parents: 53779
diff changeset
   150
      JEdit_Lib.request_focus_view
52548
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   151
      stack.foreach(_.hide_popup)
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   152
      stack = Nil
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   153
      true
a1a8248a4677 some attempts to avoid sandwiching of actions stemming from single ESCAPE key event, to avoid potential conflict with ongoing text selection;
wenzelm
parents: 52498
diff changeset
   154
    }
52664
e99a0a43720b deactivate/revoke mouse event more thoroughly, to avoid "Implicit change of text area buffer";
wenzelm
parents: 52548
diff changeset
   155
  }
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
   156
}
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
   157
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
   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
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
   160
  view: View,
53778
29eaacff4078 proper layered pane at root of parent component, not global view (e.g. relevant for tooltips for detached info windows);
wenzelm
parents: 53712
diff changeset
   161
  layered: JLayeredPane,
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   162
  location: Point,
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
   163
  rendering: Rendering,
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
   164
  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
   165
  private val info: Text.Info[XML.Body]) extends JPanel(new BorderLayout)
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
   166
{
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
  tip =>
49705
036c9a028dbd close tooltip window on escape;
wenzelm
parents: 49703
diff changeset
   168
49725
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   169
  Swing_Thread.require()
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   170
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   171
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   172
  /* controls */
f8eeff667076 explicit close button;
wenzelm
parents: 49712
diff changeset
   173
49727
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   174
  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
   175
    icon = rendering.tooltip_close_icon
49727
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   176
    tooltip = "Close tooltip window"
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   177
    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
   178
    reactions += { case _: MouseClicked => Pretty_Tooltip.dismiss(tip) }
49727
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   179
  }
2fe56b600698 make buttons closer to original mouse position;
wenzelm
parents: 49726
diff changeset
   180
49726
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   181
  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
   182
    icon = rendering.tooltip_detach_icon
49726
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   183
    tooltip = "Detach tooltip window"
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   184
    listenTo(mouse.clicks)
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   185
    reactions += {
50501
6f41f1646617 more careful handling of Dialog_Result, with active area and color feedback;
wenzelm
parents: 50206
diff changeset
   186
      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
   187
        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
   188
        Pretty_Tooltip.dismiss(tip)
49726
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   189
    }
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   190
  }
2074197dc274 detach tooltip as dockable window;
wenzelm
parents: 49725
diff changeset
   191
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
   192
  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
   193
    background = rendering.tooltip_color
49709
3062937b45b3 tuned window position to fit on screen;
wenzelm
parents: 49708
diff changeset
   194
  }
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   195
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   196
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
   197
  /* 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
   198
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
   199
  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
   200
    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
   201
      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
   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
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
  pretty_text_area.addFocusListener(new FocusAdapter {
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   205
    override def focusGained(e: FocusEvent)
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   206
    {
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   207
      tip_border(true)
56341
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   208
      Pretty_Tooltip.focus_delay.invoke()
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
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
    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
   211
    {
56341
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   212
      tip_border(false)
bfd13102eb54 observe focus change for all tooltips, e.g. relevant for focus change to unrelated components;
wenzelm
parents: 55825
diff changeset
   213
      Pretty_Tooltip.focus_delay.invoke()
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
   214
    }
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
  })
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   216
55825
694833e3e4a0 tuned signature -- separate module Font_Info;
wenzelm
parents: 54376
diff changeset
   217
  pretty_text_area.resize(Font_Info.main(PIDE.options.real("jedit_popup_font_scale")))
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
   218
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
   219
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
   220
  /* 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
   221
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   222
  def tip_border(has_focus: Boolean)
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   223
  {
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   224
    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
   225
    tip.repaint()
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   226
  }
52493
ee7218d28159 less intrusive border, notably on windows;
wenzelm
parents: 52492
diff changeset
   227
  tip_border(true)
52491
d435febab327 visually explicit focus (behaviour dependent on platform and look-and-feel);
wenzelm
parents: 52484
diff changeset
   228
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
   229
  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
   230
  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
   231
  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
   232
  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
   233
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
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
   235
  /* 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
   236
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
   237
  private val popup =
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   238
  {
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   239
    val screen = JEdit_Lib.screen_location(layered, location)
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   240
    val size =
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   241
    {
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   242
      val painter = pretty_text_area.getPainter
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   243
      val metric = JEdit_Lib.pretty_metric(painter)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   244
      val margin = rendering.tooltip_margin * metric.average
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   245
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
   246
      val formatted = Pretty.formatted(info.info, margin, metric)
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   247
      val lines =
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   248
        XML.traverse_text(formatted)(0)(
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   249
          (n: Int, s: String) => n + s.iterator.filter(_ == '\n').length)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   250
53019
be9e94594b96 more general window_geometry;
wenzelm
parents: 53003
diff changeset
   251
      val geometry = JEdit_Lib.window_geometry(tip, tip.pretty_text_area.getPainter)
53230
6589ff56cc3c determine completion geometry like tooltip;
wenzelm
parents: 53229
diff changeset
   252
      val bounds = Rendering.popup_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
   253
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   254
      val h0 = layered.getHeight
53019
be9e94594b96 more general window_geometry;
wenzelm
parents: 53003
diff changeset
   255
      val h1 = painter.getFontMetrics.getHeight * (lines + 1) + geometry.deco_height
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   256
      val h2 = h0 min (screen.bounds.height * bounds).toInt
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   257
      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
   258
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   259
      val margin1 =
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   260
        if (h1 <= h2)
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   261
          (0.0 /: split_lines(XML.content(formatted)))({ case (m, line) => m max metric(line) })
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   262
        else margin
53184
5d6ffb87ee08 confine popup to parent component, to avoid javax.swing.PopupFactory$HeavyWeightPopup and its problems with Linux window management and Mac OS X key handling;
wenzelm
parents: 53019
diff changeset
   263
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   264
      val w0 = layered.getWidth
53184
5d6ffb87ee08 confine popup to parent component, to avoid javax.swing.PopupFactory$HeavyWeightPopup and its problems with Linux window management and Mac OS X key handling;
wenzelm
parents: 53019
diff changeset
   265
      val w1 = (metric.unit * (margin1 + metric.average)).round.toInt + geometry.deco_width
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   266
      val w2 = w0 min (screen.bounds.width * bounds).toInt
53184
5d6ffb87ee08 confine popup to parent component, to avoid javax.swing.PopupFactory$HeavyWeightPopup and its problems with Linux window management and Mac OS X key handling;
wenzelm
parents: 53019
diff changeset
   267
      val w = w1 min w2
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   268
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   269
      new Dimension(w, h)
52492
0f0f80e41581 tighten tooltip size;
wenzelm
parents: 52491
diff changeset
   270
    }
53247
bd595338ca18 uniform use of isabelle.jEdit.Popup, based on generic screen location operations;
wenzelm
parents: 53230
diff changeset
   271
    new Popup(layered, tip, screen.relative(layered, size), size)
51452
14e6d761ba1c extra tooltip_delay after window.dismiss operation, to avoid flickering of quick reactivation;
wenzelm
parents: 51451
diff changeset
   272
  }
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
   273
52484
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   274
  private def show_popup
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   275
  {
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   276
    popup.show
23a09c639700 avoid potential race condition of focusLost/dismiss vs. popup.show;
wenzelm
parents: 52483
diff changeset
   277
    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
   278
    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
   279
  }
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
   280
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
   281
  private def hide_popup: Unit = popup.hide
52498
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   282
d802431fe356 clarified focus after dismiss;
wenzelm
parents: 52497
diff changeset
   283
  private def request_focus: Unit = pretty_text_area.requestFocus
49702
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
   284
}
696e91c0bc80 separate module Pretty_Tooltip;
wenzelm
parents:
diff changeset
   285