How to Refresh Image on ButtonImageGadget

Just starting out? Need help? Post your questions and find answers here.
Fips
User
User
Posts: 35
Joined: Sun Feb 20, 2022 1:03 pm

How to Refresh Image on ButtonImageGadget

Post by Fips »

Hi everyone,

I'm trying to implement a color picker. Therefore I use a ButtonImageGadget() to launch a color requester. The ButtonImageGadget is supposed to show the current selected color.
For that I draw a box in the image of the ButtonImageGadget. But the image on the button won't refresh until the i hover with my mouse over it. Tried to trigger a refreshing by resizing the button and giving the ButtonImageGadget the image-id again via SetGadgetAttribute but no succes so far.

In the example below I use two different 'styles' for which each a different color can be chosen.

So I would like to refresh the image on the ButtonImageGadget programmatically everytime the optiongadgets are changed and everytime a new color was picked.

Any ideas? I am on linux by the way, so no winapi please.

Code: Select all

EnableExplicit

Enumeration gadgets
  #opt_style1
  #opt_style2
  #btn_color
EndEnumeration

Global.i col_style1 = RGB(255,0,0), col_style2 = RGB(0,255,0)

Procedure oncloseWindoMain()
  CloseWindow(EventWindow())  
  End
EndProcedure

Procedure setImageButtonColor(ButtonNr.i,color.i)
  StartDrawing(ImageOutput(ButtonNr))
  Box(0,0,ImageWidth(ButtonNr), ImageHeight(ButtonNr), color)
  StopDrawing()
EndProcedure

