mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 13:51:13 +00:00
feat: color: add channel properties to color
Add extra properties to the `color` type. - `red` - `green` - `blue` - `alpha`
This commit is contained in:
parent
0409cb0140
commit
8c60cc74be
8 changed files with 73 additions and 3 deletions
|
@ -22,6 +22,7 @@ All notable changes to this project are documented in this file.
|
||||||
- Image: Added support for 9 slice scaling
|
- Image: Added support for 9 slice scaling
|
||||||
- Image: Added `horizontal-` and `vertical-tiling`
|
- Image: Added `horizontal-` and `vertical-tiling`
|
||||||
- Flickable: Added `flicked` callback
|
- Flickable: Added `flicked` callback
|
||||||
|
- Slint: Expose `.red`, `.green`, `.blue`, and `.alpha` properties on `color`
|
||||||
|
|
||||||
### Widgets
|
### Widgets
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,17 @@ draw the outline.
|
||||||
CSS Color names are only in scope in expressions of type `color` or `brush`. Otherwise, you can access
|
CSS Color names are only in scope in expressions of type `color` or `brush`. Otherwise, you can access
|
||||||
colors from the `Colors` namespace.
|
colors from the `Colors` namespace.
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
The following properties are exposed:
|
||||||
|
|
||||||
|
- **`red`**
|
||||||
|
- **`green`**
|
||||||
|
- **`blue`**
|
||||||
|
- **`alpha`**
|
||||||
|
|
||||||
|
All properties are in the range 0-255.
|
||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
|
||||||
All colors and brushes define the following methods:
|
All colors and brushes define the following methods:
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub enum BuiltinFunction {
|
||||||
StringToFloat,
|
StringToFloat,
|
||||||
/// the "42".is_float()
|
/// the "42".is_float()
|
||||||
StringIsFloat,
|
StringIsFloat,
|
||||||
|
ColorRgbaStruct,
|
||||||
ColorBrighter,
|
ColorBrighter,
|
||||||
ColorDarker,
|
ColorDarker,
|
||||||
ColorTransparentize,
|
ColorTransparentize,
|
||||||
|
@ -153,6 +154,21 @@ impl BuiltinFunction {
|
||||||
return_type: Box::new(crate::layout::layout_info_type()),
|
return_type: Box::new(crate::layout::layout_info_type()),
|
||||||
args: vec![Type::ElementReference],
|
args: vec![Type::ElementReference],
|
||||||
},
|
},
|
||||||
|
BuiltinFunction::ColorRgbaStruct => Type::Function {
|
||||||
|
return_type: Box::new(Type::Struct {
|
||||||
|
fields: IntoIterator::into_iter([
|
||||||
|
("red".to_string(), Type::Int32),
|
||||||
|
("green".to_string(), Type::Int32),
|
||||||
|
("blue".to_string(), Type::Int32),
|
||||||
|
("alpha".to_string(), Type::Int32),
|
||||||
|
])
|
||||||
|
.collect(),
|
||||||
|
name: Some("Color".into()),
|
||||||
|
node: None,
|
||||||
|
rust_attributes: None,
|
||||||
|
}),
|
||||||
|
args: vec![Type::Color],
|
||||||
|
},
|
||||||
BuiltinFunction::ColorBrighter => Type::Function {
|
BuiltinFunction::ColorBrighter => Type::Function {
|
||||||
return_type: Box::new(Type::Brush),
|
return_type: Box::new(Type::Brush),
|
||||||
args: vec![Type::Brush, Type::Float32],
|
args: vec![Type::Brush, Type::Float32],
|
||||||
|
@ -256,7 +272,8 @@ impl BuiltinFunction {
|
||||||
BuiltinFunction::SetSelectionOffsets => false,
|
BuiltinFunction::SetSelectionOffsets => false,
|
||||||
BuiltinFunction::ItemMemberFunction(..) => false,
|
BuiltinFunction::ItemMemberFunction(..) => false,
|
||||||
BuiltinFunction::StringToFloat | BuiltinFunction::StringIsFloat => true,
|
BuiltinFunction::StringToFloat | BuiltinFunction::StringIsFloat => true,
|
||||||
BuiltinFunction::ColorBrighter
|
BuiltinFunction::ColorRgbaStruct
|
||||||
|
| BuiltinFunction::ColorBrighter
|
||||||
| BuiltinFunction::ColorDarker
|
| BuiltinFunction::ColorDarker
|
||||||
| BuiltinFunction::ColorTransparentize
|
| BuiltinFunction::ColorTransparentize
|
||||||
| BuiltinFunction::ColorMix
|
| BuiltinFunction::ColorMix
|
||||||
|
@ -310,7 +327,8 @@ impl BuiltinFunction {
|
||||||
BuiltinFunction::SetSelectionOffsets => false,
|
BuiltinFunction::SetSelectionOffsets => false,
|
||||||
BuiltinFunction::ItemMemberFunction(..) => false,
|
BuiltinFunction::ItemMemberFunction(..) => false,
|
||||||
BuiltinFunction::StringToFloat | BuiltinFunction::StringIsFloat => true,
|
BuiltinFunction::StringToFloat | BuiltinFunction::StringIsFloat => true,
|
||||||
BuiltinFunction::ColorBrighter
|
BuiltinFunction::ColorRgbaStruct
|
||||||
|
| BuiltinFunction::ColorBrighter
|
||||||
| BuiltinFunction::ColorDarker
|
| BuiltinFunction::ColorDarker
|
||||||
| BuiltinFunction::ColorTransparentize
|
| BuiltinFunction::ColorTransparentize
|
||||||
| BuiltinFunction::ColorMix
|
| BuiltinFunction::ColorMix
|
||||||
|
|
|
@ -3048,6 +3048,9 @@ fn compile_builtin_function_call(
|
||||||
ctx.generator_state.conditional_includes.cstdlib.set(true);
|
ctx.generator_state.conditional_includes.cstdlib.set(true);
|
||||||
format!("[](const auto &a){{ auto e1 = std::end(a); auto e2 = const_cast<char*>(e1); auto r = std::strtod(std::begin(a), &e2); return e1 == e2 ? r : 0; }}({})", a.next().unwrap())
|
format!("[](const auto &a){{ auto e1 = std::end(a); auto e2 = const_cast<char*>(e1); auto r = std::strtod(std::begin(a), &e2); return e1 == e2 ? r : 0; }}({})", a.next().unwrap())
|
||||||
}
|
}
|
||||||
|
BuiltinFunction::ColorRgbaStruct => {
|
||||||
|
format!("{}.to_argb_u8()", a.next().unwrap())
|
||||||
|
}
|
||||||
BuiltinFunction::ColorBrighter => {
|
BuiltinFunction::ColorBrighter => {
|
||||||
format!("{}.brighter({})", a.next().unwrap(), a.next().unwrap())
|
format!("{}.brighter({})", a.next().unwrap(), a.next().unwrap())
|
||||||
}
|
}
|
||||||
|
|
|
@ -2492,6 +2492,7 @@ fn compile_builtin_function_call(
|
||||||
quote!(#(#a)*.as_str().parse::<f64>().unwrap_or_default())
|
quote!(#(#a)*.as_str().parse::<f64>().unwrap_or_default())
|
||||||
}
|
}
|
||||||
BuiltinFunction::StringIsFloat => quote!(#(#a)*.as_str().parse::<f64>().is_ok()),
|
BuiltinFunction::StringIsFloat => quote!(#(#a)*.as_str().parse::<f64>().is_ok()),
|
||||||
|
BuiltinFunction::ColorRgbaStruct => quote!( #(#a)*.to_argb_u8()),
|
||||||
BuiltinFunction::ColorBrighter => {
|
BuiltinFunction::ColorBrighter => {
|
||||||
let x = a.next().unwrap();
|
let x = a.next().unwrap();
|
||||||
let factor = a.next().unwrap();
|
let factor = a.next().unwrap();
|
||||||
|
|
|
@ -87,6 +87,7 @@ fn builtin_function_cost(function: &BuiltinFunction) -> isize {
|
||||||
BuiltinFunction::ItemMemberFunction(..) => isize::MAX,
|
BuiltinFunction::ItemMemberFunction(..) => isize::MAX,
|
||||||
BuiltinFunction::StringToFloat => 50,
|
BuiltinFunction::StringToFloat => 50,
|
||||||
BuiltinFunction::StringIsFloat => 50,
|
BuiltinFunction::StringIsFloat => 50,
|
||||||
|
BuiltinFunction::ColorRgbaStruct => 50,
|
||||||
BuiltinFunction::ColorBrighter => 50,
|
BuiltinFunction::ColorBrighter => 50,
|
||||||
BuiltinFunction::ColorDarker => 50,
|
BuiltinFunction::ColorDarker => 50,
|
||||||
BuiltinFunction::ColorTransparentize => 50,
|
BuiltinFunction::ColorTransparentize => 50,
|
||||||
|
|
|
@ -996,7 +996,24 @@ impl<'a> LookupObject for ColorExpression<'a> {
|
||||||
)),
|
)),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
None.or_else(|| f("brighter", member_function(BuiltinFunction::ColorBrighter)))
|
let field_access = |f: &str| {
|
||||||
|
LookupResult::from(Expression::StructFieldAccess {
|
||||||
|
base: Box::new(Expression::FunctionCall {
|
||||||
|
function: Box::new(Expression::BuiltinFunctionReference(
|
||||||
|
BuiltinFunction::ColorRgbaStruct,
|
||||||
|
ctx.current_token.as_ref().map(|t| t.to_source_location()),
|
||||||
|
)),
|
||||||
|
source_location: ctx.current_token.as_ref().map(|t| t.to_source_location()),
|
||||||
|
arguments: vec![self.0.clone()],
|
||||||
|
}),
|
||||||
|
name: f.into(),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
None.or_else(|| f("red", field_access("red")))
|
||||||
|
.or_else(|| f("green", field_access("green")))
|
||||||
|
.or_else(|| f("blue", field_access("blue")))
|
||||||
|
.or_else(|| f("alpha", field_access("alpha")))
|
||||||
|
.or_else(|| f("brighter", member_function(BuiltinFunction::ColorBrighter)))
|
||||||
.or_else(|| f("darker", member_function(BuiltinFunction::ColorDarker)))
|
.or_else(|| f("darker", member_function(BuiltinFunction::ColorDarker)))
|
||||||
.or_else(|| f("transparentize", member_function(BuiltinFunction::ColorTransparentize)))
|
.or_else(|| f("transparentize", member_function(BuiltinFunction::ColorTransparentize)))
|
||||||
.or_else(|| f("with-alpha", member_function(BuiltinFunction::ColorWithAlpha)))
|
.or_else(|| f("with-alpha", member_function(BuiltinFunction::ColorWithAlpha)))
|
||||||
|
|
|
@ -739,6 +739,24 @@ fn call_builtin_function(
|
||||||
panic!("Argument not a string");
|
panic!("Argument not a string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BuiltinFunction::ColorRgbaStruct => {
|
||||||
|
if arguments.len() != 1 {
|
||||||
|
panic!("internal error: incorrect argument count to ColorRGBAComponents")
|
||||||
|
}
|
||||||
|
if let Value::Brush(brush) = eval_expression(&arguments[0], local_context) {
|
||||||
|
let color = brush.color();
|
||||||
|
let values = IntoIterator::into_iter([
|
||||||
|
("red".to_string(), Value::Number(color.red().into())),
|
||||||
|
("green".to_string(), Value::Number(color.green().into())),
|
||||||
|
("blue".to_string(), Value::Number(color.blue().into())),
|
||||||
|
("alpha".to_string(), Value::Number(color.alpha().into())),
|
||||||
|
])
|
||||||
|
.collect();
|
||||||
|
Value::Struct(values)
|
||||||
|
} else {
|
||||||
|
panic!("First argument not a color");
|
||||||
|
}
|
||||||
|
}
|
||||||
BuiltinFunction::ColorBrighter => {
|
BuiltinFunction::ColorBrighter => {
|
||||||
if arguments.len() != 2 {
|
if arguments.len() != 2 {
|
||||||
panic!("internal error: incorrect argument count to ColorBrighter")
|
panic!("internal error: incorrect argument count to ColorBrighter")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue