From a429fb10fdae7446b107218218a747406d617195 Mon Sep 17 00:00:00 2001 From: taichi765 Date: Mon, 17 Nov 2025 16:39:46 +0900 Subject: [PATCH 1/5] TabWidget: Add orientation property and vertical layout --- internal/compiler/builtins.slint | 1 + internal/compiler/widgets/material/tabwidget.slint | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/compiler/builtins.slint b/internal/compiler/builtins.slint index 906649843b0..3f38a1d5557 100644 --- a/internal/compiler/builtins.slint +++ b/internal/compiler/builtins.slint @@ -534,6 +534,7 @@ component Tab { // Note: not a native class, handled in the lower_tabs pass export component TabWidget { in-out property current-index; + in property orientation; //-disallow_global_types_as_child_elements Tab { } diff --git a/internal/compiler/widgets/material/tabwidget.slint b/internal/compiler/widgets/material/tabwidget.slint index 5437141d76d..70a3be7ee8d 100644 --- a/internal/compiler/widgets/material/tabwidget.slint +++ b/internal/compiler/widgets/material/tabwidget.slint @@ -12,14 +12,15 @@ export component TabWidgetImpl inherits Rectangle { in property content-min-width; in property current-index; in property current-focused; - out property content-x: 0; - out property content-y: root.tabbar-preferred-height; - out property content-height: root.height - root.tabbar-preferred-height; - out property content-width: root.width; + in property orientation: Orientation.horizontal; + out property content-x: orientation==Orientation.horizontal?0:root.tabbar-preferred-width; + out property content-y: orientation==Orientation.horizontal?root.tabbar-preferred-height:0; + out property content-height: orientation==Orientation.horizontal?root.height - root.tabbar-preferred-height:root.height; + out property content-width: orientation==Orientation.horizontal?root.width:root.width - root.tabbar-preferred-width; out property tabbar-x: 0; out property tabbar-y: 0; - out property tabbar-height: root.tabbar-preferred-height; - out property tabbar-width: root.width; + out property tabbar-height: orientation==Orientation.horizontal?root.tabbar-preferred-height:root.height; + out property tabbar-width: orientation==Orientation.horizontal?root.width:root.tabbar-preferred-width; preferred-width: root.content-min-width; min-width: max(root.content-min-width, root.tabbar-preferred-width); From 4ffe12433d792c961e4cedf11f72a083ac5a265f Mon Sep 17 00:00:00 2001 From: taichi765 Date: Mon, 17 Nov 2025 16:42:19 +0900 Subject: [PATCH 2/5] TabWidget: Separate TabBarImpl component There were many duplicated part --- .../widgets/material/std-widgets.slint | 2 +- .../compiler/widgets/material/tabwidget.slint | 24 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/internal/compiler/widgets/material/std-widgets.slint b/internal/compiler/widgets/material/std-widgets.slint index e5fc545b1b0..53ddd7c4e2e 100644 --- a/internal/compiler/widgets/material/std-widgets.slint +++ b/internal/compiler/widgets/material/std-widgets.slint @@ -7,7 +7,7 @@ export { AboutSlint } from "../common/about-slint.slint"; export { StandardButton } from "../common/standardbutton.slint"; export { StyleMetrics, ScrollView, Button, CheckBox, Palette } from "std-widgets-impl.slint"; export { LineEdit } from "lineedit.slint"; -export { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget } from "tabwidget.slint"; +export { TabWidgetImpl, TabImpl, TabBarHorizontalImpl,TabBarVerticalImpl, TabWidget } from "tabwidget.slint"; export { GroupBox } from "groupbox.slint"; export { VerticalBox, HorizontalBox, GridBox } from "../common/layout.slint"; export { Slider } from "slider.slint"; diff --git a/internal/compiler/widgets/material/tabwidget.slint b/internal/compiler/widgets/material/tabwidget.slint index 70a3be7ee8d..7f7bd1800c3 100644 --- a/internal/compiler/widgets/material/tabwidget.slint +++ b/internal/compiler/widgets/material/tabwidget.slint @@ -113,7 +113,7 @@ export component TabImpl inherits Rectangle { } } -export component TabBarImpl inherits TabBarBase { +component MaterialTabBarBase inherits TabBarBase { // injected properties: // The currently focused tab in-out property current-focused: focus-scope.has-focus ? focus-scope.focused-tab : -1; @@ -122,11 +122,7 @@ export component TabBarImpl inherits TabBarBase { accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current; accessible-item-count: root.num-tabs; - Flickable { - HorizontalLayout { - @children - } - } + focus-scope := FocusScope { property focused-tab: 0; @@ -161,4 +157,20 @@ export component TabBarImpl inherits TabBarBase { } } +export component TabBarHorizontalImpl inherits MaterialTabBarBase { + Flickable { + HorizontalLayout { + @children + } + } +} + +export component TabBarVerticalImpl inherits MaterialTabBarBase { + Flickable { + VerticalLayout { + @children + } + } +} + export component TabWidget inherits TabWidget { } From eaaf4ef05907e4fad0173d2a5492171929a054aa Mon Sep 17 00:00:00 2001 From: taichi765 Date: Mon, 17 Nov 2025 16:44:52 +0900 Subject: [PATCH 3/5] TabWidget: Use separate horizontal and vertical TabBar implementations based on orientation --- internal/compiler/passes/lower_tabwidget.rs | 24 ++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/internal/compiler/passes/lower_tabwidget.rs b/internal/compiler/passes/lower_tabwidget.rs index 30bda4869a1..d5c24487817 100644 --- a/internal/compiler/passes/lower_tabwidget.rs +++ b/internal/compiler/passes/lower_tabwidget.rs @@ -30,10 +30,14 @@ pub async fn lower_tabwidget( .import_component("std-widgets.slint", "TabImpl", &mut build_diags_to_ignore) .await .expect("can't load TabImpl from std-widgets.slint"); - let tabbar_impl = type_loader - .import_component("std-widgets.slint", "TabBarImpl", &mut build_diags_to_ignore) + let tabbar_horizontal_impl = type_loader + .import_component("std-widgets.slint", "TabBarHorizontalImpl", &mut build_diags_to_ignore) .await - .expect("can't load TabBarImpl from std-widgets.slint"); + .expect("can't load TabBarHorizontalImpl from std-widgets.slint"); + let tabbar_vertical_impl = type_loader + .import_component("std-widgets.slint", "TabBarVerticalImpl", &mut build_diags_to_ignore) + .await + .expect("can't load TabBarVerticalImpl from std-widgets.slint"); let empty_type = type_loader.global_type_registry.borrow().empty_type(); doc.visit_all_used_components(|component| { @@ -43,7 +47,8 @@ pub async fn lower_tabwidget( elem, ElementType::Component(tabwidget_impl.clone()), ElementType::Component(tab_impl.clone()), - ElementType::Component(tabbar_impl.clone()), + ElementType::Component(tabbar_horizontal_impl.clone()), + ElementType::Component(tabbar_vertical_impl.clone()), &empty_type, diag, ); @@ -56,7 +61,8 @@ fn process_tabwidget( elem: &ElementRc, tabwidget_impl: ElementType, tab_impl: ElementType, - tabbar_impl: ElementType, + tabbar_horizontal_impl: ElementType, + tabbar_vertical_impl: ElementType, empty_type: &ElementType, diag: &mut BuildDiagnostics, ) { @@ -175,6 +181,14 @@ fn process_tabwidget( tabs.push(Element::make_rc(tab)); } + let mut tabbar_impl = tabbar_horizontal_impl; + if let Some(orientation) = elem.borrow().bindings.get("orientation") { + if let Expression::EnumerationValue(val) = &orientation.borrow().expression { + if val.value == 1 { + tabbar_impl = tabbar_vertical_impl; + } + } + } let tabbar = Element { id: format_smolstr!("{}-tabbar", elem.borrow().id), base_type: tabbar_impl, From 3e54dc2b2a81efcc58209e11c450a4571bc424e8 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:57:39 +0000 Subject: [PATCH 4/5] [autofix.ci] apply automated fixes --- internal/compiler/widgets/material/tabwidget.slint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/compiler/widgets/material/tabwidget.slint b/internal/compiler/widgets/material/tabwidget.slint index 7f7bd1800c3..2eb45e9c94a 100644 --- a/internal/compiler/widgets/material/tabwidget.slint +++ b/internal/compiler/widgets/material/tabwidget.slint @@ -122,7 +122,7 @@ component MaterialTabBarBase inherits TabBarBase { accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current; accessible-item-count: root.num-tabs; - + focus-scope := FocusScope { property focused-tab: 0; From 0c90d8075196a7faa5c4c4a7c0ef33b680634649 Mon Sep 17 00:00:00 2001 From: taichi765 Date: Sat, 22 Nov 2025 12:00:23 +0900 Subject: [PATCH 5/5] TabWidget: Report error when orientation property was not constant --- internal/compiler/passes/lower_tabwidget.rs | 9 ++++++++- internal/compiler/typeregister.rs | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/internal/compiler/passes/lower_tabwidget.rs b/internal/compiler/passes/lower_tabwidget.rs index d5c24487817..cd32054daa0 100644 --- a/internal/compiler/passes/lower_tabwidget.rs +++ b/internal/compiler/passes/lower_tabwidget.rs @@ -183,10 +183,17 @@ fn process_tabwidget( let mut tabbar_impl = tabbar_horizontal_impl; if let Some(orientation) = elem.borrow().bindings.get("orientation") { - if let Expression::EnumerationValue(val) = &orientation.borrow().expression { + if let Expression::EnumerationValue(val) = + super::ignore_debug_hooks(&orientation.borrow().expression) + { if val.value == 1 { tabbar_impl = tabbar_vertical_impl; } + } else { + diag.push_error( + "The orientation property only supports constants at the moment".into(), + &orientation.borrow().span, + ); } } let tabbar = Element { diff --git a/internal/compiler/typeregister.rs b/internal/compiler/typeregister.rs index 85a10d4c127..569446e3912 100644 --- a/internal/compiler/typeregister.rs +++ b/internal/compiler/typeregister.rs @@ -566,6 +566,15 @@ impl TypeRegister { _ => unreachable!(), }; + match &mut register.elements.get_mut("TabWidget").unwrap() { + ElementType::Builtin(b) => { + let tabwidget = Rc::get_mut(b).unwrap(); + tabwidget.properties.get_mut("orientation").unwrap().property_visibility = + PropertyVisibility::Constexpr; + } + _ => unreachable!(), + } + register }