Procedure onOptionGad_Change()
   If GetGadgetState(#opt_style1)
    setImageButtonColor(#btn_color,col_style1)
  ElseIf GetGadgetState(#opt_style2)
    setImageButtonColor(#btn_color,col_style2)
  EndIf    
EndProcedure

Procedure onclickButtonColor()
  Protected color.i
  
  If GetGadgetState(#opt_style1)
    color = col_style1 
  ElseIf GetGadgetState(#opt_style2)
    color = col_style2
  EndIf 
  
  color = ColorRequester(color)
  If  color <> -1
    setImageButtonColor(#btn_color,color)
    If GetGadgetState(#opt_style1)
      col_style1 = color
    ElseIf GetGadgetState(#opt_style2)
      col_style2 = color
    EndIf 
  EndIf
  
EndProcedure


  
Procedure MainWindow()
  Protected.i this_window
  Protected.i win_x, win_y, win_width, win_height, btn_width, btn_height
  Protected.i gad_width, gad_height, gad_X, gad_Y, frame, gad_dist

  
  btn_height = 40
  btn_width = 40
  frame = 10
  gad_dist = 5
  
  win_x = 100
  win_y = 300
  win_width = 250
  win_height = btn_height + 2 * frame

  CreateImage(#btn_color, btn_width * 0.75, btn_height * 0.75)


  this_window = OpenWindow(#PB_Any, win_x, win_y, win_width, win_height, "Test")
  gad_X = frame
  gad_Y = frame
  gad_width = (win_width - 2 * frame - 2 * gad_dist - btn_width) / 2
  gad_height = btn_height
  OptionGadget(#opt_style1,gad_x, gad_y, gad_width, gad_height, "Style 1")
  gad_x + gad_width + gad_dist
  OptionGadget(#opt_style2,gad_x, gad_y, gad_width, gad_height, "Style 2")
  gad_x + gad_width + gad_dist
  ButtonImageGadget(#btn_color,gad_x, gad_y, btn_width, btn_height, ImageID(#btn_color))
  onOptionGad_Change()
  
  BindEvent(#PB_Event_CloseWindow,@oncloseWindoMain(), this_window)
  BindEvent(#PB_Event_Gadget,@onOptionGad_Change(), this_window, #opt_style1)
  BindEvent(#PB_Event_Gadget,@onOptionGad_Change(), this_window, #opt_style2)
  BindEvent(#PB_Event_Gadget,@onclickButtonColor(), this_window, #btn_color)
  
  
EndProcedure


MainWindow()
Repeat 
  WaitWindowEvent()  
  
ForEver
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: How to Refresh Image on ButtonImageGadget

Post by RASHAD »

Hi
Change to

Code: Select all

Procedure onOptionGad_Change()
   If GetGadgetState(#opt_style1)
    setImageButtonColor(#btn_color,col_style1)
  ElseIf GetGadgetState(#opt_style2)
    setImageButtonColor(#btn_color,col_style2)
  EndIf
  SetGadgetAttribute(#btn_color,#PB_Button_Image,ImageID(#btn_color))      
EndProcedure
Egypt my love
Fips
User
User
Posts: 35
Joined: Sun Feb 20, 2022 1:03 pm

Re: How to Refresh Image on ButtonImageGadget

Post by Fips »

Hi Rashad,

thanks for your reply. I tried this before without any success.

After your reply I tried it again and I figured out that it seems that this does not work if you assign the same ID again. But it works somehow if you use a different image id. So I'm using a dummy image and change the image id twice:

Code: Select all

SetGadgetAttribute(#btn_color,#PB_Button_Image,ImageID(#dummy_image))
SetGadgetAttribute(#btn_color,#PB_Button_Image,ImageID(#btn_color))
Fips
lule
User
User
Posts: 31
Joined: Fri Sep 17, 2010 8:22 pm

Re: How to Refresh Image on ButtonImageGadget

Post by lule »

I ran into the same issue on Linux, but your solution wasn't fine.
the solution I found (and works on Windows), every time you want to update the ButtonImageGadget, you create and free the image:

Code: Select all

EnableExplicit

Enumeration gadgets
	#opt_style1
	#opt_style2
	#btn_color
	#hImg
EndEnumeration



Global.i col_style1 = RGB(255,0,0), col_style2 = RGB(0,255,0)

Procedure oncloseWindoMain()
	CloseWindow(EventWindow())  
	End
EndProcedure

Procedure setImageButtonColor(ButtonNr.i,color.i)
	StartDrawing(ImageOutput(ButtonNr))
	Box(0,0,ImageWidth(ButtonNr), ImageHeight(ButtonNr), color)
	StopDrawing()
EndProcedure

Procedure onOptionGad_Change()
	CreateImage(#hImg, 40 * 0.75, 40 * 0.75)
	If GetGadgetState(#opt_style1)
		setImageButtonColor(#hImg,col_style1)
	ElseIf GetGadgetState(#opt_style2)
		setImageButtonColor(#hImg,col_style2)		
	EndIf
	SetGadgetAttribute(#btn_color,#PB_Button_Image,ImageID(#hImg)) 
	FreeImage(#hImg)
EndProcedure

Procedure onclickButtonColor()
	Protected color.i
	
	If GetGadgetState(#opt_style1)
		color = col_style1 
	ElseIf GetGadgetState(#opt_style2)
		color = col_style2
	EndIf 
	
	color = ColorRequester(color)
	If  color <> -1
		
		If GetGadgetState(#opt_style1)
			col_style1 = color
		ElseIf GetGadgetState(#opt_style2)
			col_style2 = color
		EndIf 
		onOptionGad_Change()
	EndIf
	
EndProcedure



Procedure MainWindow()
	Protected.i this_window
	Protected.i win_x, win_y, win_width, win_height, btn_width, btn_height
	Protected.i gad_width, gad_height, gad_X, gad_Y, frame, gad_dist
	
	
	btn_height = 40
	btn_width = 40
	frame = 10
	gad_dist = 5
	
	win_x = 100
	win_y = 300
	win_width = 250
	win_height = btn_height + 2 * frame
	
	
	;CreateImage(#dummy_image, btn_width * 0.75, btn_height * 0.75)
	
	
	this_window = OpenWindow(#PB_Any, win_x, win_y, win_width, win_height, "Test")
	gad_X = frame
	gad_Y = frame
	gad_width = (win_width - 2 * frame - 2 * gad_dist - btn_width) / 2
	gad_height = btn_height
	OptionGadget(#opt_style1,gad_x, gad_y, gad_width, gad_height, "Style 1")
	gad_x + gad_width + gad_dist
	OptionGadget(#opt_style2,gad_x, gad_y, gad_width, gad_height, "Style 2")
	gad_x + gad_width + gad_dist
	ButtonImageGadget(#btn_color,gad_x, gad_y, btn_width, btn_height, 0)
	onOptionGad_Change()
	
	BindEvent(#PB_Event_CloseWindow,@oncloseWindoMain(), this_window)
	BindGadgetEvent(#opt_style1,@onOptionGad_Change(), #PB_EventType_LeftClick)
	BindGadgetEvent(#opt_style2,@onOptionGad_Change(), #PB_EventType_LeftClick)
	BindGadgetEvent(#btn_color,@onclickButtonColor(), #PB_EventType_LeftClick)
EndProcedure


MainWindow()
Repeat 
	WaitWindowEvent()  
	
ForEver
Linux Mint 21.1 Vera base: Ubuntu 22.04 jammy.
PureBasic 6.10 LTS (Linux - x64)
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: How to Refresh Image on ButtonImageGadget

Post by boddhi »

Code: Select all

EnableExplicit

Enumeration gadgets
  #opt_style1=1
  #opt_style2
  #btn_color
EndEnumeration
Enumeration image
  #image
EndEnumeration

;Global.i col_style1 = RGB(255,0,0), col_style2 = RGB(0,255,0)

Procedure CreateFirstImage(ArgWidth.i,ArgHeight.i)
  CreateImage(#image, ArgWidth * 0.75, ArgHeight * 0.75)
  StartDrawing(ImageOutput(#image))
  Box(0,0, ArgWidth, ArgHeight, #Black)
  StopDrawing()
EndProcedure

Procedure oncloseWindoMain()
  CloseWindow(EventWindow())  
  End
EndProcedure

Procedure setImageButtonColor()
  Protected.i ButtonNr=EventGadget()
  Protected.l Color
  Static.l PrevColor
  
  Select ButtonNr
    Case 0:Color=#Black
    Default:Color=GetGadgetData(ButtonNr)
  EndSelect
  If Color<>PrevColor
    PrevColor=Color
    StartDrawing(ImageOutput(#image))
    FillArea(0,0,Color,Color)
    StopDrawing()
    SetGadgetAttribute(#btn_color,#PB_Button_Image,ImageID(#image))
  EndIf
EndProcedure

Procedure onclickButtonColor()
	Protected.l Color.l=GetGadgetData(#btn_color)
	Protected.i ButtonNr
	
  If GetGadgetState(#opt_style1)
    ButtonNr=#opt_style1
  ElseIf GetGadgetState(#opt_style2)
    ButtonNr=#opt_style2
  Else
    ButtonNr=#btn_color
  EndIf
  If ButtonNr<>#btn_color
    Color=GetGadgetData(ButtonNr)
  EndIf
	Color = ColorRequester(color)
	
	If color <> -1
    SetGadgetData(#btn_color,Color)
    If ButtonNr<>#btn_color
      SetGadgetData(ButtonNr,Color)
    EndIf
    setImageButtonColor()
	EndIf
EndProcedure

Procedure MainWindow()
  Protected.i this_window
  Protected.i win_x, win_y, win_width, win_height, btn_width, btn_height
  Protected.i gad_width, gad_height, gad_X, gad_Y, frame, gad_dist
  
  btn_height = 40
  btn_width = 40
  frame = 10
  gad_dist = 5
  
  win_x = 100
  win_y = 300
  win_width = 250
  win_height = btn_height + 2 * frame

  this_window = OpenWindow(#PB_Any, win_x, win_y, win_width, win_height, "Test")
  gad_X = frame
  gad_Y = frame
  gad_width = (win_width - 2 * frame - 2 * gad_dist - btn_width) / 2
  gad_height = btn_height
  OptionGadget(#opt_style1,gad_x, gad_y, gad_width, gad_height, "Style 1")
  gad_x + gad_width + gad_dist
  OptionGadget(#opt_style2,gad_x, gad_y, gad_width, gad_height, "Style 2")
  gad_x + gad_width + gad_dist
  CreateFirstImage(btn_width * 0.75, btn_height * 0.75)
  ButtonImageGadget(#btn_color,gad_x, gad_y, btn_width, btn_height, ImageID(#image))
  
  SetGadgetData(#opt_style1,RGB(255,0,0))
  SetGadgetData(#opt_style2,RGB(0,255,0))
  SetGadgetData(#btn_color,0)
  setImageButtonColor()
  
  BindEvent(#PB_Event_CloseWindow,@oncloseWindoMain(), this_window)
  BindGadgetEvent(#opt_style1,@setImageButtonColor())
  BindGadgetEvent(#opt_style2,@setImageButtonColor())
  BindGadgetEvent(#btn_color,@onclickButtonColor())
EndProcedure

MainWindow()
Repeat 
  WaitWindowEvent()  
  
ForEver
 
Note: The code could be a little less complicated if one of the option gadgets were 'checked' at start.
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
Post Reply