ferroui_controls/
list_box_item.rs1use crate::i_selectable::{register_selectable, ISelectable};
2use crate::metadata::PseudoClassesAttribute;
3use crate::mixins::{PressedMixin, SelectableMixin};
4use crate::primitives::{SelectingItemsControl, TemplatedControlImpl};
5use crate::{ContentControl, ContentControlImpl, ControlImpl};
6use ferroui_base::input::{
7 InputElement, InputElementImpl, InputElementImplExt, KeyEventArgs, PointerPressedEventArgs,
8 PointerReleasedEventArgs,
9};
10use ferroui_base::interactivity::{IRoutedEventArgs, InteractiveImpl};
11use ferroui_base::layout::LayoutableImpl;
12use ferroui_base::{
13 ferro_class, ferro_impl_classes, ferro_property, instantiate, FerroObjectImpl, Ref,
14 StyledElementImpl, StyledProperty, VisualImpl,
15};
16
17#[repr(C)]
19pub struct ListBoxItem {
20 base: ContentControl,
21}
22
23ferro_class!(ListBoxItem: ContentControl);
24ferroui_base::ferro_class_info!(ListBoxItem { new: ListBoxItem::new });
25ferro_impl_classes!(
26 ListBoxItem: StyledElementImpl,
27 VisualImpl,
28 LayoutableImpl,
29 InteractiveImpl,
30 TemplatedControlImpl,
31 ContentControlImpl
32);
33
34ferroui_base::ferro_impl_classes!(ListBoxItem: FerroObjectImpl);
35
36impl InputElementImpl for ListBoxItem {
37 fn on_pointer_pressed(this: &Self, e: &PointerPressedEventArgs) {
38 Self::parent_on_pointer_pressed(this, e);
39 this.update_selection_from_event(e);
40 }
41
42 fn on_pointer_released(this: &Self, e: &PointerReleasedEventArgs) {
43 Self::parent_on_pointer_released(this, e);
44 this.update_selection_from_event(e);
45 }
46
47 fn on_key_down(this: &Self, e: &KeyEventArgs) {
48 Self::parent_on_key_down(this, e);
49 this.update_selection_from_event(e);
50 }
51}
52
53impl ControlImpl for ListBoxItem {
54 fn on_create_automation_peer(this: &Self) -> Ref<crate::automation::peers::AutomationPeer> {
55 crate::automation::peers::ListItemAutomationPeer::new(this).upcast()
56 }
57}
58
59impl ISelectable for ListBoxItem {
60 fn is_selected(&self) -> bool {
61 ListBoxItem::is_selected(self)
62 }
63
64 fn set_is_selected(&self, value: bool) {
65 ListBoxItem::set_is_selected(self, value)
66 }
67}
68
69impl ListBoxItem {
70 pub const PSEUDO_CLASSES: PseudoClassesAttribute = PseudoClassesAttribute::new(&[":pressed", ":selected"]);
72}
73
74ferroui_base::ferro_properties! { impl ListBoxItem {
75 ferro_property!(
76 pub fn is_selected_property() -> StyledProperty<bool> {
78 SelectingItemsControl::is_selected_property().add_owner::<ListBoxItem>()
79 }
80 );
81} }
82
83impl ListBoxItem {
84 pub(crate) fn static_constructor() {
85 register_selectable::<ListBoxItem>();
86 SelectableMixin::attach::<ListBoxItem>(Self::is_selected_property());
87 PressedMixin::attach::<ListBoxItem>();
88 InputElement::focusable_property().override_default_value::<ListBoxItem>(true);
89 crate::automation::AutomationProperties::is_offscreen_behavior_property()
90 .override_default_value::<ListBoxItem>(crate::automation::IsOffscreenBehavior::FromClip);
91 crate::platform::PlatformFeedback::feedback_type_property()
92 .override_default_value::<ListBoxItem>(crate::platform::FeedbackType::Auto);
93 }
94
95 pub fn construct() -> Self {
97 Self { base: ContentControl::construct() }
98 }
99
100 pub fn new() -> Ref<Self> {
101 instantiate(Self::construct())
102 }
103
104 pub fn is_selected(&self) -> bool {
106 self.get_value(Self::is_selected_property())
107 }
108
109 pub fn set_is_selected(&self, value: bool) {
110 self.set_value(Self::is_selected_property(), value)
111 }
112
113 pub fn update_selection_from_event(&self, e: &dyn IRoutedEventArgs) -> bool {
116 let this = self.to_ref().upcast();
117 match SelectingItemsControl::selecting_items_control_from_item_container(&this) {
118 Some(owner) => owner.update_selection_from_event(&this, e),
119 None => false,
120 }
121 }
122}