diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java index 68e839fcefe..04b02f53de4 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java @@ -55,7 +55,7 @@ public class ToolBar extends Composite { ToolItem [] items; ToolItem [] tabItemList; boolean ignoreResize, ignoreMouse; - ImageList imageList, disabledImageList, hotImageList; + private ImageList imageList, disabledImageList, hotImageList; static final long ToolBarProc; static final TCHAR ToolBarClass = new TCHAR (OS.TOOLBARCLASSNAME, true); static { @@ -143,6 +143,32 @@ public ToolBar (Composite parent, int style) { } } +/* + * The given image bounds are the bounds of the tool item's image and determine which shared image + * lists are used. They are intentionally not derived from the images actually added: for a disabled + * item with CHECK or RADIO style, those are the disabled images, which may have different bounds. + * Note that the icon size of an image list is defined by the first image added to it. + */ +int addImage(Rectangle imageBounds, Image image, Image hotImage, Image disabledImage) { + int listStyle = style & SWT.RIGHT_TO_LEFT; + if (imageList == null) { + imageList = display.getImageListToolBar(listStyle, imageBounds.width, imageBounds.height, getAutoscalingZoom()); + } + if (hotImageList == null) { + hotImageList = display.getImageListToolBarHot(listStyle, imageBounds.width, imageBounds.height, + getAutoscalingZoom()); + } + if (disabledImageList == null) { + disabledImageList = display.getImageListToolBarDisabled(listStyle, imageBounds.width, imageBounds.height, + getAutoscalingZoom()); + } + int index = imageList.add(image); + hotImageList.add(hotImage); + disabledImageList.add(disabledImage); + refreshImageLists(true); + return index; +} + @Override long callWindowProc (long hwnd, int msg, long wParam, long lParam) { if (handle == 0) return 0; @@ -199,6 +225,10 @@ public void layout (boolean changed) { super.layout(changed); } +void clearImage(int index) { + putImage(index, null, null, null); +} + void clearSizeCache(boolean changed) { // If changed, discard the cached layout information if (changed) { @@ -495,18 +525,6 @@ void enableWidget (boolean enabled) { } } -ImageList getDisabledImageList () { - return disabledImageList; -} - -ImageList getHotImageList () { - return hotImageList; -} - -ImageList getImageList () { - return imageList; -} - /** * Returns the item at the given, zero-relative index in the * receiver. Throws an exception if the index is out of range. @@ -869,6 +887,56 @@ boolean mnemonicMatch (char ch) { return findMnemonic (items [id [0]].text) != '\0'; } +void putImage(int index, Image image, Image hotImage, Image disabledImage) { + if (imageList != null) { + imageList.put(index, image); + } + if (hotImageList != null) { + hotImageList.put(index, hotImage); + } + if (disabledImageList != null) { + disabledImageList.put(index, disabledImage); + } +} + +private void refreshImageLists(boolean itemsChanged) { + int zoom = getAutoscalingZoom(); + long imageListHandle = getImageListHandle(imageList, zoom); + long hotImageListHandle = getImageListHandle(hotImageList, zoom); + long disabledImageListHandle = getImageListHandle(disabledImageList, zoom); + boolean imageListOutdated = isImageListOutdated(OS.TB_GETIMAGELIST, imageListHandle); + boolean hotImageListOutdated = isImageListOutdated(OS.TB_GETHOTIMAGELIST, hotImageListHandle); + boolean disabledImageListOutdated = isImageListOutdated(OS.TB_GETDISABLEDIMAGELIST, disabledImageListHandle); + if (!imageListOutdated && !hotImageListOutdated && !disabledImageListOutdated) { + return; + } + // clear the BTNS_DROPDOWN bits while the image lists are exchanged, see + // setDropDownItems() + if (itemsChanged) { + setDropDownItems(false); + } + if (imageListOutdated) { + OS.SendMessage(handle, OS.TB_SETIMAGELIST, 0, imageListHandle); + } + if (hotImageListOutdated) { + OS.SendMessage(handle, OS.TB_SETHOTIMAGELIST, 0, hotImageListHandle); + } + if (disabledImageListOutdated) { + OS.SendMessage(handle, OS.TB_SETDISABLEDIMAGELIST, 0, disabledImageListHandle); + } + if (itemsChanged) { + setDropDownItems(true); + } +} + +private static long getImageListHandle(ImageList imageList, int zoom) { + return imageList != null ? imageList.getHandle(zoom) : 0; +} + +private boolean isImageListOutdated(int getMessageCode, long expectedHandle) { + return OS.SendMessage(handle, getMessageCode, 0, 0) != expectedHandle; +} + @Override void releaseChildren (boolean destroy) { if (items != null) { @@ -1000,19 +1068,6 @@ void setDropDownItems (boolean set) { } } -void setDisabledImageList (ImageList imageList) { - long hImageList = 0; - if ((disabledImageList = imageList) != null) { - hImageList = OS.SendMessage(handle, OS.TB_GETDISABLEDIMAGELIST, 0, 0); - long newImageList = disabledImageList.getHandle(getAutoscalingZoom()); - if (hImageList == newImageList) return; - hImageList = newImageList; - } - setDropDownItems (false); - OS.SendMessage (handle, OS.TB_SETDISABLEDIMAGELIST, 0, hImageList); - setDropDownItems (true); -} - @Override public void setFont (Font font) { checkWidget (); @@ -1039,32 +1094,6 @@ public void setFont (Font font) { layoutItems (); } -void setHotImageList (ImageList imageList) { - long hImageList = 0; - if ((hotImageList = imageList) != null) { - hImageList = OS.SendMessage(handle, OS.TB_GETHOTIMAGELIST, 0, 0); - long newImageList = hotImageList.getHandle(getAutoscalingZoom()); - if (hImageList == newImageList) return; - hImageList = newImageList; - } - setDropDownItems (false); - OS.SendMessage (handle, OS.TB_SETHOTIMAGELIST, 0, hImageList); - setDropDownItems (true); -} - -void setImageList (ImageList imageList) { - long hImageList = 0; - if ((this.imageList = imageList) != null) { - hImageList = OS.SendMessage(handle, OS.TB_GETIMAGELIST, 0, 0); - long newImageList = imageList.getHandle(getAutoscalingZoom()); - if (hImageList == newImageList) return; - hImageList = newImageList; - } - setDropDownItems (false); - OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, hImageList); - setDropDownItems (true); -} - @Override public boolean setParent (Composite parent) { checkWidget (); @@ -1254,12 +1283,10 @@ void updateOrientation () { display.releaseToolImageList (imageList); display.releaseToolHotImageList (hotImageList); display.releaseToolDisabledImageList (disabledImageList); - OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, newImageList.getHandle(getAutoscalingZoom())); - OS.SendMessage (handle, OS.TB_SETHOTIMAGELIST, 0, newHotImageList.getHandle(getAutoscalingZoom())); - OS.SendMessage (handle, OS.TB_SETDISABLEDIMAGELIST, 0, newDisabledImageList.getHandle(getAutoscalingZoom())); imageList = newImageList; hotImageList = newHotImageList; disabledImageList = newDisabledImageList; + refreshImageLists(false); OS.InvalidateRect (handle, null, true); } } @@ -1744,9 +1771,7 @@ record ToolItemData(ToolItem toolItem, TBBUTTON button) { } } // Refresh the image lists so the image list for the correct zoom is used - setImageList(getImageList()); - setDisabledImageList(getDisabledImageList()); - setHotImageList(getHotImageList()); + refreshImageLists(true); boolean toolBarEnabled = getEnabled(); for (int i = 0; i < itemCount; i++) { ToolItem item = toolItems[i]; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java index 94b020a5a77..b75fbad4c86 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java @@ -535,12 +535,7 @@ void releaseImages () { * an image and one is never assigned, this is not a problem. */ if ((info.fsStyle & OS.BTNS_SEP) == 0 && info.iImage != OS.I_IMAGENONE) { - ImageList imageList = parent.getImageList (); - ImageList hotImageList = parent.getHotImageList (); - ImageList disabledImageList = parent.getDisabledImageList(); - if (imageList != null) imageList.put (info.iImage, null); - if (hotImageList != null) hotImageList.put (info.iImage, null); - if (disabledImageList != null) disabledImageList.put (info.iImage, null); + parent.clearImage(info.iImage); } } @@ -1099,21 +1094,7 @@ void updateImages (boolean enabled) { info.dwMask = OS.TBIF_IMAGE; OS.SendMessage (hwnd, OS.TB_GETBUTTONINFO, id, info); if (info.iImage == OS.I_IMAGENONE && image == null) return; - ImageList imageList = parent.getImageList (); - ImageList hotImageList = parent.getHotImageList (); - ImageList disabledImageList = parent.getDisabledImageList(); if (info.iImage == OS.I_IMAGENONE) { - Rectangle boundsInPoints = image.getBounds(); - int listStyle = parent.style & SWT.RIGHT_TO_LEFT; - if (imageList == null) { - imageList = display.getImageListToolBar (listStyle, boundsInPoints.width, boundsInPoints.height, getAutoscalingZoom()); - } - if (disabledImageList == null) { - disabledImageList = display.getImageListToolBarDisabled (listStyle, boundsInPoints.width, boundsInPoints.height, getAutoscalingZoom()); - } - if (hotImageList == null) { - hotImageList = display.getImageListToolBarHot (listStyle, boundsInPoints.width, boundsInPoints.height, getAutoscalingZoom()); - } Image disabled = disabledImage; if (disabledImage == null) { if (disabledImage2 != null) disabledImage2.dispose (); @@ -1134,27 +1115,19 @@ void updateImages (boolean enabled) { if ((style & (SWT.CHECK | SWT.RADIO)) != 0) { if (!enabled) image2 = hot = disabled; } - info.iImage = imageList.add (image2); - disabledImageList.add (disabled); - hotImageList.add (hot != null ? hot : image2); - parent.setImageList (imageList); - parent.setDisabledImageList (disabledImageList); - parent.setHotImageList (hotImageList); + info.iImage = parent.addImage(image.getBounds(), image2, hot != null ? hot : image2, disabled); } else { Image disabled = null; - if (disabledImageList != null) { - if (image != null) { - if (disabledImage2 != null) disabledImage2.dispose (); - disabledImage2 = null; - disabled = disabledImage; - if (disabledImage == null) { - disabled = image; - if (!enabled) { - disabled = disabledImage2 = new Image (display, image, SWT.IMAGE_DISABLE); - } + if (image != null) { + if (disabledImage2 != null) disabledImage2.dispose (); + disabledImage2 = null; + disabled = disabledImage; + if (disabledImage == null) { + disabled = image; + if (!enabled) { + disabled = disabledImage2 = new Image (display, image, SWT.IMAGE_DISABLE); } } - disabledImageList.put (info.iImage, disabled); } /* * Bug in Windows. When a tool item with the style @@ -1167,12 +1140,8 @@ void updateImages (boolean enabled) { if ((style & (SWT.CHECK | SWT.RADIO)) != 0) { if (!enabled) image2 = hot = disabled; } - if (imageList != null) { - imageList.put (info.iImage, image2); - } - if (hotImageList != null) { - hotImageList.put (info.iImage, hot != null ? hot : image2); - } + + parent.putImage(info.iImage, image2, hot != null ? hot : image2, disabled); if (image == null) info.iImage = OS.I_IMAGENONE; }