@@ -69,6 +69,12 @@ public class FoldIndicator extends AbstractGutterComponent {
6969 */
7070 private Color foldIconBackground ;
7171
72+ /**
73+ * The color to use for armed fold icon backgrounds, if the default icons
74+ * are used. This may be {@code null}.
75+ */
76+ private Color foldIconArmedBackground ;
77+
7278 /**
7379 * The icon used for collapsed folds.
7480 */
@@ -79,6 +85,18 @@ public class FoldIndicator extends AbstractGutterComponent {
7985 */
8086 private Icon expandedFoldIcon ;
8187
88+ /**
89+ * Used while painting; global flag to denote whether the mouse is over
90+ * a fold indicator.
91+ */
92+ private boolean mouseOverFoldIcon ;
93+
94+ /**
95+ * Used while painting; global flag to denote whether the
96+ * currently-being-painted fold should be rendered as armed.
97+ */
98+ private boolean paintFoldArmed ;
99+
82100 /**
83101 * Whether tool tips are displayed showing the contents of collapsed
84102 * fold regions.
@@ -138,6 +156,7 @@ public JToolTip createToolTip() {
138156 private Fold findOpenFoldClosestTo (Point p ) {
139157
140158 Fold fold = null ;
159+ mouseOverFoldIcon = false ;
141160
142161 RSyntaxTextArea rsta = (RSyntaxTextArea )textArea ;
143162 if (rsta .isCodeFoldingEnabled ()) { // Should always be true
@@ -147,7 +166,11 @@ private Fold findOpenFoldClosestTo(Point p) {
147166 int line = rsta .getLineOfOffset (offs );
148167 FoldManager fm = rsta .getFoldManager ();
149168 fold = fm .getFoldForLine (line );
150- if (fold ==null ) {
169+ if (fold != null ) {
170+ // The mouse is directly over the fold indicator
171+ mouseOverFoldIcon = true ;
172+ }
173+ else {
151174 fold = fm .getDeepestOpenFoldContaining (offs );
152175 }
153176 } catch (BadLocationException ble ) {
@@ -161,12 +184,27 @@ private Fold findOpenFoldClosestTo(Point p) {
161184 }
162185
163186
187+ /**
188+ * Returns the color to use for the "background" of armed fold icons. This
189+ * is ignored if custom icons are used.
190+ *
191+ * @return The background color. If this is {@code null}, there is no
192+ * special color for armed fold icons.
193+ * @see #setFoldIconArmedBackground(Color)
194+ * @see #getFoldIconBackground()
195+ */
196+ public Color getFoldIconArmedBackground () {
197+ return foldIconArmedBackground ;
198+ }
199+
200+
164201 /**
165202 * Returns the color to use for the "background" of fold icons. This
166- * is be ignored if custom icons are used.
203+ * is ignored if custom icons are used.
167204 *
168205 * @return The background color.
169206 * @see #setFoldIconBackground(Color)
207+ * @see #getFoldIconArmedBackground()
170208 */
171209 public Color getFoldIconBackground () {
172210 return foldIconBackground ;
@@ -379,11 +417,16 @@ protected void paintComponent(Graphics g) {
379417 }
380418 Fold fold = fm .getFoldForLine (line );
381419 if (fold !=null ) {
382- if (fold ==foldWithOutlineShowing && !fold .isCollapsed ()) {
383- g .setColor (getForeground ());
384- int w2 = width /2 ;
385- g .drawLine (w2 ,y +cellHeight /2 , w2 ,y +cellHeight );
386- paintingOutlineLine = true ;
420+ if (fold ==foldWithOutlineShowing ) {
421+ if (!fold .isCollapsed ()) {
422+ g .setColor (getForeground ());
423+ int w2 = width /2 ;
424+ g .drawLine (w2 ,y +cellHeight /2 , w2 ,y +cellHeight );
425+ paintingOutlineLine = true ;
426+ }
427+ if (mouseOverFoldIcon ) {
428+ paintFoldArmed = true ;
429+ }
387430 }
388431 if (fold .isCollapsed ()) {
389432 collapsedFoldIcon .paintIcon (this , g , x , y );
@@ -404,6 +447,7 @@ protected void paintComponent(Graphics g) {
404447 else {
405448 expandedFoldIcon .paintIcon (this , g , x , y );
406449 }
450+ paintFoldArmed = false ;
407451 }
408452 line ++;
409453 y += cellHeight ;
@@ -498,11 +542,16 @@ private void paintComponentWrapped(Graphics g) {
498542 }
499543 Fold fold = fm .getFoldForLine (line );
500544 if (fold !=null ) {
501- if (fold ==foldWithOutlineShowing && !fold .isCollapsed ()) {
502- g .setColor (getForeground ());
503- int w2 = width /2 ;
504- g .drawLine (w2 ,y +cellHeight /2 , w2 ,y +curLineH );
505- paintingOutlineLine = true ;
545+ if (fold ==foldWithOutlineShowing ) {
546+ if (!fold .isCollapsed ()) {
547+ g .setColor (getForeground ());
548+ int w2 = width /2 ;
549+ g .drawLine (w2 ,y +cellHeight /2 , w2 ,y +curLineH );
550+ paintingOutlineLine = true ;
551+ }
552+ if (mouseOverFoldIcon ) {
553+ paintFoldArmed = true ;
554+ }
506555 }
507556 if (fold .isCollapsed ()) {
508557 collapsedFoldIcon .paintIcon (this , g , x , y );
@@ -515,6 +564,7 @@ private void paintComponentWrapped(Graphics g) {
515564 y += curLineH ;
516565 line ++;
517566 }
567+ paintFoldArmed = false ;
518568 }
519569 else {
520570 y += curLineH ;
@@ -543,12 +593,27 @@ private int rowAtPoint(Point p) {
543593 }
544594
545595
596+ /**
597+ * Sets the color to use for the "background" of armed fold icons. This
598+ * will be ignored if custom icons are used.
599+ *
600+ * @param bg The new background color. If {@code null} is passed in,
601+ * there will be no special color for armed fold icons.
602+ * @see #getFoldIconArmedBackground()
603+ * @see #setFoldIconBackground(Color)
604+ */
605+ public void setFoldIconArmedBackground (Color bg ) {
606+ foldIconArmedBackground = bg ;
607+ }
608+
609+
546610 /**
547611 * Sets the color to use for the "background" of fold icons. This will
548612 * be ignored if custom icons are used.
549613 *
550- * @param bg The new background color.
614+ * @param bg The new background color. This should not be {@code null}.
551615 * @see #getFoldIconBackground()
616+ * @see #setFoldIconArmedBackground(Color)
552617 */
553618 public void setFoldIconBackground (Color bg ) {
554619 foldIconBackground = bg ;
@@ -631,7 +696,11 @@ public int getIconWidth() {
631696
632697 @ Override
633698 public void paintIcon (Component c , Graphics g , int x , int y ) {
634- g .setColor (foldIconBackground );
699+ Color bg = foldIconBackground ;
700+ if (paintFoldArmed && foldIconArmedBackground != null ) {
701+ bg = foldIconArmedBackground ;
702+ }
703+ g .setColor (bg );
635704 g .fillRect (x ,y , 8 ,8 );
636705 g .setColor (getForeground ());
637706 g .drawRect (x ,y , 8 ,8 );
@@ -658,12 +727,6 @@ private class Listener extends MouseInputAdapter
658727 @ Override
659728 public void mouseClicked (MouseEvent e ) {
660729
661- // // TODO: Implement code folding with word wrap enabled
662- // if (textArea.getLineWrap()) {
663- // UIManager.getLookAndFeel().provideErrorFeedback(textArea);
664- // return;
665- // }
666-
667730 Point p = e .getPoint ();
668731 int line = rowAtPoint (p );
669732
@@ -683,18 +746,23 @@ public void mouseClicked(MouseEvent e) {
683746 public void mouseExited (MouseEvent e ) {
684747 if (foldWithOutlineShowing !=null ) {
685748 foldWithOutlineShowing = null ;
749+ mouseOverFoldIcon = false ;
686750 repaint ();
687751 }
688752 }
689753
690754 @ Override
691755 public void mouseMoved (MouseEvent e ) {
756+ boolean oldMouseOverFoldIcon = mouseOverFoldIcon ;
692757 Fold newSelectedFold = findOpenFoldClosestTo (e .getPoint ());
693758 if (newSelectedFold !=foldWithOutlineShowing &&
694759 newSelectedFold !=null && !newSelectedFold .isOnSingleLine ()) {
695760 foldWithOutlineShowing = newSelectedFold ;
696761 repaint ();
697762 }
763+ else if (mouseOverFoldIcon != oldMouseOverFoldIcon ) {
764+ repaint ();
765+ }
698766 }
699767
700768 @ Override
0 commit comments