Hi,
I'm thinking of trying to make my Text RPG Game a cross-platform affair for Windows/Linux and I was just curious about a couple things..
What GUI library does PB use on Linux systems? I know at one point adding bindings for GTK was discussed but I don't think I ever saw anything come out of that (yet). So what does PB use for application GUIs if not GTK? Do bindings exist for GTK or other Frameworks in any reliable form? (Officially supported by the framework, or done by a user and kept updated, etc)
Are there any other issues I need to consider on the Linux end when making something cross-platform?
[changed topic by Rings]
What GUI library does PB use
-
IdeasVacuum
- Always Here

- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Some noob questions
..It is using GTK:
http://www.purebasic.fr/blog/?cat=7
I have not coded for Linux but the first thing to consider is how significant the differences between the Linux's might be. Funnily enough, text fonts might be an issue for example (although one way to ensure a font is there is to include it with your app).
http://www.purebasic.fr/blog/?cat=7
I have not coded for Linux but the first thing to consider is how significant the differences between the Linux's might be. Funnily enough, text fonts might be an issue for example (although one way to ensure a font is there is to include it with your app).
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
Zach
- Addict

- Posts: 1677
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Some noob questions
Cool.. Is working with it that much harder? Or can I rely on internal PB commands for gadgets, etc unless I want to use something specific?
I suppose my biggest concern would be what it uses for the equivalent of a Text Box.
i.e on Windows it uses a RichEdit control, which through some mashing of ideas, we were able to come up with an RTF parsing routine to give me multiple colored words, etc. I definitely want to retain that ability in Linux as its part of the "visual aid" part of playing the Text RPG itself.
Does GtkTextView have similar abilities or would I have to resort to something more complicated? I'm trying to avoid Bitmap/Image based text writing if possible.
Unfortunately the difference between Distros falls a little outside my responsibilities IMHO.. I would be happy getting it working and looking acceptable on 2 or 3 major distros (Ubuntu based, Fedora, and Debian based, probably). There are just too many Distros and various quirks between them for me to take the problem seriously.
I suppose my biggest concern would be what it uses for the equivalent of a Text Box.
i.e on Windows it uses a RichEdit control, which through some mashing of ideas, we were able to come up with an RTF parsing routine to give me multiple colored words, etc. I definitely want to retain that ability in Linux as its part of the "visual aid" part of playing the Text RPG itself.
Does GtkTextView have similar abilities or would I have to resort to something more complicated? I'm trying to avoid Bitmap/Image based text writing if possible.
Unfortunately the difference between Distros falls a little outside my responsibilities IMHO.. I would be happy getting it working and looking acceptable on 2 or 3 major distros (Ubuntu based, Fedora, and Debian based, probably). There are just too many Distros and various quirks between them for me to take the problem seriously.
Re: What GUI library does PB use
Font sizes are the biggest pain in the rectum that you will ever face for aligning and maintaining gadgets on windows.
This is why I started a little project called PureVD - go on laugh at the name, get it out of the way.
Naming conventions aside, it allows me to forget about issues that I might face, such as positioning gadgets regardless of font or size, resizing of windows, etc. And it has to be completely workable through a GUI, which will auto generate the window and gadget code for me - which I haven't written yet, so at the moment the forms are written by hand, but the working premise is there
I have it working on Windows and it DID work on Linux (not sure about 4.60 on linux, not tried it - it did work in 4.51 on linux though), however as I don't have any Mac access, I'm certain that it won't work at all on a Mac.
Here is a current work in progress:
purevd.pbi
and an example of usage:
This is why I started a little project called PureVD - go on laugh at the name, get it out of the way.
Naming conventions aside, it allows me to forget about issues that I might face, such as positioning gadgets regardless of font or size, resizing of windows, etc. And it has to be completely workable through a GUI, which will auto generate the window and gadget code for me - which I haven't written yet, so at the moment the forms are written by hand, but the working premise is there
I have it working on Windows and it DID work on Linux (not sure about 4.60 on linux, not tried it - it did work in 4.51 on linux though), however as I don't have any Mac access, I'm certain that it won't work at all on a Mac.
Here is a current work in progress:
purevd.pbi
Code: Select all
EnableExplicit
; All hail Freak for getting me started!
;
;{- Calculate Minimum Gadget Size
; Calculates the size required to display a Gadget properly.
;
; Supported Gadgets:
; Button, Checkbox, Option, Text, String, ComboBox, Image
;
; Note:
; For Gadgets with variable content (String, ComboBox), only the returned height
; is useful, as the width will only be an absolute minimum value.
;
; The 'Flags' parameter gives gadget flags to include in the calculation.
; Currently only #PB_Text_Border makes a difference there.
;
CompilerIf Defined(Max, #PB_Procedure) = 0
Procedure Max(a, b)
If a > b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Structure PB_Gadget
*Gadget.GtkWidget
*Container.GtkWidget
*VT
UserData.i
GadgetData.i[4]
EndStructure
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Structure OSX_Rect
top.w
left.w
bottom.w
right.w
EndStructure
#noErr = 0
CompilerEndIf
; Stores the result in *Width\w and *Height\w
;
Procedure GetRequiredSize(Gadget, *Width.Word, *Height.Word, Flags = 0)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
Protected DC.i = GetDC_(GadgetID(Gadget))
Protected oldFont = SelectObject_(DC, GetGadgetFont(Gadget))
Protected Size.Size
Select GadgetType(Gadget)
Case #PB_GadgetType_Text
Protected Text$ = RemoveString(GetGadgetText(Gadget), Chr(10))
Protected count = CountString(Text$, Chr(13)) + 1
Protected empty = 0
Protected maxheight = 0
Protected index
For index = 1 To count
Protected Line$ = StringField(Text$, index, Chr(13))
If Line$ = ""
empty + 1
Else
Protected LineSize.Size
GetTextExtentPoint32_(DC, @Line$, Len(Line$), @LineSize)
Size\cx = Max(Size\cx, LineSize\cx)
Size\cy + LineSize\cy
maxheight = Max(maxheight, LineSize\cy)
EndIf
Next index
Size\cy + empty * maxheight
If Flags & #PB_Text_Border
Size\cx + GetSystemMetrics_(#SM_CXEDGE) * 2
Size\cy + GetSystemMetrics_(#SM_CYEDGE) * 2
Else
Size\cx + 2
Size\cy + 2
EndIf
Case #PB_GadgetType_CheckBox, #PB_GadgetType_Option
Text$ = GetGadgetText(Gadget)
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx + 20
Size\cy = Max(Size\cy+2, 20)
Case #PB_GadgetType_Button
Text$ = GetGadgetText(Gadget)
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx + GetSystemMetrics_(#SM_CXEDGE)*2
Size\cy = Max(Size\cy+GetSystemMetrics_(#SM_CYEDGE)*2, 24)
Size\cx + 10
Case #PB_GadgetType_String
Text$ = GetGadgetText(Gadget) + "Hg"
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx = GetSystemMetrics_(#SM_CXEDGE)*2
Size\cy = Max(Size\cy+GetSystemMetrics_(#SM_CXEDGE)*2, 20)
Case #PB_GadgetType_ComboBox
GetTextExtentPoint32_(DC, @"Hg", 2, @Size.SIZE)
Size\cy = Max(Size\cy + 8, 21)
Size\cx = Size\cy
Case #PB_GadgetType_Image
Size\cx = GadgetWidth(Gadget)
Size\cy = GadgetHeight(Gadget)
Case #PB_GadgetType_Frame3D
Text$ = GetGadgetText(Gadget)
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx + GetSystemMetrics_(#SM_CXEDGE)*2
Size\cy = Max(Size\cy+GetSystemMetrics_(#SM_CYEDGE)*2, 24)
Size\cx + 10
EndSelect
SelectObject_(DC, oldFont)
ReleaseDC_(GadgetID(Gadget), DC)
*Width\w = Size\cx
*Height\w = Size\cy
CompilerCase #PB_OS_Linux
Protected *Gadget.PB_Gadget = IsGadget(Gadget)
Protected RealSize.GtkRequisition
Protected Size.GtkRequisition
If *Gadget And *Gadget\Container And GadgetType(Gadget) <> #PB_GadgetType_ComboBox
gtk_widget_size_request_(*Gadget\Container, @RealSize)
gtk_widget_set_size_request_(*Gadget\Container, -1, -1)
gtk_widget_size_request_(*Gadget\Container, @Size)
gtk_widget_set_size_request_(*Gadget\Container, RealSize\Width, RealSize\Height)
Else
gtk_widget_size_request_(GadgetID(Gadget), @RealSize)
gtk_widget_set_size_request_(GadgetID(Gadget), -1, -1)
gtk_widget_size_request_(GadgetID(Gadget), @Size)
gtk_widget_set_size_request_(GadgetID(Gadget), RealSize\Width, RealSize\Height)
EndIf
If GadgetType(Gadget) = #PB_GadgetType_ComboBox Or GadgetType(Gadget) = #PB_GadgetType_String
*Width\w = 20
Else
*Width\w = Size\Width
EndIf
*Height\w = Size\Height
CompilerCase #PB_OS_MacOS
Type = GadgetType(Gadget)
If Type = #PB_GadgetType_Image
*Width\w = GadgetWidth(Gadget)
*Height\w = GadgetHeight(Gadget)
ElseIf Type = #PB_GadgetType_Text
realwidth = GadgetWidth(Gadget)
*Width\w = 40
*Height\w = 20
ResizeGadget(Gadget, #PB_Ignore, #PB_Ignore, 1000, #PB_Ignore)
If GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) = #noErr
Height = Rect\bottom - Rect\top
If Height > 0
Min = 0
Max = 1000
While Max > Min+2
Mid = (Min + Max) / 2
ResizeGadget(Gadget, #PB_Ignore, #PB_Ignore, Mid, #PB_Ignore)
If GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) <> #noErr
ProcedureReturn
EndIf
If Rect\bottom - Rect\top > Height
Min = Mid
Else
Max = Mid
EndIf
Wend
*Width\w = Rect\right - Rect\left + 2
*Height\w = Max(Height, 20)
EndIf
EndIf
ResizeGadget(Gadget, #PB_Ignore, #PB_Ignore, realwidth, #PB_Ignore)
Else
If GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) = #noErr
*Width\w = Rect\right - Rect\left
*Height\w = Max(Rect\bottom - Rect\top, 20)
If Type = #PB_GadgetType_Button Or Type = #PB_GadgetType_String
*Height\w = Max(*Height\w, 24)
EndIf
Else
*Width\w = 40
*Height\w = 20
EndIf
If Type = #PB_GadgetType_String Or Type = #PB_GadgetType_ComboBox
*Width\w = 30
EndIf
EndIf
CompilerEndSelect
EndProcedure
; convinience wrappers if only one size is needed
;
Procedure.w GetRequiredWidth(Gadget, Flags = 0)
Protected Width.w, Height.w
GetRequiredSize(Gadget, @Width, @Height, Flags)
ProcedureReturn Width
EndProcedure
Procedure.w GetRequiredHeight(Gadget, Flags = 0)
Protected Width.w, Height.w
GetRequiredSize(Gadget, @Width, @Height, Flags)
ProcedureReturn Height
EndProcedure
;}
Enumeration
#Sizing_MinimumSize
#Sizing_Stretch
#Sizing_Centre
#Sizing_Fixed
#Sizing_FixedMinimumSize
EndEnumeration
Enumeration
#GeneralType_Window
#GeneralType_Container
#GeneralType_Gadget
EndEnumeration
Enumeration
#Orientation_Horizontal
#Orientation_Vertical
EndEnumeration
Enumeration 1000
#PB_GadgetType_Window
#PB_GadgetType_HBox
#PB_GadgetType_VBox
#PB_GadgetType_Spacer
; #PB_GadgetType_
; #PB_GadgetType_
; #PB_GadgetType_
; #PB_GadgetType_
; #PB_GadgetType_
EndEnumeration
Structure GadgetLayout
ID.i
ParentID.i
WindowID.i
Type.w
GeneralType.b
Name.s
MinWidth.w
MinHeight.w
DesiredWidth.w
DesiredHeight.w
FlexWidthType.b
FlexHeightType.b
ActualX.w
ActualY.w
ActualWidth.w
ActualHeight.w
ItemID.i
Orientation.b
EndStructure
Global NewList gl.GadgetLayout()
Procedure CalculateMinimumSizes(Orientation.b, ParentID.i, *AreaWidth.Word, *AreaHeight.Word, BorderTop.b = 0, BorderBottom.b = 0, BorderLeft.b = 0, BorderRight.b = 0, Spacing.b = 6)
ResetList(gl())
Protected newWidth.w = 0
Protected newHeight.w = 0
ForEach gl()
If gl()\ParentID = ParentID
If gl()\GeneralType <> #GeneralType_Gadget
Protected ContainerWidth.w = gl()\MinWidth
Protected ContainerHeight.w = gl()\MinHeight
Protected *CurrentGadget.i = @gl()
If gl()\Type = #PB_GadgetType_Frame3D
CalculateMinimumSizes(gl()\Orientation, gl()\ID, @ContainerWidth, @ContainerHeight, 20, 6, 6, 6)
Else
CalculateMinimumSizes(gl()\Orientation, gl()\ID, @ContainerWidth, @ContainerHeight, 0, 4, 0, 4)
EndIf
ChangeCurrentElement(gl(), *CurrentGadget)
gl()\MinWidth = ContainerWidth
gl()\MinHeight = ContainerHeight
EndIf
If Orientation = #Orientation_Horizontal
newWidth = newWidth + gl()\MinWidth + Spacing
If newHeight < gl()\MinHeight
newHeight = gl()\MinHeight
EndIf
Else
newHeight = newHeight + gl()\MinHeight + Spacing
If newWidth < gl()\MinWidth
newWidth = gl()\MinWidth
EndIf
EndIf
EndIf
Next
; remove the extra space at the end
If Orientation = #Orientation_Horizontal
newWidth = newWidth - Spacing
Else
newHeight = newHeight - Spacing
EndIf
newWidth = newWidth + BorderLeft + BorderRight
newHeight = newHeight + BorderTop + BorderBottom
If *AreaWidth\w < newWidth
*AreaWidth\w = newWidth
EndIf
If *AreaHeight\w < newHeight
*AreaHeight\w = newHeight
EndIf
EndProcedure
Procedure OrientGadgets(Orientation.b, ParentID.i, MinimumWidth.w, MinimumHeight.w, *AreaWidth.Word, *AreaHeight.Word, BorderTop.b = 0, BorderBottom.b = 0, BorderLeft.b = 0, BorderRight.b = 0, Spacing.b = 6)
Protected TotalMinHeight.w = MinimumHeight ;+ BorderTop + BorderBottom
Protected TotalMinWidth.w = MinimumWidth ;+ BorderLeft + BorderRight
If *AreaWidth\w < TotalMinWidth
*AreaWidth\w = TotalMinWidth
EndIf
If *AreaHeight\w < TotalMinHeight
*AreaHeight\w = TotalMinHeight
EndIf
;-------------------------------------------------
Protected RemainingAreaWidth.w = *AreaWidth\w - TotalMinWidth
Protected RemainingAreaHeight.w = *AreaHeight\w - TotalMinHeight
Protected InnerHeight.w = *AreaHeight\w - BorderTop - BorderBottom
Protected InnerWidth.w = *AreaWidth\w - BorderLeft - BorderRight
;-------------------------------------------------
Protected WidthFlexCount.w = 0
Protected HeightFlexCount.w = 0
Protected GadgetCount.w = 0
ForEach gl()
If gl()\ParentID = ParentID
GadgetCount + 1
Select gl()\FlexWidthType
Case #Sizing_Stretch, #Sizing_Centre
WidthFlexCount = WidthFlexCount + 1
EndSelect
Select gl()\FlexHeightType
Case #Sizing_Stretch, #Sizing_Centre
HeightFlexCount = HeightFlexCount + 1
EndSelect
EndIf
Next
Protected RemainingWidth.w, RemainingHeight.w
If Orientation = #Orientation_Horizontal
If WidthFlexCount = 0
RemainingWidth = RemainingAreaWidth
Else
RemainingWidth = Int(RemainingAreaWidth / WidthFlexCount)
EndIf
RemainingHeight = InnerHeight
Else
If HeightFlexCount = 0
RemainingHeight = RemainingAreaHeight
Else
RemainingHeight = Int(RemainingAreaHeight / HeightFlexCount)
EndIf
RemainingWidth = InnerWidth
EndIf
;-------------------------------------------------
Protected MaxHeight.w = 0 + BorderTop
Protected MaxWidth.w = 0 + BorderLeft
Protected ActualX.w = MaxWidth
Protected ActualY.w = MaxHeight
Protected t.i = 0
ForEach gl()
If gl()\ParentID = ParentID
gl()\ActualX = ActualX
gl()\ActualY = ActualY
Select gl()\FlexWidthType
Case #Sizing_Stretch
If Orientation = #Orientation_Horizontal
If RemainingWidth > 0
gl()\ActualWidth = gl()\MinWidth + RemainingWidth
Else
gl()\ActualWidth = gl()\MinWidth
EndIf
Else
If gl()\MinWidth < InnerWidth
gl()\ActualWidth = InnerWidth
Else
gl()\ActualWidth = gl()\MinWidth
EndIf
EndIf
Default
gl()\ActualWidth = gl()\MinWidth
EndSelect
Select gl()\FlexHeightType
Case #Sizing_Stretch, #Sizing_FixedMinimumSize
If Orientation = #Orientation_Vertical
If RemainingHeight > 0
gl()\ActualHeight = gl()\MinHeight + RemainingHeight
Else
gl()\ActualHeight = gl()\MinHeight
EndIf
Else
If gl()\MinHeight < InnerHeight
gl()\ActualHeight = InnerHeight
Else
gl()\ActualHeight = gl()\MinHeight
EndIf
EndIf
Default
gl()\ActualHeight = gl()\MinHeight
EndSelect
If gl()\GeneralType = #GeneralType_Container
Protected ContainerWidth.w = gl()\ActualWidth
Protected ContainerHeight.w = gl()\ActualHeight
Protected *CurrentGadget.i = @gl()
If gl()\Type = #PB_GadgetType_Frame3D
OrientGadgets(gl()\Orientation, gl()\ID, gl()\MinWidth, gl()\MinHeight, @ContainerWidth, @ContainerHeight, 20, 6, 6, 6)
Else
OrientGadgets(gl()\Orientation, gl()\ID, gl()\MinWidth, gl()\MinHeight, @ContainerWidth, @ContainerHeight, 0, 4, 0, 4)
EndIf
ChangeCurrentElement(gl(), *CurrentGadget)
gl()\ActualWidth = ContainerWidth
gl()\ActualHeight = ContainerHeight
EndIf
Select gl()\FlexWidthType
Case #Sizing_Centre
If Orientation = #Orientation_Horizontal
t = Int(((gl()\ActualWidth + RemainingWidth) / 2) - (gl()\ActualWidth / 2))
gl()\ActualX = gl()\ActualX + t
Else
t = Int((InnerWidth / 2) - (gl()\ActualWidth / 2))
gl()\ActualX = gl()\ActualX + t
EndIf
EndSelect
Select gl()\FlexHeightType
Case #Sizing_Centre
If Orientation = #Orientation_Horizontal
t = Int((InnerHeight / 2) - (gl()\ActualHeight / 2))
gl()\ActualY = gl()\ActualY + t
Else
t = Int(((gl()\ActualHeight + RemainingHeight) / 2) - (gl()\ActualHeight / 2))
gl()\ActualY = gl()\ActualY + t
EndIf
EndSelect
If gl()\Type <> #PB_GadgetType_Spacer
ResizeGadget(gl()\ID, gl()\ActualX, gl()\ActualY, gl()\ActualWidth, gl()\ActualHeight)
EndIf
If Orientation = #Orientation_Horizontal
MaxWidth = MaxWidth + Spacing + gl()\ActualWidth
If MaxHeight < gl()\ActualHeight
MaxHeight = gl()\ActualHeight
EndIf
If gl()\FlexWidthType = #Sizing_Centre
MaxWidth = MaxWidth + RemainingWidth ; - gl()\ActualWidth - Spacing - BorderLeft + BorderRight
EndIf
ActualX = MaxWidth
Else
MaxHeight = MaxHeight + Spacing + gl()\ActualHeight
If MaxWidth < gl()\ActualWidth
MaxWidth = gl()\ActualWidth
EndIf
If gl()\FlexHeightType = #Sizing_Centre
MaxHeight = MaxHeight + RemainingHeight
EndIf
ActualY = MaxHeight
EndIf
EndIf
Next
If Orientation = #Orientation_Horizontal
MaxWidth = MaxWidth - Spacing
Else
MaxHeight = MaxHeight - Spacing
EndIf
If *AreaWidth\w < MaxWidth + BorderRight
*AreaWidth\w = MaxWidth + BorderRight
EndIf
If *AreaHeight\w < MaxHeight + BorderBottom
*AreaHeight\w = MaxHeight + BorderBottom
EndIf
EndProcedure
Procedure.i AddGadget(pName.s, pParentID.i, pWindowID.i, pGadgetType.i, pText.s, pDesiredWidth.i, pDesiredHeight.i, pFlexWidthType.b, pFlexHeightType.b, pFlags.i = 0, pPath.s = "")
If pDesiredWidth = #PB_Any
pDesiredWidth = 0
EndIf
If pDesiredHeight = #PB_Any
pDesiredHeight = 0
EndIf
AddElement(gl())
gl()\ID = ListSize(gl())
gl()\Type = pGadgetType
gl()\ParentID = pParentID
gl()\WindowID = pWindowID
Select pGadgetType
Case #PB_GadgetType_Window
gl()\GeneralType = #GeneralType_Window
Case #PB_GadgetType_HBox, #PB_GadgetType_VBox, #PB_GadgetType_Frame3D
gl()\GeneralType = #GeneralType_Container
Default
gl()\GeneralType = #GeneralType_Gadget
EndSelect
gl()\FlexWidthType = pFlexWidthType
gl()\FlexHeightType = pFlexHeightType
gl()\Name = pName
If gl()\Type = #PB_GadgetType_HBox
gl()\Orientation = #Orientation_Horizontal
Else
gl()\Orientation = #Orientation_Vertical
EndIf
If gl()\Type = #PB_GadgetType_Window
OpenWindow(gl()\ID, 0, 0, pDesiredWidth, pDesiredHeight, pText, pFlags)
gl()\GeneralType = #GeneralType_Window
gl()\WindowID = gl()\ID
Else
If pParentID <> pWindowID
OpenGadgetList(pParentID)
EndIf
Protected HasMinimumSize.b = #True
Select gl()\Type
Case #PB_GadgetType_Button
ButtonGadget(gl()\ID, 0, 0, 0, 0, pText)
Case #PB_GadgetType_CheckBox
CheckBoxGadget(gl()\ID, 0, 0, 0, 0, pText)
Case #PB_GadgetType_ComboBox
ComboBoxGadget(gl()\ID, 0, 0, 0, 0)
Case #PB_GadgetType_Image
gl()\ItemID = LoadImage(#PB_Any, pPath)
ImageGadget(gl()\ID, 0, 0, 0, 0, ImageID(gl()\ItemID))
Case #PB_GadgetType_Option
OptionGadget(gl()\ID, 0, 0, 0, 0, pText)
Case #PB_GadgetType_String
StringGadget(gl()\ID, 0, 0, 0, 0, pText)
Case #PB_GadgetType_Text
TextGadget(gl()\ID, 0, 0, 0, 0, pText)
Case #PB_GadgetType_Frame3D
Frame3DGadget(gl()\ID, 0, 0, 20, 20, pText)
; specials
Case #PB_GadgetType_HBox, #PB_GadgetType_VBox
ContainerGadget(gl()\ID, 0, 0, 20, 20) ; , #PB_Container_Single
CloseGadgetList()
Case #PB_GadgetType_Spacer
HasMinimumSize = #False
EndSelect
If HasMinimumSize = #True
GetRequiredSize(gl()\ID, @gl()\MinWidth, @gl()\MinHeight)
If pDesiredWidth > gl()\MinWidth
gl()\MinWidth = pDesiredWidth
EndIf
If pDesiredHeight > gl()\MinHeight
gl()\MinHeight = pDesiredHeight
EndIf
Else
gl()\MinWidth = 0
gl()\MinHeight = 0
EndIf
EndIf
ProcedureReturn gl()\ID
EndProcedure
Procedure RenderGadgets(pCalculateMinimumSize.b)
ForEach gl()
If gl()\Type = #PB_GadgetType_Window
Protected WinWidth.i = WindowWidth(gl()\ID)
Protected WinHeight.i = WindowHeight(gl()\ID)
Protected minWidth.i, minHeight.i
Protected *tmpGadget.i = @gl()
CalculateMinimumSizes(#Orientation_Vertical, gl()\ID, @minWidth, @minHeight, 8, 8, 8, 8)
ChangeCurrentElement(gl(), *tmpGadget)
gl()\MinWidth = minWidth
gl()\MinHeight = minHeight
Protected ResizeToMin.b = #False
If WinWidth < minWidth : WinWidth = minWidth : ResizeToMin = #True : EndIf
If WinHeight < minHeight : WinHeight = minHeight : ResizeToMin = #True : EndIf
If ResizeToMin = #True
ResizeWindow(gl()\ID, #PB_Ignore, #PB_Ignore, WinWidth, WinHeight)
EndIf
OrientGadgets(#Orientation_Vertical, gl()\ID, minWidth, minHeight, @WinWidth, @WinHeight, 8, 8, 8, 8)
ChangeCurrentElement(gl(), *tmpGadget)
EndIf
Next
EndProcedure
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Procedure WndProc(hwnd, uMsg, wParam, lParam)
Protected result = #PB_ProcessPureBasicEvents
If uMsg = #WM_EXITSIZEMOVE
RenderGadgets(#False)
EndIf
ProcedureReturn result
EndProcedure
CompilerEndIf
Declare GadgetEventSelection(pWindowEvent, pGadgetEvent, pTypeEvent)
Declare MenuEventSelection(pWindowEvent, pMenuEvent)
Procedure EventLoop()
RenderGadgets(#False)
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
ForEach gl()
If gl()\Type = #PB_GadgetType_Window
SetWindowCallback(@WndProc(), gl()\ID)
EndIf
Next
CompilerEndIf
Repeat
Protected Event = WaitWindowEvent()
Protected Window = EventWindow()
Select Event
Case #PB_Event_Gadget
Protected Gadget = EventGadget()
Protected Type = EventType()
GadgetEventSelection(Window, Gadget, Type)
Case #PB_Event_Menu
Protected Menu = EventMenu()
MenuEventSelection(Window, Menu)
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
Case #PB_Event_SizeWindow
RenderGadgets(#False)
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Case #PB_Event_MaximizeWindow, #PB_Event_RestoreWindow
RenderGadgets(#False)
CompilerEndIf
Case #PB_Event_CloseWindow
Define Quit = 1
EndSelect
Until Quit = 1
EndProcedure
Procedure GetGadgetID(pWindowName.s, pGadgetName.s)
Protected WinID.i
ForEach gl()
If gl()\ParentID = -1 And gl()\Name = pWindowName
WinID = gl()\ID
Break
EndIf
Next
ForEach gl()
If gl()\WindowID = WinID And gl()\Name = pGadgetName
Break
EndIf
Next
ProcedureReturn gl()\ID
EndProcedure
Code: Select all
EnableExplicit
XIncludeFile "purevd.pbi"
; Test template
;{-- purevd start
Declare btnOk_Click()
Declare btnCancel_Click()
Procedure InitialiseGadgets()
Protected rv.i, WinID.i, tmpID.i
NewList Contain.i()
; AddGadget(pName.s, pParentID.i, pGadgetType.i, pText.s, pDesiredWidth.i, pDesiredHeight.i, pFlexWidthType.b, pFlexHeightType.b, pFlags.i = 0, pPath.s = "")
; add the window
AddElement(Contain())
Contain() = AddGadget("winMain", -1, -1, #PB_GadgetType_Window, "Main Window", 600, 400, 0, 0, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)
WinID = Contain()
; All controls to be added here is in a verticle arrangement (vbox)
tmpID = Contain()
AddElement(Contain())
Contain() = AddGadget("Container_frmShowOff", tmpID, WinID, #PB_GadgetType_VBox, "", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
; add a frame
tmpID = Contain()
AddElement(Contain())
Contain() = AddGadget("frmShowOff", tmpID, WinID, #PB_GadgetType_Frame3D, "Showing Off", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
; All controls to be added here is in a verticle arrangement (vbox)
tmpID = Contain()
AddElement(Contain())
Contain() = AddGadget("Items_vbox_frmShowOff", tmpID, WinID, #PB_GadgetType_VBox, "", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
; All controls to be added here is in a horizontal arrangement (hbox)
tmpID = Contain()
AddElement(Contain())
Contain() = AddGadget("Items_hbox1_frmShowOff", tmpID, WinID, #PB_GadgetType_HBox, "", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
; add a text gadget set to minimum size
AddGadget("txtShowOff1", Contain(), WinID, #PB_GadgetType_Text, "Name", #PB_Any, #PB_Any, #Sizing_MinimumSize, #Sizing_Centre)
; add a string gadget set to fill the rest of the frame
AddGadget("strShowOff1", Contain(), WinID, #PB_GadgetType_String, "<Name goes here>", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Centre)
DeleteElement(Contain()) ; back up to frame
; add another set of controls in a horizontal arrangement (hbox)
tmpID = Contain()
AddElement(Contain())
Contain() = AddGadget("Items_hbox2_frmShowOff", tmpID, WinID, #PB_GadgetType_HBox, "", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
; add a text gadget set to minimum size
AddGadget("txtShowOff2", Contain(), WinID, #PB_GadgetType_Text, "E-mail", #PB_Any, #PB_Any, #Sizing_MinimumSize, #Sizing_Centre)
; add a string gadget set to fill the rest of the frame
AddGadget("strShowOff2", Contain(), WinID, #PB_GadgetType_String, "<Password goes here>", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Centre)
DeleteElement(Contain()) ; back up to frame vbox
DeleteElement(Contain()) ; back up to frame
DeleteElement(Contain()) ; back up to window vbox
AddGadget("spacer1", Contain(), WinID, #PB_GadgetType_Spacer, "", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
AddGadget("btnOk", Contain(), WinID, #PB_GadgetType_Button, "OK", 100, 100, #Sizing_Fixed, #Sizing_Fixed)
AddGadget("btnCancel", Contain(), WinID, #PB_GadgetType_Button, "Cancel", #PB_Any, #PB_Any, #Sizing_Stretch, #Sizing_Stretch)
EndProcedure
Procedure GadgetEventSelection(pWindowEvent, pGadgetEvent, pTypeEvent)
ForEach gl()
If pWindowEvent = gl()\WindowID And gl()\ID = pGadgetEvent
Break
EndIf
Next
Select gl()\Name
Case "btnOk"
If pTypeEvent = #PB_EventType_LeftClick
btnOK_Click()
EndIf
Case "btnCancel"
If pTypeEvent = #PB_EventType_LeftClick
btnCancel_Click()
EndIf
EndSelect
EndProcedure
Procedure MenuEventSelection(pWindowEvent, pMenuEvent)
ForEach gl()
If pWindowEvent = gl()\WindowID And gl()\ID = pMenuEvent
Break
EndIf
Next
Select gl()\Name
EndSelect
EndProcedure
;}-- purevd end
Procedure btnOk_Click()
MessageRequester("Main", "Name:" + GetGadgetText(GetGadgetID("winMain", "strShowOff1")) + Chr(13)+Chr(10) + "Email:" + GetGadgetText(GetGadgetID("winMain", "strShowOff2")))
EndProcedure
Procedure btnCancel_Click()
MessageRequester("Main", "Cancel")
EndProcedure
InitialiseGadgets()
EventLoop()
EndRe: What GUI library does PB use
As another thought, to have the same rich text box across versions, perhaps you should look at TextEditGadgetEx: http://www.purebasic.fr/english/viewtop ... 12&t=45669
-
Zach
- Addict

- Posts: 1677
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: What GUI library does PB use
Actually, I had considered it at one point but I don't remember exactly why I decided against it.
Be that as it may, I looked up GTKTextView and according to this I think it may do what I need in a similar fashion as working with the RichEdit control.
Although it looks like Idle has done quite a bit of work to his Gadget now, and its being designed on PB 4.60. Perhaps I will use it in a future project, but I've committed this project to PB 4.51 for the time being.
Can PB do GTK on Windows? Maybe that is where I was confused about it not being done yet. It would be neat (and make sense) to do it GTK all the way if possible.
Be that as it may, I looked up GTKTextView and according to this I think it may do what I need in a similar fashion as working with the RichEdit control.
Although it looks like Idle has done quite a bit of work to his Gadget now, and its being designed on PB 4.60. Perhaps I will use it in a future project, but I've committed this project to PB 4.51 for the time being.
Can PB do GTK on Windows? Maybe that is where I was confused about it not being done yet. It would be neat (and make sense) to do it GTK all the way if possible.
Re: What GUI library does PB use
Well, my work was originally based on GTK - I was going to use the designer output to generate PB code.
Anyway, the only thing I've heard about about using GTK on windows is this:
Anyway, the only thing I've heard about about using GTK on windows is this:
Code: Select all
http://www.purebasic.fr/english/viewtopic.php?p=306362#p306362-
Zach
- Addict

- Posts: 1677
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: What GUI library does PB use
lol, yeah I was just reading that thread.
Re: What GUI library does PB use
TextGadgetEx might be ok if you disable select and copy paste (it's buggy and I'm to busy to fix it)
Also you might want to look at the gadget Graph100 is making
http://www.purebasic.fr/french/viewtopi ... =6&t=12125
it's a rework mash up of canvas gadgets including textGadgetEx, Buttons, Scrollbars and splitter
Also you might want to look at the gadget Graph100 is making
http://www.purebasic.fr/french/viewtopi ... =6&t=12125
it's a rework mash up of canvas gadgets including textGadgetEx, Buttons, Scrollbars and splitter
Windows 11, Manjaro, Raspberry Pi OS


-
Zach
- Addict

- Posts: 1677
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: What GUI library does PB use
Well, one thing I'd like to keep is the select/copy/paste ability. For now I think I'll just stick with what I'm doing and see how it works out in GTK when I get around to trying. I don't think it will be a ton of extra work.