Page 3 of 13

Re: Users complain boring user interface of my apps

Posted: Thu Aug 02, 2018 3:01 pm
by wombats
Qt is dual-licensed under a commercial licence and the LGPL. You can sell your program under the LGPL licence.

There is also the Qt Start-Up Plan that may suit your needs.

With the LGPL licence, we have to provide access to the Qt source code used by our program, including any modifications made to it. Does PureBasic use it without modifications? It would be helpful to know exactly which version is used so we can provide access to the right source code.

Re: Users complain boring user interface of my apps

Posted: Thu Aug 02, 2018 3:02 pm
by Kukulkan
Since 2009, QT is dual licensed with optional LGPL license. But you have to be careful, especially if you statically link QT.

@Fred: Maybe you contact QT first to make sure that everything is okay? I'm sure they will help. https://www1.qt.io/contact-us/?hsLang=en

Re: Users complain boring user interface of my apps

Posted: Thu Aug 02, 2018 3:04 pm
by wombats
Kukulkan wrote:Since 2009, QT is dual licensed with optional LGPL license. But you have to be careful, especially if you statically link QT.

@Fred: Maybe you contact QT first to make sure that everything is okay? I'm sure they will help. https://www1.qt.io/contact-us/?hsLang=en
freak stated here that it is not statically linked.

Re: Users complain boring user interface of my apps

Posted: Thu Aug 02, 2018 4:07 pm
by Kuron
the.weavster wrote:Another alternative might be making GTK3 a target on every platform.

It supports themes (including flat ones):

Then we could use Glade as the visual UI designer and have a grid with cell level styling and events.

There's lots of good stuff in the Gnome libraries, like libsoup for http clients and servers which is another weak point for PB. As long as deployment is as simple as having the required *.dll files in a libs subfolder I don't really see it as a break from PB's ethos of being self contained.
Wow, very nice.

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 12:41 am
by Michael Vogel
I would think about doing the stuff with purebasic canvas elements which is not very difficult (but homebrew dialogs with many elements are visible slower compared to standard dialogs):

Here's an old example managing simple buttons, you may test the result by downloading a windows tool for creating an image collection (to keep holiday pictures on your phone, etc.)

Just click on the setting icon (top right) or Alt+O and click on the topmost button to change the design (also play around with shift or ctrl when clicking on the button). It wouldn't be a big deal to hide the border of the buttons and do on/off toggle switches as shown in your initial example...

Image

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 4:15 am
by Kuron
My worry... Whether using Sciter, or rolling your own solution, a Metro GUI clone would be right at home on Windows. Unfortunately, on Linux and macOS, the complaints the OP was getting would possibly still be there since on these platforms, people may not be used to the Metro look.

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 4:39 am
by Bitblazer
Kuron wrote:My worry... Whether using Sciter, or rolling your own solution, a Metro GUI clone would be right at home on Windows. Unfortunately, on Linux and macOS, the complaints the OP was getting would possibly still be there since on these platforms, people may not be used to the Metro look.
Plus all people who switched back to windows 7 to avoid that ineffective marketing nonsense called Metro. Skinning solutions always create these kind of problems :s

Some people will be happy, others will hate them. Try to make them at least optional!

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 5:06 am
by wilbert
Kuron wrote:My worry... Whether using Sciter, or rolling your own solution, a Metro GUI clone would be right at home on Windows. Unfortunately, on Linux and macOS, the complaints the OP was getting would possibly still be there since on these platforms, people may not be used to the Metro look.
You are right.
I use MacOS as primary OS and wouldn't want an application to look like a Metro app.
Not only because it is inconsistent with other apps on MacOS; I just don't like the style Windows 10 uses.
If something needs to look different, I would prefer a Google Material Design look over Windows 10 Metro.

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 7:01 am
by idle
In some cases an html gui is ideal but an embedded browser still provides more utility
in the case of native browsers it's just a case of using them carefully but that can be done
using jquery based frameworks or good html5 templates.
or you can just forget about the native webgadget and serve the users browser.

If Fred's game to add sciter, it'll be a great addition.
though I'd prefer to see the webgadgets extended from the webview lib to add cross platform support
for two way calls pb to js and js to pb, then you can use it to better effect as a UI

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 2:04 pm
by DK_PETER
True...The current pb gui is a bit a'hmm, outdated.
Here's a positive feedback concerning Windows 10, though.
I truly LOVE the Metro look and enjoy everything about Windows 10.
It is one of THE best windows versions to date and I wouldn't
swap it with any other system on the market. Top dollar all the way..
Then again, I'm biased like most of you excellent fellas...:lol:
I've always been a pure windows guy. 8)

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 7:30 pm
by the.weavster
I've been experimenting with being able to define styles and then associating those styles with CanvasGadget() derived containers and buttons.
It's been fun and I've even found another way I quite like of binding callbacks to widgets.

Code: Select all

Prototype GadgetEventHandler(nGadget,nEventType)
Prototype WindowEventHandler(nWindow)

Structure AppGadget
  id.i
  parent.i
  style.s
  text.s
  isNumeric.i
  decimalPlaces.i
  allowNegatives.i
  onEvent.GadgetEventHandler
EndStructure

Structure AppWindow
  id.i
  parent.i
  style.s
  isModal.i
  onClose.WindowEventHandler
  onSize.WindowEventHandler
EndStructure

Structure WidgetStyle
  id.s
  BackColor.i
  ForeColor.i
  BorderColor.i
  BorderWidth.i
  FontID.i
EndStructure

Global NewMap appFonts.i()
Global NewMap *appGadgets.AppGadget()
Global NewMap *appWindows.AppWindow()
Global NewMap *widgetStyles.WidgetStyle()

Procedure BindGadgetCallback(gadgetID,*callback)
  *appGadgets(Str(gadgetID))\onEvent = *callback
EndProcedure

Procedure BindWindowCallback(winID,*callback,eType)
  Select eType
    Case #PB_Event_CloseWindow
      *appWindows(Str(winID))\onClose = *callback
    Case #PB_Event_SizeWindow
      *appWindows(Str(winID))\onSize = *callback
  EndSelect
EndProcedure

Procedure RegisterGadget(gdtID,winID,style.s,txt.s="")
  *g.AppGadget = AllocateStructure(AppGadget)
  *g\id = gdtID
  *g\parent = winID
  *g\style = style
  *g\text = txt
  *g\isNumeric = #False
  *g\decimalPlaces = 0
  *g\allowNegatives = #False
  key$ = Str(gdtID)
  *appGadgets(key$) = *g
EndProcedure

