Responsive context drawer width
This commit is contained in:
parent
7d7c6fa71a
commit
10f02d9d6b
4 changed files with 36 additions and 10 deletions
|
|
@ -200,11 +200,12 @@ 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) {
|
||||||
|
// Nav bar (280px) + padding (8px) + content (360px)
|
||||||
|
let mut breakpoint = 280.0 + 8.0 + 360.0;
|
||||||
//TODO: the app may return None from the context_drawer function even if show_context is true
|
//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 {
|
if self.window.show_context && !self.window.context_is_overlay {
|
||||||
1136.0
|
// Context drawer min width (344px) + padding (8px)
|
||||||
} else {
|
breakpoint += 344.0 + 8.0;
|
||||||
648.0
|
|
||||||
};
|
};
|
||||||
self.is_condensed = (breakpoint * self.scale_factor) > self.window.width as f32;
|
self.is_condensed = (breakpoint * self.scale_factor) > self.window.width as f32;
|
||||||
self.nav_bar_update();
|
self.nav_bar_update();
|
||||||
|
|
@ -218,6 +219,22 @@ impl Core {
|
||||||
&& !self.window.context_is_overlay
|
&& !self.window.context_is_overlay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn context_width(&self, has_nav: bool) -> f32 {
|
||||||
|
let window_width = (self.window.width as f32) / self.scale_factor;
|
||||||
|
|
||||||
|
// Content width (360px) + padding (8px)
|
||||||
|
let mut reserved_width = 360.0 + 8.0;
|
||||||
|
if has_nav {
|
||||||
|
// Navbar width (280px) + padding (8px)
|
||||||
|
reserved_width += 280.0 + 8.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This logic is to ensure the context drawer does not take up too much of the content's space
|
||||||
|
// The minimum width is 344px and the maximum with is 480px
|
||||||
|
// We want to keep the content at least 360px until going down to the minimum width
|
||||||
|
(window_width - reserved_width).min(480.0).max(344.0)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_show_context(&mut self, show: bool) {
|
pub fn set_show_context(&mut self, show: bool) {
|
||||||
self.window.show_context = show;
|
self.window.show_context = show;
|
||||||
self.is_condensed_update();
|
self.is_condensed_update();
|
||||||
|
|
|
||||||
|
|
@ -656,22 +656,26 @@ impl<App: Application> ApplicationExt for App {
|
||||||
let mut widgets = Vec::with_capacity(4);
|
let mut widgets = Vec::with_capacity(4);
|
||||||
|
|
||||||
// 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
|
let has_nav = if let Some(nav) = self
|
||||||
.nav_bar()
|
.nav_bar()
|
||||||
.map(|nav| id_container(nav, iced_core::id::Id::new("COSMIC_nav_bar")))
|
.map(|nav| id_container(nav, iced_core::id::Id::new("COSMIC_nav_bar")))
|
||||||
{
|
{
|
||||||
widgets.push(nav.into());
|
widgets.push(nav.into());
|
||||||
}
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
if self.nav_model().is_none() || core.show_content() {
|
if self.nav_model().is_none() || core.show_content() {
|
||||||
// Manual spacing must be used due to state workarounds below
|
// Manual spacing must be used due to state workarounds below
|
||||||
if !widgets.is_empty() {
|
if has_nav {
|
||||||
widgets.push(horizontal_space(Length::Fixed(8.0)).into());
|
widgets.push(horizontal_space(Length::Fixed(8.0)).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let main_content = self.view().map(Message::App);
|
let main_content = self.view().map(Message::App);
|
||||||
|
|
||||||
//TODO: reduce duplication
|
//TODO: reduce duplication
|
||||||
|
let context_width = core.context_width(has_nav);
|
||||||
if core.window.context_is_overlay {
|
if core.window.context_is_overlay {
|
||||||
if let Some(context) = self.context_drawer() {
|
if let Some(context) = self.context_drawer() {
|
||||||
widgets.push(
|
widgets.push(
|
||||||
|
|
@ -680,6 +684,7 @@ impl<App: Application> ApplicationExt for App {
|
||||||
Message::Cosmic(cosmic::Message::ContextDrawer(false)),
|
Message::Cosmic(cosmic::Message::ContextDrawer(false)),
|
||||||
main_content,
|
main_content,
|
||||||
context.map(Message::App),
|
context.map(Message::App),
|
||||||
|
context_width,
|
||||||
)
|
)
|
||||||
.apply(|drawer| {
|
.apply(|drawer| {
|
||||||
Element::from(id_container(
|
Element::from(id_container(
|
||||||
|
|
@ -692,6 +697,7 @@ impl<App: Application> ApplicationExt for App {
|
||||||
widgets.push(main_content);
|
widgets.push(main_content);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//TODO: hide content when out of space
|
||||||
widgets.push(main_content);
|
widgets.push(main_content);
|
||||||
if let Some(context) = self.context_drawer() {
|
if let Some(context) = self.context_drawer() {
|
||||||
widgets.push(
|
widgets.push(
|
||||||
|
|
@ -702,9 +708,10 @@ impl<App: Application> ApplicationExt for App {
|
||||||
horizontal_space(
|
horizontal_space(
|
||||||
//TODO: this width must be synced with the context drawer width
|
//TODO: this width must be synced with the context drawer width
|
||||||
// Manual spacing must be used due to state workarounds below
|
// Manual spacing must be used due to state workarounds below
|
||||||
Length::Fixed(480.0 + 8.0),
|
Length::Fixed(context_width + 8.0),
|
||||||
),
|
),
|
||||||
context.map(Message::App),
|
context.map(Message::App),
|
||||||
|
context_width,
|
||||||
)
|
)
|
||||||
.apply(|drawer| {
|
.apply(|drawer| {
|
||||||
Element::from(id_container(
|
Element::from(id_container(
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,11 @@ pub fn context_drawer<'a, Message: Clone + 'static, Content, Drawer>(
|
||||||
on_close: Message,
|
on_close: Message,
|
||||||
content: Content,
|
content: Content,
|
||||||
drawer: Drawer,
|
drawer: Drawer,
|
||||||
|
max_width: f32,
|
||||||
) -> ContextDrawer<'a, Message>
|
) -> ContextDrawer<'a, Message>
|
||||||
where
|
where
|
||||||
Content: Into<Element<'a, Message>>,
|
Content: Into<Element<'a, Message>>,
|
||||||
Drawer: Into<Element<'a, Message>>,
|
Drawer: Into<Element<'a, Message>>,
|
||||||
{
|
{
|
||||||
ContextDrawer::new(header, content, drawer, on_close)
|
ContextDrawer::new(header, content, drawer, on_close, max_width)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
|
||||||
content: Content,
|
content: Content,
|
||||||
drawer: Drawer,
|
drawer: Drawer,
|
||||||
on_close: Message,
|
on_close: Message,
|
||||||
|
max_width: f32,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
Content: Into<Element<'a, Message>>,
|
Content: Into<Element<'a, Message>>,
|
||||||
|
|
@ -92,7 +93,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
|
||||||
.style(crate::style::Container::ContextDrawer)
|
.style(crate::style::Container::ContextDrawer)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.max_width(480.0),
|
.max_width(max_width),
|
||||||
)
|
)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue