Syntax
Widget = CreateWidget(x, y, Width, Height, *UserData=#Null, Flags=#Null)Description
Creates a new standard ProGUI widget (the core “building block” for
all UI elements). A standard widget is a rectangular canvas rendered and managed entirely by ProGUI. You
control its appearance by attaching a #PG_Event_Draw handler and applying skin properties via a class, and its behaviour
through additional event handlers.
Widgets can also act as containers by attaching a layout to them (via the
#PG_Widget_LayoutFlex, #PG_Widget_LayoutGrid,
or #PG_Widget_LayoutBasic flags), allowing you to nest
child widgets inside to build complex UI hierarchies. Unlike CreateOsWidget(), standard widgets render
identically across all supported platforms.
The new widget is automatically inserted into the current layout (see LayoutSetCurrent()).
Parameters
x
The initial horizontal position of the widget relative to its parent
layout container (in DIPs). Primarily used by Basic layouts; Flex and
Grid layouts override this based on their rules.
y
The initial vertical position of the widget relative to its parent
layout container (in DIPs). Primarily used by Basic layouts; Flex and
Grid layouts override this based on their rules.
Width
The initial ideal width of the widget (in DIPs). Layout engines may
adjust this based on available space and other item properties. Use
#PG_Widget_FitContent to automatically size based on
content (e.g., a child layout's overflow).
Height
The initial ideal height of the widget (in DIPs). Layout engines may
adjust this based on available space and other item properties. Use
#PG_Widget_FitContent to automatically size based on
content.
*UserData (optional)
A custom pointer or integer value to associate with the widget. Can be
retrieved later using WidgetGetUserData(). Default is
#Null.
Flags (optional)
A combination of flags to modify the widget’s behavior and appearance.
Default is #Null.
#PG_Widget_Hide : Creates the widget in a hidden state.
#PG_Widget_NoDraw : Prevents the widget from being rendered.
#PG_Widget_NoMouse : Configures the widget to ignore mouse events (mouse events pass through).
#PG_Widget_NoSkinBackground : Disables the drawing of the skin's background for this widget.
#PG_Widget_NoSkinOutsetShadow : Disables the drawing of the skin's outset drop shadow.
#PG_Widget_NoSkinInsetShadow : Disables the drawing of the skin's inset shadow.
#PG_Widget_NoSkinBorder : Disables the drawing of the skin's border.
#PG_Widget_NoBorder : Completely disables any border rendering (skin or generated).
#PG_Widget_NoSkinRender : Combination flag that disables all skin rendering (Background, Shadows, and Border).
#PG_Widget_NoCache : Disables internal image caching for the widget's rendering.
#PG_Widget_DragWindow : Allows the parent window to be dragged by clicking and dragging this widget.
#PG_Widget_LayoutBasic : Automatically creates and attaches a Basic Layout to the widget, turning it into a container.
#PG_Widget_LayoutFlex : Automatically creates and attaches a Flex Layout to the widget.
#PG_Widget_LayoutGrid : Automatically creates and attaches a Grid Layout to the widget.
Note: Custom user flags can be defined starting from
#PG_Widget_FirstUserFlag.
Return Value
Returns a handle to the newly created widget object if successful, or
#Null if creation failed. This handle is used in subsequent
widget-related commands.
Remarks
When called, the widget is automatically inserted into the current
layout at the #PG_Last position. The current layout is
managed via LayoutPush(), LayoutPop() or LayoutSetCurrent(). If you specify one
of the #PG_Widget_Layout* flags, the widget will have a
layout container created and attached to it automatically, allowing you
to nest further widgets inside it (with the layout becoming the new
current layout).
Note: If a new widget lacks a Draw EventHandler (via AddEventHandler()) or assigned skin properties, it will render with an “Under-construction” appearance. This includes a black-and-yellow striped “hazard tape” border, a semi-transparent yellow background, and the placeholder text “Widget” - perfect for rapid prototyping and identifying missing configurations.
Examples
IncludeFile "ProGUI_PB.pbi"
StartProGUI()
Global UserDataString$
; Custom draw procedure for our widget
Procedure DrawMyWidget(Widget, EventType, *EventData.PG_EventDraw, *UserData)
DrawEllipse(*EventData\width / 2, *EventData\height / 2, *EventData\width / 2, *EventData\height / 2, 0, 0.1)
DrawBoxStroke(0, 0, *EventData\width, *EventData\height, RGB(50, 50, 50), 0.8)
; Retrieve and display widget user data if it exists
*widgetUserData = WidgetGetUserData(Widget)
If *widgetUserData
MyText$ = PeekS(*widgetUserData)
Static MyTextObj ; Static text object for efficiency
If Not MyTextObj
MyTextObj = CreateText("", "Arial", 12)
TextSetAlign(MyTextObj, #PG_Text_Align_Center)
TextSetJustify(MyTextObj, #PG_Text_Justify_Center)
EndIf
TextSetContent(MyTextObj, MyText$)
TextSetWidth(MyTextObj, *EventData\width - 10) ; Add padding
TextSetHeight(MyTextObj, *EventData\height - 10)
DrawTxt(MyTextObj, 5, 5, RGB(0,0,0), 1)
EndIf
EndProcedure
MyWindow = CreateWindow(0, 0, 400, 300, "CreateWidget Example", #PG_Window_Default | #PG_Window_LayoutFlex) ; Use Flex layout
If MyWindow
; Add padding to the current window layout
LayoutSetPadding(#Null, 10)
; Create a widget with UserData
UserDataString$ = "Widget 1"
Widget1 = CreateWidget(0, 0, 150, 50, @UserDataString$)
WidgetSetClass(Widget1, "mywidget") ; Assign a class for skinning
WidgetSetMargin(Widget1, 5)
AddEventHandler(Widget1, #PG_Event_Draw, @DrawMyWidget())
; Set the background-color skin property for "mywidget"
SkinSetValue("mywidget", "", "", "background-color", "red")
LayoutPush() ; Push the current window layout onto the stack so we can easily restore it later
; Create another widget, automatically giving it a child Flex layout
Widget2 = CreateWidget(0, 0, 100, 80, #Null, #PG_Widget_LayoutFlex)
WidgetSetMargin(Widget2, 5)
AddEventHandler(Widget2, #PG_Event_Draw, @DrawMyWidget())
; Add a sub-widget inside Widget2's layout (now the current layout)
SubWidget = CreateWidget(0, 0, 50, 20)
WidgetSetClass(SubWidget, "button") ; Different class
WidgetSetMargin(SubWidget, 10)
; (Add drawing handler for SubWidget if needed)
LayoutPop() ; Restore the window layout so it is now the current layout, newly created widgets will be added to the window
; Create a "place-holder" / "under-construction" widget with no skin class or draw event handler
Widget3 = CreateWidget(0, 0, 100, 80)
WidgetSetMargin(Widget3, 5)
WindowShow(MyWindow, #True, #PG_WindowShow_ScreenCentered)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
StopProGUI(); This example shows how to wrap CreateWidget into a reusable custom component
IncludeFile "ProGUI_PB.pbi"
StartProGUI()
Structure MyWidget
text.s
EndStructure
; Draw event handler for our widget
Procedure DrawMyWidget(Widget, EventType, *EventData.PG_EventDraw, *UserData)
Protected *myWidget.MyWidget = WidgetGetUserData(Widget)
DrawSkinText(Widget, "", 0, 0, *EventData\width, *EventData\height, *myWidget\text)
EndProcedure
; Destroy event handler for our widget
Procedure DestroyMyWidget(Widget, EventType, *EventData, *myWidget.MyWidget)
; Using the *UserData paramater of the event handler this time passed by AddEventHandler()
; instead of WidgetGetUserData(), this is entirely upto you offering flexibility.
FreeStructure(*myWidget)
Debug "custom widget freed!"
EndProcedure
; Mouse event handler for our widget
Procedure HoverMyWidget(Widget, EventType, *EventData.PG_EventMouse, *UserData)
Select EventType
Case #PG_Event_MouseEnter
WidgetSetSkinState(Widget, "hover")
Case #PG_Event_MouseLeave
WidgetSetSkinState(Widget, "")
EndSelect
EndProcedure
; Creates our custom "MyWidget"
Procedure CreateMyWidget(x.d, y.d, Width.d, Height.d, Text$)
Protected *myWidget.MyWidget, widget
*myWidget = AllocateStructure(MyWidget)
*myWidget\text = Text$
widget = CreateWidget(x, y, Width, Height, *myWidget)
WidgetSetClass(widget, "mywidget")
AddEventHandler(widget, #PG_Event_Draw, @DrawMyWidget())
AddEventHandler(widget, #PG_Event_Destroy, @DestroyMyWidget(), *myWidget)
AddEventHandler(widget, #PG_Event_MouseEnter, @HoverMyWidget())
AddEventHandler(widget, #PG_Event_MouseLeave, @HoverMyWidget())
ProcedureReturn widget
EndProcedure
; Create some CSS skin properties for our new "mywidget" class
SkinSetValue("mywidget", "", "", "color", "black")
SkinSetValue("mywidget", "", "", "font-family", "Arial")
SkinSetValue("mywidget", "", "", "font-size", "16px")
SkinSetValue("mywidget", "", "", "font-weight", "bold")
SkinSetValue("mywidget", "", "", "text-align", "center")
SkinSetValue("mywidget", "", "", "vertical-align", "center")
SkinSetValue("mywidget", "", "", "background", "linear-gradient(yellow, orange)")
SkinSetValue("mywidget", "", "", "border", "2px blue")
SkinSetValue("mywidget", "", "", "border-radius", "5px")
; Define a "hover" state for the same class
SkinSetValue("mywidget", "hover", "", "color", "crimson")
SkinSetValue("mywidget", "hover", "", "font-size", "24px")
; Define some animation transitions for the class
SkinSetValue("mywidget", "", "", "transition", "color 0.5s ease, font-size 0.5s ease-out-bounce")
MyWindow = CreateWindow(0, 0, 500, 300, "CreateWidget - Custom Self-contained Widget Example", #PG_Window_Default | #PG_Window_LayoutFlex) ; Use Flex layout
If MyWindow
; Add padding to the current window layout
LayoutSetPadding(#Null, 10)
; Create and add our custom self-contained widget to the window's flex layout
widget = CreateMyWidget(0, 0, 100, 40, "Widget 1")
WidgetSetMargin(widget, 5)
; Create another one!
widget2 = CreateMyWidget(0, 0, 120, 60, "Widget 2")
WidgetSetMargin(widget2, 5)
; Create another one!
widget3 = CreateMyWidget(0, 0, 100, 40, "Widget 3")
WidgetSetMargin(widget3, 5)
; Create another one! this time we are going to name our widget and override some CSS class properties
widget4 = CreateMyWidget(0, 0, 100, 40, "Widget 4")
WidgetSetName(widget4, "widget4")
WidgetSetMargin(widget4, 5)
SkinSetValue("#widget4", "", "", "color", "white")
SkinSetValue("#widget4", "hover", "", "border-radius", "10px")
SkinSetValue("#widget4", "", "", "transition", "color 0.5s ease, font-size 0.5s ease-out-bounce, border-radius 0.5s ease")
WindowShow(MyWindow, #True, #PG_WindowShow_ScreenCentered)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
; Free our custom widgets, this is just for demonstration purposes with the #PG_Event_Destroy event handler
FreeWidget(widget)
FreeWidget(widget2)
FreeWidget(widget3)
FreeWidget(widget4)
Delay(1000)
EndIf
StopProGUI()See Also
CreateOsWidget, LayoutInsertWidget, LayoutSetCurrent, WidgetSetClass, AddEventHandler, WidgetSetUserData, WidgetGetUserData, FreeWidget
Supported OS
Windows, Linux