Skip to content

Commit bb1b092

Browse files
HeikoKlareclaude
andcommitted
[Win32] Add tool bar tests for items rendering their own icon
ToolBarWin32Tests guards against tool items rendering a wrong or blank icon after a monitor zoom change. That defect is not specific to zoom changes though: a tool bar addresses its normal, hot and disabled image list with a single index per item, so any operation reassigning those slots can make an item render another item's icon. Adds tests covering that items keep rendering their own icon when another item is disposed, when a second tool bar uses icons of the same size and therefore shares the image lists, and after an orientation change. Like the existing test, they observe the actual rendered result via public API only and reuse its rendering and color classification. Related to #3466 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent c93465b commit bb1b092

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ToolBarWin32Tests.java

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,129 @@ void testIconsRenderedCorrectlyAfterZoomChangeWithImageListHole() {
9090
}
9191
}
9292

93+
/**
94+
* A tool bar addresses its normal, hot and disabled image list with a single
95+
* index per item, and disposing an item frees its slot in those lists for
96+
* reuse. The remaining items must keep rendering their own icon.
97+
*/
98+
@Test
99+
void testIconsRenderedCorrectlyAfterDisposingAnotherItem() {
100+
Display display = new Display();
101+
RGB[] colors = { new RGB(220, 40, 40), new RGB(40, 180, 40), new RGB(40, 40, 220) };
102+
Image[] icons = createIcons(display, colors);
103+
try {
104+
Shell shell = new Shell(display);
105+
shell.setLayout(new FillLayout());
106+
ToolBar bar = new ToolBar(shell, SWT.FLAT);
107+
ToolItem[] items = createItems(bar, icons);
108+
shell.setSize(500, 90);
109+
shell.open();
110+
111+
items[1].dispose();
112+
113+
Set<ToolItemWithExpectedColor> itemsToCheck = Set.of(
114+
new ToolItemWithExpectedColor(items[0], colors[0]),
115+
new ToolItemWithExpectedColor(items[2], colors[2]));
116+
assertTrue(waitUntilIconsRenderOwnColor(display, () -> iconsRenderOwnColor(bar, itemsToCheck, colors),
117+
TIMEOUT_MILLIS), "every tool item must render its own icon after another item is disposed");
118+
} finally {
119+
disposeAll(icons, display);
120+
}
121+
}
122+
123+
/**
124+
* Tool bars share the image lists for a given icon size, so the items of one
125+
* tool bar must not be affected by those of another tool bar using icons of the
126+
* same size.
127+
*/
128+
@Test
129+
void testIconsRenderedCorrectlyWithSecondToolBarUsingSameIconSize() {
130+
Display display = new Display();
131+
RGB[] colors = { new RGB(220, 40, 40), new RGB(40, 180, 40), new RGB(40, 40, 220), new RGB(230, 200, 30) };
132+
Image[] icons = createIcons(display, colors);
133+
try {
134+
Shell shell = new Shell(display);
135+
shell.setLayout(new FillLayout(SWT.VERTICAL));
136+
ToolBar firstBar = new ToolBar(shell, SWT.FLAT);
137+
ToolItem[] firstItems = createItems(firstBar, icons[0], icons[1]);
138+
ToolBar secondBar = new ToolBar(shell, SWT.FLAT);
139+
ToolItem[] secondItems = createItems(secondBar, icons[2], icons[3]);
140+
shell.setSize(500, 180);
141+
shell.open();
142+
143+
Set<ToolItemWithExpectedColor> firstItemsToCheck = Set.of(
144+
new ToolItemWithExpectedColor(firstItems[0], colors[0]),
145+
new ToolItemWithExpectedColor(firstItems[1], colors[1]));
146+
Set<ToolItemWithExpectedColor> secondItemsToCheck = Set.of(
147+
new ToolItemWithExpectedColor(secondItems[0], colors[2]),
148+
new ToolItemWithExpectedColor(secondItems[1], colors[3]));
149+
assertTrue(
150+
waitUntilIconsRenderOwnColor(display,
151+
() -> iconsRenderOwnColor(firstBar, firstItemsToCheck, colors)
152+
&& iconsRenderOwnColor(secondBar, secondItemsToCheck, colors),
153+
TIMEOUT_MILLIS),
154+
"every tool item must render its own icon although both tool bars share the image lists");
155+
} finally {
156+
disposeAll(icons, display);
157+
}
158+
}
159+
160+
/**
161+
* Changing the orientation moves every item's images into image lists created
162+
* for the new orientation, which must retain the assignment of items to their
163+
* icons.
164+
*/
165+
@Test
166+
void testIconsRenderedCorrectlyAfterOrientationChange() {
167+
Display display = new Display();
168+
RGB[] colors = { new RGB(220, 40, 40), new RGB(40, 180, 40), new RGB(40, 40, 220) };
169+
Image[] icons = createIcons(display, colors);
170+
try {
171+
Shell shell = new Shell(display);
172+
shell.setLayout(new FillLayout());
173+
ToolBar bar = new ToolBar(shell, SWT.FLAT);
174+
ToolItem[] items = createItems(bar, icons);
175+
shell.setSize(500, 90);
176+
shell.open();
177+
178+
bar.setOrientation(SWT.RIGHT_TO_LEFT);
179+
bar.setOrientation(SWT.LEFT_TO_RIGHT);
180+
181+
Set<ToolItemWithExpectedColor> itemsToCheck = new HashSet<>();
182+
for (int i = 0; i < items.length; i++) {
183+
itemsToCheck.add(new ToolItemWithExpectedColor(items[i], colors[i]));
184+
}
185+
assertTrue(waitUntilIconsRenderOwnColor(display, () -> iconsRenderOwnColor(bar, itemsToCheck, colors),
186+
TIMEOUT_MILLIS), "every tool item must render its own icon after an orientation change");
187+
} finally {
188+
disposeAll(icons, display);
189+
}
190+
}
191+
192+
private static Image[] createIcons(Display display, RGB[] colors) {
193+
Image[] icons = new Image[colors.length];
194+
for (int i = 0; i < colors.length; i++) {
195+
icons[i] = solidIcon(display, 16, colors[i]);
196+
}
197+
return icons;
198+
}
199+
200+
private static ToolItem[] createItems(ToolBar bar, Image... icons) {
201+
ToolItem[] items = new ToolItem[icons.length];
202+
for (int i = 0; i < icons.length; i++) {
203+
items[i] = new ToolItem(bar, SWT.PUSH);
204+
items[i].setImage(icons[i]);
205+
}
206+
return items;
207+
}
208+
209+
private static void disposeAll(Image[] icons, Display display) {
210+
for (Image icon : icons) {
211+
icon.dispose();
212+
}
213+
display.dispose();
214+
}
215+
93216
private static boolean waitUntilIconsRenderOwnColor(Display display, BooleanSupplier condition,
94217
long timeoutMillis) {
95218
long deadline = System.currentTimeMillis() + timeoutMillis;

0 commit comments

Comments
 (0)