Skip to content

Flags support in the Slint language #9195

@ogoffart

Description

@ogoffart

Feature Description

Add built-in support for bit flags in Slint to handle properties that can have multiple values at the same time. Flags are like enums but can have multiple values at the same time.

The following is just a proposed solution from which we can iterate

Declaration

Declare flags similar to enums, but use the flag keyword:

flag MyFlag {
    option-one, option-two, option-three
}

Usage

component Foo {
    // Default value is empty (no flags set)
    property <MyFlag> options;
    
    // The literal 0 means empty flags
    options: 0;
    
    // Assign one flag
    options: MyFlag.option-one;
    
    // Flags are in scope (like enum values)
    options: option-two;
    
    // Combine flags with + operator
    options: option-one + option-two;
    
    // Remove flags with - operator
    options: Global.many-options - option-two;
    
    // Test if flag is set
    background: options.contains(MyFlag.option-one) ? red : blue;
}

Language bindings

Rust

Generate code using the bitflags crate:

bitflags! {
    pub struct MyFlag: u32 {
        const OPTION_ONE = 1 << 0; 
        const OPTION_TWO = 1 << 1;
        const OPTION_THREE = 1 << 2;
    }
}

Note that we convert the kebab case to upper case as this is the convention for Rust bitflags (just like we did rename enum value to pascal case)

C++

Use enum class with custom operators:

enum class MyFlag {
    OptionOne = 1 << 0,
    OptionTwo = 1 << 1,
    OptionThree = 1 << 2,
};

MyFlag operator+(MyFlag a, MyFlag b);
MyFlag operator-(MyFlag a, MyFlag b);
// ... other operators

JavaScript

Map to objects or use Set-like behavior (TBD).

Python

Use enum.Flag from standard library or similar approach (TBD).

Implementation notes

  • Flags are their own type - no automatic conversion to/from integers (except literal 0)
  • Flag names follow kebab-case like other Slint identifiers
  • Generated code follows target language conventions (UPPER_CASE for Rust, PascalCase for C++, etc.)

Open questions

  • Should we have a keyword for empty flags besides 0? (like empty or none)
  • Should we use C-like binary operator like |, & and so on, or shall we have more meaningful operator (+, -, +=, ...)?
  • Alternative operator for testing flags instead of .contains()? (.test(), &, |= or )

Product Impact

Metadata

Metadata

Assignees

No one assigned

    Labels

    a:language-slintCompiler for the .slint language (mO,bF)rfcRequest for comments: proposals for changes

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions