More efficently resize at break point
Uses iced `events_with()` to only subscribe to window resize events. The window width is stored in a static AtomicU32 so that the subscription can compare to an old window width as to only send messages when the width crosses the break point. fix up
This commit is contained in:
parent
bdf5f7da38
commit
8eff8a33fa
1 changed files with 148 additions and 132 deletions
|
|
@ -2,17 +2,17 @@
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
|
iced_native,
|
||||||
iced_native::window,
|
iced_native::window,
|
||||||
iced::widget::{column, container, horizontal_space, row, text},
|
iced::widget::{column, container, horizontal_space, row, text},
|
||||||
iced::{self, Application, Command, Length},
|
iced::{self, Application, Command, Length, Subscription},
|
||||||
iced_lazy::responsive,
|
|
||||||
iced_winit::window::{close, drag, toggle_maximize, minimize},
|
iced_winit::window::{close, drag, toggle_maximize, minimize},
|
||||||
theme::{self, Theme},
|
theme::{self, Theme},
|
||||||
widget::{icon, list, nav_bar, nav_button, header_bar, settings, scrollable, spin_button::{SpinButtonModel, SpinMessage}},
|
widget::{icon, list, nav_bar, nav_button, header_bar, settings, scrollable, spin_button::{SpinButtonModel, SpinMessage}},
|
||||||
Element,
|
Element,
|
||||||
ElementExt,
|
ElementExt,
|
||||||
};
|
};
|
||||||
use std::vec;
|
use std::{vec, sync::atomic::{AtomicU32, Ordering}};
|
||||||
|
|
||||||
mod bluetooth;
|
mod bluetooth;
|
||||||
|
|
||||||
|
|
@ -115,6 +115,9 @@ impl Default for Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WINDOW_WIDTH: AtomicU32 = AtomicU32::new(0);
|
||||||
|
const BREAK_POINT: u32 = 900;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
title: String,
|
title: String,
|
||||||
|
|
@ -168,7 +171,8 @@ pub enum Message {
|
||||||
Minimize,
|
Minimize,
|
||||||
Maximize,
|
Maximize,
|
||||||
InputChanged,
|
InputChanged,
|
||||||
SpinButton(SpinMessage)
|
SpinButton(SpinMessage),
|
||||||
|
WindowWidthChanged(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
|
@ -179,6 +183,10 @@ impl Window {
|
||||||
).into()
|
).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_condensed(&self) -> bool {
|
||||||
|
WINDOW_WIDTH.load(Ordering::Relaxed) < BREAK_POINT
|
||||||
|
}
|
||||||
|
|
||||||
fn parent_page_button(&self, sub_page: impl SubPage) -> Element<Message> {
|
fn parent_page_button(&self, sub_page: impl SubPage) -> Element<Message> {
|
||||||
let page = sub_page.parent_page();
|
let page = sub_page.parent_page();
|
||||||
column!(
|
column!(
|
||||||
|
|
@ -258,6 +266,22 @@ impl Application for Window {
|
||||||
self.title.clone()
|
self.title.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subscription(&self) -> Subscription<Message> {
|
||||||
|
iced_native::subscription::events_with(|event, _| match event {
|
||||||
|
cosmic::iced::Event::Window(_window_id, window::Event::Resized{width, height}) => {
|
||||||
|
let old_width = WINDOW_WIDTH.load(Ordering::Relaxed);
|
||||||
|
if old_width == 0
|
||||||
|
|| old_width < BREAK_POINT && width > BREAK_POINT
|
||||||
|
|| old_width > BREAK_POINT && width < BREAK_POINT {
|
||||||
|
Some(width)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}).map(Message::WindowWidthChanged)
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Message) -> iced::Command<Self::Message> {
|
fn update(&mut self, message: Message) -> iced::Command<Self::Message> {
|
||||||
match message {
|
match message {
|
||||||
Message::Page(page) => {
|
Message::Page(page) => {
|
||||||
|
|
@ -282,6 +306,7 @@ impl Application for Window {
|
||||||
Message::RowSelected(row) => println!("Selected row {row}"),
|
Message::RowSelected(row) => println!("Selected row {row}"),
|
||||||
Message::InputChanged => {},
|
Message::InputChanged => {},
|
||||||
Message::SpinButton(msg) => self.spin_button.update(msg),
|
Message::SpinButton(msg) => self.spin_button.update(msg),
|
||||||
|
Message::WindowWidthChanged(new_width) => WINDOW_WIDTH.store(new_width, Ordering::Relaxed),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,14 +314,7 @@ impl Application for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
// TODO: Adding responsive makes this regenerate on every size change, and regeneration
|
let (sidebar_message, sidebar_toggled) = if self.is_condensed() {
|
||||||
// involves allocations for many different items. Ideally, we could only make the nav bar
|
|
||||||
// responsive and leave the content to be sized normally.
|
|
||||||
responsive(|size| {
|
|
||||||
//TODO: send a message when this happens instead of having everything be recalculated on resize
|
|
||||||
let condensed = size.width < 900.0;
|
|
||||||
|
|
||||||
let (sidebar_message, sidebar_toggled) = if condensed {
|
|
||||||
(Message::ToggleSidebarCondensed, self.sidebar_toggled_condensed)
|
(Message::ToggleSidebarCondensed, self.sidebar_toggled_condensed)
|
||||||
} else {
|
} else {
|
||||||
(Message::ToggleSidebar, self.sidebar_toggled)
|
(Message::ToggleSidebar, self.sidebar_toggled)
|
||||||
|
|
@ -361,7 +379,7 @@ impl Application for Window {
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.style(theme::Container::Custom(nav_bar::nav_bar_sections_style));
|
.style(theme::Container::Custom(nav_bar::nav_bar_sections_style));
|
||||||
|
|
||||||
if ! condensed {
|
if ! self.is_condensed() {
|
||||||
sidebar = sidebar.max_width(300)
|
sidebar = sidebar.max_width(300)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,7 +387,7 @@ impl Application for Window {
|
||||||
widgets.push(sidebar.debug(self.debug));
|
widgets.push(sidebar.debug(self.debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! (condensed && sidebar_toggled) {
|
if ! (self.is_condensed() && sidebar_toggled) {
|
||||||
let content: Element<_> = match self.page {
|
let content: Element<_> = match self.page {
|
||||||
Page::Demo => self.view_demo(),
|
Page::Demo => self.view_demo(),
|
||||||
Page::Networking(None) => settings::view_column(vec![
|
Page::Networking(None) => settings::view_column(vec![
|
||||||
|
|
@ -429,8 +447,6 @@ impl Application for Window {
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
column(vec![header, content]).into()
|
column(vec![header, content]).into()
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn theme(&self) -> Theme {
|
fn theme(&self) -> Theme {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue