Koui | User interface framework for Armory and Kha

Hi, just a kind reminder that this is still a thread about Koui, if you want to talk about that Zui issue please use the issue that is opened about that :slight_smile:

@knowledgenude There wasn’t a bug with sockets as I found out, its just the same problem as https://github.com/armory3d/armory/issues/1882 (probably related to the latest update of Kha). The text rendering seems to stop working randomly, also for Koui.

2 Likes

Sorry, we’re comparing Koui and Zui. There is no way to try Koui on a smartphone now, so we just look at one side :slight_smile:

2 Likes

@E1e5en It is just because other people may come to here interested in info about Koui and they will not like to see reference about other things except it.

Now that i had posted the Zui results, no more mention about it here. Now i just will post Koui results. We keep talking about it another topic or in the github issue :slight_smile:

@timodriaan , i don’t had updated my git version of Armory yet, then i will try to reproduce the crash by creating the elements in another time (not on init) and see what happens. I also will try to use via script, maybe if there is some bug related to nodes, with script it will work.

I didn’t want to interrupt you but I was a bit afraid that this is going to be a Zui benchmark thread^^

@knowledgenude Good news, I tested Koui on HL/C and Android and it works on both targets for me (latest Armory & Armory’s Kha version) :partying_face:

Regarding the nodes crash: I will try to build Blender in the next days to get more insight from the VS debugger but I first need to make some space on my drive.

3 Likes

Koui 2020.10 was released today! :partying_face:


Whats new?

  • Support for gradients, drop shadows and rounded corners. Koui now has its own painter classes with custom shaders
  • Massive theming improvements:
    • It is now possible to style indiviual sub-elements (e.g. a slider background and the button in the foreground) differently
    • Added “states” to theme definitions: Elements can now have different styles based on their state (_button!hover e.g.)
    • Support for global variables in the theme file (colors, etc.)
    • When adding small tweaks to existing themes it is no longer required to copy the entire theme. Instead you can now append another theme on top of an already existing one (all that happens during compile time!). However, you can still overwrite the entire default theme with the KOUI_THEME define, just as before.
    • New data type Asset for theme files that will automatically load the required assets when Koui initializes
  • Show more debug information to profile graphics performance when KOUI_DEBUG_DRAWINGTIME is set, you can now access the number of draw calls and the average drawing buffer size for Koui’s new painter (Kha’s g2/g4 calls are not taken into account)
  • Layouts that use anchor positions now have a default anchor. Added elements will use that anchor when element.anchor == Anchor.FollowLayout
  • Progressbars now can output their value as a percentage when using Haxe templates (::percentage::)
  • Faster window resize handling
  • Much better theme handling of disabled elements
  • Many bug fixes and smaller improvements
  • More unit tests to improve stability

Just to make sure: there are always smaller updates that are not part of those big updates with their own version number. Only big breaking changes get their own version number.


Example project:

Because the documentation is not yet updated, I decided to upload one of my small example projects that I use for debugging (this one doesn’t use Armory, it’s pure Kha). It has no functionality other than showing a few elements as you can see in the screenshot above. It started as a game options menu but now it’s just something weird^^

To run it, open the extracted zip folder in VSCode/Kode Studio and hit F5 (you might have to choose Electron from a dropdown, but it should work on any other target as well).

Download demo project (this forum doesn’t allow .zip uploads): https://www.dropbox.com/s/c6dll34p49c0doy/KouiDemo.zip?dl=1

Have fun :slight_smile:

4 Likes

@timodriaan, super!

Have a question: are all languages supported?

If Kha supports this, likely yes. It will of course depend on the font. The default font can be found here, if you scroll a bit down you can see the supported languages.

It is defined in the theme file here and is automatically loaded when the font file exists in the Assets directory,

1 Like

When I run KouiDemo I get:
kha/graphics4/PipelineState.hx: 96: Warning: Uniform projectionMatrix not found.

This font does not support my language. I tried another one (Alice), I still had to download it as a resource in the khafile.js file.
As a result, instead of text, just spaces. So Kha doesn’t support. Let’s figure it out :frowning_face:

You can totally ignore that warning, it’s some internal Kha stuff as far as I know. Armory had it too for a long time, I will do some research to find out how to get rid of it :slight_smile:

Edit: I found the problem: the matrix isn’t used and even if I add this to the shader, it will be optimized away from the compiler resulting in this warning. It’s probably something that needs to be either fixed in Kha or I have to use it (which I might do in the future, there are plans for it)

I still had to download it as a resource in the khafile.js file.

Yes, and there is no way around that I think. Koui just loads the font when you refer to it in the theme file. You don’t need to call kha.Assets.loadFont() anymore.

As a result, instead of text, just spaces

That’s not good. You use a .ttf font, right? Armorpaint has support for different types of character sets, it supports chinese fonts for example, maybe we can look how it’s done there. If you can make sure that it’s not a problem with your setup I will try to find out how to load non-latin fonts as well.

I’m using a .ttf font (Alice). I downloaded it and one field contains the text in Russian â€œĐąĐ”ŃŃ‚â€. The result is gaps.
There have been reports from Armorpaint that the user cannot use the sai language (el). So I’m not sure.

Then you might be right and it’s Kha that’s missing support for those characters which would be sad. Maybe Lubos will push some commits to one of the Kode repos implementing this if there is an open issue. It also doesn’t help to use unicode escape strings so it isn’t a Haxe issue.

While testing the russian string I found a bug in Armory when parsing the trait file for properties to show in the Blender UI:

location: <unknown location>:-1
Error: Traceback (most recent call last):
  File "A:\Workspace\Documents\Projekte\Forks\ArmorySDKDEV//armory/blender\arm\props_ui.py", line 566, in execute
    make.play()
  File "A:\Workspace\Documents\Projekte\Forks\ArmorySDKDEV//armory/blender\arm\make.py", line 501, in play
    arm.utils.fetch_script_props(fn) # Trait props
  File "A:\Workspace\Documents\Projekte\Forks\ArmorySDKDEV//armory/blender\arm\utils.py", line 297, in fetch_script_props
    lines = f.read().splitlines()
  File "A:\Programs\Blender\Blender 2.83\2.83\python\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 914: character maps to <undefined>

I will try to fix it tomorrow :slight_smile:



@ Everyone: I pushed another commit that improves how theme files can be overridden. Now, when you override a theme ID only those properties that are explicitly set are overriden, not the entire group of properties. This makes it possible to change some theme IDs in the overriding file without the need to create custom ones.

Lets look at the following example situation where the original theme file has an entry like this:

buttonA > _root:
	font:
		size: 18
	color:
		text: #ffffff

// buttonB has all properties from buttonA and overrides the text color
buttonB > buttonA:
	color:
		text: #000000

Lets create another theme file that will be applied on top of the theme file above with the following content:

buttonB > buttonA:
	font:
		size: 24

