Skip to content

Commit 116e72f

Browse files
committed
compiler: Expose a KeyboardShortcut struct to slint code
Language Suppord: * Rust: :check: * C++: :fail: * Python: ❓ * JS: ❓
1 parent 88cb851 commit 116e72f

File tree

18 files changed

+160
-39
lines changed

18 files changed

+160
-39
lines changed

api/node/rust/interpreter/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub fn to_value(env: &Env, unknown: JsUnknown, typ: &Type) -> Result<Value> {
290290
| Type::Easing
291291
| Type::PathData
292292
| Type::LayoutCache
293-
| Type::KeyboardShortcut
293+
| Type::KeyboardShortcutType
294294
| Type::ElementReference => Err(napi::Error::from_reason("reason")),
295295
}
296296
}

internal/common/builtin_structs.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ macro_rules! for_each_builtin_structs {
5454
}
5555
}
5656

57+
/// A `KeyboardShortcut` for use in `MenuItem` and other places
58+
struct KeyboardShortcut {
59+
@name = "slint::private_api::KeyboardShortcut"
60+
export {
61+
/// The `key` used to trigger the shortcut
62+
key: SharedString,
63+
/// `KeyboardModifier`s that need to be pressed for the shortcut to fire
64+
modifiers: KeyboardModifiers,
65+
}
66+
private {
67+
}
68+
}
69+
5770
/// Represents a Pointer event sent by the windowing system.
5871
/// This structure is passed to the `pointer-event` callback of the `TouchArea` element.
5972
struct PointerEvent {

internal/compiler/builtin_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ fn to_debug_string(
327327
| Type::Image
328328
| Type::Easing
329329
| Type::Array(_)
330-
| Type::KeyboardShortcut => {
330+
| Type::KeyboardShortcutType => {
331331
Expression::StringLiteral("<debug-of-this-type-not-yet-implemented>".into())
332332
}
333333
Type::Duration

internal/compiler/expression_tree.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ pub enum Expression {
734734

735735
EnumerationValue(EnumerationValue),
736736

737-
KeyboardShortcut(Vec<KeyboardShortcut>),
737+
KeyboardShortcut(KeyboardShortcut),
738738

739739
ReturnStatement(Option<Box<Expression>>),
740740

@@ -877,7 +877,7 @@ impl Expression {
877877
Expression::RadialGradient { .. } => Type::Brush,
878878
Expression::ConicGradient { .. } => Type::Brush,
879879
Expression::EnumerationValue(value) => Type::Enumeration(value.enumeration.clone()),
880-
Expression::KeyboardShortcut(_) => Type::KeyboardShortcut,
880+
Expression::KeyboardShortcut(_) => Type::KeyboardShortcutType,
881881
// invalid because the expression is unreachable
882882
Expression::ReturnStatement(_) => Type::Invalid,
883883
Expression::LayoutCacheAccess { .. } => Type::LogicalLength,
@@ -1412,7 +1412,7 @@ impl Expression {
14121412
Type::Enumeration(enumeration) => {
14131413
Expression::EnumerationValue(enumeration.clone().default_value())
14141414
}
1415-
Type::KeyboardShortcut => Expression::KeyboardShortcut(vec![]),
1415+
Type::KeyboardShortcutType => Expression::KeyboardShortcut(KeyboardShortcut::default()),
14161416
Type::ComponentFactory => Expression::EmptyComponentFactory,
14171417
}
14181418
}
@@ -1808,7 +1808,7 @@ pub fn pretty_print(f: &mut dyn std::fmt::Write, expression: &Expression) -> std
18081808
None => write!(f, "{}.{}", e.enumeration.name, e.value),
18091809
},
18101810
Expression::KeyboardShortcut(ks) => {
1811-
write!(f, "@keys({})", crate::langtype::keyboard_shortcuts_to_string(ks))
1811+
write!(f, "@keys({})", ks.to_string())
18121812
}
18131813
Expression::ReturnStatement(e) => {
18141814
write!(f, "return ")?;

internal/compiler/generator/cpp.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ impl CppType for Type {
506506
Type::Void => Some("void".into()),
507507
Type::Float32 => Some("float".into()),
508508
Type::Int32 => Some("int".into()),
509-
Type::String | Type::KeyboardShortcut => Some("slint::SharedString".into()),
509+
Type::String | Type::KeyboardShortcutType => Some("slint::SharedString".into()),
510510
Type::Color => Some("slint::Color".into()),
511511
Type::Duration => Some("std::int64_t".into()),
512512
Type::Angle => Some("float".into()),
@@ -3118,6 +3118,12 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
31183118
}
31193119
}
31203120
Expression::BoolLiteral(b) => b.to_string(),
3121+
Expression::KeyboardShortcutLiteral(ks) => {
3122+
format!(
3123+
"slint::private_api::KeyboardShortcut {{ .key = {}, .modifiers = {{{}, {}, {}, {}}} }}",
3124+
ks.key, ks.modifiers.alt, ks.modifiers.control, ks.modifiers.shift, ks.modifiers.meta
3125+
)
3126+
}
31213127
Expression::PropertyReference(nr) => {
31223128
let access = access_member(nr, ctx);
31233129
format!(r#"{access}.get()"#)

internal/compiler/generator/rust.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn rust_primitive_type(ty: &Type) -> Option<proc_macro2::TokenStream> {
8181
Type::Void => Some(quote!(())),
8282
Type::Int32 => Some(quote!(i32)),
8383
Type::Float32 => Some(quote!(f32)),
84-
Type::String | Type::KeyboardShortcut => Some(quote!(sp::SharedString)),
84+
Type::String => Some(quote!(sp::SharedString)),
8585
Type::Color => Some(quote!(sp::Color)),
8686
Type::ComponentFactory => Some(quote!(slint::ComponentFactory)),
8787
Type::Duration => Some(quote!(i64)),
@@ -114,6 +114,7 @@ pub fn rust_primitive_type(ty: &Type) -> Option<proc_macro2::TokenStream> {
114114
Some(quote!(sp::#i))
115115
}
116116
}
117+
Type::KeyboardShortcutType => Some(quote!(sp::KeyboardShortcut)),
117118
Type::Brush => Some(quote!(slint::Brush)),
118119
Type::LayoutCache => Some(quote!(
119120
sp::SharedVector<
@@ -2204,6 +2205,15 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
22042205
let s = s.as_str();
22052206
quote!(sp::SharedString::from(#s))
22062207
}
2208+
Expression::KeyboardShortcutLiteral(shortcut) => {
2209+
let key = shortcut.key.clone();
2210+
let alt = shortcut.modifiers.alt;
2211+
let control = shortcut.modifiers.control;
2212+
let shift = shortcut.modifiers.shift;
2213+
let meta = shortcut.modifiers.meta;
2214+
2215+
quote!(sp::KeyboardShortcut { key: #key.into(), modifiers: sp::KeyboardModifiers { alt: #alt, control: #control, shift: #shift, meta: #meta } })
2216+
},
22072217
Expression::NumberLiteral(n) if n.is_finite() => quote!(#n),
22082218
Expression::NumberLiteral(_) => quote!(0.),
22092219
Expression::BoolLiteral(b) => quote!(#b),
@@ -3254,7 +3264,7 @@ fn compile_builtin_function_call(
32543264
let ident = format_ident!("timer{}", *timer_index as usize);
32553265
quote!(_self.#ident.restart())
32563266
} else {
3257-
panic!("internal error: invalid args to RetartTimer {arguments:?}")
3267+
panic!("internal error: invalid args to RestartTimer {arguments:?}")
32583268
}
32593269
}
32603270
}

internal/compiler/langtype.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub enum Type {
5454
Array(Rc<Type>),
5555
Struct(Rc<Struct>),
5656
Enumeration(Rc<Enumeration>),
57-
KeyboardShortcut,
57+
KeyboardShortcutType,
5858

5959
/// A type made up of the product of several "unit" types.
6060
/// The first parameter is the unit, and the second parameter is the power.
@@ -102,7 +102,7 @@ impl core::cmp::PartialEq for Type {
102102
matches!(other, Type::Struct(rhs) if lhs.fields == rhs.fields && lhs.name == rhs.name)
103103
}
104104
Type::Enumeration(lhs) => matches!(other, Type::Enumeration(rhs) if lhs == rhs),
105-
Type::KeyboardShortcut => matches!(other, Type::KeyboardShortcut),
105+
Type::KeyboardShortcutType => matches!(other, Type::KeyboardShortcutType),
106106
Type::UnitProduct(a) => matches!(other, Type::UnitProduct(b) if a == b),
107107
Type::ElementReference => matches!(other, Type::ElementReference),
108108
Type::LayoutCache => matches!(other, Type::LayoutCache),
@@ -162,7 +162,7 @@ impl Display for Type {
162162
Type::Easing => write!(f, "easing"),
163163
Type::Brush => write!(f, "brush"),
164164
Type::Enumeration(enumeration) => write!(f, "enum {}", enumeration.name),
165-
Type::KeyboardShortcut => write!(f, "keyboard-shortcut"),
165+
Type::KeyboardShortcutType => write!(f, "keyboard-shortcut"),
166166
Type::UnitProduct(vec) => {
167167
const POWERS: &[char] = &['⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹'];
168168
let mut x = vec.iter().map(|(unit, power)| {
@@ -211,7 +211,7 @@ impl Type {
211211
| Self::Bool
212212
| Self::Easing
213213
| Self::Enumeration(_)
214-
| Self::KeyboardShortcut
214+
| Self::KeyboardShortcutType
215215
| Self::ElementReference
216216
| Self::Struct { .. }
217217
| Self::Array(_)
@@ -315,7 +315,7 @@ impl Type {
315315
Type::Array(_) => None,
316316
Type::Struct { .. } => None,
317317
Type::Enumeration(_) => None,
318-
Type::KeyboardShortcut => None,
318+
Type::KeyboardShortcutType => None,
319319
Type::UnitProduct(_) => None,
320320
Type::ElementReference => None,
321321
Type::LayoutCache => None,
@@ -866,18 +866,18 @@ impl PartialEq for KeyboardShortcut {
866866

867867
impl std::fmt::Display for KeyboardShortcut {
868868
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
869-
let alt = if self.modifiers.alt { "Alt+" } else { "" };
870-
let ctrl = if self.modifiers.control { "Control+" } else { "" };
871-
let meta = if self.modifiers.meta { "Meta+" } else { "" };
872-
let shift = if self.modifiers.shift { "shift+" } else { "" };
873-
write!(f, "{alt}{ctrl}{meta}{shift}{}", self.key)
869+
if self.key.is_empty() {
870+
write!(f, "")
871+
} else {
872+
let alt = if self.modifiers.alt { "Alt+" } else { "" };
873+
let ctrl = if self.modifiers.control { "Control+" } else { "" };
874+
let meta = if self.modifiers.meta { "Meta+" } else { "" };
875+
let shift = if self.modifiers.shift { "shift+" } else { "" };
876+
write!(f, "{alt}{ctrl}{meta}{shift}{}", self.key)
877+
}
874878
}
875879
}
876880

877-
pub fn keyboard_shortcuts_to_string(shortcuts: &[KeyboardShortcut]) -> String {
878-
shortcuts.iter().map(|ks| ks.to_string()).join(", ")
879-
}
880-
881881
#[derive(Clone, Debug)]
882882
pub struct EnumerationValue {
883883
pub value: usize, // index in enumeration.values

internal/compiler/llr/expression.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::{
55
GlobalIdx, PropertyReference, RepeatedElementIdx, SubComponentIdx, SubComponentInstanceIdx,
66
};
77
use crate::expression_tree::{BuiltinFunction, MinMaxOp, OperatorClass};
8-
use crate::langtype::Type;
8+
use crate::langtype::{KeyboardShortcut, Type};
99
use crate::layout::Orientation;
1010
use core::num::NonZeroUsize;
1111
use itertools::Either;
@@ -22,6 +22,9 @@ pub enum Expression {
2222
/// Bool
2323
BoolLiteral(bool),
2424

25+
// KeyboardShortcut
26+
KeyboardShortcutLiteral(KeyboardShortcut),
27+
2528
/// Reference to a property (which can also be a callback) or an element (property name is empty then).
2629
PropertyReference(PropertyReference),
2730

@@ -264,7 +267,9 @@ impl Expression {
264267
Type::Enumeration(enumeration) => {
265268
Expression::EnumerationValue(enumeration.clone().default_value())
266269
}
267-
Type::KeyboardShortcut => Expression::StringLiteral(SmolStr::new_static("")),
270+
Type::KeyboardShortcutType => {
271+
Expression::KeyboardShortcutLiteral(KeyboardShortcut::default())
272+
}
268273
Type::ComponentFactory => Expression::EmptyComponentFactory,
269274
})
270275
}
@@ -319,6 +324,7 @@ impl Expression {
319324
Self::RadialGradient { .. } => Type::Brush,
320325
Self::ConicGradient { .. } => Type::Brush,
321326
Self::EnumerationValue(e) => Type::Enumeration(e.enumeration.clone()),
327+
Self::KeyboardShortcutLiteral(_) => Type::KeyboardShortcutType,
322328
Self::LayoutCacheAccess { .. } => Type::LogicalLength,
323329
Self::BoxLayoutFunction { sub_expression, .. } => sub_expression.ty(ctx),
324330
Self::ComputeDialogLayoutCells { .. } => {
@@ -398,6 +404,7 @@ macro_rules! visit_impl {
398404
}
399405
}
400406
Expression::EnumerationValue(_) => {}
407+
Expression::KeyboardShortcutLiteral(_) => {}
401408
Expression::LayoutCacheAccess { repeater_index, .. } => {
402409
if let Some(repeater_index) = repeater_index {
403410
$visitor(repeater_index);

internal/compiler/llr/lower_expression.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use smol_str::{format_smolstr, SmolStr};
1212
use super::lower_to_item_tree::{LoweredElement, LoweredSubComponentMapping, LoweringState};
1313
use super::{Animation, PropertyIdx, PropertyReference, RepeatedElementIdx};
1414
use crate::expression_tree::{BuiltinFunction, Callable, Expression as tree_Expression};
15-
use crate::langtype::{self, EnumerationValue, Struct, Type};
15+
use crate::langtype::{EnumerationValue, Struct, Type};
1616
use crate::layout::Orientation;
1717
use crate::llr::Expression as llr_Expression;
1818
use crate::namedreference::NamedReference;
@@ -241,7 +241,7 @@ pub fn lower_expression(
241241
},
242242
tree_Expression::EnumerationValue(e) => llr_Expression::EnumerationValue(e.clone()),
243243
tree_Expression::KeyboardShortcut(ks) => {
244-
llr_Expression::StringLiteral(SmolStr::from(langtype::keyboard_shortcuts_to_string(ks)))
244+
llr_Expression::KeyboardShortcutLiteral(ks.clone())
245245
}
246246
tree_Expression::ReturnStatement(..) => {
247247
panic!("The remove return pass should have removed all return")

internal/compiler/llr/optim_passes/inline_expressions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ fn expression_cost(exp: &Expression, ctx: &EvaluationContext) -> isize {
2424
Expression::StringLiteral(_) => ALLOC_COST,
2525
Expression::NumberLiteral(_) => 0,
2626
Expression::BoolLiteral(_) => 0,
27+
Expression::KeyboardShortcutLiteral(_) => 0,
2728
Expression::PropertyReference(_) => PROPERTY_ACCESS_COST,
2829
Expression::FunctionParameterReference { .. } => return isize::MAX,
2930
Expression::StoreLocalVariable { .. } => 0,

0 commit comments

Comments
 (0)