Procedure RegisterWindow(winID,style.s,winModal=#False,parent=-1)
  *w.AppWindow = AllocateStructure(AppWindow)
  *w\id = winID
  *w\style = style
  *w\parent = parent
  *w\isModal = winModal
  key$ = Str(winID)
  *appWindows(key$) = *w
EndProcedure

Procedure Style_Font_New(id.s,fontname.s,fontsize,flags=#Null)
  nRes = LoadFont(#PB_Any,fontname,fontsize,flags)
  If nRes
    appFonts(id) = FontID(nRes)
  Else
    Debug "failed to load font"
  EndIf
EndProcedure

Procedure Style_New(stylename.s)
  *s.WidgetStyle = AllocateStructure(WidgetStyle)
  *s\id = stylename
  *s\FontID = appFonts("default")
  *s\BackColor = RGB(57,92,198)
  *s\ForeColor = RGB(255,255,255)
  *s\BorderColor = RGB(0,0,255)
  *s\BorderWidth = 2
  *widgetStyles(stylename) = *s
EndProcedure

Procedure.i Style_GetById(stylename.s)
  If FindMapElement(*widgetStyles(),stylename)
    ProcedureReturn *widgetStyles(stylename)
  Else
    ProcedureReturn *widgetStyles("default")
  EndIf
EndProcedure

Procedure.i Window_New(x,y,width,height,caption$,windowFlags=#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered,
                       stylename.s="default",winModal=#False,winParent=-1)
  *s.WidgetStyle = Style_GetById(stylename)
  window = OpenWindow(#PB_Any,x,y,width,height,caption$,windowFlags)
  SetWindowColor(window,*s\BackColor)
  RegisterWindow(window,stylename)
  ProcedureReturn window
EndProcedure

Procedure CanvasButton_Redraw(btn)
  x = GadgetX(btn) : y = GadgetY(btn)
  width = GadgetWidth(btn) : height = GadgetHeight(btn)
  caption$ = *appGadgets(Str(btn))\text
  *sg.WidgetStyle = Style_GetById(*appGadgets(Str(btn))\style)
  SetGadgetFont(btn,*sg\FontID)
  StartDrawing(CanvasOutput(btn))
  DrawingFont(*sg\FontID)
  Box(0,0,width,height,*sg\BorderColor)
  nL = width - (*sg\BorderWidth * 2)
  nT = height - (*sg\BorderWidth * 2)
  Box(*sg\BorderWidth,*sg\BorderWidth,nL,nT,*sg\BackColor)
  nL = (width - TextWidth(caption$)) / 2
  nT = (height - TextHeight(caption$)) / 2  
  DrawText(nL,nT,caption$,*sg\ForeColor,*sg\BackColor)
  StopDrawing()  
EndProcedure

Procedure.s CanvasButton_GetText(btn)
  ProcedureReturn *appGadgets(Str(btn))\text
EndProcedure

Procedure CanvasButton_SetText(btn,txt.s)
  *appGadgets(Str(btn))\text = txt
  CanvasButton_Redraw(btn)
EndProcedure

Procedure CanvasButton_New(parentID,x,y,width,height,caption$,style.s="default")
  *sg.WidgetStyle = Style_GetById(style)
  btn = CanvasGadget(#PB_Any,x,y,width,height)
  RegisterGadget(btn,parentID,style,caption$)
  CanvasButton_Redraw(btn)
  ProcedureReturn btn
EndProcedure

Procedure CanvasButton_ChangeStyle(btn,style.s)
  *appGadgets(Str(btn))\style = style
  CanvasButton_Redraw(btn)
EndProcedure

Procedure CanvasContainer_Redraw(ctr)
  x = GadgetX(ctr) : y = GadgetY(ctr)
  width = GadgetWidth(ctr)
  height = GadgetHeight(ctr)
  style.s = *appGadgets(Str(ctr))\style
  StartDrawing(CanvasOutput(ctr))
  Box(0,0,width,height,*widgetStyles(style)\BorderColor)
  nW = width - (*widgetStyles(style)\BorderWidth * 2)
  nH = height - (*widgetStyles(style)\BorderWidth * 2)
  Box(*widgetStyles(style)\BorderWidth,*widgetStyles(style)\BorderWidth,nW,nH,*widgetStyles(style)\BackColor)
  StopDrawing()   
EndProcedure

Procedure CanvasContainer_ChangeStyle(ctr,style.s)
  *appGadgets(Str(ctr))\style = style
  CanvasContainer_Redraw(ctr)
EndProcedure

Procedure CanvasContainer_New(parentID,x,y,width,height,style.s="default")
  container = CanvasGadget(#PB_Any,x,y,width,height,#PB_Canvas_Container)
  RegisterGadget(container,parentID,style)
  CanvasContainer_Redraw(container)
  ProcedureReturn container
EndProcedure

Procedure Gadget_Events()
  nGadget = EventGadget()
  nType = EventType()
  If FindMapElement(*appGadgets(),Str(nGadget))
    If *appGadgets(Str(nGadget))\onEvent <> #Null
      *appGadgets(Str(nGadget))\onEvent(nGadget,nType)
    EndIf
  EndIf
EndProcedure

Procedure Window_EventClose()
  nWindow = EventWindow()
  If FindMapElement(*appWindows(),Str(nWindow))
    If *appWindows(Str(nWindow))\onClose <> #Null
      *appWindows(Str(nWindow))\onClose(nWindow)
    EndIf
  EndIf  
EndProcedure

Procedure Window_EventSize()
  nWindow = EventWindow()
  If FindMapElement(*appWindows(),Str(nWindow))
    If *appWindows(Str(nWindow))\onSize <> #Null
      *appWindows(Str(nWindow))\onSize(nWindow)
    EndIf
  EndIf  
EndProcedure

BindEvent(#PB_Event_Gadget,@Gadget_Events())
BindEvent(#PB_Event_CloseWindow,@Window_EventClose())
BindEvent(#PB_Event_SizeWindow,@Window_EventSize())

Global frmMain, frmMain_btnClick, frmMain_btnDanger
Global frmMain_ctrLeft, frmMain_ctrRight, frmMain_btnModel

Procedure frmMain_onClose(nWindow)
  End
EndProcedure

Procedure frmMain_onSize(nWindow)
  nW = WindowWidth(nWindow)
  nH = WindowHeight(nWindow)
  SetWindowTitle(nWindow,"Demo (" + Str(nW) + " x " + Str(nH) + ")")
  ResizeGadget(frmMain_ctrLeft,#PB_Ignore,#PB_Ignore,250,nH)
  ResizeGadget(frmMain_ctrRight,#PB_Ignore,#PB_Ignore,nW-250,nH)
  nW = GadgetWidth(frmMain_ctrRight)
  nH = GadgetHeight(frmMain_ctrRight)
  ResizeGadget(frmMain_btnClick,nW-155,nH-50,#PB_Ignore,#PB_Ignore)
  ResizeGadget(frmMain_btnDanger,nW-305,nH-50,#PB_Ignore,#PB_Ignore)
EndProcedure

Procedure frmMain_btnClick_onEvent(nGadget,nType)
  If nType = #PB_EventType_LeftClick
    MessageRequester("Good","Warm Fuzzies  :-)",0)
  EndIf
EndProcedure

Procedure frmMain_btnDanger_onEvent(nGadget,nType)
  If nType = #PB_EventType_LeftClick
    If *appGadgets(Str(frmMain_btnClick))\style = "default"
      *appGadgets(Str(frmMain_btnClick))\style = "danger"
      CanvasContainer_ChangeStyle(frmMain_ctrLeft,"ooglies")
      CanvasContainer_ChangeStyle(frmMain_ctrRight,"doodah")
    Else
      *appGadgets(Str(frmMain_btnClick))\style = "default"
      CanvasContainer_ChangeStyle(frmMain_ctrLeft,"doodah")
      CanvasContainer_ChangeStyle(frmMain_ctrRight,"ooglies")
    EndIf
    CanvasButton_SetText(frmMain_btnClick,*appGadgets(Str(frmMain_btnClick))\style)
  EndIf
EndProcedure

Procedure frmMain_ctrLeft_onEvent(nGadget,nType)
  If nType = #PB_EventType_Resize
    CanvasContainer_Redraw(nGadget)
  EndIf
EndProcedure

Procedure frmMain_ctrRight_onEvent(nGadget,nType)
  If nType = #PB_EventType_Resize
    CanvasContainer_Redraw(nGadget)
  EndIf
EndProcedure

Procedure frmMain_Open()
  frmMain = Window_New(10,10,1000,600,"Demo")
  frmMain_ctrLeft = CanvasContainer_New(frmMain,0,0,250,600,"doodah")
  CloseGadgetList()
  frmMain_ctrRight = CanvasContainer_New(frmMain,250,0,750,600,"ooglies")
  frmMain_btnDanger = CanvasButton_New(frmMain,445,550,140,35,"Change","danger")
  frmMain_btnClick = CanvasButton_New(frmMain,595,550,140,35,"Nice")
  CloseGadgetList()
  
  BindWindowCallback(frmMain,@frmMain_onClose(),#PB_Event_CloseWindow)
  BindWindowCallback(frmMain,@frmMain_onSize(),#PB_Event_SizeWindow)
  BindGadgetCallback(frmMain_ctrLeft,@frmMain_ctrLeft_onEvent())
  BindGadgetCallback(frmMain_ctrRight,@frmMain_ctrRight_onEvent())
  BindGadgetCallback(frmMain_btnClick,@frmMain_btnClick_onEvent())
  BindGadgetCallback(frmMain_btnDanger,@frmMain_btnDanger_onEvent())
EndProcedure

Style_Font_New("default","Arial",12,#PB_Font_Bold)
Style_New("default")

Style_Font_New("danger","Arial",12,#PB_Font_Bold)
Style_New("danger")
*widgetStyles("danger")\BackColor = RGB(38,0,93)
*widgetStyles("danger")\BorderColor = RGB(84,39,136)
*widgetStyles("danger")\FontID = appFonts("danger")

Style_New("doodah")
*widgetStyles("doodah")\BackColor = RGB(69,117,180)
*widgetStyles("doodah")\BorderColor = RGB(255,255,255)
*widgetStyles("doodah")\BorderWidth = 2
*widgetStyles("doodah")\FontID = appFonts("danger")

Style_New("ooglies")
*widgetStyles("ooglies")\BackColor = RGB(255,255,255)
*widgetStyles("ooglies")\BorderColor = RGB(255,255,255)
*widgetStyles("ooglies")\BorderWidth = 2
*widgetStyles("ooglies")\FontID = appFonts("danger")

frmMain_Open()

Repeat
  WEvent = WaitWindowEvent()
ForEver
CanvasGadget() is very versatile.

Re: Users complain boring user interface of my apps

Posted: Fri Aug 03, 2018 10:36 pm
by Zebuddi123
@the.weavster Excellent :) I`ll be playing with this for hours and hours. Lots of possibilities

Thanks for Sharing

Zebuddi. :)

Image

Re: Users complain boring user interface of my apps

Posted: Sat Aug 04, 2018 9:12 am
by Lord
Zebuddi123 wrote:@the.weavster Excellent :) I`ll be playing with this for hours and hours. Lots of possibilities

Thanks for Sharing

Zebuddi. :)

Image
Just ugly!

Re: Users complain boring user interface of my apps

Posted: Sat Aug 04, 2018 9:14 am
by the.weavster
Glad you like it, Zebudd1123 :D

I've now tweaked it so you can assign a different style to an existing gadget on the fly and the canvas button now has gettext and settext

Re: Users complain boring user interface of my apps

Posted: Sat Aug 04, 2018 10:31 am
by chi
the.weavster wrote:CanvasGadget() is very versatile.
But unfortunately not DPI-Aware, which is a No-Go these days...