Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datastructure that represent a tree. #4218

Open
codecat opened this issue Dec 26, 2023 · 4 comments
Open

Datastructure that represent a tree. #4218

codecat opened this issue Dec 26, 2023 · 4 comments
Labels
a:language-slint Compiler for the .slint language (mO,bF) enhancement New feature or request

Comments

@codecat
Copy link

codecat commented Dec 26, 2023

This is not possible (which makes perfect sense):

struct Foo {
  foo: Foo,
}

But I think this should be possible, as it would allow us to create tree structures:

struct Foo {
  children: [Foo],
}
@codecat codecat changed the title Structs can't reference themselves as a type Structs can't reference themselves as a type (arrays specifically) Dec 26, 2023
@codecat codecat changed the title Structs can't reference themselves as a type (arrays specifically) Structs can't reference themselves as a type for arrays Dec 26, 2023
@ogoffart
Copy link
Member

True, it should be possible to have recursive datastructure. We would need that for recursive sub-menus ( #38 ) and maybe treeview kind.

This should be made possible:

struct Foo {
  children: [Foo],
}

But also

struct Foo {
  children: [{ id: string, node: Foo }] 
}

But unfortunately this is not possible:

struct Bar { id: string, node: Foo } 
struct Foo { children: [Bar] } 

Because there is no concept of forward declaration.

Also: this is currently valid code:

struct Foo { xxx: int }
struct Foo { children: [Foo] }

And changing this to take another meaning of Foo would be a breaking change. Although I guess no-one would do that.
We could make this a warning a few version before.

@ogoffart ogoffart added enhancement New feature or request a:language-slint Compiler for the .slint language (mO,bF) labels Dec 27, 2023
@ogoffart ogoffart changed the title Structs can't reference themselves as a type for arrays Datastructure that represent a tree. Feb 6, 2024
@Sullux
Copy link

Sullux commented May 25, 2024

Just to add a voice to this issue, I've spent the past few weeks assessing slint and creating sample controls and apps. I think this is a really good framework.

I also think that this feature (the ability for a struct to self-reference/express a tree) is a make-or-break feature for this framework. If there were some kind of parallel to a Turing-completeness test for a UI framework, tree expression would be a part of the test.

Personally, I cannot build apps without this. The types of apps I build depend too much on logic-generated and recusrive visual elements. Even something as simple as creating a rich text control cannot be reasonably done without this feature.

I've never contributed to a project like slint before, but I would be happy to do so if it would get this feature rolling. I think this framework deserves it!

@ogoffart
Copy link
Member

ogoffart commented Jun 5, 2024

Depending what you're trying to do, a tree can be represented as a flatten list. (For example to build a treeview, like in cargo-ui ), or use id-like things to get the value in native code.

For example, in Slint

struct MenuItem {
   text: string,
   icon: image,
   id: int, // could also be a string.
}

global MenuLogic {
   // Given a menu's id, fetch the children for that submenu
   pure callback fetch-children(int) -> [MenuItem];
}

And then the tree is held in native code and there you can have tree structure, without the need to declare a tree structure in Slint.

What is really your usecase for this feature?

@Sullux
Copy link

Sullux commented Jun 5, 2024

@ogoffart Thanks for your response!

I actually tried exactly what you describe. What you've posted is a good way to use logic to dictate UI in slint.

The shortcoming of your example is in turning it from a flat list into a tree. I'll simplify this example for brevity:

struct MenuData {
   text: string,
   id: int, // could also be a string.
   children: [int],
}

global MenuLogic {
    // Given a menu's id, fetch the children for that submenu
   pure callback fetch-children(int) -> [MenuData];
}

export component MenuItem {
    in-out property <MenuData> data;
    in property <int> indent: 0;
    VerticalLayout {
        Text {
            text: data.text;
            x: 10px * indent;
        }
        for child in data.children: MenuItem {
            data: MenuLogic.fetch-children(child);
            indent: root.indent + 1;
        }
    }
}

The above produces a compile error: unknown type MenuItem. It's the MenuItem referenced in the for loop. That is what we need to work before slint can be used for complex UI development. That feature is needed for trees, nested menus, rich text editing and a host of other use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:language-slint Compiler for the .slint language (mO,bF) enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants