feat(segmented-button): configurable close icons

This commit is contained in:
Michael Aaron Murphy 2023-02-13 15:57:30 +01:00 committed by Jeremy Soller
parent 843919e44f
commit 4fa61eeafd
10 changed files with 288 additions and 64 deletions

View file

@ -10,3 +10,4 @@ apply = "0.3.0"
fraction = "0.13.0"
libcosmic = { path = "../..", default-features = false, features = ["debug", "winit_softbuffer"] }
once_cell = "1.15"
slotmap = "1.0.6"

View file

@ -28,6 +28,8 @@ mod demo;
use self::desktop::DesktopPage;
mod desktop;
mod editor;
use self::input_devices::InputDevicesPage;
mod input_devices;
@ -51,6 +53,7 @@ pub trait SubPage {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Page {
Demo,
Editor,
WiFi,
Networking(Option<NetworkingPage>),
Bluetooth,
@ -74,6 +77,7 @@ impl Page {
use Page::*;
match self {
Demo => "Demo",
Editor => "Editor",
WiFi => "Wi-Fi",
Networking(_) => "Networking",
Bluetooth => "Bluetooth",
@ -96,6 +100,7 @@ impl Page {
use Page::*;
match self {
Demo => "document-properties-symbolic",
Editor => "text-editor-symbolic",
WiFi => "network-wireless-symbolic",
Networking(_) => "network-workgroup-symbolic",
Bluetooth => "bluetooth-active-symbolic",
@ -130,6 +135,7 @@ pub struct Window {
bluetooth: bluetooth::State,
debug: bool,
demo: demo::State,
editor: editor::State,
desktop: desktop::State,
nav_bar: segmented_button::SingleSelectModel,
nav_id_to_page: segmented_button::SecondaryMap<Page>,
@ -178,6 +184,7 @@ pub enum Message {
Demo(demo::Message),
Desktop(desktop::Message),
Drag,
Editor(editor::Message),
InputChanged,
KeyboardNav(keyboard_nav::Message),
Maximize,
@ -318,6 +325,7 @@ impl Application for Window {
window.warning_message = String::from("You were not supposed to touch that.");
window.insert_page(Page::Demo);
window.insert_page(Page::Editor);
window.insert_page(Page::WiFi);
window.insert_page(Page::Networking(None));
window.insert_page(Page::Bluetooth);
@ -386,6 +394,7 @@ impl Application for Window {
Some(demo::Output::ToggleWarning) => self.toggle_warning(),
None => (),
},
Message::Editor(message) => self.editor.update(message),
Message::Desktop(message) => match self.desktop.update(message) {
Some(desktop::Output::Page(page)) => self.page(page),
None => (),
@ -460,6 +469,7 @@ impl Application for Window {
if !(self.is_condensed() && nav_bar_toggled) {
let content: Element<_> = match self.page {
Page::Demo => self.demo.view(self).map(Message::Demo),
Page::Editor => self.editor.view(self).map(Message::Editor),
Page::Networking(None) => settings::view_column(vec![
self.page_title(self.page),
column!(

View file

@ -0,0 +1,78 @@
use cosmic::iced::widget::row;
use cosmic::iced::Length;
use cosmic::iced_winit::Alignment;
use cosmic::widget::{button, segmented_button, view_switcher};
use cosmic::{theme, Element};
use slotmap::Key;
#[derive(Clone, Copy, Debug)]
pub enum Message {
Activate(segmented_button::Entity),
AddNew,
Close(segmented_button::Entity),
}
pub struct State {
pub pages: segmented_button::SingleSelectModel,
}
impl Default for State {
fn default() -> Self {
let mut state = Self {
pages: segmented_button::Model::default(),
};
let id = state.tab_add_new();
state.pages.activate(id);
state
}
}
impl State {
pub(super) fn update(&mut self, message: Message) {
match message {
Message::Activate(id) => self.pages.activate(id),
Message::AddNew => {
self.tab_add_new();
}
Message::Close(id) => self.tab_close(id),
}
}
pub fn tab_add_new(&mut self) -> segmented_button::Entity {
let id = self.pages.insert().closable().id();
self.pages
.text_set(id, format!("Tab {}", id.data().as_ffi() & 0xffff_ffff));
id
}
pub fn tab_close(&mut self, id: segmented_button::Entity) {
if self.pages.is_active(id) {
if let Some(pos) = self.pages.position(id) {
let next = if pos == 0 { pos + 1 } else { pos - 1 };
self.pages.activate_position(next);
}
}
self.pages.remove(id);
}
pub(super) fn view<'a>(&'a self, window: &'a super::Window) -> Element<'a, Message> {
let tabs = view_switcher::horizontal(&self.pages)
.show_close_icon_on_hover(true)
.on_activate(Message::Activate)
.on_close(Message::Close)
.width(Length::Fill);
let new_tab_button = button(theme::Button::Text)
.icon(theme::Svg::Symbolic, "tab-new-symbolic", 20)
.on_press(Message::AddNew);
row!(tabs, new_tab_button)
.align_items(Alignment::Center)
.into()
}
}