Users complain boring user interface of my apps

Everything else that doesn't fall into one of the other PB categories.
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Users complain boring user interface of my apps

Post 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.
User avatar
Kukulkan
Addict
Addict
Posts: 1352
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Users complain boring user interface of my apps

Post 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
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Users complain boring user interface of my apps

Post 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.
User avatar
Kuron
Addict
Addict
Posts: 1626
Joined: Sat Oct 17, 2009 10:51 pm
Location: Pacific Northwest

Re: Users complain boring user interface of my apps

Post 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.
Best wishes to the PB community. Thank you for the memories. ♥️
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Users complain boring user interface of my apps

Post 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
User avatar
Kuron
Addict
Addict
Posts: 1626
Joined: Sat Oct 17, 2009 10:51 pm
Location: Pacific Northwest

Re: Users complain boring user interface of my apps

Post 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.
Best wishes to the PB community. Thank you for the memories. ♥️
Bitblazer
Enthusiast
Enthusiast
Posts: 733
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Users complain boring user interface of my apps

Post 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!
webpage - discord chat links -> purebasic GPT4All
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Users complain boring user interface of my apps

Post 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.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Users complain boring user interface of my apps

Post 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
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Users complain boring user interface of my apps

Post 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)
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
User avatar
the.weavster
Addict
Addict
Posts: 1536
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: Users complain boring user interface of my apps

Post 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.
Last edited by the.weavster on Sat Aug 04, 2018 10:56 am, edited 2 times in total.
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 794
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: Users complain boring user interface of my apps

Post by Zebuddi123 »

@the.weavster Excellent :) I`ll be playing with this for hours and hours. Lots of possibilities

Thanks for Sharing

Zebuddi. :)

Image
malleo, caput, bang. Ego, comprehendunt in tempore
User avatar
Lord
Addict
Addict
Posts: 847
Joined: Tue May 26, 2009 2:11 pm

Re: Users complain boring user interface of my apps

Post 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!
Image
User avatar
the.weavster
Addict
Addict
Posts: 1536
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: Users complain boring user interface of my apps

Post 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
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Users complain boring user interface of my apps

Post by chi »

the.weavster wrote:CanvasGadget() is very versatile.
But unfortunately not DPI-Aware, which is a No-Go these days...
Et cetera is my worst enemy
Post Reply