PB5.2 : create custom gadget

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

PB5.2 : create custom gadget

Post by eddy »

- Module to convert common PB gadgets into custom gadgets
- This new version is simplier:
  • No window API
  • No PB import
( You can find the old version: http://www.purebasic.fr/english/viewtop ... 12&t=35299 )
- Methods:
  • ManageGadgetCommands(*manager.GADGET_MANAGER, Gadget, State)
  • ManageGadget(*manager.GADGET_MANAGER, Gadget, *params, GadgetType)
  • UnmanageGadget(*manager.GADGET_MANAGER, Gadget)

Code: Select all

;-TOP
; Comment : Create custom PB gadget
; Author  : eddy
; Web     : http://www.purebasic.fr/english/viewtopic.php?f=12&p=418722
; File:   : CustomGadget.pbi
; Version : v0.7

DeclareModule CustomGadget
   Prototype Events(*Params, EventWindow, EventGadget, EventType)
   Prototype Call(*Gadget)
   Prototype CallByItem(*Gadget, Item)
   Prototype Resize(*Gadget, x.l, y.l, w.l, h.l)
   Prototype.i GetInteger(*Gadget)
   Prototype SetInteger(*Gadget, Value)
   Prototype.s GetString(*Gadget)
   Prototype SetString(*Gadget, Value$)
   Prototype.s GetStringByItem(*Gadget, Item)
   Prototype SetStringByItem(*Gadget, Item, Value$)
   Prototype.i GetIntegerByAttribute(*Gadget, Attribute)
   Prototype SetIntegerByAttribute(*Gadget, Attribute, Value)
   Prototype.i GetIntegerByItem(*Gadget, Item)
   Prototype SetIntegerByItemAttribute(*Gadget, Item, Attribute, Value, Column=#PB_Ignore)
   Prototype.i GetIntegerByItemAttribute(*Gadget, Item, Attribute, Column=#PB_Ignore)
   Prototype SetIntegerByItem(*Gadget, Item, Value)
   Structure GADGET_VT
      GadgetType.l      ; gadget type (used by GadgetType command)
      SizeOf.l          ; Size of structure
      
      *GadgetCallback
      *FreeGadget.Call
      *GetGadgetState.GetInteger
      *SetGadgetState.SetInteger
      *GetGadgetText.GetString
      *SetGadgetText.SetString
      *AddGadgetItem2
      *AddGadgetItem3
      *RemoveGadgetItem.CallByItem
      *ClearGadgetItems.Call
      *ResizeGadget.Resize
      *CountGadgetItems.GetInteger
      *GetGadgetItemState.GetIntegerByItem
      *SetGadgetItemState.SetIntegerByItem
      *GetGadgetItemText.GetStringByItem
      *SetGadgetItemText.SetStringByItem
      *OpenGadgetList2
      *GadgetX.GetInteger
      *GadgetY.GetInteger
      *GadgetWidth.GetInteger
      *GadgetHeight.GetInteger
      *HideGadget.SetInteger
      *AddGadgetColumn
      *RemoveGadgetColumn
      *GetGadgetAttribute.GetIntegerByAttribute
      *SetGadgetAttribute.SetIntegerByAttribute
      *GetGadgetItemAttribute.GetIntegerByItemAttribute
      *SetGadgetItemAttribute.SetIntegerByItemAttribute
      *SetGadgetColor
      *GetGadgetColor
      *SetGadgetItemColor2
      *GetGadgetItemColor2
      *SetGadgetItemData
      *GetGadgetItemData
      *GetRequiredSize
      *SetActiveGadget
      *GetGadgetFont
      *SetGadgetFont
      *SetGadgetItemImage
   EndStructure
   Structure GADGET
      *Handle           ; gadget OS handle
      *VT.GADGET_VT     ; gadget commands
      *UserData         ; gadget data (used by SetGadgetData)
      *OldCallback      ; original OS callback  (used by purebasic CALLBACK)
      Daten.i[4]        ; .....
   EndStructure
   Structure GADGET_MANAGER
      GadgetCount.i        ;gadget counter (optional)
      *OldVT.GADGET_VT  ;old commands pointers
      *NewVT.GADGET_VT  ;new commands pointers
      Map *GadgetParams()  ;gadget custom parameters
   EndStructure
   
   Declare ManageGadgetCommands(*manager.GADGET_MANAGER, Gadget, State)
   Declare ManageGadget(*manager.GADGET_MANAGER, Gadget, *params, GadgetType)
   Declare UnmanageGadget(*manager.GADGET_MANAGER, Gadget)
EndDeclareModule

Module CustomGadget
   EnableExplicit
   Procedure ManageGadgetCommands(*manager.GADGET_MANAGER, Gadget, State)
      Protected *gadget.GADGET=IsGadget(Gadget)
      If State
         *gadget\VT=*manager\NewVT
      Else
         *gadget\VT=*manager\OldVT
      EndIf
   EndProcedure
   Procedure ManageGadget(*manager.GADGET_MANAGER, Gadget, *params, GadgetType)
      Protected *gadget.GADGET=IsGadget(Gadget)
      With *manager
         If \OldVT=#Null And \NewVT=#Null
            ; define manager: custom events, custom VT, custom gadget type
            \OldVT=*gadget\VT
            \NewVT=AllocateMemory(SizeOf(GADGET_VT))
            CopyMemory(\OldVT, \NewVT, SizeOf(GADGET_VT))
            \NewVT\GadgetType=GadgetType
         EndIf
         ; use custom PB commands
         ManageGadgetCommands(*manager, Gadget, #True)
         
         ; save gadget params and increment counter
         \GadgetParams(""+*gadget)=*params
         \GadgetCount+1
      EndWith
   EndProcedure
   Procedure UnmanageGadget(*manager.GADGET_MANAGER, Gadget)
      Protected *gadget.GADGET=IsGadget(Gadget)
      With *manager
         \GadgetCount-1
         Protected *params=*manager\GadgetParams()
         DeleteMapElement(*manager\GadgetParams(), ""+*Gadget)
         If *params
            FreeMemory(*params)
         EndIf
      EndWith
   EndProcedure
EndModule
Last edited by eddy on Thu Jul 25, 2013 1:39 pm, edited 7 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: PB5 : create custom gadget

Post by eddy »

gadget with 3 buttons (PLAY,PAUSE,STOP)

Image

Code: Select all

XIncludeFile "path\CustomGadget.pbi"

; *************************
; CUSTOM PLAYER GADGET
; *************************

DeclareModule PlayerButtonsGadget
   Enumeration
      ; custom gadget type
      #PB_GadgetType_PlayerButtons=20130723
      
      ; custom gadget state
      #PB_PlayerButtons_Stopped=0
      #PB_PlayerButtons_Paused
      #PB_PlayerButtons_Playing
      
   EndEnumeration
   
   Declare.i PlayerButtonsGadget(Gadget, x, y, Width, Height, Duration=2000)
EndDeclareModule

Module PlayerButtonsGadget
   EnableExplicit
   UseModule CustomGadget
   
   Structure PLAYER_PARAMS
      Gadget.i
      ButtonStop.i
      ButtonPlay.i
      ButtonPause.i
      State.i
   EndStructure
   
   Procedure.i GetManager()
      Static manager.GADGET_MANAGER
      ProcedureReturn @manager
   EndProcedure
   Procedure.i GetParams(*Gadget.GADGET)
      Protected *manager.GADGET_MANAGER=GetManager()
      ProcedureReturn *manager\GadgetParams(""+*Gadget)
   EndProcedure
   
   
   Procedure _GadgetEvents()
      Protected EventGadget=EventGadget()
      Protected EventWindow=EventWindow()
      Protected EventType=EventType()
      Protected *params.PLAYER_PARAMS=GetGadgetData(EventGadget)
      With *params
         If EventType=#PB_EventType_LeftClick
            Select EventGadget
               Case \ButtonStop
                  SetGadgetState(\Gadget, #PB_PlayerButtons_Stopped)
                  PostEvent(#PB_Event_Gadget, EventWindow, \Gadget, #PB_EventType_LeftClick)
               Case \ButtonPause
                  SetGadgetState(\Gadget, #PB_PlayerButtons_Paused)
                  PostEvent(#PB_Event_Gadget, EventWindow, \Gadget, #PB_EventType_LeftClick)
               Case \ButtonPlay
                  SetGadgetState(\Gadget, #PB_PlayerButtons_Playing)
                  PostEvent(#PB_Event_Gadget, EventWindow, \Gadget, #PB_EventType_LeftClick)
            EndSelect
         EndIf
      EndWith
   EndProcedure
   Procedure _FreeGadget(*Gadget.GADGET)
      Protected *params.PLAYER_PARAMS=GetParams(*Gadget)
      With *params
         ; free custom data
         UnmanageGadget(GetManager(), \Gadget)
      EndWith
   EndProcedure
   Procedure _ResizeGadget(*Gadget.GADGET, x.l, y.l, w.l, h.l)
      Protected *params.PLAYER_PARAMS=GetParams(*Gadget)
      With *params
         ManageGadgetCommands(GetManager(), \Gadget, #False) ;use default PB commands
         ResizeGadget(\Gadget, x, y, w, h)
         ManageGadgetCommands(GetManager(), \Gadget, #True) ;use custom PB commands
         
         If w<>#PB_Ignore : w=w/3-2 : EndIf
         ResizeGadget(\ButtonStop, #PB_Ignore, #PB_Ignore, w, h)
         ResizeGadget(\ButtonPlay, GadgetWidth(\ButtonStop)+2, #PB_Ignore, w, h)
         ResizeGadget(\ButtonPause, (GadgetWidth(\ButtonStop)+2)*2, #PB_Ignore, w, h)
      EndWith
   EndProcedure
   Procedure _SetGadgetState(*Gadget.GADGET, State)
      Protected *params.PLAYER_PARAMS=GetParams(*Gadget)
      With *params
         \State=State
         SetGadgetState(\ButtonStop, Bool(\State=#PB_PlayerButtons_Stopped))
         SetGadgetState(\ButtonPlay, Bool(\State=#PB_PlayerButtons_Playing))
         SetGadgetState(\ButtonPause, Bool(\State=#PB_PlayerButtons_Paused))
      EndWith
   EndProcedure
   Procedure.i _GetGadgetState(*Gadget.GADGET)
      Protected *params.PLAYER_PARAMS=GetParams(*Gadget)
      ProcedureReturn *params\State
   EndProcedure
   
   Procedure.i PlayerButtonsGadget(Gadget, x, y, Width, Height, Duration=2000)
      Protected result=ContainerGadget(Gadget, 0, 0, 0, 0, #PB_Container_BorderLess)
      If result
         If Gadget=#PB_Any : Gadget=result : EndIf
         
         ; initialize custom params and custom manager
         Protected *params.PLAYER_PARAMS=AllocateMemory(SizeOf(PLAYER_PARAMS))
         Protected *manager.GADGET_MANAGER=GetManager()
         ManageGadget(*manager, Gadget, *params, #PB_GadgetType_PlayerButtons)
         
         ; create and save custom elements and custom params
         With *params
            Protected oldFontID=GetGadgetFont(#PB_Default)
            Static newFontID
            If Not newFontID : newFontID=FontID(LoadFont(#PB_Any, "Webdings", 12)) : EndIf
            SetGadgetFont(#PB_Default, newFontID)
            \Gadget=Gadget
            \ButtonStop=ButtonGadget(#PB_Any, 0, 0, 0, 0, "<", #PB_Button_Toggle)
            \ButtonPlay=ButtonGadget(#PB_Any, 0, 0, 0, 0, "4", #PB_Button_Toggle)
            \ButtonPause=ButtonGadget(#PB_Any, 0, 0, 0, 0, ";", #PB_Button_Toggle)
            CloseGadgetList()
            SetGadgetData(\ButtonStop, *params)
            SetGadgetData(\ButtonPlay, *params)
            SetGadgetData(\ButtonPause, *params)
            BindGadgetEvent(\ButtonStop, @_GadgetEvents())
            BindGadgetEvent(\ButtonPlay, @_GadgetEvents())
            BindGadgetEvent(\ButtonPause, @_GadgetEvents())
            SetGadgetFont(#PB_Default, oldFontID)
         EndWith
         ; define custom PB commands
         With *manager\NewVT
            \FreeGadget = @_FreeGadget()
            \GetGadgetState = @_GetGadgetState()
            \SetGadgetState = @_SetGadgetState()
            \ResizeGadget = @_ResizeGadget()
         EndWith
         ; redraw gadget once and reset its state
         ResizeGadget(Gadget, x, y, Width, Height)
         SetGadgetState(Gadget, #PB_PlayerButtons_Stopped)
         ProcedureReturn result
      EndIf
   EndProcedure
EndModule

UseModule PlayerButtonsGadget

If OpenWindow(100, 0, 0, 222, 200, "Gadget to display audio player buttons", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   
   PlayerButtonsGadget(2, 11, 32, 200, 5)
   *gadget.CustomGadget::GADGET=IsGadget(2)
   Debug "Test GadgetID =>"+Bool(*gadget\Handle=GadgetID(2))
   If GadgetType(2)=#PB_GadgetType_PlayerButtons : Debug "GadgetType: PlayerButtons" : EndIf
   ResizeGadget(2, #PB_Ignore, 11, #PB_Ignore, 25)
   Debug "x="+GadgetX(2)
   Debug "y="+GadgetY(2)
   Debug "w="+GadgetWidth(2)
   Debug "h="+GadgetHeight(2)
   DisableGadget(2, 1)
   DisableGadget(2, 0)
   HideGadget(2, 1)
   HideGadget(2, 0)
   
   Repeat
      e=WaitWindowEvent()
      g=EventGadget()
      t=EventType()
      w=EventWindow()
      If e=#PB_Event_Gadget And g=2 And w=100
         If t=#PB_EventType_LeftClick
            Debug FormatDate("%ii:%ss", Date())+" Click On: PlayerButtonsGadget"
            If GetGadgetState(2)=#PB_PlayerButtons_Paused : Debug "GadgetState: Paused Mode" : EndIf
            If GetGadgetState(2)=#PB_PlayerButtons_Playing : Debug "GadgetState: Playing Mode" : EndIf
            If GetGadgetState(2)=#PB_PlayerButtons_Stopped : Debug "GadgetState: Stopped Mode" : EndIf            
         EndIf
      EndIf
   Until e=#PB_Event_CloseWindow
EndIf
Last edited by eddy on Fri Jul 26, 2013 6:22 pm, edited 6 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: PB5.2 : create custom gadget

Post by yrreti »

Thanks for your code and example eddy
But just a short note.
You need to add XIncludeFile "path\CustomGadget.pbi" for it to work.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: PB5.2 : create custom gadget

Post by eddy »

yrreti wrote:Thanks for your code and example eddy
But just a short note.
You need to add XIncludeFile "path\CustomGadget.pbi" for it to work.
Right
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Post Reply