Warning testing custom components

I’m giving a try to the custom components, to understand if it would make sense to use it.

I’m getting this warning while compiling (the compilation terminate correctly and the app shows up)
The super class of 'MyTool' does not match the root node of 'assets/views/my-widget.xml' (MyWidget != haxe.ui.containers.Frame)

I’ve found it’s due to the @build called in the “child” class but I’m not sure I understand why it’s warning me

I have 2 very simple classes

MYWIDGET (a sort of wrapper with some standard stuff)

import haxe.ui.containers.Frame;
class MyWidget extends Frame
{
    public function new()
    {
        super();
    }
}

MYTOOL (the object with some specific stuff)

@:build(haxe.ui.macros.ComponentMacros.build("assets/views/my-widget.xml", {content: "assets/views/my-tool.xml"}))
class MyTool extends MyWidget
{
    public function new()
    {
         super();
    }
}

in the Main.hx I just call

        app.addComponent(new MyTool());

and the my-widget.xml

<frame id="mywidget" text="my widget" width="100%" height="auto" style="margin-left:5px;margin-right:5px;">
    <vbox width="100%" height="auto">
        <import source="${content}" />
    </vbox>
</frame>

and my-tool.xml

    <vbox style="padding-right:10px" verticalAlign="center">
        <label id="test" text="test" style="margin-right:10px" verticalAlign="center"/>
    </vbox>

Is there a better way to achieve this ?
I mean, I need to be able to specify the “content” in the MyTool class

Hmmm, yeah, so that warning is misleading. Basically its only looking one level deep for the parent / child.

So yours is: MyTool -> MyWidget -> Frame, and haxeui is expecting MyTool -> Frame, but not for any reason except for the warning, so, the warning is wrong here - you code / class structure looks completely fine to me, its the warning that is getting it wrong. Ill have to think about how to make the warning smarter, but for now i think im going to disable that warning.

Cheers,
Ian

Ok, good :+1:

You know, working on this in the night … it wouldn’t surprise me if I’m not getting some obvious point :grin:

1 Like

Stumbled on another strange (to me :slight_smile: ) error

MyWidget has no field online

In the MYWIDGET class I’ve this function

    private function setSemaphoreGreen()
    {
        this.online.resource = "assets/icons/semaphore-green.png";
    }

and this in xml

        <vbox style="padding-right:10px" verticalAlign="center">
            <image id="online" height="10" width="10" resource="assets/icons/semaphore-red.png"
                   style="margin-right:10px" verticalAlign="center"/>
        </vbox>

if I don’t use this. I get
Unknown identifier : online

if I add a property to the class (mywidget) I get
Redefinition of variable online in subclass is not allowed. Previously declared at MyWidget

Using super. (just brainstorming test :slight_smile: ) I get
haxe.ui.containers.Frame has no field online

How should I refer to a component in my methods?

Its because the macro that has run has run on your top level class (ie, MyTool), and so that is where it has added all the components with ids… ill have to have a think about this because its a) confusing and b) means you cant add it in your MyFrame class (as it already exists in MyTool).

I guess the easiest way would be to not add a component automatically if it already exists in a base class. Ill basically have to think about custom components with inheritance trees of other custom components. Im sure there is a clean way around this.

It wont be ill, at least, later tonight though.

Cheers,
Ian

Thanks

In fact, I’ve just tried it, moving the method to the child class works, but of course it nullify the benefit of inheritance

Yeah, exactly, its still useful for the import in the xml, but the usefulness of MyWidget is removed as its just a nothing class, might as well inherit from Box or something, one thing you could do in the meantime, is something like this:

    private function setSemaphoreGreen()
    {
        findComponent("online", Image).resource = "assets/icons/semaphore-green.png";
    }

in MyWidget while i think of a nicer solution

Just wondering
How can I refer to the text property of mywidget in MyWidget Class methods ?

<frame id="mywidget" text="my widget">

both mywidget.text ='test'; and findComponent("mywidget", Frame).text don’t work.
neither this.text = 'test'; that of course works in myTool class

i think this is exactly the same problem, no? The difference now is instead of a component down the tree id, its the this… I would have expected this.text to work everywhere regardless… So maybe another related-but-not-exactly-the-same issue :confused:

Yep, I guess so.
The problem here is that, since the class is the frame itself, findComponent can’t be used, correct ?

I would have expected this.text to work everywhere regardless

me too
actually this

    this.text = "test";
    trace(this.text);

doesn’t trow any error and trace the correct value, but it just doesn’t update the frame text.
If I trace this.text in myTool class i get the text from the xml

Correct, thats why im a little confused as to why .text doesnt “just work”… maybe thats a deeper bug… ill check it out.

Maybe it is just initialized for the “built” component.
In fact tracing this.text in myWidget constructor returns null

Out of interest, what backend are you using?

haxeui-openfl (needatleast20charstopost :grin: )

1 Like