diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java index 9edf33fbf84..3206695cbfe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java @@ -878,44 +878,57 @@ void drawBody(GC gc, Rectangle bounds, int state) { } } - void drawClose(GC gc, Rectangle closeRect, int closeImageState) { + void drawClose(GC gc, Rectangle closeRect, int closeImageState, boolean showDirtyIndicator) { if (closeRect.width == 0 || closeRect.height == 0) return; - // draw X with length of this constant - final int lineLength = 8; - int x = closeRect.x + Math.max(1, (closeRect.width-lineLength)/2); - int y = closeRect.y + Math.max(1, (closeRect.height-lineLength)/2); - y += parent.onBottom ? -1 : 1; int originalLineWidth = gc.getLineWidth(); - Color originalForeground = gc.getForeground(); - switch (closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) { - case SWT.NONE: { - drawCloseLines(gc, x, y , lineLength, false); - break; - } - case SWT.HOT: { - drawCloseLines(gc, x, y , lineLength, true); - break; - } - case SWT.SELECTED: { - drawCloseLines(gc, x, y , lineLength, true); - break; - } - case SWT.BACKGROUND: { - int[] shape = new int[] {x,y, x+10,y, x+10,y+10, x,y+10}; - drawBackground(gc, shape, false); - break; - } - } - gc.setLineWidth(originalLineWidth); - gc.setForeground(originalForeground); + int state = closeImageState & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND); + if (state == SWT.NONE) { + if (showDirtyIndicator) + drawDirtyIndicator(gc, closeRect, false); + else + drawCloseButton(gc, closeRect, false); + } else if (state == SWT.HOT || state == SWT.SELECTED) { + drawCloseButton(gc, closeRect, true); + } else if (state == SWT.BACKGROUND) { + if (showDirtyIndicator) + drawDirtyIndicator(gc, closeRect, false); + else + drawBackground(gc, closeRect, SWT.BACKGROUND); + } + gc.setLineWidth(originalLineWidth); + } + + private void drawDirtyIndicator(GC gc, Rectangle closeRect, boolean hot) { + String DIRTY_INDICATOR = "●"; + + Point stringExtent = gc.stringExtent(DIRTY_INDICATOR); + int x = closeRect.x + (closeRect.width - stringExtent.x) / 2; + int y = closeRect.y + (closeRect.height - stringExtent.y) / 2; + gc.drawString(DIRTY_INDICATOR, x, y, true); + } + + private void drawCloseBackground(GC gc, Rectangle closeRect, Color backgroundColor) { + Color originalBackground = gc.getBackground(); + gc.setBackground(backgroundColor); + gc.setForeground(originalBackground); + gc.fillRoundRectangle(closeRect.x + 1, closeRect.y + 2, closeRect.width - 2, closeRect.height - 2, 4, 4); + gc.setBackground(originalBackground); } - private void drawCloseLines(GC gc, int x, int y, int lineLength, boolean hot) { + + private void drawCloseButton(GC gc, Rectangle closeRect, boolean hot) { if (hot) { - gc.setLineWidth(gc.getLineWidth() + 2); - gc.setForeground(getFillColor()); + drawCloseBackground(gc, closeRect, parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); +// gc.setLineWidth(gc.getLineWidth() + 2); + gc.setForeground(gc.getBackground()); } + // draw X with length of this constant + final int lineLength = 9; + int x = closeRect.x + Math.max(1, (closeRect.width-lineLength)/2); + int y = closeRect.y + Math.max(1, (closeRect.height-lineLength)/2); + y += parent.onBottom ? -1 : 1; + gc.setLineCap(SWT.CAP_ROUND); gc.drawLine(x, y, x + lineLength, y + lineLength); gc.drawLine(x, y + lineLength, x + lineLength, y); @@ -1464,7 +1477,7 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) { gc.setBackground(orginalBackground); } } - if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState); + if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState, item.showDirty); } } @@ -1673,7 +1686,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) { gc.setFont(gcFont); } // draw close - if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState); + if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState, item.showDirty); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabItem.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabItem.java index 884c44354db..79355c87cdd 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabItem.java @@ -55,6 +55,7 @@ public class CTabItem extends Item { int closeImageState = SWT.BACKGROUND; int state = SWT.NONE; boolean showClose = false; + boolean showDirty = false; boolean showing = false; /** @@ -276,6 +277,20 @@ public boolean getShowClose() { checkWidget(); return showClose; } + +/** + * Returns true to indicate that the dirty indicator should be shown. + * Otherwise return false. + * + * @return true if the dirty indicator should be shown + * + * @since 3.129 + */ +public boolean isDirtyIndicatorShown() { + checkWidget(); + return showDirty; +} + /** * Returns the receiver's tool tip text, or null if it has * not been set. @@ -490,6 +505,21 @@ public void setShowClose(boolean close) { showClose = close; parent.updateFolder(CTabFolder.REDRAW_TABS); } + +/** + * Sets to true to indicate that the dirty indicator should be shown. + * + * @param dirty the new value whether the dirty indicator shall be shown + * + * @since 3.129 + */ +public void setShowDirty(boolean dirty) { + checkWidget(); + if (showDirty == dirty) return; + showDirty = dirty; + parent.updateFolder(CTabFolder.REDRAW_TABS); +} + /** * Sets the text to display on the tab. * A carriage return '\n' allows to display multi line text.