src/Tools/jEdit/src/rich_text_area.scala
changeset 73340 0ffcad1f6130
parent 72927 69f768aff611
child 73343 d0378baf7d06
equal deleted inserted replaced
73339:9efdebe24c65 73340:0ffcad1f6130
   105 
   105 
   106   private val set_state = new TextAreaExtension
   106   private val set_state = new TextAreaExtension
   107   {
   107   {
   108     override def paintScreenLineRange(gfx: Graphics2D,
   108     override def paintScreenLineRange(gfx: Graphics2D,
   109       first_line: Int, last_line: Int, physical_lines: Array[Int],
   109       first_line: Int, last_line: Int, physical_lines: Array[Int],
   110       start: Array[Int], end: Array[Int], y: Int, line_height: Int)
   110       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   111     {
   111     {
   112       painter_rendering = get_rendering()
   112       painter_rendering = get_rendering()
   113       painter_clip = gfx.getClip
   113       painter_clip = gfx.getClip
   114       caret_focus =
   114       caret_focus =
   115         if (caret_enabled && !painter_rendering.snapshot.is_outdated) {
   115         if (caret_enabled && !painter_rendering.snapshot.is_outdated) {
   121 
   121 
   122   private val reset_state = new TextAreaExtension
   122   private val reset_state = new TextAreaExtension
   123   {
   123   {
   124     override def paintScreenLineRange(gfx: Graphics2D,
   124     override def paintScreenLineRange(gfx: Graphics2D,
   125       first_line: Int, last_line: Int, physical_lines: Array[Int],
   125       first_line: Int, last_line: Int, physical_lines: Array[Int],
   126       start: Array[Int], end: Array[Int], y: Int, line_height: Int)
   126       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   127     {
   127     {
   128       painter_rendering = null
   128       painter_rendering = null
   129       painter_clip = null
   129       painter_clip = null
   130       caret_focus = Rendering.Focus.empty
   130       caret_focus = Rendering.Focus.empty
   131     }
   131     }
   132   }
   132   }
   133 
   133 
   134   def robust_rendering(body: JEdit_Rendering => Unit)
   134   def robust_rendering(body: JEdit_Rendering => Unit): Unit =
   135   {
   135   {
   136     robust_body(()) { body(painter_rendering) }
   136     robust_body(()) { body(painter_rendering) }
   137   }
   137   }
   138 
   138 
   139 
   139 
   147 
   147 
   148     def is_active: Boolean = the_text_info.isDefined
   148     def is_active: Boolean = the_text_info.isDefined
   149     def text_info: Option[(String, Text.Info[A])] = the_text_info
   149     def text_info: Option[(String, Text.Info[A])] = the_text_info
   150     def info: Option[Text.Info[A]] = the_text_info.map(_._2)
   150     def info: Option[Text.Info[A]] = the_text_info.map(_._2)
   151 
   151 
   152     def update(new_info: Option[Text.Info[A]])
   152     def update(new_info: Option[Text.Info[A]]): Unit =
   153     {
   153     {
   154       val old_text_info = the_text_info
   154       val old_text_info = the_text_info
   155       val new_text_info =
   155       val new_text_info =
   156         new_info.map(info => (text_area.getText(info.range.start, info.range.length), info))
   156         new_info.map(info => (text_area.getText(info.range.start, info.range.length), info))
   157 
   157 
   171         } JEdit_Lib.invalidate_range(text_area, r2)
   171         } JEdit_Lib.invalidate_range(text_area, r2)
   172         the_text_info = new_text_info
   172         the_text_info = new_text_info
   173       }
   173       }
   174     }
   174     }
   175 
   175 
   176     def update_rendering(r: JEdit_Rendering, range: Text.Range)
   176     def update_rendering(r: JEdit_Rendering, range: Text.Range): Unit =
   177     { update(rendering(r)(range)) }
   177       update(rendering(r)(range))
   178 
   178 
   179     def reset { update(None) }
   179     def reset: Unit = update(None)
   180   }
   180   }
   181 
   181 
   182   // owned by GUI thread
   182   // owned by GUI thread
   183 
   183 
   184   private val highlight_area =
   184   private val highlight_area =
   199 
   199 
   200   private def area_active(): Boolean =
   200   private def area_active(): Boolean =
   201     active_areas.exists({ case (area, _) => area.is_active })
   201     active_areas.exists({ case (area, _) => area.is_active })
   202 
   202 
   203   private val focus_listener = new FocusAdapter {
   203   private val focus_listener = new FocusAdapter {
   204     override def focusLost(e: FocusEvent) { robust_body(()) { active_reset() } }
   204     override def focusLost(e: FocusEvent): Unit = { robust_body(()) { active_reset() } }
   205   }
   205   }
   206 
   206 
   207   private val window_listener = new WindowAdapter {
   207   private val window_listener = new WindowAdapter {
   208     override def windowIconified(e: WindowEvent) { robust_body(()) { active_reset() } }
   208     override def windowIconified(e: WindowEvent): Unit = { robust_body(()) { active_reset() } }
   209     override def windowDeactivated(e: WindowEvent) { robust_body(()) { active_reset() } }
   209     override def windowDeactivated(e: WindowEvent): Unit = { robust_body(()) { active_reset() } }
   210   }
   210   }
   211 
   211 
   212   private val mouse_listener = new MouseAdapter {
   212   private val mouse_listener = new MouseAdapter {
   213     override def mouseClicked(e: MouseEvent) {
   213     override def mouseClicked(e: MouseEvent): Unit =
       
   214     {
   214       robust_body(()) {
   215       robust_body(()) {
   215         hyperlink_area.info match {
   216         hyperlink_area.info match {
   216           case Some(Text.Info(range, link)) =>
   217           case Some(Text.Info(range, link)) =>
   217             if (!link.external) {
   218             if (!link.external) {
   218               try { text_area.moveCaretPosition(range.start) }
   219               try { text_area.moveCaretPosition(range.start) }
   244         SwingUtilities.convertPointFromScreen(point, painter)
   245         SwingUtilities.convertPointFromScreen(point, painter)
   245         painter.contains(point)
   246         painter.contains(point)
   246     }
   247     }
   247 
   248 
   248   private val mouse_motion_listener = new MouseMotionAdapter {
   249   private val mouse_motion_listener = new MouseMotionAdapter {
   249     override def mouseDragged(evt: MouseEvent) {
   250     override def mouseDragged(evt: MouseEvent): Unit =
       
   251     {
   250       robust_body(()) {
   252       robust_body(()) {
   251         active_reset()
   253         active_reset()
   252         Completion_Popup.Text_Area.dismissed(text_area)
   254         Completion_Popup.Text_Area.dismissed(text_area)
   253         Pretty_Tooltip.dismiss_descendant(text_area.getPainter)
   255         Pretty_Tooltip.dismiss_descendant(text_area.getPainter)
   254       }
   256       }
   255     }
   257     }
   256 
   258 
   257     override def mouseMoved(evt: MouseEvent) {
   259     override def mouseMoved(evt: MouseEvent): Unit =
       
   260     {
   258       robust_body(()) {
   261       robust_body(()) {
   259         val x = evt.getX
   262         val x = evt.getX
   260         val y = evt.getY
   263         val y = evt.getY
   261         val control = JEdit_Lib.command_modifier(evt)
   264         val control = JEdit_Lib.command_modifier(evt)
   262 
   265 
   309 
   312 
   310   private val background_painter = new TextAreaExtension
   313   private val background_painter = new TextAreaExtension
   311   {
   314   {
   312     override def paintScreenLineRange(gfx: Graphics2D,
   315     override def paintScreenLineRange(gfx: Graphics2D,
   313       first_line: Int, last_line: Int, physical_lines: Array[Int],
   316       first_line: Int, last_line: Int, physical_lines: Array[Int],
   314       start: Array[Int], end: Array[Int], y: Int, line_height: Int)
   317       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   315     {
   318     {
   316       robust_rendering { rendering =>
   319       robust_rendering { rendering =>
   317         val fm = text_area.getPainter.getFontMetrics
   320         val fm = text_area.getPainter.getFontMetrics
   318 
   321 
   319         for (i <- physical_lines.indices) {
   322         for (i <- physical_lines.indices) {
   487 
   490 
   488   private val text_painter = new TextAreaExtension
   491   private val text_painter = new TextAreaExtension
   489   {
   492   {
   490     override def paintScreenLineRange(gfx: Graphics2D,
   493     override def paintScreenLineRange(gfx: Graphics2D,
   491       first_line: Int, last_line: Int, physical_lines: Array[Int],
   494       first_line: Int, last_line: Int, physical_lines: Array[Int],
   492       start: Array[Int], end: Array[Int], y: Int, line_height: Int)
   495       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   493     {
   496     {
   494       robust_rendering { rendering =>
   497       robust_rendering { rendering =>
   495         val painter = text_area.getPainter
   498         val painter = text_area.getPainter
   496         val fm = painter.getFontMetrics
   499         val fm = painter.getFontMetrics
   497         val lm = painter.getFont.getLineMetrics(" ", painter.getFontRenderContext)
   500         val lm = painter.getFont.getLineMetrics(" ", painter.getFontRenderContext)
   548 
   551 
   549   private val foreground_painter = new TextAreaExtension
   552   private val foreground_painter = new TextAreaExtension
   550   {
   553   {
   551     override def paintScreenLineRange(gfx: Graphics2D,
   554     override def paintScreenLineRange(gfx: Graphics2D,
   552       first_line: Int, last_line: Int, physical_lines: Array[Int],
   555       first_line: Int, last_line: Int, physical_lines: Array[Int],
   553       start: Array[Int], end: Array[Int], y: Int, line_height: Int)
   556       start: Array[Int], end: Array[Int], y: Int, line_height: Int): Unit =
   554     {
   557     {
   555       robust_rendering { rendering =>
   558       robust_rendering { rendering =>
   556         val search_pattern = get_search_pattern()
   559         val search_pattern = get_search_pattern()
   557         for (i <- physical_lines.indices) {
   560         for (i <- physical_lines.indices) {
   558           if (physical_lines(i) != -1) {
   561           if (physical_lines(i) != -1) {
   631   /* caret -- outside of text range */
   634   /* caret -- outside of text range */
   632 
   635 
   633   private class Caret_Painter(before: Boolean) extends TextAreaExtension
   636   private class Caret_Painter(before: Boolean) extends TextAreaExtension
   634   {
   637   {
   635     override def paintValidLine(gfx: Graphics2D,
   638     override def paintValidLine(gfx: Graphics2D,
   636       screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int)
   639       screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int): Unit =
   637     {
   640     {
   638       robust_rendering { _ =>
   641       robust_rendering { _ =>
   639         if (before) gfx.clipRect(0, 0, 0, 0)
   642         if (before) gfx.clipRect(0, 0, 0, 0)
   640         else gfx.setClip(painter_clip)
   643         else gfx.setClip(painter_clip)
   641       }
   644       }
   648   private val after_caret_painter2 = new Caret_Painter(false)
   651   private val after_caret_painter2 = new Caret_Painter(false)
   649 
   652 
   650   private val caret_painter = new TextAreaExtension
   653   private val caret_painter = new TextAreaExtension
   651   {
   654   {
   652     override def paintValidLine(gfx: Graphics2D,
   655     override def paintValidLine(gfx: Graphics2D,
   653       screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int)
   656       screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int): Unit =
   654     {
   657     {
   655       robust_rendering { rendering =>
   658       robust_rendering { rendering =>
   656         if (caret_visible) {
   659         if (caret_visible) {
   657           val caret = text_area.getCaretPosition
   660           val caret = text_area.getCaretPosition
   658           if (caret_enabled && start <= caret && caret == end - 1) {
   661           if (caret_enabled && start <= caret && caret == end - 1) {
   681   }
   684   }
   682 
   685 
   683 
   686 
   684   /* activation */
   687   /* activation */
   685 
   688 
   686   def activate()
   689   def activate(): Unit =
   687   {
   690   {
   688     val painter = text_area.getPainter
   691     val painter = text_area.getPainter
   689     painter.addExtension(TextAreaPainter.LOWEST_LAYER, set_state)
   692     painter.addExtension(TextAreaPainter.LOWEST_LAYER, set_state)
   690     painter.addExtension(TextAreaPainter.LINE_BACKGROUND_LAYER + 1, background_painter)
   693     painter.addExtension(TextAreaPainter.LINE_BACKGROUND_LAYER + 1, background_painter)
   691     painter.addExtension(TextAreaPainter.TEXT_LAYER, text_painter)
   694     painter.addExtension(TextAreaPainter.TEXT_LAYER, text_painter)
   702     text_area.addKeyListener(key_listener)
   705     text_area.addKeyListener(key_listener)
   703     text_area.addFocusListener(focus_listener)
   706     text_area.addFocusListener(focus_listener)
   704     view.addWindowListener(window_listener)
   707     view.addWindowListener(window_listener)
   705   }
   708   }
   706 
   709 
   707   def deactivate()
   710   def deactivate(): Unit =
   708   {
   711   {
   709     active_reset()
   712     active_reset()
   710     val painter = text_area.getPainter
   713     val painter = text_area.getPainter
   711     view.removeWindowListener(window_listener)
   714     view.removeWindowListener(window_listener)
   712     text_area.removeFocusListener(focus_listener)
   715     text_area.removeFocusListener(focus_listener)