slint-ui / slint Goto Github PK
View Code? Open in Web Editor NEWSlint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
Home Page: https://slint.dev
License: Other
Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
Home Page: https://slint.dev
License: Other
This ticket tracks the ability to extend the existing support for states with transitions to be applied to properties when states are entered/exited.
Acceptance Criteria: Basic transitions can be used in .60
files, the syntax is documented and tested.
https://www.sixtyfps.io/demos/printerdemo/
I can go into the fax, but then I can't press any of the numbers.
However sometimes I can.
Maybe making that page mobile friendly (viewport tag etc) and disabling scrolling makes the focus behaviour better? (just a wild guess).
Could also be related to #15
iOS 13.3
Currently we have
property <int> my_property: 42;
callback foo; // no way to declare arguments
Proposed:
my_property := property(int) : 42;
// callback with no parameters
my_signal := callback;
// callback with parameters
my_signal2 := callback(int, string);
// callback with two parameter and a handler
my_signal3 := callback(xx: int, yy: string) => {
use(xx);
use(yy);
}
// handler for callback
my_signal => { /* ... */ }
my_signal2(aa, bb) => { /* ... */ }
Rationale is that :=
is used to declare new names for elements already, so we can re-use it for signals / properties.
The compiler can detect that a property is not used and not create it so it does not take memory at runtime
This ticket tracks the feature of being able to enter plain text (no formatting) using a keyboard.
Acceptance criteria: It's possible to enter text using a simple single-line text input field. A cursor is visible and can be placed with the keyboard and mouse. Text can be selected with the mouse.
Depends on #55
This ticket tracks the plan of making it easier to use the C++ API of SixtyFPS by making it available via the Conan C++ package manager.
Acceptance Criteria: Documentation that explains how to use Conan to easily use the existing CMake integration in C++ Applications. This may imply the availability of binary packages, but source packages would also be acceptable.
I would like the ability to share constants or perhaps properties across different components, such as settings like common colours.
One such way would be to have a const
keyword in a .60
file, which is part of the regular lookup process but results in those values being inlined:
export const <color> DefaultActiveColor : black;
const <string> DefaultName = "ok";
const <length> DefaultSize = 24lx;
export Button := Rectangle {
const <string> foo : "hello"
color: DefaultActiveColor;
}
import * as Colors from "theme_colors.60";
Rectangle {
color: Colors.DefaultActiveColor;
}
Acceptance Criteria: A way of sharing common constants across different components without duplicating them. This also needs to be documented in the language reference.
In the gallery example, when pressing the plus/minus buttons on the spin box, the button at the top flickers mysteriously.
When releasing the mouse button outside the active area (panel delimited by black border), it's still possible to move the slider when moving the mouse.
Steps to reproduce:
At the risk of this being a very open task, this ticket tracks the foundation of accessibility support. This is by no means everything, but it's a start.
Acceptance Criteria: It's possible to navigate the widget gallery demo using voiceover and a keyboard on at least one platform (such as macOS or Linux). This means the text of labels, etc. is read, it's possible to use the keyboard to navigate between different elements and activate them.
This ticket tracks the ability to declare popup menus in .60
markup as well as the ability to integrate them into a menu bar.
This needs further refinement/triaging regarding a more actionable acceptance criteria.
Currently the compiler inlines every usage of a component, which will resulting in the duplication of binding code and increases the size of the binary.
This ticket tracks the ability of the compiler to avoid this inlining step, based on heuristics or explicit annotations.
There are currently three reserved element id:
root
always refers to the component itselfself
always refers to the element in which the binding is inparent
refers to the parent of self
We got feedback that root
was confusing because it is ambiguous whether it refer to the application root (i.e, the Window
) or to the element root.
Since we cannot give a custom name to the component root element, we need a keyword name to access it.
Potential suggestions would be to use self
for the component root, and this
for the element contained in the binding. or vice versa. or use component
instead or root
.
This ticket tracks the infrastructure for the language server support and thus IDE integration.
Proposed acceptance criteria:
* The build produces a binary that supports the minimal language server protocol.
* The existing vs code extension template is extended to include launching the LSP binary for .60
files.
* The server tries to compile the edited .60
markup code and reports errors and warnings.
Currently the unit system is implemented like this:
px
is a physical pixel, for example 100px
.lx
is a logical pixel, for example 100
. It is scaled to physical pixels according to the window's device pixel ratio.This is inconsistent with CSS and we want to promote the use of scalable pixels.
We propose to change this:
px
becomes the logical pixel that's scaled according to the DPR.phx
becomes the physical, unscaled pixel.Allow for the convenient use of the common color names in .60
markup.
We could use https://crates.io/crates/css-color-parser2
The documentation of the language reference should also mention what syntax is possible.
You can use plain names if it's evident to the compiler that the property type is a color. If that's not clear, then a Color.
prefix is required. The hashed variant is always a color. This permits the following two variants:
Rectangle {
color: rgba(00, ff, 00, ff);
}
or
Rectangle {
signal hsl;
color: Color.hsl(12, 34, 56);
}
Sometimes we have components that wrap others, such as LineEdit
maybe using a TextInput
internally. In that case we want to expose the TextEdit
's text
property in LineEdit
, so that setting it forwards and reading it will fetch from the internal TextInput
.
The ability to alias properties would help accomplish that.
Acceptance criteria: Aliases implemented, tested and documented.
This would permit more compatibility or similarity with CSS and allow for properties like font-size
, padding-top
, etc.
We should normalise such names internally to use underscores (type-name
-> type_name
). Such a change has additional implications on the name lookup: If a name that's being looked up appears to be in normalised form (contains underscore) and we find it, then we should continue a lookup for the name with underscores replaced by dashes and produce an error message if we find that one, too.
In the generate code we should use the normalised form.
This ticket tracks the availability of support for a basic "online live editor" that allows editing .60
markup code in a text field in a web browser and update a separate canvas preview, for example by pressing an "Update Preview" button or by updating automatically.
This could be integrated into our documentation and allow users to explore examples further by playing around with them.
We want to be able to easily format strings with other expression.
Possible syntax:
text: `The window with is ${ root.width / 1px } and its title is ${ root.title }` ;
Advantage is that people coming from JS will be familiar with this.
\{
text: "The window with is \{ root.width / 1px } and its title is \{ root.title }";
The advantage is that there is only one form of string. (I think JS uses backtick because using normal quote would not have been backward compatible, but we don't have this problem)
The question is how good does it play with translation?
Imagine we support this syntax:
text: tr!"The window with is \{ root.width / 1px } and its title is \{ root.title }";
The translation extracting tool could extract the string "The window with is {0} and its title is {1}" as the string to be translated.
Right now, everything happens in the same thread. The event loop is running and all the binding are run in the same thread. The user code (in C++ or rust) is also expected to run in the main thread.
We would like to consider running the sixtyfps eventloop in another thread.
We need to make sure that we do not have partial update. (if the user calls instance.set_x(42); instance.set_y(42);
we do not want the rendering engine to render a frame with x set to the new value, and y to the previous value)
The user code should be able to control where its code is run (bindings evaluation, signal handler) by default, everything should happen in the user's thread.
Implementation wise, we would require to lock the component (or the window, or globally?) before doing property update, and unlock it when finish (think of it as begin_transation, end_transaction) We could automatically lock from the property setters, and unlock from the event loop.
Example of code (in rust but we could imagine something similar in C++)
let instance = MyWindow::new();
instance.on_some_signal(|| {
// always called form this thread
do_some_computation();
instance.set_property_x(42); // locks the rendering thread
instance.set_property_y(42); // lock is already locked in this thread, so does not blocks
// the lock will be released automatically when the event loop executes.
})
instance.show(); // returns immediatly
// sixtyfps::run(); // would run the event loop and blocks
while sixtyfps::next_frame().await {} // delegate the event loop to an async executor
There would be two kind of binding: main-thread binding, and render-thread binding. The sixtyfps compiler can decide which binding can be run in the render thread, and which binding need to run in the main thread.
The lock() operation would look like this (atomic pseudo code)
while locked_thread != this_thread {
if locked_thread == nil { locked_thread = this_thread; return; }
wait_condition.wait(); // blocks
if event_to_process { process_the_events() }
}
This ticket tracks the plan to make the Rust crates available on crates.io for easy use by everyone.
Acceptance Criteria: It's possible to use the Rust API via crates.io.
macOs backend for the rendering of the native style.
This ticket tracks the idea to render the graphics primitives using QPainter to a QImage and then somehow into the Window.
This would allow integrating the existing "Qt style" in a more seamless and efficient way.
Acceptance Criteria: Rendering primitives are rendered using QPainter.
This ticket tracks the ability of items to clip their contents and the content of their children to either the item's boundaries or a specified geometry.
Currently the tests in tests/cases
have to repeat the code between the three language rust
, cpp
, js
and that is fastidious as we cannot easily copy_paste.
We should make the tests more alike by adding some assert_eq
function to C++
We should have a more generic test pseudo language that allow to do operations, maybe in 60
```generic
instance.property_foo = 42
assert_eq(instance.property_foo, 42);
```
For accessibility reasons, the UI need to be usable with the keyboard.
So we need a keyboard focus. (also for text input)
Element that can gain the focus should be known to the compiler, and would have a has_focus
property which specify if the element currently has the focus.
active_focus
and focus
? (i.e: is it possible that a element has the focus property set to true while not in fact, having the current focus because, say, another component is active in another "tab" or "window")We would also need a way to tell where the focus should go by pressing tab. By default, one would compute the most reasonable chain geometrically. but this should be possible to override in the .60 using tab index property, or some kind of chaining
A regular rust build will create header files in target/debug/include, for example. That's fine with sixtyfps, but for users it's not fine - it means every user will have that in their target/ directories.
We need to find a different location that we can find again, or somehow do this only when running within sixtyfps.
This ticket tracks the availability of an item that can be used to view a sub-set of a list of data coming from a model and that allows scrolling/panning.
The for
syntax can be used to express the delegation of data to separate components that are instantiated depending on the visibility.
Proposed example syntax:
ContactListView := ListView {
property<[ { name: string } ]> contacts;
for data in contacts : MyContactDelegate {}
}
ContactListView {
contacts: {
[ {name: "Olivier"} ]
}
}
Depends on #41
Acceptance Criteria: There exists a implemented, tested and documented ListView type. It can be implemented using a for
statement and a flickable for example.
We want the ability to
Having proper expression_tree even in case of error is going to be important if we want to do refactoring on possibly incomplete code.
The wasm demos are not "touchable" in Firefox mobile (or when enabling the touch mode in the developer tools on the desktop).
This might be related to rust-windowing/winit#1286 and might require a workaround on our end.
This ticket tracks the ability to translate a Slint user interface in a way that allows annotating translatable strings,
@tr(...)
macro with the same syntax as the rust tr!
macro from the tr crate. (cf woboq/tr#1 )Put all the string in a global object and do the translation in native code
See #33 (comment)
We should consider:
parent.width * img.width / img.height
is not allowed because it is interpreted as (parent.width * img.width) / img.height
which multiplies two lenght which is not allowed. While parent.width * (img.width / img.height)
works fine. So we should allow higher dimensions, at least in partial results.Native windows backend for the native style
Commit 9fbb40d introduced a debug statement, but it still full of FIXME
The function arguments need to be handled.
The backend need to be chosen.
ideally, debug("hello", 3+3);
should print
foobar.slint:42: hello 6
But the backend should be selected. There could be a runtime function that actually do the print, and the generated code could call it.
This ticket tracks the ability to set/get properties of window items that are rendered using the windowing system, such as the title or an icon image.
A list of possible properties:
Make it possible to use layouts in .60
files that are based on the CSS flex box layout.
Stretch offers itself as an implementation in Rust for that purpose.
Acceptance criteria: Flex layouts can be used in .60
files and their API is documented.
The types table at https://www.sixtyfps.io/docs/cpp/markdown/langref.html#types looks broken.
rowspan/colspan properties are understood in the compiler, but these properties are not used at runtime.
Currently the rendering primitives stored in the rendering cache are not freed when an item gets destructed. This should be fixed by giving the CachedRenderingData a destructor called from all environments, add an Rc<> to the cache and notify the cache to free the entry.
This project is funded through NGIO Core via NLNet - https://nlnet.nl/project/SlintAndroid/
Here's a possible breakdown of tasks that we devised. We estimate this in the range of ~4 months of work.
Update: Check the documentation to try the android backend: https://docs.rs/slint/latest/slint/android/index.html
It would be great to have a top-level CMake build that builds the run-time library, the compiler, etc. everything needed in one go. That would make it much easier for C++ developers to use.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.