Custom Gadget Template?

Just starting out? Need help? Post your questions and find answers here.
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Custom Gadget Template?

Post by collectordave »

Hi All

Just looking at maybe producing a custom gadget based on the canvas gadget so searched for pointers on the forum most I do not understand so decided to try my own.

It turned into what I call a template.

Before I go any further can anyone see any problems looming on the horizon?

Now Joined github the code and test programme can be downloaded here

https://github.com/collectordave/Custom-Gadgets

Cheers

cd
Last edited by collectordave on Wed Dec 21, 2016 4:36 pm, edited 2 times in total.
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Custom Gadget Template?

Post by collectordave »

Just another small question.

Is it possible to capture a resize event if the user\programmer resizes the gadget?

There seems to be no canvas gadget changed messages.

Regards

cd
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
mestnyi
Addict
Addict
Posts: 1098
Joined: Mon Nov 25, 2013 6:41 am

Re: Custom Gadget Template?

Post by mestnyi »

it

Code: Select all

;Create The Canvas For The Gadget
  If Gadget = #PB_Any
    ThisGadget = CanvasGadget(#PB_Any, x,y,width,height)
  Else
    ThisGadget = Gadget
    CanvasGadget(Gadget, x,y,width,height)
  EndIf
  
I think it would be better

Code: Select all

;Create The Canvas For The Gadget
  Protected ID = CanvasGadget(Gadget, X,Y,Width,Height) : If IsGadget(ID) : Gadget = ID : EndIf
  
Is it possible to capture a resize event if the user\programmer resizes the gadget?

Code: Select all

DeclareModule CustomGadget
  Enumeration #PB_EventType_FirstCustomValue
    #PB_EventType_Size
    #PB_EventType_Move
  EndEnumeration
  
  Declare GadgetEvents()
  Declare AddGadget(ThisGadget.i)
  Declare GadgetResize( Gadget )
EndDeclareModule

Module CustomGadget
  
  Global Dim gadgetArray.i(0)
  
  Procedure GadgetResize( Gadget )
    Protected GadgetMove, GadgetSize, GadgetX, GadgetY, GadgetWidth, GadgetHeight.i
    Protected Window = GetActiveWindow()
    
    If IsGadget( Gadget )
      Structure StructGadgetResize
        GadgetX.i
        GadgetY.i
        GadgetWidth.i
        GadgetHeight.i
      EndStructure : Static NewMap Map.StructGadgetResize()
      
      GadgetX = GadgetX( Gadget ) 
      GadgetY = GadgetY( Gadget )
      GadgetWidth = GadgetWidth( Gadget )
      GadgetHeight = GadgetHeight( Gadget )
      
      With Map( Str( Gadget ) )
        ; Debug MapSize(Map())
        If MapKey( Map() ) = Str( Gadget )
          If GadgetX      <> \GadgetX      : \GadgetX      = GadgetX      : GadgetMove = #True : EndIf
          If GadgetY      <> \GadgetY      : \GadgetY      = GadgetY      : GadgetMove = #True : EndIf
          If GadgetWidth  <> \GadgetWidth  : \GadgetWidth  = GadgetWidth  : GadgetSize = #True : EndIf
          If GadgetHeight <> \GadgetHeight : \GadgetHeight = GadgetHeight : GadgetSize = #True : EndIf
        Else
          \GadgetX      = GadgetX 
          \GadgetY      = GadgetY
          \GadgetWidth  = GadgetWidth
          \GadgetHeight = GadgetHeight
        EndIf
      EndWith
    Else
      If MapSize(Map())
        Debug "MapSize "+MapSize(Map())
        Debug "FreeMap"
        ClearMap(Map())
        FreeMap(Map())
      EndIf
    EndIf
    
    If GadgetMove : PostEvent( #PB_Event_Gadget, Window, Gadget, #PB_EventType_Move ) : EndIf
    If GadgetSize : PostEvent( #PB_Event_Gadget, Window, Gadget, #PB_EventType_Size ) : EndIf
    
;     If IsGadget( Gadget )
;       CompilerIf #PB_Compiler_OS = #PB_OS_Windows
;         RedrawWindow_( GadgetID( Gadget ), #Null,#Null,#RDW_INVALIDATE|#RDW_UPDATENOW )
;       CompilerElse
;         ;gtk_widget_queue_draw_ ( GadgetID( Gadget ));g_list_nth_data_( gtk_container_get_children_( gtk_bin_get_child_( WindowID( EventWindow() ))), 0))
;       CompilerEndIf
;     EndIf
    
  EndProcedure
  
  Procedure AddGadget(ThisGadget.i)

    ReDim gadgetArray(ArraySize(gadgetArray())+1)
    gadgetArray(ArraySize(gadgetArray())) = ThisGadget
      
  EndProcedure
    
  Procedure GadgetEvents()
    
    Define CurrentGadget.i
    
    ;Which Gadget
    For iLoop = 0 To ArraySize(gadgetArray())
      If EventGadget() = gadgetArray(iLoop)
        CurrentGadget = iLoop
      EndIf
    Next iLoop    
    
    Select EventType()
       
      Case #PB_EventType_MouseEnter
        Debug "Mouse Entered Gadget " + Str(CurrentGadget)
        ResizeGadget( EventGadget(), #PB_Ignore, #PB_Ignore, 155, #PB_Ignore)
        GadgetResize( EventGadget() )
        
      Case #PB_EventType_MouseLeave 
        Debug "Mouse Left Gadget " + Str(CurrentGadget)       
        ResizeGadget( EventGadget(), #PB_Ignore, #PB_Ignore, 135, #PB_Ignore)
        GadgetResize( EventGadget() )
        
      Case #PB_EventType_MouseMove 
        ;Debug "MouseMove On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_MouseWheel
        Debug "MouseWheel  On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_LeftButtonDown
        Debug "LeftButtonDown On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_LeftButtonUp
        Debug "LeftButtonUp On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_LeftClick 
        Debug "LeftClick On Gadget " + Str(CurrentGadget) 
      Case #PB_EventType_LeftDoubleClick
        Debug "LeftDoubleClick On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_RightButtonDown
         Debug "RightButtonDown On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_RightButtonUp
        Debug "RightButtonUp On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_RightClick
        Debug "RightClick On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_RightDoubleClick
        Debug "RightDoubleClick On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_MiddleButtonDown
        Debug "MiddleButtonDown On Gadget " + Str(CurrentGadget)         
      Case #PB_EventType_MiddleButtonUp
         Debug "MiddleButtonUp On Gadget " + Str(CurrentGadget)        
         
      Case #PB_EventType_Size
         Debug "#PB_EventType_Size " + Str(CurrentGadget)        
 
    EndSelect
    
  EndProcedure

  
EndModule

Procedure CustomGadget(Gadget, X,Y,Width,Height)
  Protected ID
  
  ;Create The Canvas For The Gadget
  ID = CanvasGadget(Gadget, X,Y,Width,Height) 
  If IsGadget(ID) : Gadget = ID : EndIf
  
  ;Bind This gadgets Events
  BindGadgetEvent(Gadget, CustomGadget::@GadgetEvents())
  
  ;Add To The Custom Gadget Array
  CustomGadget::AddGadget(Gadget)
  CustomGadget::GadgetResize( Gadget )
  
EndProcedure


; then a little programme To test so far:-
; 
; winMain.pb
; 
; Code:
; IncludeFile "CustomGadget.pbi"

Global Window_0

  Window_0 = OpenWindow(#PB_Any, 0, 0, 600, 400, "", #PB_Window_SystemMenu)
  CustomGadget(#PB_Any,250, 40, 130, 80)
  CustomGadget(23,100, 40, 130, 80)  
  CustomGadget(#PB_Any,100, 240, 130, 80)
  CustomGadget(#PB_Any,250, 240, 130, 80)
  
  Repeat
    
  Event = WaitWindowEvent()
    
  Select Event
    Case #PB_Event_CloseWindow
     End

    Case #PB_Event_Gadget
      
      Select EventGadget()

      EndSelect
      
  EndSelect
  
ForEver
And so, to do through api
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Custom Gadget Template?

Post by collectordave »

Code in first post updated for Keyboard and resize.

So the template now allows you to create as many Custom Gadgets on a window as you like and can use the flags for the canvas gadget including keyboard stuff and it reacts to a resize event on the gadget.

Would like a changed event for the canvas gadget which would remove a lot of the code. If you see the need as well please go to this topic and say yes to the resize\changed event.
http://www.purebasic.fr/english/viewtop ... =3&t=67229

Regards

cd
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: Custom Gadget Template?

Post by Bisonte »

Without API (works with 5.50 at windows and linux mint 18, can't test on Mac)

Only the Resize Thing

Code: Select all

Enumeration #PB_EventType_FirstCustomValue
  #PB_EventType_GadgetReSize
EndEnumeration

Procedure _ResizeGadget(Gadget, x, y, Width, Height)
  
  Protected Window
  
  If IsGadget(Gadget)
    Result = ResizeGadget(Gadget, x, y, Width, Height)
    Window = GetGadgetData(Gadget)
    If IsWindow(Window)
      PostEvent(#PB_Event_Gadget, Window, Gadget, #PB_EventType_GadgetResize)
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure

Macro ResizeGadget(Gadget, x, y, Width, Height)
  _ResizeGadget(Gadget, x, y, Width, Height)
EndMacro

Procedure Ev_Gadget()

  Debug "Resize"
    
EndProcedure

Procedure CustomGadget(Gadget, x, y, Width, Height, Window)
  
  ID = CanvasGadget(Gadget, x, y, Width, Height)
  If Gadget = #PB_Any : Gadget = ID : EndIf
  
  BindGadgetEvent(Gadget, @Ev_Gadget(), #PB_EventType_GadgetReSize)
  
  If IsWindow(Window)
    If WindowID(Window) = UseGadgetList(0)
      Debug "Ok"
      SetGadgetData(Gadget, Window)
    EndIf
  EndIf
  
EndProcedure

;: DEMO +++++++

OpenWindow(10, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)

ButtonGadget(1, 10, 10, 100, 20, "Klick")
CustomGadget(2, 50, 50, 100, 100, 10)

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow
      Quit = #True
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          If a = 0
            a=1
            ResizeGadget(2, 50, 50, 110, 110)
          Else
            a = 0
            ResizeGadget(2, 50, 50, 100, 100)
          EndIf
          
      EndSelect
      
  EndSelect
  
Until Quit
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
mestnyi
Addict
Addict
Posts: 1098
Joined: Mon Nov 25, 2013 6:41 am

Re: Custom Gadget Template?

Post by mestnyi »

we have

Code: Select all

BindGadgetEvent()

Why not have?

Code: Select all

PostGadgetEvent()
Because of this, we have to so perverted

Code: Select all

If IsWindow(Window)
    If WindowID(Window) = UseGadgetList(0)
      Debug "Ok"
      SetGadgetData(Gadget, Window)
    EndIf
  EndIf
Fred :evil:
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Custom Gadget Template?

Post by collectordave »

Hi

Thanks for the replies.

I can see some problems with adding a macro to replace resize gadget when adding multiple custom gadgets which may require the custom gadget to have a dependance on another module which would have to be xincludefile in each custom gadget.

So I have gone with the first solution sorry Bisonte.

However there is some merit in holding on to the window Id of the window on which the gadget has been created especialy if the custom gadget has to return any custom events back to the window on which it was creted, so I am now adding this.

Will post next version as soon as tested.

the best answer is to have a changed event for the canvas gadget as I have asked for here http://www.purebasic.fr/english/viewtop ... =3&t=67229

I have to agree that a PostgadgetEvent() would be helpfull as well.

Regards

cd
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: Custom Gadget Template?

Post by Bisonte »

collectordave wrote:So I have gone with the first solution sorry Bisonte.
Never mind. It's just another way, this is PureBasic ;)
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
mestnyi
Addict
Addict
Posts: 1098
Joined: Mon Nov 25, 2013 6:41 am

Re: Custom Gadget Template?

Post by mestnyi »

better in my decision using a macro written Bisonte

Code: Select all

DeclareModule CustomGadget
  Enumeration #PB_EventType_FirstCustomValue
    #PB_EventType_Size
    #PB_EventType_Move
  EndEnumeration
  
  Declare GadgetEvents()
  Declare AddGadget(ThisGadget.i)
  Declare Free(ThisGadget.i)
  Declare Resize(Gadget, X, Y, Width, Height)
EndDeclareModule

Module CustomGadget
  Procedure GadgetResize( Gadget )
    Protected GadgetMove, GadgetSize, GadgetX, GadgetY, GadgetWidth, GadgetHeight.i
    Protected Window = GetActiveWindow()
    
    If IsGadget( Gadget )
      Structure StructGadgetResize
        GadgetX.i
        GadgetY.i
        GadgetWidth.i
        GadgetHeight.i
      EndStructure : Static NewMap Map.StructGadgetResize()
      
      GadgetX = GadgetX( Gadget ) 
      GadgetY = GadgetY( Gadget )
      GadgetWidth = GadgetWidth( Gadget )
      GadgetHeight = GadgetHeight( Gadget )
      
      With Map( ) 
        If FindMapElement(Map(), Str( Gadget ))
          If GadgetX      <> \GadgetX      : \GadgetX      = GadgetX      : GadgetMove = #True : EndIf
          If GadgetY      <> \GadgetY      : \GadgetY      = GadgetY      : GadgetMove = #True : EndIf
          If GadgetWidth  <> \GadgetWidth  : \GadgetWidth  = GadgetWidth  : GadgetSize = #True : EndIf
          If GadgetHeight <> \GadgetHeight : \GadgetHeight = GadgetHeight : GadgetSize = #True : EndIf
        Else
          AddMapElement(Map(), Str( Gadget ))
          \GadgetX      = GadgetX 
          \GadgetY      = GadgetY
          \GadgetWidth  = GadgetWidth
          \GadgetHeight = GadgetHeight
        EndIf
      EndWith
    Else
      If MapSize(Map())
        Debug "MapSize "+MapSize(Map())
        Debug "FreeMap"
        ClearMap(Map())
        FreeMap(Map())
      EndIf
    EndIf
    
    If GadgetMove : PostEvent( #PB_Event_Gadget, Window, Gadget, #PB_EventType_Move ) : EndIf
    If GadgetSize : PostEvent( #PB_Event_Gadget, Window, Gadget, #PB_EventType_Size ) : EndIf
    
  EndProcedure
  Procedure Resize(Gadget, X, Y, Width, Height)
    If IsGadget(Gadget) : ResizeGadget(Gadget, X, Y, Width, Height) : EndIf : GadgetResize( Gadget )
  EndProcedure
  Macro ResizeGadget(Gadget, X, Y, Width, Height) : Resize(Gadget, X, Y, Width, Height) : EndMacro
  
  Global Dim gadgetArray.i(0)
  
  Procedure AddGadget(ThisGadget.i)
    
    ReDim gadgetArray(ArraySize(gadgetArray())+1)
    gadgetArray(ArraySize(gadgetArray())) = ThisGadget
    
  EndProcedure
  
  Procedure Free(ThisGadget.i)
    
    GadgetResize( #PB_Any )
    FreeArray(gadgetArray())

  EndProcedure
  
  Procedure GadgetEvents()
    
    Define CurrentGadget.i
    
    ;Which Gadget
    For iLoop = 0 To ArraySize(gadgetArray())
      If EventGadget() = gadgetArray(iLoop)
        CurrentGadget = iLoop
      EndIf
    Next iLoop    
    
    Select EventType()
        
      Case #PB_EventType_MouseEnter
        Debug "Mouse Entered Gadget " + Str(CurrentGadget)
        ResizeGadget( EventGadget(), #PB_Ignore, #PB_Ignore, 155, #PB_Ignore)
        
      Case #PB_EventType_MouseLeave 
        Debug "Mouse Left Gadget " + Str(CurrentGadget)       
        ResizeGadget( EventGadget(), #PB_Ignore, #PB_Ignore, 135, #PB_Ignore)
        
      Case #PB_EventType_MouseMove 
        ;Debug "MouseMove On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_MouseWheel
        Debug "MouseWheel  On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_LeftButtonDown
        Debug "LeftButtonDown On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_LeftButtonUp
        Debug "LeftButtonUp On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_LeftClick 
        Debug "LeftClick On Gadget " + Str(CurrentGadget) 
      Case #PB_EventType_LeftDoubleClick
        Debug "LeftDoubleClick On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_RightButtonDown
        Debug "RightButtonDown On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_RightButtonUp
        Debug "RightButtonUp On Gadget " + Str(CurrentGadget)        
      Case #PB_EventType_RightClick
        Debug "RightClick On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_RightDoubleClick
        Debug "RightDoubleClick On Gadget " + Str(CurrentGadget)           
      Case #PB_EventType_MiddleButtonDown
        Debug "MiddleButtonDown On Gadget " + Str(CurrentGadget)         
      Case #PB_EventType_MiddleButtonUp
        Debug "MiddleButtonUp On Gadget " + Str(CurrentGadget)        
        
      Case #PB_EventType_Size
        Debug "#PB_EventType_Size " + Str(CurrentGadget)        
        
        
      Case #PB_EventType_Move
        Debug "#PB_EventType_Move " + Str(CurrentGadget)        
        
    EndSelect
    
  EndProcedure
EndModule

Procedure CustomGadget(Gadget, X,Y,Width,Height, Flag = 0)
  Protected ID
  
  ;Create The Canvas For The Gadget
  ID = CanvasGadget(Gadget, X,Y,Width,Height, Flag) 
  If IsGadget(ID) : Gadget = ID : EndIf
  
  ;Bind This gadgets Events
  BindGadgetEvent(Gadget, CustomGadget::@GadgetEvents())
  
  ;Add To The Custom Gadget Array
  CustomGadget::AddGadget(Gadget)
  CustomGadget::Resize( Gadget, X,Y,Width,Height )
  
  ProcedureReturn Gadget
EndProcedure

Macro ResizeGadget(Gadget, X, Y, Width, Height) : CustomGadget::Resize(Gadget, X, Y, Width, Height) : EndMacro

; then a little programme To test so far:-
; 
; winMain.pb
; 
; Code:
; IncludeFile "CustomGadget.pbi"

Enumeration FormGadget
  #btnRedraw  
  #CustomGadget1
  #CustomGadget2
EndEnumeration

Global Window_0,CustomGadget3.i,CustomGadget4.i

Window_0 = OpenWindow(#PB_Any, 0, 0, 600, 400, "", #PB_Window_SystemMenu)
CustomGadget(#CustomGadget1,250, 40, 130, 80,0)
CustomGadget(#CustomGadget2,100, 40, 130, 80,0)  
CustomGadget3 = CustomGadget(#PB_Any,100, 240, 130, 80,0)
CustomGadget4 = CustomGadget(#PB_Any,250, 240, 130, 80,#PB_Canvas_Keyboard | #PB_Canvas_DrawFocus)
ButtonGadget(#btnRedraw, 470, 340, 70, 30, "")

Repeat
  
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow
      
      End
      
    Case #PB_Event_Gadget
      
      Select EventGadget()
          
        Case #btnRedraw
          
          ResizeGadget(CustomGadget3,110,160,100,#PB_Ignore)
          
      EndSelect
      
  EndSelect
  
ForEver
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Custom Gadget Template?

Post by collectordave »

Hi all

Changed the code for the template to bisonte suggestion seems to work.

Code updated same link as first post.

Kind Regards

cd
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
mestnyi
Addict
Addict
Posts: 1098
Joined: Mon Nov 25, 2013 6:41 am

Re: Custom Gadget Template?

Post by mestnyi »

Link does not work
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Custom Gadget Template?

Post by collectordave »

Just tried it this second and worked fine!

regards

cd
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Post Reply