@@ -69,6 +69,12 @@ public class FoldIndicator extends AbstractGutterComponent {
69
69
*/
70
70
private Color foldIconBackground ;
71
71
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
+
72
78
/**
73
79
* The icon used for collapsed folds.
74
80
*/
@@ -79,6 +85,18 @@ public class FoldIndicator extends AbstractGutterComponent {
79
85
*/
80
86
private Icon expandedFoldIcon ;
81
87
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
+
82
100
/**
83
101
* Whether tool tips are displayed showing the contents of collapsed
84
102
* fold regions.
@@ -138,6 +156,7 @@ public JToolTip createToolTip() {
138
156
private Fold findOpenFoldClosestTo (Point p ) {
139
157
140
158
Fold fold = null ;
159
+ mouseOverFoldIcon = false ;
141
160
142
161
RSyntaxTextArea rsta = (RSyntaxTextArea )textArea ;
143
162
if (rsta .isCodeFoldingEnabled ()) { // Should always be true
@@ -147,7 +166,11 @@ private Fold findOpenFoldClosestTo(Point p) {
147
166
int line = rsta .getLineOfOffset (offs );
148
167
FoldManager fm = rsta .getFoldManager ();
149
168
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 {
151
174
fold = fm .getDeepestOpenFoldContaining (offs );
152
175
}
153
176
} catch (BadLocationException ble ) {
@@ -161,12 +184,27 @@ private Fold findOpenFoldClosestTo(Point p) {
161
184
}
162
185
163
186
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
+
164
201
/**
165
202
* 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.
167
204
*
168
205
* @return The background color.
169
206
* @see #setFoldIconBackground(Color)
207
+ * @see #getFoldIconArmedBackground()
170
208
*/
171
209
public Color getFoldIconBackground () {
172
210
return foldIconBackground ;
@@ -379,11 +417,16 @@ protected void paintComponent(Graphics g) {
379
417
}
380
418
Fold fold = fm .getFoldForLine (line );
381
419
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
+ }
387
430
}
388
431
if (fold .isCollapsed ()) {
389
432
collapsedFoldIcon .paintIcon (this , g , x , y );
@@ -404,6 +447,7 @@ protected void paintComponent(Graphics g) {
404
447
else {
405
448
expandedFoldIcon .paintIcon (this , g , x , y );
406
449
}
450
+ paintFoldArmed = false ;
407
451
}
408
452
line ++;
409
453
y += cellHeight ;
@@ -498,11 +542,16 @@ private void paintComponentWrapped(Graphics g) {
498
542
}
499
543
Fold fold = fm .getFoldForLine (line );
500
544
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
+ }
506
555
}
507
556
if (fold .isCollapsed ()) {
508
557
collapsedFoldIcon .paintIcon (this , g , x , y );
@@ -515,6 +564,7 @@ private void paintComponentWrapped(Graphics g) {
515
564
y += curLineH ;
516
565
line ++;
517
566
}
567
+ paintFoldArmed = false ;
518
568
}
519
569
else {
520
570
y += curLineH ;
@@ -543,12 +593,27 @@ private int rowAtPoint(Point p) {
543
593
}
544
594
545
595
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
+
546
610
/**
547
611
* Sets the color to use for the "background" of fold icons. This will
548
612
* be ignored if custom icons are used.
549
613
*
550
- * @param bg The new background color.
614
+ * @param bg The new background color. This should not be {@code null}.
551
615
* @see #getFoldIconBackground()
616
+ * @see #setFoldIconArmedBackground(Color)
552
617
*/
553
618
public void setFoldIconBackground (Color bg ) {
554
619
foldIconBackground = bg ;
@@ -631,7 +696,11 @@ public int getIconWidth() {
631
696
632
697
@ Override
633
698
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 );
635
704
g .fillRect (x ,y , 8 ,8 );
636
705
g .setColor (getForeground ());
637
706
g .drawRect (x ,y , 8 ,8 );
@@ -658,12 +727,6 @@ private class Listener extends MouseInputAdapter
658
727
@ Override
659
728
public void mouseClicked (MouseEvent e ) {
660
729
661
- // // TODO: Implement code folding with word wrap enabled
662
- // if (textArea.getLineWrap()) {
663
- // UIManager.getLookAndFeel().provideErrorFeedback(textArea);
664
- // return;
665
- // }
666
-
667
730
Point p = e .getPoint ();
668
731
int line = rowAtPoint (p );
669
732
@@ -683,18 +746,23 @@ public void mouseClicked(MouseEvent e) {
683
746
public void mouseExited (MouseEvent e ) {
684
747
if (foldWithOutlineShowing !=null ) {
685
748
foldWithOutlineShowing = null ;
749
+ mouseOverFoldIcon = false ;
686
750
repaint ();
687
751
}
688
752
}
689
753
690
754
@ Override
691
755
public void mouseMoved (MouseEvent e ) {
756
+ boolean oldMouseOverFoldIcon = mouseOverFoldIcon ;
692
757
Fold newSelectedFold = findOpenFoldClosestTo (e .getPoint ());
693
758
if (newSelectedFold !=foldWithOutlineShowing &&
694
759
newSelectedFold !=null && !newSelectedFold .isOnSingleLine ()) {
695
760
foldWithOutlineShowing = newSelectedFold ;
696
761
repaint ();
697
762
}
763
+ else if (mouseOverFoldIcon != oldMouseOverFoldIcon ) {
764
+ repaint ();
765
+ }
698
766
}
699
767
700
768
@ Override
0 commit comments