feat(app): allow context drawer to be laid out next to content
This commit is contained in:
parent
a962865230
commit
e56a94b783
3 changed files with 71 additions and 21 deletions
|
|
@ -32,6 +32,7 @@ pub struct Window {
|
||||||
pub header_title: String,
|
pub header_title: String,
|
||||||
pub use_template: bool,
|
pub use_template: bool,
|
||||||
pub content_container: bool,
|
pub content_container: bool,
|
||||||
|
pub context_is_overlay: bool,
|
||||||
pub sharp_corners: bool,
|
pub sharp_corners: bool,
|
||||||
pub show_context: bool,
|
pub show_context: bool,
|
||||||
pub show_headerbar: bool,
|
pub show_headerbar: bool,
|
||||||
|
|
@ -126,6 +127,7 @@ impl Default for Core {
|
||||||
header_title: String::new(),
|
header_title: String::new(),
|
||||||
use_template: true,
|
use_template: true,
|
||||||
content_container: true,
|
content_container: true,
|
||||||
|
context_is_overlay: true,
|
||||||
sharp_corners: false,
|
sharp_corners: false,
|
||||||
show_context: false,
|
show_context: false,
|
||||||
show_headerbar: true,
|
show_headerbar: true,
|
||||||
|
|
@ -198,10 +200,34 @@ impl Core {
|
||||||
/// Call this whenever the scaling factor or window width has changed.
|
/// Call this whenever the scaling factor or window width has changed.
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
fn is_condensed_update(&mut self) {
|
fn is_condensed_update(&mut self) {
|
||||||
self.is_condensed = (600.0 * self.scale_factor) > self.window.width as f32;
|
//TODO: the app may return None from the context_drawer function even if show_context is true
|
||||||
|
let breakpoint = if self.window.show_context && !self.window.context_is_overlay {
|
||||||
|
1136.0
|
||||||
|
} else {
|
||||||
|
648.0
|
||||||
|
};
|
||||||
|
self.is_condensed = (breakpoint * self.scale_factor) > self.window.width as f32;
|
||||||
self.nav_bar_update();
|
self.nav_bar_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn condensed_conflict(&self) -> bool {
|
||||||
|
// There is a conflict if the view is condensed and both the nav bar and context drawer are open on the same layer
|
||||||
|
self.is_condensed
|
||||||
|
&& self.nav_bar.toggled_condensed
|
||||||
|
&& self.window.show_context
|
||||||
|
&& !self.window.context_is_overlay
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_show_context(&mut self, show: bool) {
|
||||||
|
self.window.show_context = show;
|
||||||
|
self.is_condensed_update();
|
||||||
|
// Ensure nav bar is closed if condensed view and context drawer is opened
|
||||||
|
if self.condensed_conflict() {
|
||||||
|
self.nav_bar.toggled_condensed = false;
|
||||||
|
self.is_condensed_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the nav panel is visible or not
|
/// Whether the nav panel is visible or not
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn nav_bar_active(&self) -> bool {
|
pub fn nav_bar_active(&self) -> bool {
|
||||||
|
|
@ -233,6 +259,16 @@ impl Core {
|
||||||
pub(crate) fn nav_bar_set_toggled_condensed(&mut self, toggled: bool) {
|
pub(crate) fn nav_bar_set_toggled_condensed(&mut self, toggled: bool) {
|
||||||
self.nav_bar.toggled_condensed = toggled;
|
self.nav_bar.toggled_condensed = toggled;
|
||||||
self.nav_bar_update();
|
self.nav_bar_update();
|
||||||
|
// Ensure context drawer is closed if condensed view and nav bar is opened
|
||||||
|
if self.condensed_conflict() {
|
||||||
|
self.window.show_context = false;
|
||||||
|
self.is_condensed_update();
|
||||||
|
// Sync nav bar state if the view is no longer condensed after closing the context drawer
|
||||||
|
if !self.is_condensed {
|
||||||
|
self.nav_bar.toggled = toggled;
|
||||||
|
self.nav_bar_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn nav_bar_update(&mut self) {
|
pub(crate) fn nav_bar_update(&mut self) {
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ impl<T: Application> Cosmic<T> {
|
||||||
},
|
},
|
||||||
|
|
||||||
Message::ContextDrawer(show) => {
|
Message::ContextDrawer(show) => {
|
||||||
self.app.core_mut().window.show_context = show;
|
self.app.core_mut().set_show_context(show);
|
||||||
return self.app.on_context_drawer();
|
return self.app.on_context_drawer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,13 @@ pub use self::core::Core;
|
||||||
pub use self::settings::Settings;
|
pub use self::settings::Settings;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::theme::THEME;
|
use crate::theme::THEME;
|
||||||
use crate::widget::{context_drawer, id_container, menu, nav_bar, popover};
|
use crate::widget::{context_drawer, horizontal_space, id_container, menu, nav_bar, popover};
|
||||||
use apply::Apply;
|
use apply::Apply;
|
||||||
use iced::Subscription;
|
|
||||||
#[cfg(all(feature = "winit", feature = "multi-window"))]
|
#[cfg(all(feature = "winit", feature = "multi-window"))]
|
||||||
use iced::{multi_window::Application as IcedApplication, window};
|
use iced::{multi_window::Application as IcedApplication, window};
|
||||||
#[cfg(any(not(feature = "winit"), not(feature = "multi-window")))]
|
#[cfg(any(not(feature = "winit"), not(feature = "multi-window")))]
|
||||||
use iced::{window, Application as IcedApplication};
|
use iced::{window, Application as IcedApplication};
|
||||||
|
use iced::{Length, Subscription};
|
||||||
pub use message::Message;
|
pub use message::Message;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
#[cfg(feature = "single-instance")]
|
#[cfg(feature = "single-instance")]
|
||||||
|
|
@ -581,6 +581,11 @@ pub trait ApplicationExt: Application {
|
||||||
self.core_mut().set_context_title(title);
|
self.core_mut().set_context_title(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the context drawer visibility.
|
||||||
|
fn set_show_context(&mut self, show: bool) {
|
||||||
|
self.core_mut().set_show_context(show);
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the header bar title.
|
/// Set the header bar title.
|
||||||
fn set_header_title(&mut self, title: String) {
|
fn set_header_title(&mut self, title: String) {
|
||||||
self.core_mut().set_header_title(title);
|
self.core_mut().set_header_title(title);
|
||||||
|
|
@ -648,7 +653,7 @@ impl<App: Application> ApplicationExt for App {
|
||||||
.is_some_and(|i| i == self.main_window_id());
|
.is_some_and(|i| i == self.main_window_id());
|
||||||
|
|
||||||
let content_row = crate::widget::row::with_children({
|
let content_row = crate::widget::row::with_children({
|
||||||
let mut widgets = Vec::with_capacity(2);
|
let mut widgets = Vec::with_capacity(3);
|
||||||
|
|
||||||
// Insert nav bar onto the left side of the window.
|
// Insert nav bar onto the left side of the window.
|
||||||
if let Some(nav) = self
|
if let Some(nav) = self
|
||||||
|
|
@ -659,24 +664,33 @@ impl<App: Application> ApplicationExt for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.nav_model().is_none() || core.show_content() {
|
if self.nav_model().is_none() || core.show_content() {
|
||||||
let main_content = self.view().map(Message::App);
|
widgets.push(self.view().map(Message::App));
|
||||||
|
|
||||||
widgets.push(if let Some(context) = self.context_drawer() {
|
if let Some(context) = self.context_drawer() {
|
||||||
context_drawer(
|
widgets.push(
|
||||||
&core.window.context_title,
|
context_drawer(
|
||||||
Message::Cosmic(cosmic::Message::ContextDrawer(false)),
|
&core.window.context_title,
|
||||||
main_content,
|
Message::Cosmic(cosmic::Message::ContextDrawer(false)),
|
||||||
context.map(Message::App),
|
//TODO: this is a hack to allow toggling overlay
|
||||||
)
|
horizontal_space(if core.window.context_is_overlay {
|
||||||
.apply(|drawer| {
|
Length::Shrink
|
||||||
Element::from(id_container(
|
} else {
|
||||||
drawer,
|
//TODO: this width must be synced with the context drawer width
|
||||||
iced_core::id::Id::new("COSMIC_context_drawer"),
|
Length::Fixed(480.0)
|
||||||
))
|
}),
|
||||||
})
|
context.map(Message::App),
|
||||||
|
)
|
||||||
|
.apply(|drawer| {
|
||||||
|
Element::from(id_container(
|
||||||
|
drawer,
|
||||||
|
iced_core::id::Id::new("COSMIC_context_drawer"),
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
main_content
|
//TODO: this element is added to prevent state issues
|
||||||
});
|
widgets.push(horizontal_space(Length::Shrink).into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
widgets
|
widgets
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue