Most up-to-date alternative UI libraryfor Windows

Just starting out? Need help? Post your questions and find answers here.
StackC
New User
New User
Posts: 8
Joined: Sat Jun 17, 2023 6:35 pm

Most up-to-date alternative UI libraryfor Windows

Post by StackC »

Hello folks,

I would like to have my Windows UI application appear in a "flat design", something like this: https://i.ytimg.com/vi/eyb7Gla-ePo/maxresdefault.jpg

Are there any existing libraries for PureBasic allowing to create these kind of UI applications for Windows?
Olli
Addict
Addict
Posts: 1198
Joined: Wed May 27, 2020 12:26 pm

Re: Most up-to-date alternative UI libraryfor Windows

Post by Olli »

Is your desktop actually set to this flat design ?
StackC
New User
New User
Posts: 8
Joined: Sat Jun 17, 2023 6:35 pm

Re: Most up-to-date alternative UI libraryfor Windows

Post by StackC »

What do you mean by that?
User avatar
mk-soft
Always Here
Always Here
Posts: 6204
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Most up-to-date alternative UI libraryfor Windows

Post by mk-soft »

Purebasic uses the OS Common Controls (ComCtl32.dll v6.x)
Thus depending on a setting (default flat)
But not Visual Style
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
StackC
New User
New User
Posts: 8
Joined: Sat Jun 17, 2023 6:35 pm

Re: Most up-to-date alternative UI libraryfor Windows

Post by StackC »

I see what you mean. But I would like to enforce the flat design in my application.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Most up-to-date alternative UI libraryfor Windows

Post by RASHAD »

See PB dialog lib

Sample :

Code: Select all


XML$ ="<window id='1' name='test' text='test' minwidth='0' minheight='0' flags='#PB_Window_BorderLess|#PB_Window_ScreenCentered'>" +
      "      <vbox expand='item:3'>" +
      "        <hbox expand='item:3'>" +
      "            <singlebox expand='no' >" +
      "                <buttonimage name='but1' id='0' text='Button 1' width='200' height='80' /> " +
      "            </singlebox>" +
      "            <gridbox columns='1'>" +
      "                <option name='option1' text='Option 1' id='1' align='left' />" +
      "                <option name='option2' text='Option 2' id='2' align='left'/>" +
      "                <option name='option3' text='Option 3' id='3' />" +
      "                <checkbox name='check1' text='CheckBox 1' id='5' />" +
      "            </gridbox>" +
      "            <empty  />"+
      "            <gridbox name='grid2' columns='3' colspacing='1' >" +
      "                  <text name='but1' id ='10' text='' width='29' height='22' /> " +
      "                  <text name='but2' id ='11' text='' width='27' height='22'/> " +
      "                  <text name='but3' id ='12' text='' width='49' height='22' /> " +
      "            </gridbox>" +
      "        </hbox>" +
      "         <hbox spacing='0' expand='no' height='18'>" +
      "                <empty width='8' />"+
      "                <button id ='40' text='File' width='40' height='18' /> " +
      "                <button id ='41' text='Edit' width='40' height='18'/> " +
      "                <button id ='42' text='Help' width='40' height='18' /> " +      
      "         </hbox>" +
      "         <singlebox  margin='left:10,top:10,right:10,bottom:10' width='auto' height='200'>" +
      "                  <listicon  text='Column 0' id='50' flags='#PB_ListIcon_GridLines| #PB_ListIcon_FullRowSelect'/>" +       
      ;"                  <editor text='Ok...&#xA;&#xA;Test' />" +
"         </singlebox>" +
"      </vbox>" +
"</window>"

Global Dialog,Bkgcolor,Run,Theme,dpix.d,dpiy.d

LoadFont(1, "Georgia", 26)
LoadFont(0,"Marlett",12)

ExamineDesktops()
olddesktop = DesktopWidth(0)
dpix = DesktopResolutionX()
dpiy = DesktopResolutionY()

Procedure IsMouseOver(hWnd) 
  GetWindowRect_(hWnd,r.RECT) 
  GetCursorPos_(p.POINT) 
  Result = PtInRect_(r,p\y << 32 + p\x) 
  ProcedureReturn Result 
EndProcedure

Procedure WindowProc(hwnd, uMsg, wParam, lParam)
  Select uMSG     
    Case #WM_CTLCOLORSTATIC
      Select GetProp_(lParam, "PB_ID");GetDlgCtrlID_(lParam)
        Case 1 To 5 
          SetBkMode_(wParam,#TRANSPARENT)
          SetTextColor_(wParam, $000000)            
          ProcedureReturn Bkgcolor         
      EndSelect 
      
    Case #WM_SETTINGCHANGE
      SystemParametersInfo_(#SPI_GETWORKAREA, 0, r.RECT, 0)
      If GetWindowState(0) = #PB_Window_Maximize
        MoveWindow_(WindowID(0),r\left-4,r\top-4,r\right-r\left+8,r\bottom-r\top+8,1)
      EndIf    
      
    Case #WM_SIZE,#WM_MOVE
      GetWindowRect_(WindowID(0),r.RECT)
      MoveWindow_(WindowID(1),r\left+4,r\top+4,r\right-r\left-8,r\bottom-r\top-8,1)
      If GetWindowState(0) = #PB_Window_Normal
        Run = 0 
        SetGadgetText(11,Chr($31))
      EndIf  
      
    Case #WM_LBUTTONDOWN
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
      
  EndSelect    
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

#XmlEncoding = #PB_UTF8

OpenWindow(0,0,0,2,2,"",#PB_Window_BorderLess| #WS_SIZEBOX)

If Color = 0 And Theme = 1
  If OSVersion() >= #PB_OS_Windows_Vista
    hdc = GetWindowDC_(0)          
    Color = GetPixel_(hdc,2,2)
    ReleaseDC_(0,hdc)
  Else
    Color = GetSysColor_(#COLOR_ACTIVECAPTION)
  EndIf
ElseIf Color = 0 And Theme = 0
  Color = $D6D6D8
EndIf

Bkgcolor  = CreateSolidBrush_(Color)

SetWindowLongPtr_(WindowID(0),#GWL_STYLE,GetWindowLongPtr_(WindowID(0),#GWL_STYLE)|#WS_SIZEBOX)
SetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE,#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0),0,1,#LWA_ALPHA) 

XML.i = CatchXML(#PB_Any, @XML$, StringByteLength(XML$), 0, #XmlEncoding) 
Dialog.i = CreateDialog(#PB_Any)
OpenXMLDialog(Dialog.i, XML.i, "test")

SetWindowLongPtr_( WindowID(1), #GWL_HWNDPARENT,WindowID(0))

Image = CreateImage(#PB_Any, 200*dpix,80*dpiy)
StartDrawing(ImageOutput(Image.i))
Box(0,0,200*dpix,80*dpiy, $FEFEFE)
DrawingFont(FontID(1))
DrawingMode(#PB_2DDrawing_Transparent )
DrawText(25*dpix,20*dpiy,"RASHAD",$FF0000,$FEFEFE)
StopDrawing()

ResizeImage(Image,200,80,#PB_Image_Smooth)

i.ICONINFO
i\fIcon = 1
i\hbmMask = ImageID( Image)
i\hbmColor = ImageID( Image)    
dImage = CreateIconIndirect_(i)

SetGadgetAttribute(0,#PB_Button_Image, dImage)

SetWindowColor(1,Color)
SetWindowLongPtr_(WindowID(1),#GWL_STYLE,GetWindowLongPtr_(WindowID(1),#GWL_STYLE)|#WS_BORDER)

SetWindowLongPtr_(GadgetID(10),#GWL_STYLE,GetWindowLongPtr_(GadgetID(10),#GWL_STYLE)|#SS_CENTERIMAGE | #SS_CENTER| #SS_NOTIFY)
SetWindowLongPtr_(GadgetID(11),#GWL_STYLE,GetWindowLongPtr_(GadgetID(11),#GWL_STYLE)|#SS_CENTERIMAGE | #SS_CENTER| #SS_NOTIFY)
SetWindowLongPtr_(GadgetID(12),#GWL_STYLE,GetWindowLongPtr_(GadgetID(12),#GWL_STYLE)|#SS_CENTERIMAGE | #SS_CENTER| #SS_NOTIFY)

SetGadgetColor(10,#PB_Gadget_BackColor,Color)
If Theme = 1
  SetGadgetColor(10,#PB_Gadget_FrontColor,0)
Else
  SetGadgetColor(10,#PB_Gadget_FrontColor,Color ! $FFFFFF)
EndIf
SetGadgetText(10,Chr($30))
SetGadgetFont(10,FontID(0))

SetGadgetColor(11,#PB_Gadget_BackColor,Color)
If Theme = 1
  SetGadgetColor(11,#PB_Gadget_FrontColor,0)
Else
  SetGadgetColor(11,#PB_Gadget_FrontColor,Color ! $FFFFFF)
EndIf
SetGadgetText(11,Chr($31))
SetGadgetFont(11,FontID(0))

SetGadgetColor(12,#PB_Gadget_BackColor,$1F1FCC)
SetGadgetColor(12,#PB_Gadget_FrontColor,$FFFFFF)
SetGadgetText(12,Chr($72))
SetGadgetFont(12,FontID(0))

; SetWindowLongPtr_(GadgetID(40),#GWL_STYLE,GetWindowLongPtr_(GadgetID(40),#GWL_STYLE)|#BS_HOLLOW)
; SetWindowLongPtr_(GadgetID(41),#GWL_STYLE,GetWindowLongPtr_(GadgetID(41),#GWL_STYLE)|#BS_HOLLOW)
; SetWindowLongPtr_(GadgetID(42),#GWL_STYLE,GetWindowLongPtr_(GadgetID(42),#GWL_STYLE)|#BS_HOLLOW)

SetGadgetItemAttribute(50,0,#PB_ListIcon_ColumnWidth ,120,0)
AddGadgetColumn(50, 1, "Column 1", 250)
For col = 2 To 5
  AddGadgetColumn(50, col, "Column "+Str(col), 150)
Next
AddGadgetItem(50, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(50, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")

SetWindowCallback(@WindowProc())

nWidth = 480*dpix
nHeight = 350*dpiy
ResizeWindow(0,(GetSystemMetrics_(#SM_CXSCREEN) - nWidth) >> 1,(GetSystemMetrics_(#SM_CYSCREEN) - nHeight) >>1,nWidth,nHeight)
WindowBounds(0,480*dpix,350*dpiy,#PB_Ignore,#PB_Ignore)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #WM_MOUSEMOVE
      If OSVersion() >= #PB_OS_Windows_8 Or (OSVersion() < #PB_OS_Windows_8 And Theme = 1)
        If IsMouseOver(GadgetID(12))
          SetGadgetColor(12,#PB_Gadget_BackColor,$5959E5)
        Else
          SetGadgetColor(12,#PB_Gadget_BackColor,$1F1FCC)
        EndIf
        If IsMouseOver(GadgetID(11))
          SetGadgetColor(11,#PB_Gadget_BackColor,$FE5451)
          SetGadgetColor(11,#PB_Gadget_FrontColor,#White)
        Else
          SetGadgetColor(11,#PB_Gadget_BackColor,Color)
          SetGadgetColor(11,#PB_Gadget_FrontColor,#Black)
        EndIf 
        If IsMouseOver(GadgetID(10))
          SetGadgetColor(10,#PB_Gadget_BackColor,$FE5451)
          SetGadgetColor(10,#PB_Gadget_FrontColor,#White)
        Else
          SetGadgetColor(10,#PB_Gadget_BackColor,Color)
          SetGadgetColor(10,#PB_Gadget_FrontColor,#Black)
        EndIf
      EndIf
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 10
          SetWindowState(0,#PB_Window_Minimize)
          SetGadgetColor(10,#PB_Gadget_BackColor,Color)
          SetGadgetColor(10,#PB_Gadget_FrontColor,Color ! $FFFFFF) 
          
        Case 11;DialogGadget(Dialog.i, "but2")
          Run ! 1
          If Run = 1                                                                    
            SystemParametersInfo_(#SPI_GETWORKAREA, 0, r.RECT, 0)
            SetWindowState(0,#PB_Window_Maximize)                                           
            MoveWindow_(WindowID(0),r\left-4,r\top-4,r\right-r\left+8,r\bottom-r\top+8,1)
            SetGadgetColor(11,#PB_Gadget_BackColor,Color)
            If Theme = 1
              SetGadgetColor(11,#PB_Gadget_FrontColor,0)
            Else
              SetGadgetColor(11,#PB_Gadget_FrontColor,Color ! $FFFFFF)
            EndIf
            SetGadgetText(11,Chr($32))
          Else
            SetWindowState(0,#PB_Window_Normal)
            SetGadgetColor(11,#PB_Gadget_BackColor,Color)
            If Theme = 1
              SetGadgetColor(11,#PB_Gadget_FrontColor,0)
            Else
              SetGadgetColor(11,#PB_Gadget_FrontColor,Color ! $FFFFFF)
            EndIf
            SetGadgetText(11,Chr($31))
          EndIf
          
        Case 12
          Quit = 1
          
      EndSelect
      
  EndSelect
Until Quit = 1 Or GetAsyncKeyState_(#VK_ESCAPE) & $8000 = 32768

Egypt my love
Olli
Addict
Addict
Posts: 1198
Joined: Wed May 27, 2020 12:26 pm

Re: Most up-to-date alternative UI libraryfor Windows

Post by Olli »

Olli
Addict
Addict
Posts: 1198
Joined: Wed May 27, 2020 12:26 pm

Re: Most up-to-date alternative UI libraryfor Windows

Post by Olli »

So, what Rashad did, it is for Windows OS and the standard gadget set of pureBasic.

But if there is not only the flat design you are searching to work, but the graphic interface to draw as you exactly want to imagine (pixel by pixel if needed), here is an other approach, an other example (hoping the dpi will be good...) where there are no gadget anymore, and you have everything to build :

Code: Select all

Structure main
    *screen
EndStructure

Structure screen
    *root
    win.i
    Name.s
    Fgs.i
    iW.i
    iH.i
    
    *sp[4096]
    *spX[4096]
    *spY[4096]
    *spGroup[4096]
    
    mouseOn.i
    activeGroup.i
EndStructure

Macro new(pointor, struc)
    pointor.struc = AllocateMemory(SizeOf(struc) )
    InitializeStructure(pointor, struc)
EndMacro

Procedure over(mx, my, x, y, w, h)
    If mx => x
        If my => y
            If mx < x + w
                If  my < y + h                    
                    ProcedureReturn 1
                EndIf
            EndIf
        EndIf
    EndIf    
EndProcedure 

Procedure menuSync()
    Protected win = EventWindow()
    Protected *this.screen = GetWindowData(win)
    With *this
        If \mouseOn > -1
            If \activeGroup = \mouseOn
                \activeGroup = 0
            Else
                \activeGroup = \mouseOn
            EndIf            
            ;Debug \activeGroup
        EndIf
    EndWith
    
EndProcedure

Procedure screenSync()
    Static x, y
    Protected win = EventWindow()
    Protected *this.screen = GetWindowData(win)
    With *this
        ClearScreen(0)
        \mouseOn = -1
        For i = 1 To 4095
            If IsSprite(\sp[i] )
                mx = WindowMouseX(win)
                my = WindowMouseY(win)
                over = 0
                If over(mx, my, \spX[i], \spY[i], SpriteWidth(\sp[i] ), SpriteHeight(\sp[i] ) )
                    SpriteBlendingMode(1, 0)
                    over = 1
                Else
                    SpriteBlendingMode(#PB_Sprite_BlendSourceColor, #PB_Sprite_BlendInvertSourceColor)
                EndIf
                If \spGroup[i] = \activeGroup Or \spGroup[i] = 0
                    If over
                        \mouseOn = i
                    EndIf
                    DisplayTransparentSprite(\sp[i], \spX[i], \spY[i] )
                EndIf
            EndIf
        Next
        FlipBuffers()
    EndWith
EndProcedure

Procedure screenOpen(*root)
    new(*this, screen)
    With *this
        \root = *root
        \Fgs = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered
        \Fgs | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
        \win = OpenWindow(#PB_Any, 0, 0, 400, 300, \Name, \Fgs)
        ExamineDesktops()
        \iW = DesktopWidth(0)
        \iH = DesktopHeight(0)
        InitSprite()
        OpenWindowedScreen(WindowID(\win), 0, 0, \iW, \iH)
        AddWindowTimer(\win, 'GT', 16)
        SetWindowData(\win, *this)
        BindEvent(#PB_Event_Timer, @screenSync(), \win)
        BindEvent(#PB_Event_LeftClick, @menuSync(), \win)
    EndWith    
    ProcedureReturn *this
EndProcedure

Procedure centerText(x, y, w, h, text.s, color1.i, color0.i)
    Protected tW = TextWidth(text)
    Protected tH = TextHeight(text)
    DrawText((w - tW) / 2 + 1, (h  - tH) / 2 + 1, text, color1, color0)
EndProcedure

Global content.s, contentIndex.i, contentTerminated.i

Procedure setContent(ctn.s)
    content = ctn
    contentIndex = 1
    contentTerminated = 0
EndProcedure

Procedure.s ctn()
    Protected result.s = StringField(content, contentIndex, ";")
    contentIndex + 1
    If contentIndex > (CountString(content, ";") + 1)
        contentTerminated = 1
    EndIf
    ProcedureReturn result
EndProcedure

Procedure colour()
    Protected a.i = Val("$" + ctn() )
    Protected r = RGBA((a >> 6 & 3) * 85, (a >> 4 & 3) * 85, (a >> 2 & 3) * 85, (a & 3) * 85)
    ProcedureReturn r
EndProcedure


Procedure spriteDraw(ctn.s)
    Protected sw, sh
    Protected.d x, y, w = 1, h = 1
    Protected  i.i, op.s
    setContent(ctn)
    sw = Val(ctn() )
    sh = Val(ctn() )
    Protected sp = CreateSprite(#PB_Any, sw, sh)
    x * sw
    y * sh
    w * sw
    h * sh
    StartDrawing(SpriteOutput(sp) )
    DrawingMode(#PB_2DDrawing_AllChannels)
    Repeat
        op = ctn()
        If op = "box"
            Box(x, y, w, h, colour() )
        EndIf
        If op = "reduce"
            i = Val(ctn() )
            x + i
            y + i
            w - i - i
            h - i - i
        EndIf
        If op = "ctext"
            text.s = ctn()
            c.i = colour()
            centerText(x, y, w, h, text, c, colour() )
        EndIf
    Until contentTerminated
    StopDrawing()
    ProcedureReturn sp
EndProcedure

Procedure scButton(w, h, text.s)
    Protected r = spriteDraw(Str(w) + ";" + Str(h) + ";box;2F;reduce;2;box;00;ctext;" + text + ";BF;00")
    ProcedureReturn r
EndProcedure

Procedure scLocate(*sc.screen, i, x, y)
    *sc\spX[i] = x
    *sc\spY[i] = y
EndProcedure

Procedure scMenu(*sc.screen, group, i, x, y, w, h, menu.s, vertical = 0)
    For j = 0 To CountString(menu, ";")
        scLocate(*sc, i + j, x, y)        
        *sc\sp[i + j] = scButton(w, h, StringField(menu, j + 1, ";") )
        *sc\spGroup[i + j] = group
        If vertical
            y + h
        Else
            x + w
        EndIf
    Next
EndProcedure

Procedure main()    
    Protected *sc.screen
    new(*this, main)
    With *this
        \screen = screenOpen(*this)
        scMenu(\screen, 0, 1, 0, 0, 48, 24, "FILE;EDIT;HELP")
        scMenu(\screen, 1, 4, 0, 24, 96, 24, "NEW;OPEN;SAVE;SAVE AS;CLOSE;CLOSE ALL;MISC;QUIT", 1)
        scMenu(\screen, 4, 32, 32, 32, 96, 24, "NEW IMAGE;NEW SOUND;NEW TEXT", 1)
        scMenu(\screen, 2, 16, 48, 24, 96, 24, "CUT;COPY;PASTE;DELETE;PASTE FROM;COPY TO", 1)
        scMenu(\screen, 3, 24, 96, 24, 96, 24, "HELP;ABOUT", 1)
        Repeat
        Until WaitWindowEvent() = #PB_Event_CloseWindow
    EndWith    
EndProcedure

End main() ; good...
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: Most up-to-date alternative UI libraryfor Windows

Post by firace »

StackC wrote: Sat Jun 17, 2023 6:39 pm Hello folks,

I would like to have my Windows UI application appear in a "flat design", something like this: https://i.ytimg.com/vi/eyb7Gla-ePo/maxresdefault.jpg

Are there any existing libraries for PureBasic allowing to create these kind of UI applications for Windows?
Not a full UI framework, but for simple layouts, feel free to check out my UI library (free for personal use), if you don't need a cross-platform solution. The below UI is built using just 6 lines of code!

Note: Credits to Rashad for the rounded StringGadget!

Image
Last edited by firace on Mon Jun 19, 2023 11:33 am, edited 3 times in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Most up-to-date alternative UI libraryfor Windows

Post by RASHAD »

Hi firace
Thanks
I am not so good with HTML or JAVA but I belief that it can be done with one of these and can be executed with PB WebGadget() :wink:
Egypt my love
StackC
New User
New User
Posts: 8
Joined: Sat Jun 17, 2023 6:35 pm

Re: Most up-to-date alternative UI libraryfor Windows

Post by StackC »

Thanks guys for your answers.

@firace: looks nice. Actually, I do not need a lot widgets. Just the following:
* Button
* Inout box (StringGadget)
* Checkbox
* Radio button
* Progressbar

Is your UI library DPI-aware and fully unicode-compliant? I would be glad to play around with your lib.
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: Most up-to-date alternative UI libraryfor Windows

Post by firace »

StackC wrote: Mon Jun 19, 2023 4:02 pm Thanks guys for your answers.

@firace: looks nice. Actually, I do not need a lot widgets. Just the following:
* Button
* Inout box (StringGadget)
* Checkbox
* Radio button
* Progressbar

Is your UI library DPI-aware and fully unicode-compliant? I would be glad to play around with your lib.

In its current version, the library has the following primary components:
ModernWindowML (with custom title bar)
StringGadgetML
ButtonGadgetML
TextGadgetML
SideMenuML

So some of your requirements are not currently satisfied, but it is possible to use any of the built-in PureBasic gadgets (such as CheckboxGadget, OptionGadget or ProgressbarGadget) together with the above components. However note that some of those gadgets require non-trivial API hacks to customize their colors.

DPI awareness is on the roadmap (shouldn't be too hard to implement), and regarding Unicode,
the library should be just as compliant as PureBasic.
User avatar
mk-soft
Always Here
Always Here
Posts: 6204
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Most up-to-date alternative UI libraryfor Windows

Post by mk-soft »

So times with the standard gadget (comctl32).
Of course, you can do better with a little more effort

Code: Select all

;- TOP

#DWMWA_USE_IMMERSIVE_DARK_MODE = 20
Prototype DwmSetWindowAttribute(hwnd.i, dwAttribute.l, *pvAttribute, cbAttribute.l)
Global DwmSetWindowAttribute.DwmSetWindowAttribute  

; ----

Procedure InitDwnAPI()
  Protected lib
  lib = OpenLibrary(#PB_Any, "dwmapi")  
  If lib
    DwmSetWindowAttribute = GetFunction(lib, "DwmSetWindowAttribute")
  EndIf
  ProcedureReturn lib
EndProcedure : InitDwnAPI()

Procedure SetTitleDarkMode(Window, State)
  If DwmSetWindowAttribute
    DwmSetWindowAttribute(WindowID(Window), #DWMWA_USE_IMMERSIVE_DARK_MODE, @State, SizeOf(State))
  EndIf
EndProcedure

; ********

;-Window

#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  #MainMenuAbout
  #MainMenuExit
EndEnumeration

Enumeration Gadgets
  #MainStringFirstName
  #MainStringLastName
  #MainButtonOk
EndEnumeration

#FirstGadget = #MainStringFirstName
#LastGadget = #MainButtonOk

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

; ----

Global FrontColor = $F0FAFF
Global BackColor = $242424

Global ButtonFont = LoadFont(#PB_Any, "", 13)
Global TextFont = LoadFont(#PB_Any, "", 15)

Procedure ButtonColorGadget(Gadget, x, y, Width, Height, Text.s, FrontColor = $F0F0F0, BackColor = $404040)
  Protected id, image, dx, dy
  image = CreateImage(#PB_Any, Width, Height, 32, BackColor)
  If StartDrawing(ImageOutput(image))
    dx = TextWidth(Text)
    dy = TextHeight(Text)
    DrawingFont(FontID(ButtonFont))
    DrawText(Width / 2 - dx / 2, Height / 2 - dy / 2, Text, FrontColor, BackColor)
  EndIf
  id = ButtonImageGadget(Gadget, x, y, Width, Height, ImageID(image), Flags)
  FreeImage(image)
  ProcedureReturn id
EndProcedure

; ----

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) ; - MenuHeight() - StatusBarHeight(#MainStatusBar)
  ; Resize gadgets
EndProcedure

Procedure Main()
  Protected dx, dy, i
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 580, 400, #ProgramTitle , #MainStyle | #PB_Window_Invisible)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) ; - MenuHeight() - StatusBarHeight(#MainStatusBar)
    SetGadgetFont(#PB_Default, FontID(TextFont))
    StringGadget(#MainStringFirstName, 40, 40, 240, 35, "FirstName")
    StringGadget(#MainStringLastName, 300, 40, 240, 35, "LastName")
    ButtonColorGadget(#MainButtonOk, 40, 100, 500, 40, "Sign In", FrontColor, $71B33C)
    
    
    ; Colors
    For i = #FirstGadget To #LastGadget
      SetGadgetColor(i, #PB_Gadget_FrontColor, FrontColor)
      SetGadgetColor(i, #PB_Gadget_BackColor, BackColor)
    Next
    
    SetTitleDarkMode(#Main, #True)
    SetWindowColor(0, BackColor)
    
    HideWindow(#Main, #False)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    ; Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              Break
              
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
            
          Case #MainMenuAbout
            MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
              
          Case #MainMenuExit
            PostEvent(#PB_Event_CloseWindow, #Main, #Null)
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply