haxeui / haxeui-kha

The Kha backend of the HaxeUI framework -
http://haxeui.org
MIT License
45 stars 16 forks source link

UI components not correcly rendered when resizing the window (MacOS) #42

Closed maxfish closed 4 years ago

maxfish commented 4 years ago

Whenever the app window is resized, the components within it are not rendered correctly and they appear differently based on the size of the window. It is enough to resize the window vertically, the horizontal size doesn't seem to affect the UI.

Expected Behavior

They components should be always rendered in the same way

Current Behavior

The components are rendered in a few different ways during the window resize, one of them seems to be the "correct" one.

Possible Solution

N/A I've tried using Toolkit.autoScale=false before Toolkit.init(), but it didn't help

Steps to Reproduce (for bugs)

  1. Start the example app on MacOS Catalina
  2. Resize the window

Media

From the gist below From a more complex test (animated)

Test app / minimal test case

Gist

main.xml

<?xml version="1.0" encoding="utf-8"?>
<hbox id="main" width="100%" height="100%" style="background-color: white;padding:10px">
    <button id="testButton1" text="Click Me!"/>
    <button id="testButton2" text="Click Me!" />
</hbox>

Main.hx

package;

import kha.Assets;
import kha.System;
import kha.Framebuffer;
import haxe.ui.Toolkit;
import haxe.ui.components.Button;
import haxe.ui.core.Component;
import haxe.ui.core.Screen;
import haxe.ui.macros.ComponentMacros;

class Main {
    public static function main() {
        System.start({title: "HaxeUIApp", width: 400, height: 300}, function(Window) {
            new App();
        });
    }
}

class App {
    private var _main:Component;

    public function new() {
        Assets.loadEverything(onAssetsLoaded);
    }

    function onAssetsLoaded() {
        Toolkit.init();
        Screen.instance.addComponent(ComponentMacros.buildComponent("../assets/main.xml"));
        System.notifyOnFrames(render);
    }

    function render(framebuffers:Array<Framebuffer>):Void {
        for (framebuffer in framebuffers) {
            var g = framebuffer.g2;
            g.begin(true, 0x000000);
            Screen.instance.renderTo(g);
            g.end();
        }
    }
}

Context

When affected by the bug, the UI is unusable for any non-test application

Your Environment

XANOZOID commented 4 years ago

Seems related to #41 !

ianharrigan commented 4 years ago

Can we also confirm this (and #41) are still issues on latest git version? (i suspect the latter is)

maxfish commented 4 years ago

Here are the commits, both libraries are up to date with master haxeui-core - 1f611de9f18a31e15534e77fbc80d56891d54b36 haxeui-kha - 020524df65f6df5ea7efa392badcad3d8176e42b

ianharrigan commented 4 years ago

Ok, cool... Thought you were using the haxelib versionof haxeui-kha and i havent made a release in a while.

Cheers, Ian

maxfish commented 4 years ago

I can also confirm #41 is happening with those versions. I have one root hbox set to 100%,100% that is not resized when the window changes size

maxfish commented 4 years ago

I've found the problem, the borders are the ones that flicker during the resize. The cause seems to be the way how a Rect of strength=1 is drawn.

Replacing the loop at https://github.com/haxeui/haxeui-kha/blob/020524df65f6df5ea7efa392badcad3d8176e42b/haxe/ui/backend/kha/StyleHelper.hx#L124 with:

            g.fillRect(x, y, w, borderSize); // top
            g.fillRect(x, y + h - borderSize, w, borderSize); // bottom
            g.fillRect(x, y, borderSize, h); // left
            g.fillRect(x + w - borderSize, y, borderSize, h); // right

solves the issue. I guess, just like the compound border, the borderSize and the Toolkit.scale should be taken in consideration.

Considering that currently, on my system, Toolkit.scale is 1 and border strength is 1, I think the culprit is how drawRect deals with lines of 1px.

maxfish commented 4 years ago

If I'm not mistaken, the implementation that is running for my setup is CanvasGraphics.hx.

If so then the difference is due to the fact that drawRect uses the Canvas' path functions, fillRect instead uses the available fillRect function.

maxfish commented 4 years ago

At this point, I don't think there is anything to fix in haxeui-kha. I've been able to easily reproduce the issue in pure Kha, I'm going to create an issue on that project, link it here and I guess we can close this.

maxfish commented 4 years ago

This commit, mentioned here, enables HiDPI, it solves the problem, but messes up with the whole UI since it looks like haxeui-kha doesn't deal with the hi dpi and everything is very small. The maintainers of Kha think that HiDPI support shouldn't be the default and so things are going to remain as they are.

I'm going to apply the patch above and live with it. My plan is to use a native backend at a certain point.

ianharrigan commented 4 years ago

Hmmm, thats interesting - i appreciate the info. So you applied the HiDPI stuff and then everything was super small? I wonder if haxeui-kha can / should account for that?

maxfish commented 4 years ago

Yes, everything went very small.

Screenshot 2020-04-26 at 16 41 28

Apart from that, at the startup the window is all gray and I have to resize it to make the ui show up.

Since Kha won't implement a HiDPI fix, and HaxeUI-Kha seems to be using drawRect() only for the border, should we apply the patch to the lib? I actually think that fillRect() is faster than a series of rendered paths

maxfish commented 4 years ago

I've created https://github.com/Kode/Kha/issues/1195 hoping someone could fix the problem on the Kha side

ianharrigan commented 4 years ago

right... fillrect sounds like it might be a nice solution then?

maxfish commented 4 years ago

Yes, fillRect works just fine. I'm preparing a pull request

ianharrigan commented 4 years ago

Fantastic! Thanks loads :)