slint
slint copied to clipboard
Using `clip: true` with software renderer does not clip rounded border
mcu: esp32c2 std-idf rust
x86 debian:
esp32c2:
[package]
name = "esp32c2"
version = "0.1.0"
authors = ["xiaguangbo"]
edition = "2021"
resolver = "2"
rust-version = "1.71"
[profile.release]
opt-level = "s"
[profile.dev]
debug = true # Symbols are nice and they don't increase the size on Flash
opt-level = "z"
[features]
default = ["std", "embassy", "esp-idf-svc/native"]
pio = ["esp-idf-svc/pio"]
std = ["alloc", "esp-idf-svc/binstart", "esp-idf-svc/std"]
alloc = ["esp-idf-svc/alloc"]
nightly = ["esp-idf-svc/nightly"]
experimental = ["esp-idf-svc/experimental"]
embassy = [
"esp-idf-svc/embassy-sync",
"esp-idf-svc/critical-section",
"esp-idf-svc/embassy-time-driver",
]
[dependencies]
log = { version = "*", default-features = false }
esp-idf-svc = { version = "*", default-features = false }
num-traits = "*"
chrono = "*"
rand = "*"
slint = { version = "*", default-features = false, features = ["compat-1-2", "renderer-software", "unsafe-single-threaded"] }
[build-dependencies]
embuild = "*"
slint-build = "*"
struct TileData {
image: image,
image_visible: bool,
solved: bool,
}
component MemoryTile inherits Rectangle {
in property <bool> open_curtain;
in property <bool> solved;
in property <image> icon;
callback clicked;
height: 50px;
width: 50px;
border-radius: self.width / 2;
background: solved ? #34CE57 : #3960D5;
clip: true;
animate background { duration: 800ms; }
Image {
source: icon;
width: parent.width;
height: parent.height;
}
// Left curtain
Rectangle {
background: #193076;
x: 0px;
width: open_curtain ? 0px : (parent.width / 2);
height: parent.height;
clip: true;
animate width {
duration: 250ms;
easing: ease-in;
}
Image {
width: root.width - 25px;
height: root.height - 25px;
x: 13px;
y: 13px;
source: @image-url("../icons/tile_logo.png");
}
}
// Right curtain
Rectangle {
background: #193076;
x: open_curtain ? parent.width : (parent.width / 2);
width: open_curtain ? 0px : (parent.width / 2);
height: parent.height;
clip: true;
animate width {
duration: 250ms;
easing: ease-in;
}
animate x {
duration: 250ms;
easing: ease-in;
}
Image {
width: root.width - 25px;
height: root.height - 25px;
x: parent.width - self.width - 13px;
y: 13px;
source: @image-url("../icons/tile_logo.png");
}
}
TouchArea {
clicked => {
// Delegate to the user of this element
root.clicked();
}
width: 100%;
height: 100%;
}
}
export component AppWindow inherits Window {
width: 240px;
height: 320px;
callback check_if_pair_solved();
// Added
in property <bool> disable_tiles;
// Added
in-out property <[TileData]> memory_tiles: [
{ image: @image-url("../icons/at.png") },
{ image: @image-url("../icons/balance-scale.png") },
{ image: @image-url("../icons/bicycle.png") },
{ image: @image-url("../icons/bus.png") },
{ image: @image-url("../icons/cloud.png") },
{ image: @image-url("../icons/cogs.png") },
{ image: @image-url("../icons/motorcycle.png") },
{ image: @image-url("../icons/video.png") },
];
for tile[i] in memory_tiles: MemoryTile {
x: mod(i, 4) * (root.width / 4);
y: floor(i / 4) * (root.width / 4);
width: 50px;
height: 50px;
icon: tile.image;
open_curtain: tile.image_visible || tile.solved; // 任何一个满足都打开帘子
// propagate the solved status from the model to the tile
solved: tile.solved;
clicked => {
// old: tile.image_visible = !tile.image_visible;
// new:
// 可不可以点击
if (!root.disable_tiles) {
tile.image_visible = !tile.image_visible;
root.check_if_pair_solved();
}
}
}
}