Page 1 of 1

Image border and repaint

Posted: Thu Jan 15, 2026 7:22 am
by Sergey

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, 100, 83)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, 100, 83)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
	If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)	 ; imagegadget with border
	EndIf
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Just size window to right (wider) and than to left
And again to right and to left
You'l see repaint artifacts as shadow or path (I don't know it name)
by second image, not by first image

Win10x64 PB630

Re: Image border and repaint

Posted: Thu Jan 15, 2026 8:35 am
by breeze4me
This seems to be an issue related to the image gadget's automatic resizing feature based on image size.

Workaround 1:

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, #PB_Ignore, #PB_Ignore)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, #PB_Ignore, #PB_Ignore)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
	If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)	 ; imagegadget with border
	EndIf
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Workaround 2:

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, 100, 83)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, 100, 83)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
  ;ContainerGadget(10, 0, 0, 445, 105)
  ;SetGadgetColor(10, #PB_Gadget_BackColor, #Blue)
  If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)   ; imagegadget with border
		
		SetWindowLong_(GadgetID(1), #GWL_STYLE, GetWindowLong_(GadgetID(1), #GWL_STYLE) | #WS_CLIPSIBLINGS)
		
	EndIf
	;CloseGadgetList()
	
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Image border and repaint

Posted: Thu Jan 15, 2026 9:45 am
by Sergey
Thank you breeze4me
With #PB_Ignore works well

But if I specify the same value as it was, then nothing should change
Such as with #PB_Ignore ...in one word - PureBasic's magic :D

Re: Image border and repaint

Posted: Thu Jan 15, 2026 10:37 am
by BarryG
Another workaround (added line 7 with "InvalidateRect"):

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, 100, 83)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, 100, 83)
	InvalidateRect_(WindowID(0),0,1)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
	If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)	 ; imagegadget with border
	EndIf
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Image border and repaint

Posted: Thu Jan 15, 2026 11:20 am
by mk-soft
BarryG wrote: Thu Jan 15, 2026 10:37 am Another workaround (added line 7 with "InvalidateRect"):
It is not always necessary to use the Windows API. Should also be cross-platform ...

Re: Image border and repaint

Posted: Thu Jan 15, 2026 2:41 pm
by breeze4me
Sergey wrote: Thu Jan 15, 2026 9:45 am But if I specify the same value as it was, then nothing should change
The problem occurs because the size specified initially does not correspond to the actual gadget size.
The image is larger than the gadget client area, causing the drawing issue.

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, 100, 83)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, 100, 83)
	
	GetWindowRect_(GadgetID(1), r.RECT)
	Debug "Actual size: " + Str(r\right - r\left) + " " + Str(r\bottom - r\top)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
	If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)   ; imagegadget with border
		
		GetWindowRect_(GadgetID(1), r.RECT)
		Debug "Actual size(init): " + Str(r\right - r\left) + " " + Str(r\bottom - r\top)
	EndIf
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Code: Select all

Actual size(init): 104 87      <--- 96 DPI (100%)
Actual size: 100 83
Actual size: 100 83
Actual size: 100 83
Actual size: 100 83
...
If the actual size of the gadget is specified in the resize function, that issue does not occur.

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, 100, 83)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, 104, 87)      ; <---
	
	GetWindowRect_(GadgetID(1), r.RECT)
	Debug "Actual size: " + Str(r\right - r\left) + " " + Str(r\bottom - r\top)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
	If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)   ; imagegadget with border
		
		GetWindowRect_(GadgetID(1), r.RECT)
		Debug "Actual size(init): " + Str(r\right - r\left) + " " + Str(r\bottom - r\top)
	EndIf
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Specifying the #PB_Ignore value prevents the issue by calculating the actual gadget size and setting the gadget size accordingly.

Code: Select all

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - GadgetWidth(1) - 10 - GadgetWidth(0) - 10 - 200, 10, 100, 83)
	ResizeGadget(1, winw - GadgetWidth(1) - 10 - 100, 10, #PB_Ignore, #PB_Ignore)      ; <---
	
	GetWindowRect_(GadgetID(1), r.RECT)
	Debug "Actual size: " + Str(r\right - r\left) + " " + Str(r\bottom - r\top)
EndProcedure

If OpenWindow(0, 0, 0, 445, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
	If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Map.bmp")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 230, 10, 100, 83, ImageID(0), #PB_Image_Border)   ; imagegadget with border
		
		GetWindowRect_(GadgetID(1), r.RECT)
		Debug "Actual size(init): " + Str(r\right - r\left) + " " + Str(r\bottom - r\top)
	EndIf
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Code: Select all

Actual size(init): 104 87
Actual size: 104 87
Actual size: 104 87
Actual size: 104 87
...
Edit:
After testing, the issue also occurs when the image is larger than the borderless image gadget.

Code: Select all

UsePNGImageDecoder()

Procedure resize()
	Protected winW = WindowWidth(0)
	Protected winH = WindowHeight(0)
	
	ResizeGadget(0, winw - 900, 10, 300, 300)
	ResizeGadget(1, winw - 400, 10, 300, 300)
EndProcedure

If OpenWindow(0, 0, 0, 1100, 600, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget |#PB_Window_ScreenCentered)
  ;ContainerGadget(10, 0, 0, WindowWidth(0), WindowHeight(0))
  ;SetGadgetColor(10, #PB_Gadget_BackColor, #Green)
  If LoadImage(0, #PB_Compiler_Home + "\Examples\3D\Data\Textures\grass1.png")
		ImageGadget(0,  10, 10, 100, 83, ImageID(0))                     ; imagegadget standard
		ImageGadget(1, 530, 10, 100, 83, ImageID(0), #PB_Image_Border)   ; imagegadget with border
		
		;SetWindowLong_(GadgetID(0), #GWL_STYLE, GetWindowLong_(GadgetID(0), #GWL_STYLE) | #WS_CLIPSIBLINGS)
		;SetWindowLong_(GadgetID(1), #GWL_STYLE, GetWindowLong_(GadgetID(1), #GWL_STYLE) | #WS_CLIPSIBLINGS)
		
	EndIf
	;CloseGadgetList()
	
	BindEvent(#PB_Event_SizeWindow, @resize())
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf