Skip to content

Commit 5639d0c

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 422f742 commit 5639d0c

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
@@ -878,44 +878,57 @@ void drawBody(GC gc, Rectangle bounds, int state) {
878878
}
879879
}
880880

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

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

914-
private void drawCloseLines(GC gc, int x, int y, int lineLength, boolean hot) {
919+
920+
private void drawCloseButton(GC gc, Rectangle closeRect, boolean hot) {
915921
if (hot) {
916-
gc.setLineWidth(gc.getLineWidth() + 2);
917-
gc.setForeground(getFillColor());
922+
drawCloseBackground(gc, closeRect, parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
923+
// gc.setLineWidth(gc.getLineWidth() + 2);
924+
gc.setForeground(gc.getBackground());
918925
}
926+
// draw X with length of this constant
927+
final int lineLength = 9;
928+
int x = closeRect.x + Math.max(1, (closeRect.width-lineLength)/2);
929+
int y = closeRect.y + Math.max(1, (closeRect.height-lineLength)/2);
930+
y += parent.onBottom ? -1 : 1;
931+
919932
gc.setLineCap(SWT.CAP_ROUND);
920933
gc.drawLine(x, y, x + lineLength, y + lineLength);
921934
gc.drawLine(x, y + lineLength, x + lineLength, y);
@@ -1464,7 +1477,7 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) {
14641477
gc.setBackground(orginalBackground);
14651478
}
14661479
}
1467-
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState);
1480+
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState, item.showDirty);
14681481
}
14691482
}
14701483

@@ -1673,7 +1686,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) {
16731686
gc.setFont(gcFont);
16741687
}
16751688
// draw close
1676-
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState);
1689+
if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState, item.showDirty);
16771690
}
16781691
}
16791692

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 3.129
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 3.129
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)