-
Notifications
You must be signed in to change notification settings - Fork 604
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
Create multiple components in generated Rust and C++ code #784
Comments
This would be a nice improvement. The current solution of using a bunch of property bindings on the top level Window element is quite clunky. |
The goal here is to support multiple windows. One would still need to make properties accessible in the top level, or in a global singleton component. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
We discussed this topic a bit this morning and decided to each think about separately how to solve this. This is what I think could be considered as a solution: The proposal covers to questions:
Example Codepalette.slint:
main.slint:
dialog.slint:
build.rs
Shared GlobalsThe proposed solution affects only the generated code:
Internal implications to Rust generated code: At the moment, each generated component that is not inlined results in a "Per-Window" Specific StateThe question of how to create state that is per-window is a special case of the general question: How can (possibly unrelated) components share state? The proposed solution uses interfaces:
A component can implement the interface:
That means it provides the declared properties and callbacks. A component can require that instantiating it requires access to a single instance of an interface:
This requirement propagates to anyone using this component:
Optional Exposure to RustWe could also consider exposing main.slint:
// generated
mod ui {
trait SharedState {
fn get_shared_property(&self) -> SharedString;
fn set_shared_property(&self, SharedString);
}
struct App {
// ...
}
impl App {
pub fn create(required_shared_state: &Rc<dyn SharedState>)
}
}
struct AppState {
// ...
}
impl ui::SharedState for AppState {
...
}
fn main() {
let shared_state = Rc::new(AppState{});
let app = ui::main::App::create(&shared_state);
} |
Has there been any progress towards this issue as of late? |
Not much progress. @preland : since you are asking, could you elaborate on your exact use case, this would maybe help to design this feature |
The use case is for an open source Rust DAW which is going through an overhaul of the entire codebase, so we are looking into alternative UI frameworks. One req for the project’s UI is support for multiple windows |
RE use cases, I'm evaluating UI toolkits for an industrial use case where we would most likey drive 6 full-screened displays full of video feeds, indicators and buttons, ideally from one app (though we might have to split it up). multi-window support is also not in egui yet, so we're probably going to have to go with bindings to one of the huge mature UI frameworks. |
Note that multi-window do work in Slint if you either
This commit show how to do it with one of our demo: #2094 The limitations are:
We need to improve on that. But I think for the use case of @andrew-otiv, the current situation might actually be good enough. |
I think there is another, possibly more serious issue with this workaround: If you want two components that refer to the same struct, you will get duplicate definitions. For example, with a main window defined here:
and a second window defined here:
with the workaround above instantiating is as follows:
You get the following, because
This seems to mean you can't even have multiple windows that use any of the same structs (and I wonder about other components)? Am I missing some detail of the workaround, or is this just straight up impossible? EDIT: It looks like ultimately I'm running into the "globals aren't shared", which makes using this for any but trivial multi-window applications (that is, things like confirmatory dialogs) seemingly impossible. 😭 |
From my little experience with slint I see this as one of the biggest drawbacks. In my case using the main window as a kind of "controller" is not a big deal (I use dialogs that just go over the content of the current window) but the main use case I see for multiple components definition is to have some shared logic in a widget. For instance I'm making a pretty dumb import { Button, VerticalBox } from "std-widgets.slint";
import { Button, ScrollView, ListView, HorizontalBox} from "std-widgets.slint";
export component PathEdit inherits HorizontalBox {
in property <string> label: "Path:";
in property <string> default_path: "/some/path";
max-height: 96px;
Text {
text: root.label;
vertical-alignment: center;
color:gray;
}
TextInput {
text: root.default-path;
horizontal-alignment: left;
vertical-alignment: center;
horizontal-stretch: 1;
font-size: 1.5rem;
padding: 1.5rem;
}
Button {
text:"...";
vertical-stretch: 1;
}
} I tried what is suggested in #2094, but I couldn't make it work, I'll try the exact example now. What I tried that didn't work: Reimport Error (TextStyle is defined multiple times):
Only the last is exposed
|
Is Slint have a |
I found that: https://slint.dev/releases/1.3.2/docs/slint/src/language/builtins/elements#dialog |
Just to add in my strong interest in this feature and my use case. The application we'd build will need the ability to have components within the main window be able to be popped out, so the user can multitask and make use of multiple monitors/OS-level window management. So in this case the component being popped out would want to have a shared state with the parent window/component. Also generally interested in the use cases described above as well. Another thing I would mention related to the global state, and this may be wrong because I'm still learning the framework, but because the main window and global states need to both be exported in the same |
Glad to see this closed! Is it documented yet? |
No, it is not yet documented. Cf also #5467 |
Is this possible yet? I want to be able to nest windows but I don't think its implemented yet? Is there a workaround? |
The
export
keyword in.60
files can be used to make a custom component usable from other.60
files, and it is also used to mark a component for becoming "visible" to generated Rust and C++ code.Currently, only the last component in the main
.60
file that is compiled is "exported". In Rust a struct and in C++ a class is generated for it, with the knownshow()
, etc. functions and accessors for declared properties. It also provides API to access singletons.We may want to extend support in the compiler to allow exporting and thus creating multiple structs/classes, using the
export
keyword.There are open questions in this context, such as what should happen to data structures marked as
global
? How can they be shared? Where could state that is local to the created component/window go?The text was updated successfully, but these errors were encountered: