LCUI – A small C library for building user interfaces with XML and CSS
github.com
github.com
I looked into existing options like QT, but found them to be extremely large and full of things I didn't need. I don't blame them for that; they're designed to support a huge range of inputs and have a lot of associated assets. I've also heard that it's possible to build custom 'lite' distributions. But it looked imposing enough to get into as a user that I was about ready to just write buttons and dropdowns and scroll bars in raw OpenGL. It was gonna be messy.
But then, I decided to just use a web browser.
And it was so easy. You can have an OpenGL ES 3 canvas surrounded by UI elements which don't look horrendous, with just an hour or two of setup. The whole thing can respond very gracefully to things like window resizing without much added effort. It is very easy to pass values between the GL context and the UI elements. It is trivial to save/load configurations with any sort of web framework.
Something that could offer similar usability in C definitely sounds exciting. I mean, I complained about QT being bloated, but so is a modern web browser. Most people just happen to already have one pre-configured, and most developers just happen to already be familiar with how one works.
Nuklear
This is a minimal state immediate mode graphical user interface toolkit written in ANSI C and licensed under public domain.
(edit) Wow, that looks way more powerful and embeddable than I was expecting. I'll have to give it a try.
Nim's syntax is very python like, but it's statically typed and compiles to C. Best of both worlds.
Do you really prefer to learn a different API and library for every different part of your app ?
Qt is not focused on being a useful tool that you simply put next to your other modules, and plays nice when it's called. Qt wants to be a framework that drives your application. Qt expects you to speak in its own datatypes, not type-agnostic flat memory.
I mean, I've only used Qt very briefly, but how would I, for example, use Qt widget functionality to add a nice menu to my existing 3d game? It's uncommon enough that I can't easily find how to do it, and I wouldn't be surprised if it's next to impossible.
With Qt, Qt itself is the app, your code is just a plug-in. :-)
I don't think that would be very desirable: Qt widgets are made to mimick the desktop OS themes... I doubt you want these in games. However, you could use QtQuick, here is for instance an example of integration with a 3d game engine: https://github.com/MaxSavenkov/nya_qt And another which integrates with the creative coding framework openFrameworks: https://github.com/aklevy/ofUnderQml ; doing for instance a HUD à la Scaleform with these is fairly realistic given the nice scene graph of QtQuick
I don't think Qt, or QML for that matter, is flexible enough to fit into an existing, complex architecture with its own concepts and data structures. What I need is something that I can feed my own inputs through a simple plain data API, and get back plain data results that I can further process, preferably without any other side effects.
I don't want to structure my code heavily towards a framework. I don't think that is flexible or maintainable. I don't want to use a framework that takes over the process and the processes' I/O and the main loop, and that I can't extend without plugging hard to maintain code into lots of magical sockets. Which also only gets you so far; you'll never be able to bend the framework to do quite what you need; and you'll waste hours and hours reading documentation and browsing obscure github projects to find clues how to bend it a little more. And of course, these clues will be invalid in the next version. This is my experience with Qt at least (as well as with CMake, for example).
What makes you think you can't ? Pass input events to the relevant Qt objects once per frame, tell it to render to an FBO and do whatever you want with the result.
> through a simple plain data API,
I'm working on large app made in Qt and the number of times where I call Qt functions taking Qt containers as arguments, eg QList or QVectors can be counted on the fingers of one hand. What do you have in mind for instance ?
> I don't think that is flexible or maintainable.
The number of reliable large applications based on frameworks certainly shows otherwise. Even in video games, could you cite more than five big AAA game in the last decade that were not based on UDK, CryEngine and its variants, or Unity3D ?
> I don't want to use a framework that takes over the process and the processes' I/O and the main loop,
That's what I was referring to when I mentioned code reusability. Event loops & IO have been abstracted away for a long time, yet people refuse to use these abstractions for reasons unknown to me and keep reinventing game loops in every game, instead of just referring to some lifecycle schema like Unity3D's (https://docs.unity3d.com/Manual/ExecutionOrder.html) or Qt's (http://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph.html). These schemas did not come out of thin air, but of years of experimenting on different categories of apps and seeing what works and what does not ; 99% of the time you don't need to deviate from them, especially if you're not making an AAA.
> This is my experience with Qt at least (as well as with CMake, for example).
I feel like we're living in a parallel world. Qt maintains API and ABI compatibility for major versions, the last breakage was in Qt 4 -> 5 transition 6 years ago. And a large part of the apps I use still have CMake 2.6 - 2.8 level buildscripts while we're at 3.10, and they still work as-is.
Well I had to do a little dashboard application and the interfacing from C++ to QML was... laborious, to say the least. It was quite hard to find the right magic words to do seemingly simple things like getting a list of dropdown items over to QML. If you don't have to work with Qt containers most of the time, I figure you have good abstractions in place. (So you're not working directly with Qt after all?) I wanted to do that too, but my employer wasn't happy with me not using enough QStrings and QStringLists and what not.
> Even in video games, could you cite more than five big AAA game in the last decade that were not based on UDK, CryEngine and its variants, or Unity3D?
I don't play many games, and if AAA means "graphically impressive but possibly not a conceptual innovation", then my answer would be "no". I would be hard pressed to quote 5 AAA games at all. (I sometimes play FIFA on a friend's PS3 (yes it's dull), and here we have the first exception. Whatever)
However I happen to "know" that many Indie game developers prefer to control their own codebase, that they know in and out, and that they can cut and trim and slice and dice, to try out new ideas. (This includes more commonly known titles like Super Meat Boy, Braid, The Witness).
> keep reinventing game loops
Why should I not "reinvent" a game loop? It's a trivial thing to do. No big deal. I'd rather do it myself than starting with a big preconceived framework that starts with words like "Awake", "OnEnable", "OnLevelWasLoaded", "OnApplicationPause" (What's a level? Why would I have such a thing?).
> I feel like we're living in a parallel world.
I would like my applications to last much longer than 6 years. And I would really be surprised if there were not more problems. Regarding CMake, I wasted >20h in multiple attempts fighting an existing CMake build system including a tangled mess of CMake scripts. It's really hard to understand and maintain. The documentation is not good, it doesn't try to teach you the underlying conceptual models. I then decided to just put my build description in a python file and generate the build system myself. 3h until it first worked, very little maintenance afterwards. Plus, I now have the flexibility to easily add more facets as the system evolves, and to easily derive other useful dev tools from the python structures. (Small downside, would possibly have to write more build system generators if there were multiple supported platforms. But while CMake makes some of this a no-brainer, it's almost never just "now compile for this other platform", and other aspects to porting get relatively harder with CMake).
It seems you are less informed than my first impression was. I did a few web searches, and the AAA titles using especially Unity seem to be far and far between. It's not good enough technically for top-notch performance (seems to require a garbage collector).
Also there are so many types of games that they cannot possibly supported by just two generic engines. For example, Open-World games need their own. Or military games like Call of Duty have their own. (And of course many Indie games have their own, as I said in the other comment).
Also most bigger publishers breed their own engines to save the fees for licencing a third party engine.
Bethesda games, generally open world, use an engine (https://en.wikipedia.org/wiki/Gamebryo for older games and https://en.wikipedia.org/wiki/Creation_Engine for most recent), they certainly don't go reimplementing it.
> Or military games like Call of Duty have their own.
No, they used the id engine and improved it over time.
> Also most bigger publishers breed their own engines to save the fees for licencing a third party engine.
Like ? for instance Bioware (as part of EA) uses Unreal engine. You mentioned FIFA games: they also use engines shared across a huge swath of games: https://en.wikipedia.org/wiki/Ignite_(game_engine) and https://en.wikipedia.org/wiki/Frostbite_(game_engine)
The only big release I know not using an engine shared across multiple game series is the recent Witcher games engine.
The killer app is if this was all done at compile time. Use common web technologies to design the UI, translate that into lightweight GUI code.
One advantage of this approach compared to the minimal UI libraries is that you can expect it to work well with a massive array of hardware – elements like scroll boxes should work seamlessly with touchscreens, apple trackpads and regular wheel mice, text input elements should respect the user's navigation key bindings. Accessibility features like voiceover should be supported. The downside is of course the weight of the browser engine compared to a tiny C library, however it'd be an interesting experiment to see how much bloat could be stripped out of a browser if you only care about a subset of features, i.e, WebGL can go, legacy layout modes can go etc
For painting, I have positive experience with this cross-platform C library: https://github.com/memononen/nanovg It’s tiny, has very few dependencies, and the performance is good even on relatively slow hardware like Broadcom or Mali embedded GPUs.
However, it lacks higher level stuff. There’s no layout, input handling, styles, controls, advanced typesetting, or animations.
> options like QT, but found them to be extremely large and full of things I didn't need
> But then, I decided to just use a web browser.
https://en.wikipedia.org/wiki/IUP_(software)
http://webserver2.tecgraf.puc-rio.br/iup/
"IUP is a multi-platform toolkit for building graphical user interfaces. It offers a simple API in three basic languages: C, Lua and LED. IUP's purpose is to allow a program source code to be compiled in different systems without any modification. Its main advantages are:
high performance, due to the fact that it uses native interface elements. fast learning by the user, due to the simplicity of its API."
ATTENTION: THIS PROJECT IS STILL BEING DEVELOPED AND IS NOT UNMAINTAINED. PLEASE DO NOT ASSUME THAT JUST BECAUSE THERE HASN'T BEEN A COMMIT ON THE MASTER BRANCH IN MONTHS IT HAS BEEN ABANDONED. THANK YOU!
but a bit below, it shows Build failing.
The only failing builds are for pull requests and other branches.
The image URL in README.md should probably be changed to https://travis-ci.org/andlabs/libui.svg?branch=master (from just https://travis-ci.org/andlabs/libui.svg).
About 20 years ago, in 1998, Netscape Communicator 5.0 was released as an alpha version and introduced the new toolkit to build the GUI of the browser with XML, CSS and Javascript. Shortly after, the Mozilla foundation started and Netscape 6 was released.
At this time, around year 2000, it was an outstanding technology, and it could have become the defacto standard for cross platform GUIs...
Sadly, the Mozilla Foundation didn't sponsored this technology enough (in my opinion) to make it become the leader for cross-platform GUI development. Because of lack of interest as a core technology by Mofo, the problems with tooling around build and packaging, documentation, legacy components, newcomers accessibility were not resolved.
Firefox 57 removes the support of XUL for extensions but if I m not wrong it still uses XUL in some windows and the gecko engine (which render XUL).
After XUL, we saw interests of this concept of XML-based toolkits by Adobe (Flex), Microsoft (XAML), Gnome (Glade), QT (QML, maybe the winner ?), HaxeUI. There are probably more.
XUL is the oldest implementation of XML-based GUI toolkit that I know. There are probably some before.
It really works well, and their Blend tool, makes it easy enough for even non-developers to design the UI component.
It was around when I was taking my baby steps with GUI development, and nothing else I tried later came even close.
LCUI doesn't seem to rely on a specific browser but still remains fairly small so that seems pretty good.
It's a shame that it requires X11 on Linux, though. As the renderer must already be decoupled from the rest of the code to support Windows and Linux, I imagine it shouldn't be too hard to rip out the X11 bindings and write to a framebuffer directly instead.
I have not had a chance to try it out for myself yet, but I have recently learned that webkit includes a direct-to-opengl renderer such that one can skip the Qt or GTK backend and write HTML/CSS/JS that outputs to the framebuffer directly.
Icy Glare ... Hahaha. Give me clean mono-language "source" code any day please.
Unfortunately, not many programming languages with German keywords exist. ;-)
No, as a German, I understand your concern. The problem is, you need to be fluent in the language AND use names that fit the variables. I work in High Performance Computing and the code physicists write isn't accessible to me most of the times, just because they use one and two letter variables from their formulas in their code.
Also, from what I can see, the documentation seems to be in Chinese: https://lcui.lc-soft.io/guide/zh-cn/
the the GPL license might be of an issue though, then again, the author said he will switch to LGPL in 1.0.0 release, so all is good!
1. shall not be CPU consuming. That famous 13% CPU consumption on blinking caret (https://github.com/Microsoft/vscode/issues/22900) is not acceptable.
2. shall be as compact as possible.
3. shall follow modern UI trends on the long run and without major code refactoring. See: 10 years of UI evolution of Norton 360: https://sciter.com/from-skeuomorph-to-flat-ui-evolution-of-o... with Sciter.
4. Shall support Section 508 / Accessibility as they used by governments and in official institutions.
5. Shall support flexible layouts and screen sizes used in the wild. UI nailed down to pixel grids in light of high-DPI Retina's is not an option anymore. Sciter UIs work on 500 mln PCs and Macs and counting.
6. UI these days shall be GPU accelerated, Retina has 9 times more pixels than 96ppi "classic" screens.
7. Code-behind-UI shall be flexible and GCable as UI objects ownership graph is complex and may contain loops: "on-this-button-click-hide-that-and-expand-those-and-disable-the-button-until-done".
8. Shall support multiple languages and adjust layout to them: https://sciter.com/images/wt-langs.png
All that...
Consumes a lot of resources.
Fails to follow design guidelines of the platform, but then again, maybe "modern trends" are more important than following the design language of the platform ¯\_(ツ)_/¯
It’s a quirk of the translation/language barrier that it may seem that he’s attacking the author, but just replace “the author” with a first person pronoun and re-read.
To anyone else thinking of developing your own GUI toolkit, please reconsider. It would probably be better for you to just use one of the established ones, unless you have the resources to flesh out all of the tedious but important stuff like accessibility.
Edit: I'm sorry if I offended any developers or sounded like I was devaluing your work. That wasn't my intent, and I actually tried hard to keep the tone of this comment under control. It's just very frustrating every time I read about yet another inaccessible GUI toolkit.
I'm genuinely annoyed and sad when I'm dealing with shitty UI/UX and realize that something may be completly unaccessible for his use.
He made me more aware of the general problems and it's something I always keep in the back of my mind when explaining or doing things (things like pictures, diagrams, white board drawings, etc are a no-no).
I would like to see more people aware and thinking of this and not forget of the issue for new experiences with new UIs.
Some time ago i looked into this since i am creating a toolkit (unrelated to the linked one) and thought that it would be nice to add some accessibility support - at least for screen readers. Unix doesn't have an accessibility API nor does X, AT-SPI is basically GNOME's version which works via ATK and/or D-Bus. D-Bus is not an acceptable requirement for my case since it is a system that adds a lot of extra unnecessary complexity and implementing ATK (like Firefox) does is an even bigger no-no And really the only thing that uses AT-SPI is Gnome's Orca (KDE users use that too) and that project doesn't look very healthy (lots of bug - including several major bugs that are there for years, the wiki is a mess that has notes from 2011 about "cleaning it up").
So i just dropped the idea since it doesn't seem to be any way for this to work with X itself - nobody bothered to specify any protocol that works with pure X. It is something i might look into myself in the future, but honestly it is not a big priority for me.
> This is a lot of work, but it's necessary if the toolkit is going to be used for anything other than games or toys.
There are a ton of programs that do not provide accessibility features tech and are not games nor toys (in fact i'd guess that the majority of programs you'd find in a Linux distro do not provide anything like that - and a quick look at Orca's bugtracker makes it clear that even those that seem to do it have many issues). Also i think you'd have a better response from the people who are writing the actual code if you aren't trying to devalue their work by calling it games and toys.
> It would probably be better for you to just use one of the established ones,
It would be even better if the established toolkits didn't suck as much and broke their APIs every 2-3 years, making the programs that depend on them have a shorter lifespan than the supported versions of Windows (let alone reaching a point where they can even dream about Windows' backwards compatibility).
I'm sorry; that's not what I meant to do. I only meant that I know it's not reasonable to expect developers of games and other software that's just for fun to go out of their way to implement accessibility. But for any software that might be used in a job, for education, for interacting with a company or government agency, or even for communication in general, accessibility is really important. I know a blind guy who almost lost his job because he couldn't use a specific piece of inaccessible software; he only kept his job because the company found something entirely different for him to do. And yes, a lot of important software is not accessible. We need to change that.
About AT-SPI and D-Bus, could you implement AT-SPI support as a plugin, so it's there for those who need it but doesn't add D-BUS as a hard dependency? That's what Qt does.
> About AT-SPI and D-Bus, could you implement AT-SPI support as a plugin, so it's there for those who need it but doesn't add D-BUS as a hard dependency? That's what Qt does.
I'll need to look into it, if i go into that route i'll most likely make it an optional build-time feature that is enabled by default if the relevant header files are found and try to load it dynamically instead of making it a plugin (the toolkit can be compiled as a static library to create self-contained executables). This is also what i'm doing with OpenGL support that may not always exist - the toolkit and application work, it just disables the OpenGL stuff.
But this is something i'll check in the future, at the moment the toolkit is barely usable even by people with perfect sight :-P.
[1]: http://wiki.freepascal.org/LCL_Accessibility [2]: https://github.com/williamhunter/pascal-bindings-for-c
But of course, over 90% of computer users have this "unable to command line" disability, so they need a GUI. I was thinking of writing my own. Small, simple, and completely oblivious to accessibility issues—except maybe font sizes.
Would that be okay? I mean, who cares about GUI accessibility if you can do the same thing on the command line? Unless the command line is not accessible for some unfathomable reason?
The xml layout parser is at: https://github.com/lc-soft/LCUI/blob/develop/src/gui/builder...
The CSS parser at: https://github.com/lc-soft/LCUI/blob/develop/src/gui/css_par...
Making UI design easy sounds great. Bundling a web browser in every program does not.
I wonder how easy it is to use this with languages like python ?
I'm also curious about what the lc-finder is.
Anyone already running a profile-guided fuzzer on this then?
UIs in OpenGL are a pita, and the best I've ever seen done that didn't involve HTML-like or HTML-based design was in VGUI. Attempting to build a modern UI kit for a basic game engine today easily results in producing a lump sum on the order of 10k SLOC just to add some critical functionality to your app/game.
Plus it doesn't add anything positive the UI/UX beyond a few devs wanting a .exe instead of an URL, and not having to deal with the quirks of each browser/OS.
I never liked MSHTML, Active Destkop, XUL, and I really don't see why Electron should be treated in any different way, just because learning how to use native APIS or writing an simple abstraction layer is "too complicated".
If devs want to do a web app, do a web app, deal with browser quirks, use web workers, just don't package a browser with it.
A Dom based parser could be, but also depends of number of nodes and nesting.
Love sax by the way. I just switched over one of our sites to use a sax based parser because the default rails .to_hash was choking on 100MB+ XML files.
They could always add an option to compile it, much like xaml, it may even be as simple as a xslt transform.
Speeding up start times is a laudable goal, but this comment makes it sound as if the performance implications are more significant than that.
I don't see libxml2 being slower than any other markup language parser. In comparison to how slow some JSON (an easier to parse language) parsers are, libXML2 is actually quite fast.