What GUI library does PB use

Linux specific forum
Zach
Addict
Addict
Posts: 1677
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

What GUI library does PB use

Post by Zach »

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]
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Some noob questions

Post by IdeasVacuum »

..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).
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Zach
Addict
Addict
Posts: 1677
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Some noob questions

Post by Zach »

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.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: What GUI library does PB use

Post by Foz »

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

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
and an example of usage:

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()

End
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: What GUI library does PB use

Post by Foz »

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
Addict
Posts: 1677
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: What GUI library does PB use

Post by Zach »

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.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: What GUI library does PB use

Post by Foz »

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:

Code: Select all

http://www.purebasic.fr/english/viewtopic.php?p=306362#p306362
Zach
Addict
Addict
Posts: 1677
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: What GUI library does PB use

Post by Zach »

lol, yeah I was just reading that thread.
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: What GUI library does PB use

Post by idle »

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
Windows 11, Manjaro, Raspberry Pi OS
Image
Zach
Addict
Addict
Posts: 1677
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: What GUI library does PB use

Post by Zach »

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.
Post Reply