Previously, this would result in the buttonB having a white color (#ffffff) and a font size of 24px because buttonB from the original theme file would be completely overriden. Now, buttonB has a black color (#000000) and a font size of 24 as one would expect.

This makes it very easy for example to just set another default font without having to copy all contents from the _root ID.

3 Likes

Ok I got it working:

Button with russian textt

Kha loads only certain font glyphs but you can set the character range with kha.graphics2.Graphics.fontGlyphs. Now the question is how the API for this should look like (or should that be a thing each user has to do?).

There could be preconfigured glyph ranges for some languages that could be switched on or off (so that multiple laguages are possible at the same time) but there will always be cases where that preconfigured setup is wrong. Should it be possible to set a custom range then? Or even a custom range per locale? What do you think?

Maybe like this?

// or better setFontGlyphs()? That would be more correct maybe
FontUtil.setLocale("ru");
FontUtil.addLocale("en");
FontUtil.removeLocale("en");
FontUtil.setGlyphRange([for (i in 32...383) i]);
FontUtil.addGlyphRange([for (i in 1024...1119) i]);

// This allows to load in translation files and automatically register all glyphs.
// Of course this is not efficient for dynamic user input in text fields
FontUtil.addGlyphRangeFromString("Ă€Ă¶ĂŒĂŸ");

Fixes for Armory are coming later today btw :slight_smile:

1 Like

Thank you so much :smiley: :+1:t2:

The default settings should be as general as possible.
But the main thing is that in case of a problem, the user will receive an answer: not just does not show the font, but a warning to the console/log, if possible. To immediately understand the problem. I think so.

Own range - I think it’s necessary, the user can use different fonts.
It is also necessary to apply the range to the locale, again for flexibility - another language, another font, different settings.
Maybe:

    FontUtil.addLocale("ru", [for (i in 32...383) i]); // if the second parameter is not specified, the default is
    FontUtil.addLocale("en", [for (i in 32...383) i]);
    FontUtil.setActiveLocale("ru"); // and the last one added will automatically become active
    FontUtil.getActiveLocale();
    FontUtil.setGlyphRange("ru", [for (i in 32...383) i]);
    FontUtil.addGlyphRange("ru", [for (i in 1024...1119) i]);
    FontUtil.removeLocale("en");
1 Like

Implemented: https://koui.gitlab.io/api/koui/utils/FontUtil.html

In your case, import koui.utils.FontUtil and call FontUtil.loadGlyphsFromLocale("ru") in the initialization callback and everything should work in the latest Git version (a little warning: I might move some of the utils classes to other places in the future).

I changed the API again to better adhere to the naming conventions (glyphs/codepoints etc.), maybe it will get some changes in the future if it isn’t as helpful as it should. For now it works and you can load/unload character sets which is helpful if there is a language setting in the game options menu for example.

3 Likes

Is it possible in KOUI to animate parameters
like alpha/transparency, color and scale?

Not yet, altough I recently implemented a few things that will help with animation support and that is definitely planned. Do you need animations that are triggered by events/in the code or should they be automated via the theme? The latter will take some time until getting implemented because it requires changes to the theme system.

3 Likes

Do you need animations that are triggered by events/in the code or should they be automated via the theme

Theme animation would be already quite nice.
Calling UI animation via event-triggers is obviously a beauty to have
but at least to have something happening in the UI would be very helpful.

2 Likes

So when doing this:

package arm;

import koui.Koui;
import koui.elements.*;
import koui.events.EventHandler;
import koui.events.Events;

class KouiTest extends iron.Trait {
	public function new() {
		super();

		notifyOnInit(function() {
			Koui.init(() -> {
                var button = new Button("Click me!");
                button.setPosition(400, 180);
			});
		});
	}
}

I get a completely red screen and the output is this:

 Trace: TypeError: Cannot read property 'length' of null
        at Function.koui_effects_Effect.initAll (<anonymous>:48440:17)
        at <anonymous>:48314:23
        at onLoaded (<anonymous>:23404:4)
        at kha_Assets.loadFont.fileName (<anonymous>:23376:5)
        at <anonymous>:23477:3
        at <anonymous>:24374:3
        at Function.kha_LoaderImpl.loadBlobFromDescription (<anonymous>:24370:2)
        at Function.kha_LoaderImpl.loadFontFromDescription (<anonymous>:24373:17)
        at Function.kha_Assets.loadFont (<anonymous>:23475:17)
        at loadFunc (<anonymous>:23375:15)

Any ideas?
(Blender 2.83, A3D latest official build.)

The whole testproject is here, I’d like to know if this works on your end.

1 Like

Hi, thanks for the report. I accidentally forgot to include a line in one of the last commits. Should be fixed now in the latest master branch :slight_smile:

Please note that you have to add the button to a layout before you can actually see it. If you want to use the default base layout, just write Koui.add(button) and everything should work.

6 Likes

Awesome! Yeah, I just went step by step to see where it breaks.
And so that the code is shorter for you to see. :wink:

4 Likes