cosmic/widget/
mod.rs

1// Copyright 2022 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4//! The COSMIC widget library
5//!
6//! This module contains a wide variety of widgets used throughout the COSMIC app ecosystem.
7//!
8//! # Overview
9//!
10//! Add widgets to your application view by calling the modules and functions below.
11//! Widgets are constructed by chaining their property methods using a functional paradigm.
12//! Modules may contain additional functions for constructing different variations of a widget.
13//! Each module will typically have one widget with the same name as the module, which will be re-exported here.
14//!
15//! ```no_run,ignore
16//! use cosmic::prelude::*;
17//! use cosmic::{cosmic_theme, theme, widget};
18//!
19//! const REPOSITORY: &str = "https://github.com/pop-os/libcosmic";
20//!
21//! let cosmic_theme::Spacing { space_xxs, .. } = theme::spacing();
22//!
23//! let link = widget::button::link(REPOSITORY)
24//!     .on_press(Message::LaunchUrl(REPOSITORY))
25//!     .padding(0);
26//!
27//! let content = widget::column()
28//!     .push(widget::icon::from_name("my-app-icon"))
29//!     .push(widget::text::title3("My App Name"))
30//!     .push(link)
31//!     .align_items(Alignment::Center)
32//!     .spacing(space_xxs);
33//! ```
34//!
35//! Widgets may borrow data from your application struct, and should do so to avoid allocating.
36//!
37//! ```no_run,ignore
38//! let text = widget::text::body(&self.cached_text);
39//! ```
40//!
41//! Use the [`cosmic::Apply`](crate::Apply) trait to embed widgets into other widgets which accept them.
42//!
43//! ```no_run,ignore
44//! let button = widget::icon::from_name("printer-symbolic")
45//!     .apply(widget::button::icon)
46//!     .on_press(Message::Print);
47//! ```
48
49// Re-exports from Iced
50#[doc(inline)]
51pub use iced::widget::{Canvas, canvas};
52
53#[doc(inline)]
54pub use iced::widget::{Checkbox, checkbox};
55
56#[doc(inline)]
57pub use iced::widget::{ComboBox, combo_box};
58
59#[doc(inline)]
60pub use iced::widget::{Container, container};
61
62#[doc(inline)]
63pub use iced::widget::{Space, horizontal_space, vertical_space};
64
65#[doc(inline)]
66pub use iced::widget::{Image, image};
67
68#[doc(inline)]
69pub use iced::widget::{Lazy, lazy};
70
71#[doc(inline)]
72pub use iced::widget::{MouseArea, mouse_area};
73
74#[doc(inline)]
75pub use iced::widget::{PaneGrid, pane_grid};
76
77#[doc(inline)]
78pub use iced::widget::{ProgressBar, progress_bar};
79
80#[doc(inline)]
81pub use iced::widget::{Responsive, responsive};
82
83#[doc(inline)]
84pub use iced::widget::{Slider, VerticalSlider, slider, vertical_slider};
85
86#[doc(inline)]
87pub use iced::widget::{Svg, svg};
88
89#[doc(inline)]
90pub use iced::widget::{TextEditor, text_editor};
91
92#[doc(inline)]
93pub use iced_core::widget::{Id, Operation, Widget};
94
95pub mod aspect_ratio;
96
97#[cfg(feature = "autosize")]
98pub mod autosize;
99
100pub(crate) mod responsive_container;
101
102#[cfg(feature = "surface-message")]
103mod responsive_menu_bar;
104#[cfg(feature = "surface-message")]
105#[doc(inline)]
106pub use responsive_menu_bar::{ResponsiveMenuBar, responsive_menu_bar};
107
108pub mod button;
109#[doc(inline)]
110pub use button::{Button, IconButton, LinkButton, TextButton};
111
112pub(crate) mod common;
113
114pub mod calendar;
115#[doc(inline)]
116pub use calendar::{Calendar, calendar};
117
118pub mod card;
119#[doc(inline)]
120pub use card::*;
121
122pub mod color_picker;
123#[doc(inline)]
124pub use color_picker::{ColorPicker, ColorPickerModel};
125
126#[cfg(feature = "qr_code")]
127#[doc(inline)]
128pub use iced::widget::qr_code;
129
130pub mod context_drawer;
131#[doc(inline)]
132pub use context_drawer::{ContextDrawer, context_drawer};
133
134#[doc(inline)]
135pub use column::{Column, column};
136pub mod column {
137    //! A container which aligns its children in a column.
138
139    pub type Column<'a, Message> = iced::widget::Column<'a, Message, crate::Theme, crate::Renderer>;
140
141    #[must_use]
142    /// A container which aligns its children in a column.
143    pub fn column<'a, Message>() -> Column<'a, Message> {
144        Column::new()
145    }
146
147    #[must_use]
148    /// A pre-allocated [`column`].
149    pub fn with_capacity<'a, Message>(capacity: usize) -> Column<'a, Message> {
150        Column::with_capacity(capacity)
151    }
152
153    #[must_use]
154    /// A [`column`] that will be assigned an [`Iterator`] of children.
155    pub fn with_children<'a, Message>(
156        children: impl IntoIterator<Item = crate::Element<'a, Message>>,
157    ) -> Column<'a, Message> {
158        Column::with_children(children)
159    }
160}
161
162pub mod layer_container;
163#[doc(inline)]
164pub use layer_container::{LayerContainer, layer_container};
165
166pub mod context_menu;
167#[doc(inline)]
168pub use context_menu::{ContextMenu, context_menu};
169
170pub mod dialog;
171#[doc(inline)]
172pub use dialog::{Dialog, dialog};
173
174/// An element to distinguish a boundary between two elements.
175pub mod divider {
176    /// Horizontal variant of a divider.
177    pub mod horizontal {
178        use iced::widget::{Rule, horizontal_rule};
179
180        /// Horizontal divider with default thickness
181        #[must_use]
182        pub fn default<'a>() -> Rule<'a, crate::Theme> {
183            horizontal_rule(1).class(crate::theme::Rule::Default)
184        }
185
186        /// Horizontal divider with light thickness
187        #[must_use]
188        pub fn light<'a>() -> Rule<'a, crate::Theme> {
189            horizontal_rule(1).class(crate::theme::Rule::LightDivider)
190        }
191
192        /// Horizontal divider with heavy thickness.
193        #[must_use]
194        pub fn heavy<'a>() -> Rule<'a, crate::Theme> {
195            horizontal_rule(4).class(crate::theme::Rule::HeavyDivider)
196        }
197    }
198
199    /// Vertical variant of a divider.
200    pub mod vertical {
201        use iced::widget::{Rule, vertical_rule};
202
203        /// Vertical divider with default thickness
204        #[must_use]
205        pub fn default<'a>() -> Rule<'a, crate::Theme> {
206            vertical_rule(1).class(crate::theme::Rule::Default)
207        }
208
209        /// Vertical divider with light thickness
210        #[must_use]
211        pub fn light<'a>() -> Rule<'a, crate::Theme> {
212            vertical_rule(4).class(crate::theme::Rule::LightDivider)
213        }
214
215        /// Vertical divider with heavy thickness.
216        #[must_use]
217        pub fn heavy<'a>() -> Rule<'a, crate::Theme> {
218            vertical_rule(10).class(crate::theme::Rule::HeavyDivider)
219        }
220    }
221}
222
223pub mod dnd_destination;
224#[doc(inline)]
225pub use dnd_destination::{DndDestination, dnd_destination};
226
227pub mod dnd_source;
228#[doc(inline)]
229pub use dnd_source::{DndSource, dnd_source};
230
231pub mod dropdown;
232#[doc(inline)]
233pub use dropdown::{Dropdown, dropdown};
234
235pub mod flex_row;
236#[doc(inline)]
237pub use flex_row::{FlexRow, flex_row};
238
239pub mod grid;
240#[doc(inline)]
241pub use grid::{Grid, grid};
242
243mod header_bar;
244#[doc(inline)]
245pub use header_bar::{HeaderBar, header_bar};
246
247pub mod icon;
248#[doc(inline)]
249pub use icon::{Icon, icon};
250
251pub mod id_container;
252#[doc(inline)]
253pub use id_container::{IdContainer, id_container};
254
255#[cfg(feature = "animated-image")]
256pub mod frames;
257
258pub use taffy::JustifyContent;
259
260pub mod list;
261#[doc(inline)]
262pub use list::{ListColumn, list_column};
263
264pub mod menu;
265
266pub mod nav_bar;
267#[doc(inline)]
268pub use nav_bar::{nav_bar, nav_bar_dnd};
269
270pub mod nav_bar_toggle;
271#[doc(inline)]
272pub use nav_bar_toggle::{NavBarToggle, nav_bar_toggle};
273
274pub mod popover;
275#[doc(inline)]
276pub use popover::{Popover, popover};
277
278pub mod radio;
279#[doc(inline)]
280pub use radio::{Radio, radio};
281
282pub mod rectangle_tracker;
283#[doc(inline)]
284pub use rectangle_tracker::{RectangleTracker, rectangle_tracking_container};
285
286#[doc(inline)]
287pub use row::{Row, row};
288
289pub mod row {
290    //! A container which aligns its children in a row.
291
292    pub type Row<'a, Message> = iced::widget::Row<'a, Message, crate::Theme, crate::Renderer>;
293
294    #[must_use]
295    /// A container which aligns its children in a row.
296    pub fn row<'a, Message>() -> Row<'a, Message> {
297        Row::new()
298    }
299
300    #[must_use]
301    /// A pre-allocated [`row`].
302    pub fn with_capacity<'a, Message>(capacity: usize) -> Row<'a, Message> {
303        Row::with_capacity(capacity)
304    }
305
306    #[must_use]
307    /// A [`row`] that will be assigned an [`Iterator`] of children.
308    pub fn with_children<'a, Message>(
309        children: impl IntoIterator<Item = crate::Element<'a, Message>>,
310    ) -> Row<'a, Message> {
311        Row::with_children(children)
312    }
313}
314
315pub mod scrollable;
316#[doc(inline)]
317pub use scrollable::scrollable;
318pub mod segmented_button;
319pub mod segmented_control;
320
321pub mod settings;
322
323pub mod spin_button;
324#[doc(inline)]
325pub use spin_button::{SpinButton, spin_button, vertical as vertical_spin_button};
326
327pub mod tab_bar;
328
329pub mod table;
330#[doc(inline)]
331pub use table::{compact_table, table};
332
333pub mod text;
334#[doc(inline)]
335pub use text::{Text, text};
336
337pub mod text_input;
338#[doc(inline)]
339pub use text_input::{
340    TextInput, editable_input, inline_input, search_input, secure_input, text_input,
341};
342
343pub mod toaster;
344#[doc(inline)]
345pub use toaster::{Toast, ToastId, Toasts, toaster};
346
347mod toggler;
348#[doc(inline)]
349pub use toggler::toggler;
350
351#[doc(inline)]
352pub use tooltip::{Tooltip, tooltip};
353
354#[cfg(all(feature = "wayland", feature = "winit"))]
355pub mod wayland;
356
357pub mod tooltip {
358    use crate::Element;
359
360    pub use iced::widget::tooltip::Position;
361
362    pub type Tooltip<'a, Message> =
363        iced::widget::Tooltip<'a, Message, crate::Theme, crate::Renderer>;
364
365    pub fn tooltip<'a, Message>(
366        content: impl Into<Element<'a, Message>>,
367        tooltip: impl Into<Element<'a, Message>>,
368        position: Position,
369    ) -> Tooltip<'a, Message> {
370        let xxs = crate::theme::spacing().space_xxs;
371
372        Tooltip::new(content, tooltip, position)
373            .class(crate::theme::Container::Tooltip)
374            .padding(xxs)
375            .gap(1)
376    }
377}
378
379pub mod warning;
380#[doc(inline)]
381pub use warning::*;
382
383pub mod wrapper;
384#[doc(inline)]
385pub use wrapper::*;
386
387#[cfg(feature = "markdown")]
388#[doc(inline)]
389pub use iced::widget::markdown;
390
391#[cfg(feature = "about")]
392pub mod about;
393#[cfg(feature = "about")]
394#[doc(inline)]
395pub use about::about;