cosmic/widget/segmented_button/mod.rs
1// Copyright 2022 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4//! A widget providing a conjoined set of linear items that function in conjunction as a single button.
5//!
6//! ## Example
7//!
8//! Add the model and a message variant in your application for handling selections.
9//!
10//! ```ignore
11//! use iced_core::Length;
12//! use cosmic::theme;
13//! use cosmic::widget::segmented_button;
14//!
15//! enum AppMessage {
16//! Selected(segmented_button::Key)
17//! }
18//!
19//! struct App {
20//! model: segmented_button::SingleSelectModel,
21//! }
22//! ```
23//!
24//! Then add choices to the model, while activating the first.
25//!
26//! ```ignore
27//! application.model = segmented_button::Model::builder()
28//! .insert(|b| b.text("Choice A").data(0u16))
29//! .insert(|b| b.text("Choice B").data(1u16))
30//! .insert(|b| b.text("Choice C").data(2u16))
31//! .build();
32//! ```
33//!
34//! Or incrementally insert items with
35//!
36//! ```ignore
37//! let id = application.model.insert()
38//! .text("Choice C")
39//! .icon("custom-icon")
40//! .data(3u16)
41//! .data("custom-meta")
42//! .id();
43//! ```
44//!
45//! Then use it in the view method to create segmented button widgets.
46//!
47//! ```ignore
48//! let widget = segmented_button::horizontal(&application.model)
49//! .style(theme::SegmentedButton::ViewSeitcher)
50//! .button_height(32)
51//! .button_padding([16, 10, 16, 10])
52//! .button_spacing(8)
53//! .icon_size(16)
54//! .spacing(8)
55//! .on_activate(AppMessage::Selected);
56//! ```
57//!
58//! And respond to events like so:
59//!
60//! ```ignore
61//! match message {
62//! AppMessage::Selected(id) => {
63//! application.model.activate(id);
64//!
65//! if let Some(number) = application.model.data::<u16>(id) {
66//! println!("activated item with number {number}");
67//! }
68//!
69//! if let Some(text) = application.text(id) {
70//! println!("activated button with text {text}");
71//! }
72//! }
73//! }
74//! ```
75
76mod horizontal;
77mod model;
78mod style;
79mod vertical;
80mod widget;
81
82pub use self::horizontal::{HorizontalSegmentedButton, horizontal};
83pub use self::model::{
84 BuilderEntity, Entity, EntityMut, Model, ModelBuilder, MultiSelect, MultiSelectEntityMut,
85 MultiSelectModel, Selectable, SingleSelect, SingleSelectEntityMut, SingleSelectModel,
86};
87pub use self::style::{Appearance, ItemAppearance, ItemStatusAppearance, StyleSheet};
88pub use self::vertical::{VerticalSegmentedButton, vertical};
89pub use self::widget::{Id, SegmentedButton, SegmentedVariant, focus};
90
91/// Associates extra data with an external secondary map.
92///
93/// The secondary map internally uses a `Vec`, so should only be used for data that
94pub type SecondaryMap<T> = slotmap::SecondaryMap<Entity, T>;
95
96/// Associates extra data with an external sparse secondary map.
97///
98/// Sparse maps internally use a `HashMap`, for data that is sparsely associated.
99pub type SparseSecondaryMap<T> = slotmap::SparseSecondaryMap<Entity, T>;