Coder Social home page Coder Social logo

slint-ui / slint Goto Github PK

View Code? Open in Web Editor NEW
15.0K 91.0 487.0 31.75 MB

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.

Home Page: https://slint.dev

License: Other

Rust 72.08% C++ 4.22% JavaScript 0.33% CMake 0.51% HTML 0.03% Python 0.54% TypeScript 3.50% Shell 0.09% CSS 0.11% C 0.01% Objective-C 0.52% Java 0.27% Slint 17.79%
rust embedded-devices language gui wasm cpp javascript ui webassembly declarative-ui

slint's People

Contributors

a1ecbr0wn avatar aurindam avatar aursen avatar be-ing avatar bjorn avatar chrischinchilla avatar colelawrence avatar darknight avatar fieran100 avatar flovangh avatar flukejones avatar guiguiprim avatar hunger avatar jamesblacklock avatar jpnurmi avatar jrmoulton avatar jturcotte avatar levrik avatar lukas-jung avatar mikom avatar montel avatar notfirefox avatar ogoffart avatar patrickelectric avatar ryban avatar rybertm avatar task-jp avatar tronical avatar waqar144 avatar zajozor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slint's Issues

Upload packages to crates.io

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.

Add support for property aliases

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.

Styling

We want the ability to

  • Change the style globably for all widgets
  • Make it easy to write your own style which is applied globaly
  • Change the style of particular widgets

ListView

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.

QPainter-based backend

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.

`debug()` statement: show filename and line number

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.

Accessibility: support for screen readers

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.

Better syntax for properties and callback declaration.

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.

Add support for de-inlining in the compiler

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.

Add support for translations

This ticket tracks the ability to translate a Slint user interface in a way that allows annotating translatable strings,

  • having the infrastructure and documentation for extracting said strings from .slint
  • using a third-party tool to translate them and feed the translations back into the Slint build process.
  • Finally the translation that's chosen at compile time should be embedded in the resulting compiled code and be visible at run-time.
  • This may include support for multiple languages and choosing between them at runtime (Language can be changed at runtime)

Proposal.

  • Use a @tr(...) macro with the same syntax as the rust tr! macro from the tr crate. (cf woboq/tr#1 )
  • update the xtr tool on crate.io to also support .slint file
  • Behind the scene, use gettext

Workaround until this is implemented.

Put all the string in a global object and do the translation in native code
See #33 (comment)

Optimize unused property

The compiler can detect that a property is not used and not create it so it does not take memory at runtime

Make it possible to define constants

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.

Add support for FlexBox layout

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.

Online Editor

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.

Improve testing ergonomics within `tests/cases`

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);
```

Add support for clipping items

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.

Add support for css named colors in the compiler

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);
}

Slider not releasing mouse control in Widget Gallery Demo

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:

  • left click on the slider
  • move mouse outside the active area
  • release mouse button
  • go back inside the active area
  • slider is still following the mouse

Keyboard focus

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.

  • Do we need a difference between 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

Don't pollute target/<profile>/ directory with includes

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.

Free GL resources when destroying items

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.

Add support for window icon

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:

  • title
  • icon
  • size constraints (maximum size, fixed size, etc.)

Make C++ packages available via Conan

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.

Add basic language server support

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.

String iterpolation

We want to be able to easily format strings with other expression.
Possible syntax:

  1. Same as javascript
 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.

  1. Using normal quote and use \{
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.

Error recovery

  • In the parser: once there is a parsing error (because of a failing except), further parsing error for that node should be silenced.
  • If there is a parse error, we should still be able to build an object tree. The problem is that right now we panic if the expected nodes are missing, but we should take that into account and have empty or error nodes in our object_tree and expression_tree

Having proper expression_tree even in case of error is going to be important if we want to do refactoring on possibly incomplete code.

Name of special element ids (root, self)

There are currently three reserved element id:

  • root always refers to the component itself
  • self always refers to the element in which the binding is in
  • parent 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.

Basic text input

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

Add support for transitions

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.

Change unit system regarding pixels

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.

Threading

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() }
}

Global CMake build that builds everything

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.

Add support for popup menus and menubar

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.

Add support for dashes in identifiers

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.

Initial Android Support

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.

  1. Base Android Port Milestone. This milestone covers the foundation of the port, to allow for the cross-compilation of a Rust based Slint application, deployment to a device, and showing primitive graphics on the screen, including text labels. Rendering is to be done with Skia, for GPU acceleration and native looking text rendering.
  1. Text Input Integration Milestone. This milestone covers the work to allow the user to interact with text input fields in Slint in a way that is consistent with other Android applications.
  • Show or hide the Android system virtual keyboard depending on focus on text input fields.
  • Ensure visibility of text input fields when focused and the virtual keyboard occupies a part of the screen. This includes scrolling and resizing the user interface.
  • Add support for text selection handles by rendering them at the correct location and allowing the user to interact with them way.
  1. Dialog and Menu Widgets. This milestone will add first-class support for Material Design Dialog and Menu components. Dialogs in general and Menus specifically are crucial for many application workflows on Android.
  • Add support for dialog components in the material design style and rendering them in a way that makes them appear like native dialogs.
  • Add support for declaring menu structures in the Slint language, rendering them with the material design style, and obtaining the user-selected menu item choice in native code.
  1. Date and Time Picker Widgets. This milestone will add support for Date and Time picker widgets, for use in dialogs. Both user interface elements represent complex controls and data models, due to different time zones and localization.
  • Add support for a widget in the material design style to allow the user to select a date, based on the system calendar and an optional provided input date.
  • Add support for a widget in the material design style for picking a time, based on the system time and an optional provided input time.

Update: Check the documentation to try the android backend: https://docs.rs/slint/latest/slint/android/index.html

More ergonomic unit handling

We should consider:

  • Allow 0 literal without unit to be converted to any unit.
  • Right now, someething like 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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.