Posted: Sun Feb 03, 2008 11:22 pm
How difficult would it be to change the meter and also the led gadget to work with negative values and also dynamic range adjustment?


http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
EnableExplicit
;MeterGadget is a mix of a gadget and a image, a few procedures have been made to make
;gadget handling easier. In general a MeterGadget behaves almost like a normal ImageGadget.
;Otherwise normal gadget functions can be used (that works with ImageGadget)
;and obviously since it is a imagegadget it has the same gadget events returned as well.
;Tooltips can be set just like with any other ImageGadget.
;flags constants are the same as the flags constants used for ImageGadget like #PB_Image_Border
;IMPORTANT! SetGadgetData() MUST NOT be used with the MeterGadget,
;it's used for the structure pointers.
;Use SetMeterGadgetData() and GetMeterGadgetData() instead.
Structure MeterGadgetTable_struct
point.l
color.l
EndStructure
Structure MeterGadget_struct
image.l
imageid.l
x.l
y.l
w.l
h.l
bgcolor.l
fgcolor.l
linecolor.l
offset.l
userdata.l
flags.l
*table.MeterGadgetTable_struct
EndStructure
;Create #Image and #Gadget etc.
Procedure.l MeterGadget(gadget.l,x.l,y.l,width.l,height.l,bgcolor.l,fgcolor.l,linecolor.l,flags.l=#Null)
Protected *m.MeterGadget_struct,result.l=#Null,n.l,p.l=0,newgadget.l,*table
If IsGadget(gadget)
*m=GetGadgetData(gadget)
If *m
result=*m\image
EndIf
EndIf
*m=AllocateMemory(SizeOf(MeterGadget_struct))
If *m
*m\flags=flags
If *m\flags=#PB_Image_Border
*m\w=width-2
*m\h=height-2
Else
*m\w=width
*m\h=height
EndIf
*m\table=AllocateMemory(SizeOf(MeterGadget_struct) * *m\w)
If *m\table
*m\x=x
*m\y=y
*m\bgcolor=bgcolor
*m\fgcolor=fgcolor
*m\linecolor=linecolor
*m\image=CreateImage(#PB_Any,width,height,#PB_Image_DisplayFormat)
If IsImage(*m\image)
*m\imageid=ImageID(*m\image)
If StartDrawing(ImageOutput(*m\image))
Box(p,p,*m\w,*m\h,*m\bgcolor)
For n=0 To *m\h Step 10
LineXY(p,n,*m\w,n,*m\fgcolor)
Next
For n=0 To width Step 10
LineXY(n,p,n,*m\h,*m\fgcolor)
Next
StopDrawing()
result=ImageGadget(gadget,*m\x,*m\y,*m\w,*m\h,*m\imageid,flags)
EndIf
EndIf
If gadget=#PB_Any
newgadget=result
Else
newgadget=gadget
EndIf
EndIf
If IsGadget(newgadget)
SetGadgetData(newgadget,*m)
Else
If IsImage(*m\image)
FreeImage(*m\image)
EndIf
If *m\table
FreeMemory(*m\table)
EndIf
FreeMemory(*m)
EndIf
EndIf
ProcedureReturn result
EndProcedure
;Use this instead of FreeGadget() to avoid memory leaks.
;Only needed if you need to free/remove a gadget.
;All resources are automatically freed at program end like normal PB gadgets though.
Procedure FreeMeterGadget(gadget.l)
Protected *m.MeterGadget_struct
If IsGadget(gadget)
*m=GetGadgetData(gadget)
FreeGadget(gadget)
If *m
If IsImage(*m\image)
FreeImage(*m\image)
EndIf
FreeMemory(*m)
EndIf
EndIf
EndProcedure
;Use this instead of SetGadgetState()
Procedure SetMeterGadgetState(gadget.l,state.l)
Protected *m.MeterGadget_struct,result.l,*table1.MeterGadgetTable_struct,*table2.MeterGadgetTable_struct
Protected n.l,y1.l,y2.l,bottom.l,percent.f,h.l,p.l
*m=GetGadgetData(gadget)
If *m\offset=10
*m\offset=0
EndIf
If *m\flags=#PB_Image_Border
p=1
Else
p=0
EndIf
For n=0 To *m\w-1
*table1=*m\table+(n*SizeOf(MeterGadgetTable_struct))
*table2=*m\table+((n+1)*SizeOf(MeterGadgetTable_struct))
*table1\point=*table2\point
*table1\color=*table2\color
Next
*table2\point=state
*table2\color=*m\linecolor
If StartDrawing(ImageOutput(*m\image))
Box(p,p,*m\w,*m\h,*m\bgcolor)
For n=0 To *m\h Step 10
LineXY(p,n,*m\w,n,*m\fgcolor)
Next
For n=0 To *m\w+*m\offset Step 10
LineXY(n-*m\offset,p,n-*m\offset,*m\h,*m\fgcolor)
Next
For n=0 To *m\w
*table1=*m\table+(n*SizeOf(MeterGadgetTable_struct))
*table2=*m\table+((n+1)*SizeOf(MeterGadgetTable_struct))
bottom=*m\h
percent=(*table1\point/100.0)
h=Int(percent * *m\h)
y1=bottom-h
percent=(*table2\point/100)
h=Int(percent * *m\h)
y2.l=bottom-h
LineXY(n+1,y1,n+1,y2,*table2\color)
Next
*m\offset+1
StopDrawing()
SetGadgetState(gadget,*m\imageid)
EndIf
EndProcedure
;Use this instead of GetGadgetState(). Not that usefull but may be handy to have.
Procedure.l GetMeterGadgetState(gadget.l)
Protected *m.MeterGadget_struct
*m=GetGadgetData(gadget)
ProcedureReturn *m\offset
EndProcedure
;Use this instead of SetGadgetData().
Procedure SetMeterGadgetData(gadget.l,userdata.l)
Protected *m.MeterGadget_struct
*m=GetGadgetData(gadget)
*m\userdata=userdata
EndProcedure
;Use this instead of GetGadgetData().
Procedure.l GetMeterGadgetData(gadget.l)
Protected *m.MeterGadget_struct
*m=GetGadgetData(gadget)
ProcedureReturn *m\userdata
EndProcedure
;Use this to get #Image
Procedure.l GetMeterGadgetImage(gadget.l)
Protected *m.MeterGadget_struct,result.l=#Null
*m=GetGadgetData(gadget)
ProcedureReturn *m\image
EndProcedure
;Use this to set gadget color
Procedure.l SetMeterGadgetColor(gadget.l,colortype.l,color.l)
Protected *m.MeterGadget_struct,result.l=#Null
*m=GetGadgetData(gadget)
Select colortype
Case #PB_Gadget_BackColor
*m\bgcolor=color
Case #PB_Gadget_FrontColor
*m\fgcolor=color
Case #PB_Gadget_LineColor
*m\linecolor=color
EndSelect
EndProcedure
;Use this to get gadget color
Procedure.l GetMeterGadgetColor(gadget.l,colortype.l)
Protected *m.MeterGadget_struct,result.l=#Null
*m=GetGadgetData(gadget)
Select colortype
Case #PB_Gadget_BackColor
result=*m\bgcolor
Case #PB_Gadget_FrontColor
result=*m\fgcolor
Case #PB_Gadget_LineColor
result=*m\linecolor
EndSelect
ProcedureReturn result
EndProcedure
;******************************************************************************
;- Example of use
Define event.l,gadget.l,filename$,pattern$,patternpos.l,oldtime.l,newtime.l
Enumeration 1
#Window
EndEnumeration
Enumeration 1
#Meter1
#Meter2
#Meter3
#Trackbar
#Saveimage
#Changecolor1
#Changecolor2
#Changecolor3
EndEnumeration
If OpenWindow(#Window,0,0,470,460,"Meter Control",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)=#False
End
EndIf
If CreateGadgetList(WindowID(#Window))=#False
End
EndIf
If MeterGadget(#Meter1,90,10,290,180,RGB($0,$0,$0),RGB($0,$7F,$0),RGB($0,$FF,$0))=#False
End
EndIf
If MeterGadget(#Meter2,90,200,290,40,RGB($0,$0,$0),RGB($7F,$0,$0),RGB($FF,$FF,$0))=#False
End
EndIf
If MeterGadget(#Meter3,90,240,290,40,RGB($0,$0,$0),RGB($0,$0,$7F),RGB($0,$FF,$FF))=#False
End
EndIf
If TrackBarGadget(#Trackbar,110,300,260,30,0,100)=#False
End
EndIf
If ButtonGadget(#Saveimage,160,350,140,20,"Save Meter 1 Image")=#False
End
EndIf
If ButtonGadget(#Changecolor1,160,370,140,20,"Change Meter 1 Line Color")=#False
End
EndIf
If ButtonGadget(#Changecolor2,160,390,140,20,"Change Meter 2 Back Color")=#False
End
EndIf
If ButtonGadget(#Changecolor3,160,410,140,20,"Change Meter 2 Front Color")=#False
End
EndIf
;Meter 1 only updates "manually" (by moving trackbar for example)
;some other form of userinput or info could be used to feed it as well.
;Meter 2 only updates when there is no events,
;and as the waitloop is set to 10ms this is the max update rate.
;Meter 3 updates only each 50ms, regardless of user input or not.
;However for this to work properly the waitloop need to be 50ms or lower.
oldtime=ElapsedMilliseconds()
Repeat
newtime=ElapsedMilliseconds()
If (newtime-oldtime)>49 ;if 50ms or higher then update Meter 3
oldtime=newtime
; ADDITION
SetGadgetState(#Trackbar,Random(100))
SetMeterGadgetState(#Meter1,GetGadgetState(#Trackbar))
SetMeterGadgetState(#Meter3,GetGadgetState(#Trackbar))
EndIf
event=WaitWindowEvent(10)
If event
Select event
Case #PB_Event_Gadget
gadget=EventGadget()
Select gadget
Case #Trackbar ;User input, update meter 1.
SetMeterGadgetState(#Meter1,GetGadgetState(#Trackbar))
Case #Saveimage
pattern$="Bitmap (*.bmp)|*.bmp|"
patternpos=0
filename$=SaveFileRequester("Save image as:","",pattern$,patternpos)
If filename$
If GetExtensionPart(filename$)<>"bmp"
filename$+".bmp"
EndIf
SaveImage(GetMeterGadgetImage(#Meter1),filename$,#PB_ImagePlugin_BMP)
EndIf
Case #Changecolor1
SetMeterGadgetColor(#Meter1,#PB_Gadget_LineColor,RGB(Random($FF),Random($FF),Random($FF)))
Case #Changecolor2
SetMeterGadgetColor(#Meter2,#PB_Gadget_BackColor,RGB(Random($FF),Random($FF),Random($FF)))
Case #Changecolor3
SetMeterGadgetColor(#Meter3,#PB_Gadget_FrontColor,RGB(Random($FF),Random($FF),Random($FF)))
EndSelect
EndSelect
Else ;No event has happen for the last 10ms, Update meter 2.
SetMeterGadgetState(#Meter2,GetGadgetState(#Trackbar))
EndIf
Until event=#PB_Event_CloseWindow
End
Thanx for the tip!DoubleDutch wrote:doctorized: Nothing really to do with the thread, but if you want code to look like other code thats posted then highlight it and then click the 'Code' button just above the forum text edit box.
Code: Select all
EnableExplicit
;MeterGadget is a mix of a gadget and a image, a few procedures have been made to make
;gadget handling easier. In general a MeterGadget behaves almost like a normal ImageGadget.
;Otherwise normal gadget functions can be used (that works with ImageGadget)
;and obviously since it is a imagegadget it has the same gadget events returned as well.
;Tooltips can be set just like with any other ImageGadget.
;flags constants are the same as the flags constants used for ImageGadget like #PB_Image_Border
;IMPORTANT! SetGadgetData() MUST NOT be used with the MeterGadget,
;it's used for the structure pointers.
;Use SetMeterGadgetData() and GetMeterGadgetData() instead.
Structure MeterGadgetTable_struct
point.l
color.l
EndStructure
Structure MeterGadget_struct
image.l
imageid.l
x.l
y.l
w.l
h.l
bgcolor.l
fgcolor.l
linecolor.l
offset.l
userdata.l
flags.l
*table.MeterGadgetTable_struct
EndStructure
;Create #Image and #Gadget etc.
Procedure.l MeterGadget(gadget.l, x.l, y.l, width.l, height.l, bgcolor.l, fgcolor.l, linecolor.l, flags.l = #Null)
Protected *m.MeterGadget_struct, result.l = #Null, n.l, p.l = 0, newgadget.l, *table
If IsGadget(gadget)
*m = GetGadgetData(gadget)
If *m
result = *m\image
EndIf
EndIf
*m = AllocateMemory(SizeOf(MeterGadget_struct))
If *m
*m\flags = flags
If *m\flags = #PB_Image_Border
*m\w = width - 2
*m\h = height - 2
Else
*m\w = width
*m\h = height
EndIf
*m\table = AllocateMemory(SizeOf(MeterGadget_struct) * *m\w)
If *m\table
*m\x = x
*m\y = y
*m\bgcolor = bgcolor
*m\fgcolor = fgcolor
*m\linecolor = linecolor
*m\image = CreateImage(#PB_Any, width, height, #PB_Image_DisplayFormat)
If IsImage(*m\image)
*m\imageid = ImageID(*m\image)
If StartDrawing(ImageOutput(*m\image))
Box(p, p, *m\w, *m\h, *m\bgcolor)
For n = 0 To *m\h Step 10
LineXY(p, n, *m\w, n, *m\fgcolor)
Next
For n = 0 To width Step 10
LineXY(n, p, n, *m\h, *m\fgcolor)
Next
StopDrawing()
; result=ImageGadget(gadget,*m\x,*m\y,*m\w,*m\h,*m\imageid,flags) replaced by CanvasGadget
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
result = CanvasGadget(gadget, *m\x, *m\y, *m\w, *m\h, flags)
EndIf
EndIf
If gadget = #PB_Any
newgadget = result
Else
newgadget = gadget
EndIf
EndIf
If IsGadget(newgadget)
SetGadgetData(newgadget, *m)
Else
If IsImage(*m\image)
FreeImage(*m\image)
EndIf
If *m\table
FreeMemory(*m\table)
EndIf
FreeMemory(*m)
EndIf
StartDrawing(CanvasOutput(newgadget))
DrawImage(*m\imageid, 0, 0)
StopDrawing()
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EndIf
ProcedureReturn result
EndProcedure
;Use this instead of FreeGadget() to avoid memory leaks.
;Only needed if you need to free/remove a gadget.
;All resources are automatically freed at program end like normal PB gadgets though.
Procedure FreeMeterGadget(gadget.l)
Protected *m.MeterGadget_struct
If IsGadget(gadget)
*m = GetGadgetData(gadget)
FreeGadget(gadget)
If *m
If IsImage(*m\image)
FreeImage(*m\image)
EndIf
FreeMemory(*m)
EndIf
EndIf
EndProcedure
;Use this instead of SetGadgetState()
Procedure SetMeterGadgetState(gadget.l, state.l)
Protected *m.MeterGadget_struct, result.l, *table1.MeterGadgetTable_struct, *table2.MeterGadgetTable_struct
Protected n.l, y1.l, y2.l, bottom.l, percent.f, h.l, p.l
*m = GetGadgetData(gadget)
If *m\offset = 10
*m\offset = 0
EndIf
If *m\flags = #PB_Image_Border
p = 1
Else
p = 0
EndIf
For n = 0 To *m\w - 1
*table1 = *m\table + (n*SizeOf(MeterGadgetTable_struct))
*table2 = *m\table + ((n + 1)*SizeOf(MeterGadgetTable_struct))
*table1\point = *table2\point
*table1\color = *table2\color
Next
*table2\point = state
*table2\color = *m\linecolor
If StartDrawing(ImageOutput(*m\image))
Box(p, p, *m\w, *m\h, *m\bgcolor)
For n = 0 To *m\h Step 10
LineXY(p, n, *m\w, n, *m\fgcolor)
Next
For n = 0 To *m\w + *m\offset Step 10
LineXY(n - *m\offset, p, n - *m\offset, *m\h, *m\fgcolor)
Next
For n = 0 To *m\w
*table1 = *m\table + (n*SizeOf(MeterGadgetTable_struct))
*table2 = *m\table + ((n + 1)*SizeOf(MeterGadgetTable_struct))
bottom = *m\h
percent = (*table1\point / 100.0)
h = Int(percent * *m\h)
y1 = bottom - h
percent = (*table2\point / 100)
h = Int(percent * *m\h)
y2.l = bottom - h
LineXY(n + 1, y1, n + 1, y2, *table2\color)
Next
*m\offset + 1
StopDrawing()
; SetGadgetState(gadget,*m\imageid) replaced by CanvasGadget
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
StartDrawing(CanvasOutput(gadget))
DrawImage(*m\imageid, 0, 0)
StopDrawing()
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EndIf
EndProcedure
;Use this instead of GetGadgetState(). Not that usefull but may be handy to have.
Procedure.l GetMeterGadgetState(gadget.l)
Protected *m.MeterGadget_struct
*m = GetGadgetData(gadget)
ProcedureReturn *m\offset
EndProcedure
;Use this instead of SetGadgetData().
Procedure SetMeterGadgetData(gadget.l, userdata.l)
Protected *m.MeterGadget_struct
*m = GetGadgetData(gadget)
*m\userdata = userdata
EndProcedure
;Use this instead of GetGadgetData().
Procedure.l GetMeterGadgetData(gadget.l)
Protected *m.MeterGadget_struct
*m = GetGadgetData(gadget)
ProcedureReturn *m\userdata
EndProcedure
;Use this to get #Image
Procedure.l GetMeterGadgetImage(gadget.l)
Protected *m.MeterGadget_struct, result.l = #Null
*m = GetGadgetData(gadget)
ProcedureReturn *m\image
EndProcedure
;Use this to set gadget color
Procedure.l SetMeterGadgetColor(gadget.l, colortype.l, color.l)
Protected *m.MeterGadget_struct, result.l = #Null
*m = GetGadgetData(gadget)
Select colortype
Case #PB_Gadget_BackColor
*m\bgcolor = color
Case #PB_Gadget_FrontColor
*m\fgcolor = color
Case #PB_Gadget_LineColor
*m\linecolor = color
EndSelect
EndProcedure
;Use this to get gadget color
Procedure.l GetMeterGadgetColor(gadget.l, colortype.l)
Protected *m.MeterGadget_struct, result.l = #Null
*m = GetGadgetData(gadget)
Select colortype
Case #PB_Gadget_BackColor
result = *m\bgcolor
Case #PB_Gadget_FrontColor
result = *m\fgcolor
Case #PB_Gadget_LineColor
result = *m\linecolor
EndSelect
ProcedureReturn result
EndProcedure
;******************************************************************************
;- Example of use
Define event.l, gadget.l, filename$, pattern$, patternpos.l, oldtime.l, newtime.l
Enumeration 1
#Window
EndEnumeration
Enumeration 1
#Meter1
#Meter2
#Meter3
#Trackbar
#Saveimage
#Changecolor1
#Changecolor2
#Changecolor3
EndEnumeration
If OpenWindow(#Window, 0, 0, 470, 460, "Meter Control", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = #False
End
EndIf
If MeterGadget(#Meter1, 90, 10, 290, 180, RGB($0, $0, $0), RGB($0, $7F, $0), RGB($0, $FF, $0)) = #False
End
EndIf
If MeterGadget(#Meter2, 90, 200, 290, 40, RGB($0, $0, $0), RGB($7F, $0, $0), RGB($FF, $FF, $0)) = #False
End
EndIf
If MeterGadget(#Meter3, 90, 240, 290, 40, RGB($0, $0, $0), RGB($0, $0, $7F), RGB($0, $FF, $FF)) = #False
End
EndIf
If TrackBarGadget(#Trackbar, 110, 300, 260, 30, 0, 100) = #False
End
EndIf
If ButtonGadget(#Saveimage, 160, 350, 140, 20, "Save Meter 1 Image") = #False
End
EndIf
If ButtonGadget(#Changecolor1, 160, 370, 140, 20, "Change Meter 1 Line Color") = #False
End
EndIf
If ButtonGadget(#Changecolor2, 160, 390, 140, 20, "Change Meter 2 Back Color") = #False
End
EndIf
If ButtonGadget(#Changecolor3, 160, 410, 140, 20, "Change Meter 2 Front Color") = #False
End
EndIf
;Meter 1 only updates "manually" (by moving trackbar for example)
;some other form of userinput or info could be used to feed it as well.
;Meter 2 only updates when there is no events,
;and as the waitloop is set to 10ms this is the max update rate.
;Meter 3 updates only each 50ms, regardless of user input or not.
;However for this to work properly the waitloop need to be 50ms or lower.
oldtime = ElapsedMilliseconds()
Repeat
newtime = ElapsedMilliseconds()
If (newtime - oldtime) > 49 ;if 50ms or higher then update Meter 3
oldtime = newtime
; ADDITION
SetGadgetState(#Trackbar, Random(100))
SetMeterGadgetState(#Meter1, GetGadgetState(#Trackbar))
SetMeterGadgetState(#Meter3, GetGadgetState(#Trackbar))
EndIf
event = WaitWindowEvent(10)
If event
Select event
Case #PB_Event_Gadget
gadget = EventGadget()
Select gadget
Case #Trackbar ;User input, update meter 1.
SetMeterGadgetState(#Meter1, GetGadgetState(#Trackbar))
Case #Saveimage
pattern$ = "Bitmap (*.bmp)|*.bmp|"
patternpos = 0
filename$ = SaveFileRequester("Save image as:", "", pattern$, patternpos)
If filename$
If GetExtensionPart(filename$) <> "bmp"
filename$ + ".bmp"
EndIf
SaveImage(GetMeterGadgetImage(#Meter1), filename$, #PB_ImagePlugin_BMP)
EndIf
Case #Changecolor1
SetMeterGadgetColor(#Meter1, #PB_Gadget_LineColor, RGB(Random($FF), Random($FF), Random($FF)))
Case #Changecolor2
SetMeterGadgetColor(#Meter2, #PB_Gadget_BackColor, RGB(Random($FF), Random($FF), Random($FF)))
Case #Changecolor3
SetMeterGadgetColor(#Meter3, #PB_Gadget_FrontColor, RGB(Random($FF), Random($FF), Random($FF)))
EndSelect
EndSelect
Else ;No event has happen for the last 10ms, Update meter 2.
SetMeterGadgetState(#Meter2, GetGadgetState(#Trackbar))
EndIf
Until event = #PB_Event_CloseWindow
End
SoS wrote:Hi
I use up to 12 Gadgets at once in a private Project and they flicker.
I have changed the Code to use a Canvasgadget and thus eliminates the flicker.![]()
The Code works on PB 5.21 86/64