Immediate-Mode-UI / Nuklear

A single-header ANSI C immediate mode cross-platform GUI library
https://immediate-mode-ui.github.io/Nuklear/doc/index.html
Other
9.06k stars 542 forks source link

[5.x] Community sourced Nuklear Default skin and Design file #548

Open FrostKiwi opened 1 year ago

FrostKiwi commented 1 year ago

Nuklear's ability to apply skins has always been one of the things, that are advertised as a main feature. Furthermore, 9-Slice has supercharged this feature to support scaling. (huge thanks to @Michael-Kelley for making this possible) Which makes it all the more sad, that there exists no sample to properly showcase this. The sample in this repo has been added in 2016 and mentioned by users to be insufficient. (https://github.com/Immediate-Mode-UI/Nuklear/issues/286) So I suggest we all work together on one community sourced default skin, to showcase the abilites of Nuklear and Immediate-mode GUIs as a whole. nuklearv5 Breeze

The main goal of this PR is to create a nice sample Krita project file, where everyone can work together and as a starting point for new Skin creations and how to include them in Nuklear.

The Design File

I used KDE Krita to create Skins for Nuklear. Everything in this PR, every choise, every color has all been chosen on a whim, please treat it as an open canvas and change anything and everything to your liking. The design file and sample texture are in example/skins. A sample program show casing this is available in demo/glfw_opengl3_SkinDemo, though that quick and dirty sample demo should be ultimately removed.

Video tutorial

Since working with Krita and specifically its Vector drawing and styling ability for use in Nuklear is not straightforward, I created a video tutorial going through the use of the Design file: https://www.youtube.com/watch?v=X1Aui6o_V2A

File structure

image

Possibility of Automated skin import data

Manually providing coordinates to the style elements has been already mentioned by @vurtun in the 2016 commit to be huge pain.

One thing that is pretty clear for me now is that I need a way to read in a style from file or memory since manually setting up properties, colors and images is quite a pain.

Krita's Plug-in System has the ability to pull data from the file using Python, as mentioned at 8:38 If this PR is decided to be a fruitful way forward, it would be an excellent shortcut, if someone could take time and create an Export feature, that exports each Vector element's position, whilst honoring layer effects, like dropshadows and strokes, in the format that Nuklear requires. (From the top left corner of each element) Or in the worst case, checking the alpha values of each layer and exporting the top left non-alpha zero pixel position and the bottom right non-alpha pixel position as postion and width / height as required by nk_image.

Bug regarding missing style settings

As mentioned at 18:24 in the video, there is a bug, that makes Krita forget values of layers styles. An annoyance to the workflow proposed here. This bug is tracked here: https://bugs.kde.org/show_bug.cgi?id=466545

Further clarification

cblc commented 1 year ago

It would be nice that, even if you consider this a work-in-progress, you write this sample as backend-independent, just like the samples in demo/common, which you can then include with whatever backend you use. I see you are basing it on the GLFW backend, which for me is a no-no (I use sdl_gl2, because of the number of platforms that I need to support, which GLFW doesn't support). If you wrote the sample like those in demo/common, we could include it from our backend and it would work in all backends.

dumblob commented 1 year ago

Hi @FrostKiwi, I just want to quickly mention that I fully support this initiative (at least at the "passive" level :wink:).

Some thoughts to some of your additional points:

9-Slice elements break once going below their edge size - This is a fundamental limitaion of 9-Slice and widgets will need to have a minimum size because of that. Going further, a constraint system might make sense, where eg. a group or window may not be smaller than an automatically determined limit to ensure 9-Slice child widgets don't break. In my personal Nuklear usage, I have even modified things like the progress bar to switch between 9-slice and a normal edge to scale from small to big without cuts. (The inner percentage bar was a rounded glass design, which was cut of at low progress bar percentages)

I personally very much dislike minimum sizes as they add up surprisingly quickly and one ends up with non-scalable layout with cropped or weirdly scrolling interface (which is much worse than having super thin scaled-down widgets).

So I support your "hack" to e.g. ignore 9-slice edges and use just the inner part (in each direction independently).

Effects like drop shadows break padding and allignment - Since effects like these are baked, they do indeed change the visual size of a widget. At least padding has to be adjusted, though there are some other consequences. As such, we may choose to omit these. Depending on the feeling of everyone.

We should aim for having the non-shadow widget part both horizontally and vertically centered in the bounding box. So that means either ignoring the shadow or accounting for the shadow in the diagonally opposite corner with empty space.

I think the latter is (potentially) nicer looking yet the drawbacks are IMHO acceptable (esp. hovering the non-shadow as well as shadow corners will "react" and change hover style etc. - which feels weird in practice as the cursor is not yet above the actual widget but as I said I think this is acceptable for now - the right solution would be to have two visuals per widget state and one would be just "background" meant for shadows/glow/etc. - which would not react to any user input - and the other would be "foreground" - which would be the usual actual widget i.e. reacting to user input which in turn could of course also change the background etc.)

dumblob commented 1 year ago

Btw. @FrostKiwi I noticed Krita guys need some more info about the bug you filed (thanks btw.!) - see latest comments https://bugs.kde.org/show_bug.cgi?id=466545 .