I've been experimenting with being able to define styles and then associating those styles with CanvasGadget() derived containers and buttons.
It's been fun and I've even found another way I quite like of binding callbacks to widgets.
Code: Select all
Prototype GadgetEventHandler(nGadget,nEventType)
Prototype WindowEventHandler(nWindow)
Structure AppGadget
id.i
parent.i
style.s
text.s
isNumeric.i
decimalPlaces.i
allowNegatives.i
onEvent.GadgetEventHandler
EndStructure
Structure AppWindow
id.i
parent.i
style.s
isModal.i
onClose.WindowEventHandler
onSize.WindowEventHandler
EndStructure
Structure WidgetStyle
id.s
BackColor.i
ForeColor.i
BorderColor.i
BorderWidth.i
FontID.i
EndStructure
Global NewMap appFonts.i()
Global NewMap *appGadgets.AppGadget()
Global NewMap *appWindows.AppWindow()
Global NewMap *widgetStyles.WidgetStyle()
Procedure BindGadgetCallback(gadgetID,*callback)
*appGadgets(Str(gadgetID))\onEvent = *callback
EndProcedure
Procedure BindWindowCallback(winID,*callback,eType)
Select eType
Case #PB_Event_CloseWindow
*appWindows(Str(winID))\onClose = *callback
Case #PB_Event_SizeWindow
*appWindows(Str(winID))\onSize = *callback
EndSelect
EndProcedure
Procedure RegisterGadget(gdtID,winID,style.s,txt.s="")
*g.AppGadget = AllocateStructure(AppGadget)
*g\id = gdtID
*g\parent = winID
*g\style = style
*g\text = txt
*g\isNumeric = #False
*g\decimalPlaces = 0
*g\allowNegatives = #False
key$ = Str(gdtID)
*appGadgets(key$) = *g
EndProcedure
Procedure RegisterWindow(winID,style.s,winModal=#False,parent=-1)
*w.AppWindow = AllocateStructure(AppWindow)
*w\id = winID
*w\style = style
*w\parent = parent
*w\isModal = winModal
key$ = Str(winID)
*appWindows(key$) = *w
EndProcedure
Procedure Style_Font_New(id.s,fontname.s,fontsize,flags=#Null)
nRes = LoadFont(#PB_Any,fontname,fontsize,flags)
If nRes
appFonts(id) = FontID(nRes)
Else
Debug "failed to load font"
EndIf
EndProcedure
Procedure Style_New(stylename.s)
*s.WidgetStyle = AllocateStructure(WidgetStyle)
*s\id = stylename
*s\FontID = appFonts("default")
*s\BackColor = RGB(57,92,198)
*s\ForeColor = RGB(255,255,255)
*s\BorderColor = RGB(0,0,255)
*s\BorderWidth = 2
*widgetStyles(stylename) = *s
EndProcedure
Procedure.i Style_GetById(stylename.s)
If FindMapElement(*widgetStyles(),stylename)
ProcedureReturn *widgetStyles(stylename)
Else
ProcedureReturn *widgetStyles("default")
EndIf
EndProcedure
Procedure.i Window_New(x,y,width,height,caption$,windowFlags=#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered,
stylename.s="default",winModal=#False,winParent=-1)
*s.WidgetStyle = Style_GetById(stylename)
window = OpenWindow(#PB_Any,x,y,width,height,caption$,windowFlags)
SetWindowColor(window,*s\BackColor)
RegisterWindow(window,stylename)
ProcedureReturn window
EndProcedure
Procedure CanvasButton_Redraw(btn)
x = GadgetX(btn) : y = GadgetY(btn)
width = GadgetWidth(btn) : height = GadgetHeight(btn)
caption$ = *appGadgets(Str(btn))\text
*sg.WidgetStyle = Style_GetById(*appGadgets(Str(btn))\style)
SetGadgetFont(btn,*sg\FontID)
StartDrawing(CanvasOutput(btn))
DrawingFont(*sg\FontID)
Box(0,0,width,height,*sg\BorderColor)
nL = width - (*sg\BorderWidth * 2)
nT = height - (*sg\BorderWidth * 2)
Box(*sg\BorderWidth,*sg\BorderWidth,nL,nT,*sg\BackColor)
nL = (width - TextWidth(caption$)) / 2
nT = (height - TextHeight(caption$)) / 2
DrawText(nL,nT,caption$,*sg\ForeColor,*sg\BackColor)
StopDrawing()
EndProcedure
Procedure.s CanvasButton_GetText(btn)
ProcedureReturn *appGadgets(Str(btn))\text
EndProcedure
Procedure CanvasButton_SetText(btn,txt.s)
*appGadgets(Str(btn))\text = txt
CanvasButton_Redraw(btn)
EndProcedure
Procedure CanvasButton_New(parentID,x,y,width,height,caption$,style.s="default")
*sg.WidgetStyle = Style_GetById(style)
btn = CanvasGadget(#PB_Any,x,y,width,height)
RegisterGadget(btn,parentID,style,caption$)
CanvasButton_Redraw(btn)
ProcedureReturn btn
EndProcedure
Procedure CanvasButton_ChangeStyle(btn,style.s)
*appGadgets(Str(btn))\style = style
CanvasButton_Redraw(btn)
EndProcedure
Procedure CanvasContainer_Redraw(ctr)
x = GadgetX(ctr) : y = GadgetY(ctr)
width = GadgetWidth(ctr)
height = GadgetHeight(ctr)
style.s = *appGadgets(Str(ctr))\style
StartDrawing(CanvasOutput(ctr))
Box(0,0,width,height,*widgetStyles(style)\BorderColor)
nW = width - (*widgetStyles(style)\BorderWidth * 2)
nH = height - (*widgetStyles(style)\BorderWidth * 2)
Box(*widgetStyles(style)\BorderWidth,*widgetStyles(style)\BorderWidth,nW,nH,*widgetStyles(style)\BackColor)
StopDrawing()
EndProcedure
Procedure CanvasContainer_ChangeStyle(ctr,style.s)
*appGadgets(Str(ctr))\style = style
CanvasContainer_Redraw(ctr)
EndProcedure
Procedure CanvasContainer_New(parentID,x,y,width,height,style.s="default")
container = CanvasGadget(#PB_Any,x,y,width,height,#PB_Canvas_Container)
RegisterGadget(container,parentID,style)
CanvasContainer_Redraw(container)
ProcedureReturn container
EndProcedure
Procedure Gadget_Events()
nGadget = EventGadget()
nType = EventType()
If FindMapElement(*appGadgets(),Str(nGadget))
If *appGadgets(Str(nGadget))\onEvent <> #Null
*appGadgets(Str(nGadget))\onEvent(nGadget,nType)
EndIf
EndIf
EndProcedure
Procedure Window_EventClose()
nWindow = EventWindow()
If FindMapElement(*appWindows(),Str(nWindow))
If *appWindows(Str(nWindow))\onClose <> #Null
*appWindows(Str(nWindow))\onClose(nWindow)
EndIf
EndIf
EndProcedure
Procedure Window_EventSize()
nWindow = EventWindow()
If FindMapElement(*appWindows(),Str(nWindow))
If *appWindows(Str(nWindow))\onSize <> #Null
*appWindows(Str(nWindow))\onSize(nWindow)
EndIf
EndIf
EndProcedure
BindEvent(#PB_Event_Gadget,@Gadget_Events())
BindEvent(#PB_Event_CloseWindow,@Window_EventClose())
BindEvent(#PB_Event_SizeWindow,@Window_EventSize())
Global frmMain, frmMain_btnClick, frmMain_btnDanger
Global frmMain_ctrLeft, frmMain_ctrRight, frmMain_btnModel
Procedure frmMain_onClose(nWindow)
End
EndProcedure
Procedure frmMain_onSize(nWindow)
nW = WindowWidth(nWindow)
nH = WindowHeight(nWindow)
SetWindowTitle(nWindow,"Demo (" + Str(nW) + " x " + Str(nH) + ")")
ResizeGadget(frmMain_ctrLeft,#PB_Ignore,#PB_Ignore,250,nH)
ResizeGadget(frmMain_ctrRight,#PB_Ignore,#PB_Ignore,nW-250,nH)
nW = GadgetWidth(frmMain_ctrRight)
nH = GadgetHeight(frmMain_ctrRight)
ResizeGadget(frmMain_btnClick,nW-155,nH-50,#PB_Ignore,#PB_Ignore)
ResizeGadget(frmMain_btnDanger,nW-305,nH-50,#PB_Ignore,#PB_Ignore)
EndProcedure
Procedure frmMain_btnClick_onEvent(nGadget,nType)
If nType = #PB_EventType_LeftClick
MessageRequester("Good","Warm Fuzzies :-)",0)
EndIf
EndProcedure
Procedure frmMain_btnDanger_onEvent(nGadget,nType)
If nType = #PB_EventType_LeftClick
If *appGadgets(Str(frmMain_btnClick))\style = "default"
*appGadgets(Str(frmMain_btnClick))\style = "danger"
CanvasContainer_ChangeStyle(frmMain_ctrLeft,"ooglies")
CanvasContainer_ChangeStyle(frmMain_ctrRight,"doodah")
Else
*appGadgets(Str(frmMain_btnClick))\style = "default"
CanvasContainer_ChangeStyle(frmMain_ctrLeft,"doodah")
CanvasContainer_ChangeStyle(frmMain_ctrRight,"ooglies")
EndIf
CanvasButton_SetText(frmMain_btnClick,*appGadgets(Str(frmMain_btnClick))\style)
EndIf
EndProcedure
Procedure frmMain_ctrLeft_onEvent(nGadget,nType)
If nType = #PB_EventType_Resize
CanvasContainer_Redraw(nGadget)
EndIf
EndProcedure
Procedure frmMain_ctrRight_onEvent(nGadget,nType)
If nType = #PB_EventType_Resize
CanvasContainer_Redraw(nGadget)
EndIf
EndProcedure
Procedure frmMain_Open()
frmMain = Window_New(10,10,1000,600,"Demo")
frmMain_ctrLeft = CanvasContainer_New(frmMain,0,0,250,600,"doodah")
CloseGadgetList()
frmMain_ctrRight = CanvasContainer_New(frmMain,250,0,750,600,"ooglies")
frmMain_btnDanger = CanvasButton_New(frmMain,445,550,140,35,"Change","danger")
frmMain_btnClick = CanvasButton_New(frmMain,595,550,140,35,"Nice")
CloseGadgetList()
BindWindowCallback(frmMain,@frmMain_onClose(),#PB_Event_CloseWindow)
BindWindowCallback(frmMain,@frmMain_onSize(),#PB_Event_SizeWindow)
BindGadgetCallback(frmMain_ctrLeft,@frmMain_ctrLeft_onEvent())
BindGadgetCallback(frmMain_ctrRight,@frmMain_ctrRight_onEvent())
BindGadgetCallback(frmMain_btnClick,@frmMain_btnClick_onEvent())
BindGadgetCallback(frmMain_btnDanger,@frmMain_btnDanger_onEvent())
EndProcedure
Style_Font_New("default","Arial",12,#PB_Font_Bold)
Style_New("default")
Style_Font_New("danger","Arial",12,#PB_Font_Bold)
Style_New("danger")
*widgetStyles("danger")\BackColor = RGB(38,0,93)
*widgetStyles("danger")\BorderColor = RGB(84,39,136)
*widgetStyles("danger")\FontID = appFonts("danger")
Style_New("doodah")
*widgetStyles("doodah")\BackColor = RGB(69,117,180)
*widgetStyles("doodah")\BorderColor = RGB(255,255,255)
*widgetStyles("doodah")\BorderWidth = 2
*widgetStyles("doodah")\FontID = appFonts("danger")
Style_New("ooglies")
*widgetStyles("ooglies")\BackColor = RGB(255,255,255)
*widgetStyles("ooglies")\BorderColor = RGB(255,255,255)
*widgetStyles("ooglies")\BorderWidth = 2
*widgetStyles("ooglies")\FontID = appFonts("danger")
frmMain_Open()
Repeat
WEvent = WaitWindowEvent()
ForEver
CanvasGadget() is very versatile.