Toolbar+ dropdown arrow, popupmenu, toggle buttons, gadgets
Posted: Wed Aug 21, 2013 11:42 pm

- ADDED : option to auto center all gadgets
- ADDED : toolbar container to include PB common gadgets (button, text, spin,etc .... )
- ADDED : toolbar grouped toggle buttons
- ADDED : toolbar drop-down style button
- ADDED : toolbar popup menu
- ADDED : toolbar custom popup
- new event type #PB_EventType_ToolbarPopup associated to event #PB_Event_Menu
- ToolbarPopupX() and ToolbarPopupY() to determine popup position

Code: Select all
;:=============================================================================
;:- ToolbarPlus.pbi
;:- Author : Eddy
;:- Date : August 31, 2013
;:- Compiler : PureBasic 5.20 beta 15
;:- Target OS : Windows
;:- Source --------------------------------------------------------------------
;:- http://www.purebasic.fr/english/viewtopic.php?f=40&t=56155
;:=============================================================================
EnableExplicit
Global CurrentGadgetListToolbar=#PB_Ignore
Enumeration 1
#PB_EventType_ToolbarPopup
EndEnumeration
Procedure ToolBarCustomCallback(hWnd, message, wParam, lParam) ;ToolbarPlus callback procedure.
;detect click on toolbar buttons
Protected *ToolbarID
Protected buttonID
Select message
Case #WM_COMMAND
*ToolbarID=lParam
buttonID=wParam ;(wParam -> high word = 0)
Case #WM_NOTIFY
Protected *NMTOOLBAR.NMTOOLBAR=lParam
With *NMTOOLBAR
If \hdr\code=#TBN_DROPDOWN
*ToolbarID=\hdr\hwndFrom
buttonID=\iItem
Protected dropdown=1
EndIf
EndWith
EndSelect
;check if toolbar is customized
If *ToolbarID And GetProp_(*ToolbarID, "PurebasicCustomToolbar")
;get button info
Protected buttonRect.RECT
Protected buttonInfo.TBBUTTONINFO
buttonInfo\cbSize=SizeOf(TBBUTTONINFO)
buttonInfo\dwMask=#TBIF_COMMAND|#TBIF_STATE|#TBIF_STYLE|#TBIF_IMAGE|#TBIF_SIZE|#TBIF_LPARAM;|#TBIF_TEXT
Protected buttonIndex=SendMessage_(*ToolBarID, #TB_GETBUTTONINFO, buttonID, @buttonInfo)
;get parameters for displaying popup
SendMessage_(*ToolBarID, #TB_GETRECT, buttonID, @buttonRect.RECT)
MapWindowPoints_(*ToolBarID, 0, @buttonRect, 2)
Protected popupPos=buttonRect\left +(buttonRect\bottom << 16)
Protected popupMenu=buttonInfo\lParam
Protected popupParentWindow=GetProp_(*ToolBarID, "PurebasicCustomToolbarWindow")
;check if toolbar button can display popup
If dropdown Or (buttonInfo\fsStyle & #TBSTYLE_DROPDOWN)=0 Or (buttonInfo\fsStyle & #BTNS_WHOLEDROPDOWN)
If popupMenu=#PB_Any
;post custom event for displaying popup
PostEvent(#PB_Event_Menu, popupParentWindow, buttonID, #PB_EventType_ToolbarPopup, popupPos)
ProcedureReturn 0
ElseIf IsMenu(popupMenu)
;display popup menu
DisplayPopupMenu(popupMenu, WindowID(popupParentWindow), buttonRect\left, buttonRect\bottom)
ProcedureReturn 0
EndIf
EndIf
EndIf
ProcedureReturn CallWindowProc_(GetProp_(hWnd, "PurebasicCustomToolbarParentCB"), hWnd, message, wParam, lParam)
EndProcedure
Procedure ToolbarCenterGadget(Gadget, Toolbar=#PB_Any) ;Center gadget vertically inside ToolbarContainer
If Toolbar=#PB_Any : Toolbar=CurrentGadgetListToolbar : EndIf
ResizeGadget(Gadget, #PB_Ignore, (ToolBarHeight(Toolbar)-GadgetHeight(Gadget)-2)/2, #PB_Ignore, #PB_Ignore)
EndProcedure
Procedure ToolbarFindGadget(*childControl, Flags) ;Examine child controls to find gadget
Protected gadget=GetDlgCtrlID_(*childControl)
If IsGadget(gadget) And GadgetType(gadget)<>#PB_GadgetType_Container
If Flags
ToolbarCenterGadget(gadget)
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Procedure.i ToolbarPopupX() ;Determines popup position X
Protected popupPos=EventData()
ProcedureReturn PeekW(@popupPos)
EndProcedure
Procedure.i ToolbarPopupY() ;Determines popup position Y
Protected popupPos=EventData()>> 16
ProcedureReturn PeekW(@popupPos)
EndProcedure
Procedure.i OpenToolbarGadgetList(Toolbar, useLargeIcons=#False, AutoCenterGadgets=#True) ;Open toolbar gadget list
If IsToolBar(Toolbar)
Protected *ToolBarID=ToolBarID(Toolbar)
;use bigger standard icon
If useLargeIcons
Protected *standardIcons = ImageList_Create_(24, 24, #ILC_COLOR32 | #ILC_MASK, 14, 30)
SendMessage_(*ToolBarID, #TB_SETIMAGELIST, 0, *standardIcons)
SendMessage_(*ToolBarID, #TB_LOADIMAGES, #IDB_STD_LARGE_COLOR, #HINST_COMMCTRL)
SendMessage_(*ToolBarID, #TB_LOADIMAGES, #IDB_STD_LARGE_COLOR, #HINST_COMMCTRL)
#ILCF_MOVE=0
#ILCF_SWAP=1
*standardIcons=SendMessage_(*ToolBarID, #TB_GETIMAGELIST, 0, 0)
Protected i
For i=30 To 0 Step -1
If i>15
ImageList_Remove_(*standardIcons, i)
Else
ImageList_Copy_(*standardIcons, i, *standardIcons, i+1, #ILCF_SWAP)
EndIf
Next
SendMessage_(*ToolBarID, #TB_SETIMAGELIST, 0, *standardIcons)
SendMessage_(*ToolBarID, #TB_AUTOSIZE, 0, 0)
EndIf
;change toolbar style to allow dropdown arrow buttons
Protected newToolBarStyle=SendMessage_(*ToolBarID, #TB_GETEXTENDEDSTYLE, 0, 0)| #TBSTYLE_EX_DRAWDDARROWS
SendMessage_(*ToolBarID, #TB_SETEXTENDEDSTYLE, 0, newToolBarStyle)
SetProp_(*ToolBarID, "PurebasicCustomToolbar", #True)
;allow to center all gadgets
SetProp_(*ToolBarID, "AutoCenterGadgets", AutoCenterGadgets)
;allow popup menu
Protected popupParentWindow=GetProp_(GetAncestor_(*ToolBarID, #GA_ROOT), "PB_WindowID")-1
SetProp_(*ToolBarID, "PurebasicCustomToolbarWindow", popupParentWindow)
Protected *toolbarParent=GetAncestor_(*ToolBarID, #GA_PARENT)
If GetProp_(*toolbarParent, "PurebasicCustomToolbarParentCB")=0
SetProp_(*toolbarParent, "PurebasicCustomToolbarParentCB", SetWindowLong_(*toolbarParent, #GWL_WNDPROC, @ToolBarCustomCallback()))
EndIf
;save previous gadget list and current toolbar
If SetProp_(*ToolBarID, "PreviousGadgetList", UseGadgetList(*ToolBarID))
CurrentGadgetListToolbar=Toolbar
ProcedureReturn Bool(UseGadgetList(0))
EndIf
EndIf
EndProcedure
Procedure CloseToolbarGadgetList() ;Close toolbar gadget list
Protected Toolbar=CurrentGadgetListToolbar
Protected *ToolBarID=ToolBarID(Toolbar)
;close last container gadget
If GetProp_(*ToolBarID, "LastOpenContainer")
CloseGadgetList()
EndIf
;auto center gadgets
If GetProp_(*ToolBarID, "AutoCenterGadgets")
EnumChildWindows_(*ToolBarID, @ToolbarFindGadget(), #True)
EndIf
;restore previous gadget list
UseGadgetList(GetProp_(*ToolBarID, "PreviousGadgetList"))
;clean all properties
RemoveProp_(*ToolBarID, "PreviousGadgetList")
RemoveProp_(*ToolBarID, "LastOpenContainer")
RemoveProp_(*ToolBarID, "AutoCenterGadgets")
;reset current toolbar
CurrentGadgetListToolbar=#PB_Ignore
EndProcedure
Procedure.i AddToolbarContainer(Width, Flag=#PB_Container_BorderLess) ;Add toolbar container
Protected Toolbar=CurrentGadgetListToolbar
Protected *ToolBarID=ToolBarID(Toolbar)
Protected buttonIndex=SendMessage_(*ToolBarID, #TB_BUTTONCOUNT, 0, 0)
ToolBarSeparator()
;set separator width
Protected separator.TBBUTTON
SendMessage_(*ToolBarID, #TB_GETBUTTON, buttonIndex, @separator)
separator\iBitmap=width
SendMessage_(*ToolBarID, #TB_DELETEBUTTON, buttonIndex, 0)
SendMessage_(*ToolBarID, #TB_INSERTBUTTON, buttonIndex, separator)
;get separator position
Protected rc.RECT
SendMessage_(*ToolBarID, #TB_GETITEMRECT, buttonIndex, @rc.RECT)
Protected x=rc\left
Protected y=0
Protected h=ToolBarHeight(Toolbar)
Protected w=width
;close last container gadget inside toolbar
If GetProp_(*ToolBarID, "LastOpenContainer")
CloseGadgetList()
EndIf
;create new container gadget inside toolbar
SetProp_(*ToolBarID, "LastOpenContainer", #True)
ProcedureReturn ContainerGadget(#PB_Any, x, y, w, h, Flag)
EndProcedure
Procedure SetToolBarArrow(SimpleArrow=#False) ;Creates a drop-down style button
Protected Toolbar=CurrentGadgetListToolbar
Protected *ToolBarID=ToolBarID(Toolbar)
;get button info
Protected buttonIndex=SendMessage_(*ToolBarID, #TB_BUTTONCOUNT, 0, 0)-1
Protected button.TBBUTTON
SendMessage_(*ToolBarID, #TB_GETBUTTON, buttonIndex, @button)
If (button\fsStyle & #TBSTYLE_SEP) : ProcedureReturn 0 : EndIf
;change button style
If SimpleArrow
button\fsStyle=button\fsStyle | #TBSTYLE_DROPDOWN | #BTNS_WHOLEDROPDOWN
Else
button\fsStyle=button\fsStyle | #TBSTYLE_DROPDOWN
EndIf
SendMessage_(*ToolBarID, #TB_DELETEBUTTON, buttonIndex, 0)
SendMessage_(*ToolBarID, #TB_INSERTBUTTON, buttonIndex+1, button)
EndProcedure
Procedure SetToolBarToggle(Grouped=#False) ;Creates toggle button (buttons can be grouped)
Protected Toolbar=CurrentGadgetListToolbar
Protected *ToolBarID=ToolBarID(Toolbar)
;get button info
Protected buttonIndex=SendMessage_(*ToolBarID, #TB_BUTTONCOUNT, 0, 0)-1
Protected button.TBBUTTON
SendMessage_(*ToolBarID, #TB_GETBUTTON, buttonIndex, @button)
If (button\fsStyle & #TBSTYLE_SEP) : ProcedureReturn 0 : EndIf
;change button
If Grouped
button\fsStyle=button\fsStyle | #TBSTYLE_CHECKGROUP
Else
button\fsStyle=button\fsStyle | #TBSTYLE_CHECK
EndIf
SendMessage_(*ToolBarID, #TB_DELETEBUTTON, buttonIndex, 0)
SendMessage_(*ToolBarID, #TB_INSERTBUTTON, buttonIndex+1, button)
EndProcedure
Procedure SetToolBarPopup(PopupMenu=#PB_Any) ;Specifies that the button will display a popup menu or custom popup.
Protected Toolbar=CurrentGadgetListToolbar
Protected *ToolBarID=ToolBarID(Toolbar)
;get button info
Protected buttonIndex=SendMessage_(*ToolBarID, #TB_BUTTONCOUNT, 0, 0)-1
Protected button.TBBUTTON
SendMessage_(*ToolBarID, #TB_GETBUTTON, buttonIndex, @button)
If (button\fsStyle & #TBSTYLE_SEP) : ProcedureReturn 0 : EndIf
;change button
button\dwData=PopupMenu
SendMessage_(*ToolBarID, #TB_DELETEBUTTON, buttonIndex, 0)
SendMessage_(*ToolBarID, #TB_INSERTBUTTON, buttonIndex+1, button)
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
DisableExplicit
; ******************************************
; EXAMPLE 1 : CUSTOM TOOLBAR GADGETS
; ******************************************
win=OpenWindow(#PB_Any, 0, 0, 700, 200, "ToolBar", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
;{/// CREATE TOOLBAR TOP
toolbar=CreateToolBar(#PB_Any, WindowID(win))
If OpenToolbarGadgetList(toolbar)
If AddToolbarContainer(100)
txt=TextGadget(#PB_Any, 0, 0, 60, 14, "ToolbarPlus")
EndIf
ToolBarStandardButton(10, #PB_ToolBarIcon_New, #PB_ToolBar_Toggle)
SetToolBarButtonState(toolbar, 10, 1)
ToolBarStandardButton(11, #PB_ToolBarIcon_Save)
SetToolBarPopup() ; <----- allow custom popup
ToolBarSeparator()
If AddToolbarContainer(40)
combo=ComboBoxGadget(#PB_Any, 0, 0, 40, #PB_Ignore)
EndIf
ToolBarSeparator()
If AddToolbarContainer(40)
button=ButtonGadget(#PB_Any, 0, 0, 40, ToolBarHeight(toolbar)-4, "OK", #PB_Button_Toggle)
EndIf
ToolBarSeparator()
If AddToolbarContainer(125)
string=StringGadget(#PB_Any, 0, 0, 50, 20, "String", #PB_String_UpperCase)
check=CheckBoxGadget(#PB_Any, 55, 0, 70, 20, "CheckMe")
EndIf
ToolBarSeparator()
If AddToolbarContainer(90)
opt1=OptionGadget(#PB_Any, 0, 0, 30, 20, "1")
opt2=OptionGadget(#PB_Any, 30, 0, 30, 20, "2")
opt3=OptionGadget(#PB_Any, 60, 0, 30, 20, "3")
EndIf
ToolBarSeparator()
If AddToolbarContainer(65)
bar1=ProgressBarGadget(#PB_Any, 0, 0, 20, 20, 0, 100, #PB_ProgressBar_Vertical)
bar2=ProgressBarGadget(#PB_Any, 25, 0, 40, 20, 0, 100)
EndIf
ToolBarSeparator()
If AddToolbarContainer(150)
link=HyperLinkGadget(#PB_Any, 0, 0, 150, 14, "http://www.purebasic.com", $0000FF, #PB_HyperLink_Underline)
EndIf
CloseToolbarGadgetList()
EndIf
SetGadgetColor(txt, #PB_Gadget_BackColor, RGB(255, 0, 0))
SetGadgetColor(txt, #PB_Gadget_FrontColor, RGB(255, 255, 255))
SetGadgetState(check, 1)
SetGadgetState(bar1, 20)
SetGadgetState(bar2, 60)
AddGadgetItem(combo, -1, "A")
AddGadgetItem(combo, -1, "B")
ToolBarToolTip(toolbar, 10, "New document")
GadgetToolTip(bar1, "veritcal progressbar")
;}
;{/// CREATE TOOLBAR BOTTOM
bottomContainer=ContainerGadget(#PB_Any, 0, ToolBarHeight(toolbar), WindowWidth(win), 32, #PB_Container_Double)
If bottomContainer
If CreateImage(0, 32, 16)
StartDrawing(ImageOutput(0))
Box(0, 0, 32, 16, RGB(10, 152, 100))
Box(8, 4, 16, 8, RGB(255, 0, 0))
StopDrawing()
EndIf
If CreatePopupMenu(100)
MenuItem(10, "MenuID 10")
MenuItem(20, "MenuID 20")
EndIf
bottomToolbar=CreateToolBar(#PB_Any, GadgetID(bottomContainer))
If OpenToolbarGadgetList(bottomToolbar)
If AddToolbarContainer(110)
spin=SpinGadget(#PB_Any, 5, 0, 40, 20, 0, 100, #PB_Spin_ReadOnly)
track=TrackBarGadget(#PB_Any, 50, 0, 60, 20, 0, 10, #PB_TrackBar_Ticks)
EndIf
ToolBarSeparator()
If AddToolbarContainer(133)
scroll=ScrollBarGadget(#PB_Any, 0, 0, 64, 20, 0, 100, 10)
btImage=ButtonImageGadget(#PB_Any, 69, 0, 64, ToolBarHeight(bottomToolbar)-2, ImageID(0))
EndIf
ToolBarSeparator()
ToolBarImageButton(20, ImageID(0))
ToolBarStandardButton(15, #PB_ToolBarIcon_Find)
SetToolBarArrow()
SetToolBarPopup(100)
ToolBarStandardButton(16, #PB_ToolBarIcon_Print)
SetToolBarArrow(#True)
SetToolBarPopup(100)
ToolBarStandardButton(17, #PB_ToolBarIcon_Paste)
SetToolBarPopup(100)
ToolBarSeparator()
ToolBarStandardButton(20, #PB_ToolBarIcon_Help)
SetToolBarToggle(#True)
ToolBarStandardButton(21, #PB_ToolBarIcon_Help)
SetToolBarToggle(#True)
ToolBarStandardButton(22, #PB_ToolBarIcon_Help)
SetToolBarToggle(#True)
If AddToolbarContainer(225)
ip=IPAddressGadget(#PB_Any, 0, 0, 120, 20)
date=DateGadget(#PB_Any, 125, 0, 100, 20)
EndIf
ToolBarSeparator()
CloseToolbarGadgetList()
EndIf
SetGadgetColor(spin, #PB_Gadget_BackColor, RGB(255, 225, 10))
SetGadgetFont(spin, LoadFont(1, "Arial", 12, #PB_Font_Bold))
SetGadgetText(spin, "1")
CloseGadgetList()
EndIf
;}
Repeat
e=WaitWindowEvent()
w=EventWindow()
g=EventGadget()
m=EventMenu()
t=EventType()
d=EventData()
Select e
Case #PB_Event_ActivateWindow
;set random ip address
SetGadgetState(ip, MakeIPAddress(127, 0, 0, Random(255)))
Case #PB_Event_Menu
Debug "eventMenu="+Str(m)+" eventWindow="+Str(w)+" eventType="+Str(t)+" eventData="+Str(d)
;toolbar custom eventType to display custom popup
If m=11 And t=#PB_EventType_ToolbarPopup
DisplayPopupMenu(100, WindowID(w), ToolbarPopupX(), ToolbarPopupY())
EndIf
Case #PB_Event_Gadget
If IsGadget(g)
Debug "eventGadget="+Str(g)+" eventType="+Str(t)+" eventData="+Str(d)+" state="+Str(GetGadgetState(g))
EndIf
;update spin
SetGadgetText(spin, Str(GetGadgetState(spin)))
EndSelect
Until e=#PB_Event_CloseWindow
End
CompilerEndIf