1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0

//! A widget providing a conjoined set of linear items that function in conjunction as a single button.
//!
//! ## Example
//!
//! Add the model and a message variant in your application for handling selections.
//!
//! ```ignore
//! use iced_core::Length;
//! use cosmic::theme;
//! use cosmic::widget::segmented_button;
//!
//! enum AppMessage {
//!     Selected(segmented_button::Key)
//! }
//!
//! struct App {
//!     model: segmented_button::SingleSelectModel,
//! }
//! ```
//!
//! Then add choices to the model, while activating the first.
//!
//! ```ignore
//! application.model = segmented_button::Model::builder()
//!     .insert(|b| b.text("Choice A").data(0u16))
//!     .insert(|b| b.text("Choice B").data(1u16))
//!     .insert(|b| b.text("Choice C").data(2u16))
//!     .build();
//! ```
//!
//! Or incrementally insert items with
//!
//! ```ignore
//! let id = application.model.insert()
//!     .text("Choice C")
//!     .icon("custom-icon")
//!     .data(3u16)
//!     .data("custom-meta")
//!     .id();
//! ```
//!
//! Then use it in the view method to create segmented button widgets.
//!
//! ```ignore
//! let widget = segmented_button::horizontal(&application.model)
//!     .style(theme::SegmentedButton::ViewSeitcher)
//!     .button_height(32)
//!     .button_padding([16, 10, 16, 10])
//!     .button_spacing(8)
//!     .icon_size(16)
//!     .spacing(8)
//!     .on_activate(AppMessage::Selected);
//! ```
//!
//! And respond to events like so:
//!
//! ```ignore
//! match message {
//!     AppMessage::Selected(id) => {
//!         application.model.activate(id);
//!
//!         if let Some(number) = application.model.data::<u16>(id) {
//!             println!("activated item with number {number}");
//!         }
//!
//!         if let Some(text) = application.text(id) {
//!             println!("activated button with text {text}");
//!         }
//!     }
//! }
//! ```

mod horizontal;
mod model;
mod style;
mod vertical;
mod widget;

pub use self::horizontal::{horizontal, HorizontalSegmentedButton};
pub use self::model::{
    BuilderEntity, Entity, EntityMut, Model, ModelBuilder, MultiSelect, MultiSelectEntityMut,
    MultiSelectModel, Selectable, SingleSelect, SingleSelectEntityMut, SingleSelectModel,
};
pub use self::style::{Appearance, ItemAppearance, ItemStatusAppearance, StyleSheet};
pub use self::vertical::{vertical, VerticalSegmentedButton};
pub use self::widget::{focus, Id, SegmentedButton, SegmentedVariant};

/// Associates extra data with an external secondary map.
///
/// The secondary map internally uses a `Vec`, so should only be used for data that
pub type SecondaryMap<T> = slotmap::SecondaryMap<Entity, T>;

/// Associates extra data with an external sparse secondary map.
///
/// Sparse maps internally use a `HashMap`, for data that is sparsely associated.
pub type SparseSecondaryMap<T> = slotmap::SparseSecondaryMap<Entity, T>;