Page 1 of 1

How to Refresh Image on ButtonImageGadget

Posted: Wed Aug 10, 2022 12:54 pm
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

Re: How to Refresh Image on ButtonImageGadget

Posted: Wed Aug 10, 2022 1:05 pm
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

Re: How to Refresh Image on ButtonImageGadget

Posted: Wed Aug 10, 2022 2:01 pm
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

Re: How to Refresh Image on ButtonImageGadget

Posted: Mon Sep 09, 2024 7:13 pm
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

Re: How to Refresh Image on ButtonImageGadget

Posted: Tue Sep 10, 2024 9:20 pm
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.