Image border and repaint

Post bugreports for the Windows version here
Sergey
User
User
Posts: 74
Joined: Wed Jan 12, 2022 2:41 pm

Image border and repaint

Post 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
breeze4me
Enthusiast
Enthusiast
Posts: 654
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Image border and repaint

Post 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
Sergey
User
User
Posts: 74
Joined: Wed Jan 12, 2022 2:41 pm

Re: Image border and repaint

Post 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
BarryG
Addict
Addict
Posts: 4305
Joined: Thu Apr 18, 2019 8:17 am

Re: Image border and repaint

Post 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
User avatar
mk-soft
Always Here
Always Here
Posts: 6501
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Image border and repaint

Post 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 ...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
breeze4me
Enthusiast
Enthusiast
Posts: 654
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Image border and repaint

Post 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
Post Reply