From a913fdcd7294e7521909a4b4f6a357513df2da6d Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 19 Jan 2024 10:26:27 +0100 Subject: [PATCH 1/2] CTabFolderRender: Factor out shared functionality related to close icon --- .../swt/custom/CTabFolderRenderer.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) 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 2f01705fe3e..a91ba68f322 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 @@ -360,15 +360,13 @@ protected Point computeSize (int part, int state, GC gc, int wHint, int hHint) { width += getTextPadding(item, state) * 2; - if (parent.showClose || item.showClose) { - if ((state & SWT.SELECTED) != 0 || parent.showUnselectedClose) { - if (!applyLargeTextPadding(parent)) { - if (width > 0) width += INTERNAL_SPACING; - } else { - if (width > 0) width -= INTERNAL_SPACING; - } - width += computeSize(PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x; + if (shouldDrawCloseIcon(item)) { + if (!applyLargeTextPadding(parent)) { + if (width > 0) width += INTERNAL_SPACING; + } else { + if (width > 0) width -= INTERNAL_SPACING; } + width += computeSize(PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x; } } break; @@ -379,6 +377,13 @@ protected Point computeSize (int part, int state, GC gc, int wHint, int hHint) { return new Point(width, height); } + private boolean shouldDrawCloseIcon(CTabItem item) { + CTabFolder folder = item.getParent(); + boolean showClose = folder.showClose || item.showClose; + boolean isSelectedOrShowCloseForUnselected = (item.state & SWT.SELECTED) != 0 || folder.showUnselectedClose; + return showClose && isSelectedOrShowCloseForUnselected; + } + /** * Returns padding for the text of a tab when image is not available or is hidden. * @@ -1416,7 +1421,7 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) { // draw Image Rectangle trim = computeTrim(itemIndex, SWT.NONE, 0, 0, 0, 0); int xDraw = x - trim.x; - if (parent.single && (parent.showClose || item.showClose)) xDraw += item.closeRect.width; + if (parent.single && shouldDrawCloseIcon(item)) xDraw += item.closeRect.width; Image image = item.getImage(); if (image != null && !image.isDisposed() && parent.showSelectedImage) { Rectangle imageBounds = image.getBounds(); @@ -1469,7 +1474,7 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) { gc.setBackground(orginalBackground); } } - if (parent.showClose || item.showClose) drawClose(gc, item.closeRect, item.closeImageState); + if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState); } } @@ -1631,7 +1636,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) { Rectangle imageBounds = image.getBounds(); // only draw image if it won't overlap with close button int maxImageWidth = x + width - xDraw - (trim.width + trim.x); - if (parent.showUnselectedClose && (parent.showClose || item.showClose)) { + if (shouldDrawCloseIcon(item)) { maxImageWidth -= item.closeRect.width + INTERNAL_SPACING; } if (imageBounds.width < maxImageWidth) { @@ -1649,7 +1654,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) { // draw Text xDraw += getTextPadding(item, state); int textWidth = x + width - xDraw - (trim.width + trim.x); - if (parent.showUnselectedClose && (parent.showClose || item.showClose)) { + if (shouldDrawCloseIcon(item)) { textWidth -= item.closeRect.width + INTERNAL_SPACING; } if (textWidth > 0) { @@ -1667,7 +1672,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) { gc.setFont(gcFont); } // draw close - if (parent.showUnselectedClose && (parent.showClose || item.showClose)) drawClose(gc, item.closeRect, item.closeImageState); + if (shouldDrawCloseIcon(item)) drawClose(gc, item.closeRect, item.closeImageState); } } From 3779c51b4ab80dce90f55f77bafb9bd665603ad9 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 19 Jan 2024 12:32:25 +0100 Subject: [PATCH 2/2] Fix size of tab items when large text padding is used The recently introduced option to not show images in tab folders currently works as follows: A large padding is applied to the tab item as a separator with the text being centered within this padding. For tabs showing a close icon (which in particular is the currently selected on), this icon is added right at the right end of the tab item, such that the text is centered in between the left end of the tab item and the close button. This does not look perfect and while the padding is necessary as a separator for tabs only containing a text, having close icons and, in case of the selected tab, also a different background is sufficient as a separator. This change adapts the appearance of tab items having a close icon when having images disabled. It uses the same size for the tab as if no close icon was drawn and then reduces the area in which the text is centered to the remaining space left to the close icon. This looks cleaner and has the effect that tabs within a tab folder have a fixed with, such that when changing the selection all tabs keep their size and positions. Only the texts within the tab items change their positions depending on whether the close icon is shown or not. --- .../org/eclipse/swt/custom/CTabFolder.java | 24 +++++------ .../swt/custom/CTabFolderRenderer.java | 42 +++++++++---------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java index 2bc6a7b9bc9..a10b47e6b83 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java @@ -2972,19 +2972,17 @@ boolean setItemSize(GC gc) { for (int i = 0; i < items.length; i++) { CTabItem tab = items[i]; int width = widths[i]; - if (tab.height != tabHeight || tab.width != width) { - changed = true; - tab.shortenedText = null; - tab.shortenedTextWidth = 0; - tab.height = tabHeight; - tab.width = width; - tab.closeRect.width = tab.closeRect.height = 0; - if (showClose || tab.showClose) { - if (i == selectedIndex || showUnselectedClose) { - Point closeSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT); - tab.closeRect.width = closeSize.x; - tab.closeRect.height = closeSize.y; - } + changed = true; + tab.shortenedText = null; + tab.shortenedTextWidth = 0; + tab.height = tabHeight; + tab.width = width; + tab.closeRect.width = tab.closeRect.height = 0; + if (showClose || tab.showClose) { + if (i == selectedIndex || showUnselectedClose) { + Point closeSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT); + tab.closeRect.width = closeSize.x; + tab.closeRect.height = closeSize.y; } } } 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 a91ba68f322..3e2c18a1343 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 @@ -358,14 +358,10 @@ protected Point computeSize (int part, int state, GC gc, int wHint, int hHint) { } } - width += getTextPadding(item, state) * 2; - - if (shouldDrawCloseIcon(item)) { - if (!applyLargeTextPadding(parent)) { - if (width > 0) width += INTERNAL_SPACING; - } else { - if (width > 0) width -= INTERNAL_SPACING; - } + if (shouldApplyLargeTextPadding(parent)) { + width += getLargeTextPadding(item) * 2; + } else if (shouldDrawCloseIcon(item)) { + if (width > 0) width += INTERNAL_SPACING; width += computeSize(PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x; } } @@ -385,26 +381,19 @@ private boolean shouldDrawCloseIcon(CTabItem item) { } /** - * Returns padding for the text of a tab when image is not available or is hidden. - * - * @param item CTabItem - * @param state current state - * + * Returns padding for the text of a tab item when showing images is disabled for the tab folder. */ - private int getTextPadding(CTabItem item, int state) { + private int getLargeTextPadding(CTabItem item) { CTabFolder parent = item.getParent(); String text = item.getText(); if (text != null && parent.getMinimumCharacters() != 0) { - if (applyLargeTextPadding(parent)) { - return TABS_WITHOUT_ICONS_PADDING; - } + return TABS_WITHOUT_ICONS_PADDING; } - return 0; } - private boolean applyLargeTextPadding(CTabFolder tabFolder) { + private boolean shouldApplyLargeTextPadding(CTabFolder tabFolder) { return !tabFolder.showSelectedImage && !tabFolder.showUnselectedImage; } @@ -1438,7 +1427,7 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) { } // draw Text - xDraw += getTextPadding(item, state); + xDraw += getLeftTextMargin(item); int textWidth = rightEdge - xDraw - (trim.width + trim.x); if (!parent.single && item.closeRect.width > 0) textWidth -= item.closeRect.width + INTERNAL_SPACING; if (textWidth > 0) { @@ -1478,6 +1467,17 @@ void drawSelected(int itemIndex, GC gc, Rectangle bounds, int state ) { } } + private int getLeftTextMargin(CTabItem item) { + int margin = 0; + if (shouldApplyLargeTextPadding(parent)) { + margin += getLargeTextPadding(item); + if (shouldDrawCloseIcon(item)) { + margin -= item.closeRect.width / 2; + } + } + return margin; + } + void drawTabArea(GC gc, Rectangle bounds, int state) { Point size = parent.getSize(); int[] shape = null; @@ -1652,7 +1652,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) { } } // draw Text - xDraw += getTextPadding(item, state); + xDraw += getLeftTextMargin(item); int textWidth = x + width - xDraw - (trim.width + trim.x); if (shouldDrawCloseIcon(item)) { textWidth -= item.closeRect.width + INTERNAL_SPACING;