Photon Micro GUI
cycfi.com
cycfi.com
I don’t actually know what the best cross-platform solution is. Is wxWidgets fully functional in a context where it doesn’t own the event loop? I suspect not on Windows in particular. Yes, yes, I know it’s ugly 90s C++, but really, what’s more important, code aesthetics or usability?
Likewise, accessibility capabilities rely on very standard generic UI capabilities. Once you go beyond that with professional tooling, accessibility will have to be custom as well.
Real time scrubbing and mixing with...a screen reader...how does that even work? I’m sure it could work, but you would still wind up with something as custom as seen here, perhaps even more so. Accessibility isn’t a free lunch except in very generic limited use contexts.
> but really, what’s more important, code aesthetics or usability?
Well, if you want software developers to write using it, code aesthetics is pretty important. Code aesthetics is usability to software developers. End-user usability does tend to trump code aesthetics if you want to get money out of the software you write, but even then, code aesthetics is still a consideration.
Um, I have normal but aging sight, and I still can't get a DAW that actually scales its widget to something other than 200% (or 150% if I'm reaaaaally lucky).
I have no GUI that renders at useful speeds using OpenGL or Vulkan.
The Photon author didn't just create this to be contrary. Modern OS GUIs don't work very well for things like DAWs because DAWs often operate much more like a game wherein the screen is animated and has 60fps of stuff going on.
Rather than complaining, write us all an open source GUI that doesn't suck and people will happily use that and then people will write the accessibility hooks for it.
First of all, I doubt that writing yet another toolkit of my own would be the solution. How could I know that anyone would adopt it? And as for spending time contributing to an existing toolkit, which toolkit? I read about several per year here on HN. That's why I've been pleading with developers to use platform widgets, or cross-platform toolkits that wrap those widgets (like wxWidgets), wherever I can. But the replies on this thread have convinced me that sometimes, the platform widgets really do leave a lot to be desired. So, I don't know what to do instead.
You don't. But if it's better, people will actually use it. This is currently a glaring hole in the software development landscape screaming for a better solution.
I'm currently in a similar boat as the Photon author and I have a much more prosaic application. But I have a lot of interaction with OpenGL and the GUI system, and none of the GUI toolkits like that.
Photon is simply doing the same thing that GTK did originally--GTK was written specifically for the GIMP and only later did it become general purpose.
> And as for spending time contributing to an existing toolkit, which toolkit?
That's your choice to make. And your efforts help make those decisions. The toolkit that attracts motivated people and improves starts gaining momentum and attracts more people. Even a single motivated individual can tip the balance when things are unsettled.
Unfortunately, this is not a well-trod and settled area. Part of being on the bleeding edge is that you get cut.
This is puzzling to me. Do sighted DAW users really rely on such a high-bandwidth, continuous flow of visual information? What kind of information? Mainly volume meters, or other things as well?
FWIW, I'm just starting to dabble with a DAW myself. But I know that blind people have successfully done all stages of music and other audio production using a DAW. From what I understand, they do it by concentrating solely on the audio itself during real-time playback and recording. But the UI does need to be accessible for non-real-time work, e.g. plugin configuration, switching tracks, switching instruments, or making precise edits.
Yes. Volume meters, equalizers, beat counters, loop counters, etc. I can go on and on.
There is a reason why people use specific DAWs for specific purposes (Hip-hop guys seem to gravitate to Ableton Live, for example).
Having said that, hey, this is Open Source! Like Reaper, I am willing to support accessibility if you, or anyone else is willing to do the extra effort.
It's possible that blind DAW users have just gotten tired of trying to advocate for accessibility in plugins. I thought I had a chance on this thread, since I would potentially be reaching several developers, including future plugin developers who haven't yet chosen a toolkit, instead of having to write to one at a time.
My guess is that the answer to this is similar to "what is more important, developer friendliness or minding resource use for users with less capable computers?" that gave rise to Electron.
And i'll also bet that there are way more users that have low end computers than users who rely on OS-supplied usability features.
He needs to take the controls people know and understand and replace them with cryptic methods that require new learning, and are hidden from view by default. Otherwise no one will take it seriously as a modern UI.
Gestures?
But another advantage of knobs is the ability to turn them, quickly and yet accurately, with thumb and first finger. Some even have push-pull gear reduction, to go between fast and accurate.
So you'd think that a GUI knob would use some analogous two-finger twisting gesture. With thumb and first finger.
Skeuomorphism worshippers have a lot of nerve to complain about abstract GUI philosophies when their own cult hasn't eradicated these design atrocities. Gosh, it sure looks pretty though...
From my own experience, knobs are far superior to sliders in audio applications, as all the adjustments are typically guided by hearing, and sliders' values can jump if you click in a wrong place. This just disturbs the flow. Most of the work with audio software UI is fine tuning parameters, often by a few percent, so relativistic nature of click-drag is perfect for this. Sure, there're relativistic sliders, but they feel rather unintuitive.
http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic=%2F...
And kudos to you being willing to change it now that you know. It probably only really affects old OS and embedded nerds like me, and as an amateur musician I do find your project interesting, but I have to admit I got my hopes up that QNX Photon had finally been open sourced, or at least brought up to modern standards with a new release.
That means it should render nicely at any resolution, the author says, "resolution independent and allows for HDPI displays".
But using Cairo means it should not have a good performance at high resolutions. I have yet to find a fork of Cairo GPU accelerated that supports all the API. So it may fit the bill if you are coding a simple interface, but it will be too slow to render at 60FPS and at high resolution.
What comes closest for me is Dear ImGui, but I never saw an interface with those nicely rendered buttons in real-time done with Dear ImGui.
I'm trying to follow all thr efforts in native desktop GUI tools and am currently using Dear ImGui for something which will only be used internally.
It looks like you still need to roll your own.
I am currently working with Dear ImGui and found a pipeline where I put SVG icons in a true type front and can then render them resolution independent with Dear ImGui.
(sorry English is not my first language)
This GUI looks great, too. It’d be interesting to have python bindings to it.
A long time ago I wrote a tiny audio synth. And yep, I wrote my own minimal GUI which had stuff like sliders, and most importantly knobs which general GUIs typically don't provide.
Now I'm working on a non-audio webapp, and I have a problem where a knob would be the ideal solution. Searched far and wide for a Vue knob, and what I found was not usable. It worked if you "rotated" it circularly, but it didn't work if you pulled it up/down like a slider. You might say "use a slider then if you want to pull it up/down". True, but a slider takes a lot of UI space which sometimes is very precious. More importantly, the slider resolution is limited to it's height, while a knob could for example use the whole screen height for a full turn.
Then you hit the second requirement: complete bitmap theming, many times of a skeuomorphic kind. This is extremely difficult to do in something like Gtk/Qt.
https://doc.qt.io/qt-5/qtwidgets-widgets-styles-example.html
2. See the diamond-shaped radio buttons in the second example. :)
3. 3D embossed arrows on scroll bars.
They don't provide knobs because they're a bad idea for input. Holding mousedown while drawing an invisible arc with the cursor is an awkward way to change a value. Sliders are generally better but still not great on interfaces with cursors (they're better on touchscreens). Skeuomorphism can be a useful visual design cue but it needs to be secondary to the input capabilities of the device.
Up and down arrow buttons(or plus/minus, or whatever makes sense for the value) are very compact and operable with a variety of input methods. Buttons need a way display the value but there are many options including putting them in the center of a ring of numbers like a knob would use.
I remember learning soft synths when I was 11 - 12 years old and back then it maybe took me a few minutes to get it. Come on.
I like knobs because the distance from the center of that control (radius of your arc movement) can be a “fineness” or “coarseness” control. I think sliders don’t usually offer this.
Arrow buttons are pointless when you're trying to dial in a value - which is the whole point of using knobs in audio software. They don't give you adjustable granularity or an easy way to continuously adjust - and if you do give it those functions, you've made a knob without the visual feedback of knob position. Or like you say, put it in the center of a ring of numbers, but again, you've just made a knob!
The knob behavior you're describing is essentially an invisible slider. An invisible line is better than an invisible arc but it's still not good. Why not make it visible? A visible slider could appear on mousedown so there's something that corresponds to the gesture.
In your first example, you've just made a knob that doesn't look like a knob.
In your second example, you're confusing mouse position and gesture. Linear sliders map mouse position to state changes, rotaries map gesture. Another way of looking at it is that a rotary slider's state is decoupled from the input, and in doing so, is a much more responsive control. Not to mention, you have an infinite 2D area to traverse to change the knob value with respect to the widget itself, not a finite, defined path.
And the huge reason that linear sliders (at least off the shelf ones) are impossible to use for audio UIs is that 99% of your user's time is spent adjusting from the previous position, not resetting it to a new one. That means any behavior where a click resets the position (like clicking just past the current position) is broken. Not just because it's trash UX for the application, but because in audio systems jumping parameter values can cause artifacts, and mitigating them is not without cost in performance and fidelity.
That doesn't make them intuitive, they're merely familiar to people already familiar with such audio software.
> hotkey like ctrl to swap between coarse/fine tuning of the parameters
Image editors and video editors have keys like that too, they're not related to knobs.
> In your first example, you've just made a knob that doesn't look like a knob
That's great! I preserved the functionality while making the action more apparent.
> a rotary slider's state is decoupled from the input
That's what I'm criticizing.
> Not to mention, you have an infinite 2D area to traverse to change the knob value with respect to the widget itself, not a finite, defined path.
The visual feedback of both sliders and knobs are both restricted to finite, defined paths. Whether the control of the input is restricted to that path depends on how it was designed. With some sliders, you can only move the control when the cursor remains without the bounds of the slider the iTunes volume control for example. With other sliders, once you've clicked on the control, the cursor can be outside the slider, I think this is the "infinite 2D area" you're talking about. The macOS menu bar volume and Sound Preferences sliders are examples of this latter behavior, I also found this example (you need to click the play button for the code to run).
https://editor.p5js.org/Joemckay/sketches/rk2edzTIb
> That means any behavior where a click resets the position (like clicking just past the current position) is broken
Yes, for what knobs are used for, you wouldn't want a slider control to jump to whatever point on its line was clicked on. This is another behavior that is found on some sliders (both iTunes and macOS Sound volume controls) but not others (the P5 example above).
https://soundquest.jp/files/uploads/2018/10/massivex-replica...
On a more meta level, a whole industry decided after 30 years of iterations that knobs that work like invisible sliders are the best controls, and you - who by the looks never had any extensive use of audio software - are claiming that they are all wrong, because of some philosophic argument. You might be true, you might be the rare visionary who sees a better way of doing things where other cannot, but the burden of proof is on you.
I think many music apps these days give you the option buried somewhere in settings.
That’s what I did. Made it slide by default (because I hate trying to twist a virtual knob). I briefly had a translucent rectangle popup when the control was in slider mode but it turned out not to be helpful as linear dragging seemed to make sense to everyone and I only had like eight options in total.
The one nice innovation I had was automatically detecting horizontal or vertical drags - useful for things like pan controls where a horizontal motion makes more sense.
Perhaps the solution is to make the slider pop up if you press a button?
I don't think so. It's a pretty standard exercise to try to create an ui framework so of course we're bound to see tons of them.
If they can already do it for such distinct devices as Mac, iPhone, iPad, TV and Watch, there's no reason it can' be adapted for Windows, Linux and Android as well.
This is something that should have happened 5 years ago, before Electron etc. had a chance to fill in a obviously much-needed need.
Really, why do we need anything more than "Button" to describe a button, or "List" to describe a list, on any GUI? HTML solved this a trillion years ago, it's a wonder it took so long to be wholeheartedly adopted for native UIs. I know Microsoft tried with WPF/XAML but it didn't seem to catch on.
I have always looked to things like the Calculator and Notepad as a signal of confidence; I know there’s little reason to rewrite them, but the proof of the pudding would be if Microsoft updated something as “simple” as those applets to their championed UI framework.
I know Visual Studio (and their abandoned Expression Studio) is/was built with WPF, but what’s the score in the “wild”?
No one uses MFC/ATL for greenfield applications on Windows.
When C++ comes into play, it is plugged via DLLs or COM into .NET applications (or even via C++/CX, C++/WinRT or C++/CLI).
As for pure Win32 C style, for greenfield apps, only if are feeling masochist.
Not counting 3rd party alternatives here like Qt, Delphi or C++ Builder.
What's the Windows' analogue of Swift+SwiftUI? i.e. telling someone new to the platform about what to focus on.
- How does rendering work? Is it using retained mode or not?
- Does the system prevent unnecessary work, such as repainting of certain elements (even when scrolling, since scrolling can be implemented using a less expensive bitblt)?
- How easy (natural) is it to change the UI hierarchy once it is running?
- Is memory management natural? Is there a form of garbage collection or reference counting for UI elements? How easy is it to accidentally refer to deleted UI elements?
- Does it make use of a GPU if available?
And then one of my Boost (https://www.boost.org/) peers twitted about it, and ended up being posted here.
It seems I have a lot of work to do...
[0]: https://en.wikipedia.org/wiki/Foreign_function_interface
The bigger issue is that Crystal really needs first-class Windows support before people will use it for GUIs...
[1]: https://bitbucket.org/duangle/oui-blendish/src/default/
What's interesting is that Lasarus is closest to it, but I would prefer higher level language. Is there a Tcl interpreter written in Java? Then Tcl/Tk could be also an option.
Sorry for a bit off-topic rambling, but I would love to see something like it.
Also FWIW my LIL scripting language, is sort of Tcl-like and has a Free Pascal implementation (and also a C one) with a (optional) Lazarus drag-drop component: http://runtimeterror.com/tech/lil/
I also have a Lazarus component for FPLIL for exposing a Tk-ish (well, not exactly, but on a similar spirit) API: https://i.imgur.com/G8hto0N.gif
Though that last one isn't available anywhere... perhaps i should upload it at the LIL site above. It is just that it hadn't had much testing (i mainly wrote it for my 3D world editor so that scripts can expose simple UIs on the sidebar or in dialog boxes but haven't used it much elsewhere).
EDIT: i decided to take a few minutes and upload the LILGUI stuff to the site above.
TBH i do not have much experience with Tcl itself outside of writing a few Tk utilities to automate a few bits on my job some years ago. I followed its approach mainly because it sounded like a good combination for being very simple to implement and very flexible to work with, making it ideal for a hosted scripting language (though it doesn't fit all tasks - far from it, especially in places you want even a hint of performance).
So i can't really judge how exactly it differs from Tcl language-wise. It is not compatible as it provides much fewer functions and those work in a different manner. For example there isn't uplevel, but there is upeval which works in a similar manner (though the depth is always one but they can be nested) and there is also downeval (used through upeval to evaluate code back at the environment from where upeval was called), topeval (like upeval but at the toplevel environment), enveval (eval in a function-like environment with optional variable passing in and out) and jaileval (eval in a new, optionally clean, LIL context). Also there isn't much in terms of state notification outside of watch (which i think it works like Tcl's trace but only for variable writes).
I think the syntax is compatible with Tcl (i haven't done any excessive testing to be sure though, LIL was done mainly by "eyeballing" Tcl) so it could be possible to write shims in LIL to be able to write code that works in both, but TBH i wouldn't rely on that.
So i call it just "Tcl-like" in the same sense that JavaScript is a C-like language.
Those were the days! I had BeOS as my only OS for over a year until it became clear that Palm wasn't going to continue supporting and updating it. It wasn't long after that I got into QNX, initially because of my interest in embedded systems, but after running Photon on a test machine I fell in love with it almost as much as I loved BeOS.