Skip to content

Commit af3fc88

Browse files
committed
Change rendering of dirty indicator in tabs - using a circle
Tabs render dirty parts by showing a `*` in front of the tab name (e.g., in front of the file name. This information is hard to see by developers. This change introduces a graphical indicator on the close button to highlight dirty (unsaved) changes.
1 parent f50772b commit af3fc88

File tree

2 files changed

+76
-33
lines changed

2 files changed

+76
-33
lines changed

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java

+46-33
Original file line numberDiff line numberDiff line change
@@ -877,44 +877,57 @@ void drawBody(GC gc, Rectangle bounds, int state) {
877877
}
878878
}
879879

880-
void drawClose(GC gc, Rectangle closeRect, int closeImageState) {
880+
void drawClose(GC gc, Rectangle closeRect, int closeImageState, boolean showDirtyIndicator) {
881881
if (closeRect.width == 0 || closeRect.height == 0) return;
882882

883-
// draw X with length of this constant
884-
final int lineLength = 8;
885-
int x = closeRect.x + Math.max(1, (closeRect.width-lineLength)/2);
886-
int y = closeRect.y + Math.max(1, (closeRect.height-lineLength)/2);
887-
y += parent.onBottom ? -1 : 1;
888883
int originalLineWidth = gc.getLineWidth();
889-
Color originalForeground = gc.getForeground();
890-
switch (closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) {
891-
case SWT.NONE: {
892-
drawCloseLines(gc, x, y , lineLength, false);
893-
break;
894-
}
895-
case SWT.HOT: {
896-
drawCloseLines(gc, x, y , lineLength, true);
897-
break;
898-
}
899-
case SWT.SELECTED: {
900-
drawCloseLines(gc, x, y , lineLength, true);
901-
break;
902-
}
903-
case SWT.BACKGROUND: {
904-
int[] shape = new int[] {x,y, x+10,y, x+10,y+10, x,y+10};
905-
drawBackground(gc, shape, false);
906-
break;
907-
}
908-
}
909-
gc.setLineWidth(originalLineWidth);
910-
gc.setForeground(originalForeground);
884+
int state = closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND);
885+
if (state == SWT.NONE) {
886+
if (showDirtyIndicator)
887+
drawDirtyIndicator(gc, closeRect, false);
888+
else
889+
drawCloseButton(gc, closeRect, false);
890+
} else if (state == SWT.HOT || state == SWT.SELECTED) {
891+
drawCloseButton(gc, closeRect, true);
892+
} else if (state == SWT.BACKGROUND) {
893+
if (showDirtyIndicator)
894+
drawDirtyIndicator(gc, closeRect, false);
895+
else
896+
drawBackground(gc, closeRect, SWT.BACKGROUND);
897+
}
898+
gc.setLineWidth(originalLineWidth);
899+
}
900+
901+
private void drawDirtyIndicator(GC gc, Rectangle closeRect, boolean hot) {
902+
String DIRTY_INDICATOR = "●";
903+
904+
Point stringExtent = gc.stringExtent(DIRTY_INDICATOR);
905+
int x = closeRect.x + (closeRect.width - stringExtent.x) / 2;
906+
int y = closeRect.y + (closeRect.height - stringExtent.y) / 2;
907+
gc.drawString(DIRTY_INDICATOR, x, y, true);
908+
}
909+
910+
private void drawCloseBackground(GC gc, Rectangle closeRect, Color backgroundColor) {
911+
Color originalBackground = gc.getBackground();
912+
gc.setBackground(backgroundColor);
913+
gc.setForeground(originalBackground);
914+
gc.fillRoundRectangle(closeRect.x + 1, closeRect.y + 2, closeRect.width - 2, closeRect.height - 2, 4, 4);
915+
gc.setBackground(originalBackground);
911916
}
912917

913-
private void drawCloseLines(GC gc, int x, int y, int lineLength, boolean hot) {
918+
919+
private void drawCloseButton(GC gc, Rectangle closeRect, boolean hot) {
914920
if (hot) {
915-
gc.setLineWidth(gc.getLineWidth() + 2);
916-
gc.setForeground(getFillColor());
921+
drawCloseBackground(gc, closeRect, parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
922+
// gc.setLineWidth(gc.getLineWidth() + 2);
923+
gc.setForeground(gc.getBackground());
917924
}
925+
// draw X with length of this constant
926+
final int lineLength = 9;
927+
int x = closeRect.x + Math.max(1, (closeRect.width-lineLength)/2);
928+
int y = closeRect.y + Math.max(1, (closeRect.height-lineLength)/2);
929+
y += parent.onBottom ? -1 : 1;
930+
918931
gc.setLineCap(SWT.CAP_ROUND);
919932
gc.drawLine(x, y, x + lineLength, y + lineLength);
920933
gc.drawLine(x, y + lineLength, x + lineLength, y);
@@ -1463,7 +1476,7 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) {
14631476
gc.setBackground(orginalBackground);
14641477
}
14651478
}
1466-
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState);
1479+
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState, item.showDirty);
14671480
}
14681481
}
14691482

@@ -1672,7 +1685,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) {
16721685
gc.setFont(gcFont);
16731686
}
16741687
// draw close
1675-
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState);
1688+
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState, item.showDirty);
16761689
}
16771690
}
16781691

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabItem.java

+30
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class CTabItem extends Item {
5555
int closeImageState = SWT.BACKGROUND;
5656
int state = SWT.NONE;
5757
boolean showClose = false;
58+
boolean showDirty = false;
5859
boolean showing = false;
5960

6061
/**
@@ -276,6 +277,20 @@ public boolean getShowClose() {
276277
checkWidget();
277278
return showClose;
278279
}
280+
281+
/**
282+
* Returns <code>true</code> to indicate that the dirty indicator should be shown.
283+
* Otherwise return <code>false</code>.
284+
*
285+
* @return <code>true</code> if the dirty indicatorn should be shown
286+
*
287+
* @since 4.35
288+
*/
289+
public boolean getShowDirty() {
290+
checkWidget();
291+
return showClose;
292+
}
293+
279294
/**
280295
* Returns the receiver's tool tip text, or null if it has
281296
* not been set.
@@ -490,6 +505,21 @@ public void setShowClose(boolean close) {
490505
showClose = close;
491506
parent.updateFolder(CTabFolder.REDRAW_TABS);
492507
}
508+
509+
/**
510+
* Sets to <code>true</code> to indicate that the dirty indicator should be shown.
511+
*
512+
* @param dirty the new value whether the dirty indicator shall be shown
513+
*
514+
* @since 4.35
515+
*/
516+
public void setShowDirty(boolean dirty) {
517+
checkWidget();
518+
if (showDirty == dirty) return;
519+
showDirty = dirty;
520+
parent.updateFolder(CTabFolder.REDRAW_TABS);
521+
}
522+
493523
/**
494524
* Sets the text to display on the tab.
495525
* A carriage return '\n' allows to display multi line text.

0 commit comments

Comments
 (0)