Added:
Possibility to include custom gadgets (such as canvas-based gadgets)
Margins and spacing between child-gadgets
Many top levels autosize-containers
For testing, i have included the nice canvas toggle button of einander (http://www.purebasic.fr/english/viewtop ... nvasbutton) with few modifications ...
Hope this will be useful to someone ...
Code: Select all
;{ added for testing a custom (canvas-based) gadget
;===================================================================
;Canvas Toggle Buttons
;by einander - PureBasic 4.60 Beta 3
EnableExplicit
Enumeration ; 6 CanvasButton states
#Normal=0
#Selected
#Pressed
#HoverSelected
#HoverUnSelected
#Disabled
EndEnumeration
Global Dim _Stat$(6)
_Stat$(2)="Pressed"
_Stat$(3)="HoverSelected"
_Stat$(4)="HoverUnSelected"
_Stat$(5)="Disabled"
Global _Myfont10=FontID(LoadFont(#PB_Any,"arial",10))
Global _Myfont12=FontID(LoadFont(#PB_Any,"times new roman",12))
Global _Myfont14=FontID(LoadFont(#PB_Any,"georgia",14))
Global _Myfont16=FontID(LoadFont(#PB_Any,"impact",16))
;
Structure BtnColors
TextRGB.L
BackRGB.L
EndStructure
;
Structure CanvasButton
Indx.I
gNum.I
FontID.I
Text.S
Selected.I
Stat.I
RGB.BtnColors[6] ; Colors :\L1=TextColor, \L2=BackColor
EndStructure
;
Procedure CenterTxt(X,Y,Wi,He,Text.S)
Protected TextWidth=TextWidth(Text),TextHeight=TextHeight(Text)
Protected X1=X+Wi,Y1=Y+He
If TextWidth>Wi : DrawText(X,(Y+Y1)/2-TextHeight/2 , Text)
Else : DrawText((X+X1)/2-TextWidth/2, (Y1+Y)/2-TextHeight/2 , Text)
EndIf
EndProcedure
Procedure CBDraw(*CB.CanvasButton)
With *Cb
Protected Wi=GadgetWidth(*Cb\gNum)
Protected He=GadgetHeight(*Cb\gNum)
;Protected Img=CreateImage(#PB_Any,Wi,He)
;StartDrawing(ImageOutput(Img)) ;background Color, Gradient with #White
StartDrawing(CanvasOutput(*Cb\gNum)) ; mdified by said as an image cant be created with 0 width/ 0 height
DrawingMode(#PB_2DDrawing_Gradient)
FrontColor(\RGB[\Stat]\BackRGB)
BackColor(#White)
LinearGradient(Wi/2,0, Wi/2,He) ; try (0,0,Wi,He) to diagonal Gradient
;LinearGradient(0,0, Wi,He) ; try (0,0,Wi,He) to diagonal Gradient
Box(0,0,Wi,He)
DrawingMode(#PB_2DDrawing_Transparent) ; Button Text
DrawingFont(\Fontid)
FrontColor(\RGB[\Stat]\TextRGB)
CenterTxt(0,0,Wi,He,\Text)
StopDrawing()
;SetGadgetAttribute(*Cb\gNum,#PB_Canvas_Image,ImageID(Img))
;FreeImage(Img)
EndWith
EndProcedure
;
Procedure CanvasButton(CBNum,X,Y,Wi,He,Text.S,Fontid,Indx,*Cb.CanvasButton,Flags=-1)
Protected I
With *Cb
If Flags=-1:Flags=#PB_Canvas_Keyboard
Else :Flags|#PB_Canvas_Keyboard
EndIf
\Text=Text
\gNum =CanvasGadget(CBNum,X,Y,Wi,He,Flags)
If CBNum<>#PB_Any:\gNum=CBNum:EndIf
SetGadgetAttribute(\gNum,#PB_Canvas_Cursor,#PB_Cursor_Hand)
\Fontid=Fontid
\Indx=Indx
Restore BtnColors
For I=0 To 5
Read.I \RGB[I]\TextRGB
Read.I \RGB[I]\BackRGB
Next
CBDraw(*Cb)
SetGadgetData(\gNum, *Cb) ; added by said
EndWith
EndProcedure
;
Procedure GetCanvasState(*Cb.CanvasButton)
With *Cb
Select EventType()
Case #PB_EventType_LeftButtonDown
\Selected!1 :\Stat=#Pressed : CBDraw(*Cb)
Case #PB_EventType_MouseEnter,#PB_EventType_LeftButtonUp
If \Selected :\Stat=#HoverSelected : CBDraw(*Cb)
Else :\Stat=#HoverUnSelected : CBDraw(*Cb)
EndIf
Case #PB_EventType_MouseLeave
If \Selected :\Stat=#Selected : CBDraw(*Cb)
Else :\Stat=#Normal : CBDraw(*Cb)
EndIf
EndSelect
If \Stat>1: ProcedureReturn \Stat:EndIf
EndWith
EndProcedure
; had to add a custom-resize as per prototype _CustomResize (said)
Procedure ResizeCanvasButton(Gadget, X, Y, Width, Height)
ResizeGadget(Gadget, X, Y, Width, Height)
CBDraw(GetGadgetData(Gadget))
EndProcedure
DataSection ; try here other color pairs <<<<<<<<<<<<<
BtnColors:
Data.I $464646 , $888888 ;Normal : DarkGray, LightGray
Data.I $0000FF , $6666FF ;Selected : Red, Light Red
Data.I $000000 , $0082FF ;Pressed : Black, Dark Orange
Data.I $FF00FF , $00A5FF ;HoverSelected : Magenta, Orange
Data.I $000000 , $00A5FF ;HoverUnSelected : Black, Orange
Data.I $888888 , $CECECE ;Disabled : Light Gray , Pale Gray
EndDataSection
Define CB1.CanvasButton
Define CB2.CanvasButton
;===================== end of einander's cnavas-button ========================
;}
EnableExplicit
Enumeration
#AutosizeGadget_Horizontal
#AutosizeGadget_Vertical
EndEnumeration
Prototype _CustomResize(Gadget.i, X.i, Y.i, Width.i, Height.i)
Structure AS_Child_Struc
Gadget.i
Proportion.f
CustomResize._CustomResize
EndStructure
Structure AS_Container_Struc
IsParent.i ; true/false
Gadget.i
Mode.i
HMargin.i ; horizontal margin left and right
VMargin.i ; vertical margin top and bottom
Spacing.i ; spacing btweenn childs hor or ver
List Childs.AS_Child_Struc()
EndStructure
Global NewList AS_Containers.AS_Container_Struc()
Procedure AS_StartParent( Gadget, x, y, width, height, mode=#AutosizeGadget_Horizontal, hMargin=0, vMargin=0, spacing=0)
ContainerGadget(Gadget,x,y,width,height)
AddElement( AS_Containers() )
AS_Containers()\IsParent= #True
AS_Containers()\Gadget = Gadget
AS_Containers()\Mode = mode
AS_Containers()\HMargin = hMargin
AS_Containers()\VMargin = vMargin
AS_Containers()\Spacing = spacing
EndProcedure
Procedure AS_StopParent()
; closes current main resizable parent and moves to previous parent if any
CloseGadgetList()
Protected nn
Repeat
If AS_Containers()\IsParent : nn+1 : EndIf
If Not PreviousElement(AS_Containers())
ResetList(AS_Containers())
Break
EndIf
If nn >= 1 : Break : EndIf
ForEver
EndProcedure
Procedure AS_StartGrouping(Proportion.f=1.0, mode=#AutosizeGadget_Horizontal, hMargin=0, vMargin=0, spacing=0)
; Group is a dynamic container Hor or Ver
; param Proportion has 2 usages if >= 0 => actual proportion
; < 0 => fised width/height
Protected gadget_number, fixedSize
If Proportion >= 0
gadget_number = ContainerGadget(#PB_Any,0,0,0,0)
Else
fixedSize = Int(-Proportion)
If mode=#AutosizeGadget_Horizontal
gadget_number = ContainerGadget(#PB_Any,0,0,0,fixedSize)
Else
gadget_number = ContainerGadget(#PB_Any,0,0,fixedSize,0)
EndIf
Proportion = 0
EndIf
AddElement(AS_Containers()\Childs())
AS_Containers()\Childs()\Gadget = gadget_number
AS_Containers()\Childs()\Proportion = Proportion
AS_Containers()\Childs()\CustomResize = 0
SetGadgetColor(gadget_number, #PB_Gadget_BackColor, GetGadgetColor(AS_Containers()\Gadget, #PB_Gadget_BackColor))
AddElement( AS_Containers() )
AS_Containers()\IsParent= #False
AS_Containers()\Gadget = gadget_number
AS_Containers()\Mode = mode
AS_Containers()\HMargin = hMargin
AS_Containers()\VMargin = vMargin
AS_Containers()\Spacing = spacing
EndProcedure
Procedure AS_StopGrouping()
; closes current group
CloseGadgetList()
PreviousElement(AS_Containers())
EndProcedure
Procedure AS_AddChild(Gadget, Proportion.f, *CustomResizeFunc = 0)
;LastElement(AS_Containers())
;LastElement(AS_Containers()\Childs())
AddElement(AS_Containers()\Childs())
AS_Containers()\Childs()\Gadget = Gadget
AS_Containers()\Childs()\Proportion = Proportion
AS_Containers()\Childs()\CustomResize = *CustomResizeFunc
EndProcedure
Procedure AS_ResizeParent(Gadget = -1)
Protected mode,w,h,pos,gdt,hm,vm,ss,nn
Protected.f prop,totspan,childw_base,childh,childh_base,childw
FirstElement(AS_Containers())
If Gadget <> -1 ; resize s[ecific parent (-1 => all parents)
Repeat
If AS_Containers()\IsParent And AS_Containers()\Gadget = Gadget : Break : EndIf
If Not NextElement(AS_Containers()) : Break : EndIf
ForEver
EndIf
Repeat
mode = AS_Containers()\Mode
hm = AS_Containers()\HMargin
vm = AS_Containers()\VMargin
ss = AS_Containers()\Spacing
w = GadgetWidth(AS_Containers()\Gadget)
h = GadgetHeight(AS_Containers()\Gadget)
nn = ListSize(AS_Containers()\Childs())
totspan = 0
ForEach AS_Containers()\Childs()
If AS_Containers()\Childs()\Proportion > 0
totspan = totspan + AS_Containers()\Childs()\Proportion
Else
If mode=#AutosizeGadget_Horizontal
w = w - GadgetWidth(AS_Containers()\Childs()\Gadget)
Else
h = h - GadgetHeight(AS_Containers()\Childs()\Gadget)
EndIf
EndIf
Next
w = w - (2*hm)
h = h - (2*vm)
If nn > 1
If mode=#AutosizeGadget_Horizontal
w = w - ((nn-1)*ss)
Else
h = h - ((nn-1)*ss)
EndIf
EndIf
If w < 0 : w = 0 : EndIf
If h < 0 : h = 0 : EndIf
If mode=#AutosizeGadget_Horizontal
childh = h : pos = hm : If totspan > 0 : childw_base = w*1.0/totspan : EndIf
ForEach AS_Containers()\Childs()
prop = AS_Containers()\Childs()\Proportion
gdt = AS_Containers()\Childs()\Gadget
If prop > 0
If AS_Containers()\Childs()\CustomResize = 0
ResizeGadget(gdt, pos, vm, Int(childw_base * prop), childh)
Else
AS_Containers()\Childs()\CustomResize(gdt, pos, vm, Int(childw_base * prop), childh)
EndIf
Else
If AS_Containers()\Childs()\CustomResize = 0
ResizeGadget(gdt, pos, vm, GadgetWidth(gdt), childh)
Else
AS_Containers()\Childs()\CustomResize(gdt, pos, vm, GadgetWidth(gdt), childh)
EndIf
EndIf
pos = pos + GadgetWidth(gdt) + ss
Next
Else
childw = w : pos = vm : If totspan > 0 : childh_base = h*1.0/totspan : EndIf
ForEach AS_Containers()\Childs()
prop = AS_Containers()\Childs()\Proportion
gdt = AS_Containers()\Childs()\Gadget
If prop > 0
If AS_Containers()\Childs()\CustomResize = 0
ResizeGadget(gdt, hm, pos, childw, Int(childh_base * prop))
Else
AS_Containers()\Childs()\CustomResize(gdt, hm, pos, childw, Int(childh_base * prop))
EndIf
Else
If AS_Containers()\Childs()\CustomResize = 0
ResizeGadget(gdt, hm, pos, childw, GadgetHeight(gdt))
Else
AS_Containers()\Childs()\CustomResize(gdt, hm, pos, childw, GadgetHeight(gdt))
EndIf
EndIf
pos = pos + GadgetHeight(gdt) + ss
Next
EndIf
If Not NextElement(AS_Containers()) : Break : EndIf
If (Gadget <> -1) And AS_Containers()\IsParent And (AS_Containers()\Gadget <> Gadget) : Break : EndIf
ForEver
EndProcedure
; =======
; EXAMPLE
Enumeration
#g_autosize_main
#g_toplabel : #g_bottomlabel_left : #g_bottomlabel_right
#g_label0 : #g_label1
#g_b0 : #g_b1 : #g_b2
EndEnumeration
If Not OpenWindow(0, 100, 200, 320, 240, "AutosizeGadget()", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget) : End : EndIf
AS_StartParent(#g_autosize_main,0,0,WindowWidth(0),WindowHeight(0),#AutosizeGadget_Vertical,0,0,10) ;,"0120",#g_toplabel,#g_autosize0,#g_autosize1,#g_autosize_bottom)
SetGadgetColor(#g_autosize_main, #PB_Gadget_BackColor, 0)
AS_AddChild(#g_toplabel, 0)
TextGadget(#g_toplabel,0,0,320,24,"AutosizeGadget test")
AS_StartGrouping(1.5, #AutosizeGadget_Horizontal,2,0,10)
CanvasButton(#g_b0,0,0,0,0,"Button 1",_Myfont10,1,@Cb1) : AS_AddChild(#g_b0, 1, @ResizeCanvasButton())
CanvasButton(#g_b1,0,0,0,0,"Button 2",_Myfont12,2,@Cb2) : AS_AddChild(#g_b1, 3, @ResizeCanvasButton())
ButtonGadget(#g_b2,0,0,0,0,"Button 3") : AS_AddChild(#g_b2, 1)
AS_StopGrouping()
AS_StartGrouping(3,#AutosizeGadget_Horizontal,2,25,2)
AS_AddChild(#g_label0, 4)
AS_AddChild(#g_label1, 1)
TextGadget(#g_label0,0,0,0,0,"Text 1",#PB_Text_Border)
TextGadget(#g_label1,0,0,0,0,"Text 2",#PB_Text_Border)
AS_StopGrouping()
AS_StartGrouping(-24, #AutosizeGadget_Horizontal,0,0,30)
AS_AddChild(#g_bottomlabel_left, 1)
AS_AddChild(#g_bottomlabel_right, 1)
TextGadget(#g_bottomlabel_left,0,0,0,0,"Bottom left",#PB_Text_Border)
TextGadget(#g_bottomlabel_right,0,0,0,0,"Bottom right",#PB_Text_Border|#PB_Text_Right)
AS_StopGrouping()
AS_StopParent()
Define EvID
Repeat
EvID = WaitWindowEvent()
Select EvID
Case #PB_Event_SizeWindow
ResizeGadget(#g_autosize_main,0,0,WindowWidth(0),WindowHeight(0))
AS_ResizeParent()
Case #PB_Event_Gadget
Select EventGadget()
Case #g_b0 : GetCanvasState(@CB1)
Case #g_b1 : GetCanvasState(@CB2)
EndSelect
EndSelect
Until EvID = #PB_Event_CloseWindow