summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-06-05 06:52:07 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-06-05 06:52:07 +0200
commit4e1e0e0890b83fb1c4c4406791e3aa63bba58a93 (patch)
treef74e6712955a4a7239e6a91adfe4c754d876ed52 /native
parenta11bcf5af0be26671ba90097c64021014ab2092d (diff)
downloadiced-4e1e0e0890b83fb1c4c4406791e3aa63bba58a93.tar.gz
iced-4e1e0e0890b83fb1c4c4406791e3aa63bba58a93.tar.bz2
iced-4e1e0e0890b83fb1c4c4406791e3aa63bba58a93.zip
Draft drawing logic for `Content` and `TitleBar`
Diffstat (limited to 'native')
-rw-r--r--native/src/widget/pane_grid.rs34
-rw-r--r--native/src/widget/pane_grid/content.rs77
-rw-r--r--native/src/widget/pane_grid/title_bar.rs121
3 files changed, 205 insertions, 27 deletions
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs
index 4c037ee9..bf9c76fd 100644
--- a/native/src/widget/pane_grid.rs
+++ b/native/src/widget/pane_grid.rs
@@ -29,8 +29,8 @@ pub use state::{Focus, State};
pub use title_bar::TitleBar;
use crate::{
- keyboard, layout, mouse, Clipboard, Element, Event, Hasher, Layout, Length,
- Point, Size, Widget,
+ container, keyboard, layout, mouse, row, Clipboard, Element, Event, Hasher,
+ Layout, Length, Point, Size, Widget,
};
/// A collection of panes distributed using either vertical or horizontal splits
@@ -86,7 +86,7 @@ use crate::{
/// [`PaneGrid`]: struct.PaneGrid.html
/// [`State`]: struct.State.html
#[allow(missing_debug_implementations)]
-pub struct PaneGrid<'a, Message, Renderer> {
+pub struct PaneGrid<'a, Message, Renderer: container::Renderer> {
state: &'a mut state::Internal,
pressed_modifiers: &'a mut keyboard::ModifiersState,
elements: Vec<(Pane, Content<'a, Message, Renderer>)>,
@@ -99,7 +99,10 @@ pub struct PaneGrid<'a, Message, Renderer> {
on_key_press: Option<Box<dyn Fn(KeyPressEvent) -> Option<Message> + 'a>>,
}
-impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
+impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer>
+where
+ Renderer: container::Renderer,
+{
/// Creates a [`PaneGrid`] with the given [`State`] and view function.
///
/// The view function will be called to display each [`Pane`] present in the
@@ -362,7 +365,7 @@ pub struct KeyPressEvent {
impl<'a, Message, Renderer> Widget<Message, Renderer>
for PaneGrid<'a, Message, Renderer>
where
- Renderer: self::Renderer,
+ Renderer: self::Renderer + container::Renderer,
{
fn width(&self) -> Length {
self.width
@@ -604,7 +607,8 @@ where
layout: Layout<'_>,
cursor_position: Point,
) -> Renderer::Output {
- renderer.draw(
+ self::Renderer::draw(
+ renderer,
defaults,
&self.elements,
self.state.picked_pane(),
@@ -636,7 +640,7 @@ where
///
/// [`PaneGrid`]: struct.PaneGrid.html
/// [renderer]: ../../renderer/index.html
-pub trait Renderer: crate::Renderer + Sized {
+pub trait Renderer: crate::Renderer + container::Renderer + Sized {
/// Draws a [`PaneGrid`].
///
/// It receives:
@@ -672,9 +676,17 @@ pub trait Renderer: crate::Renderer + Sized {
fn draw_pane<Message>(
&mut self,
defaults: &Self::Defaults,
- title_bar: Option<&TitleBar<'_, Message, Self>>,
- body: &Element<'_, Message, Self>,
- layout: Layout<'_>,
+ title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>,
+ body: (&Element<'_, Message, Self>, Layout<'_>),
+ cursor_position: Point,
+ ) -> Self::Output;
+
+ fn draw_title_bar<Message>(
+ &mut self,
+ defaults: &Self::Defaults,
+ style: &Self::Style,
+ title: (&Element<'_, Message, Self>, Layout<'_>),
+ controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>,
cursor_position: Point,
) -> Self::Output;
}
@@ -682,7 +694,7 @@ pub trait Renderer: crate::Renderer + Sized {
impl<'a, Message, Renderer> From<PaneGrid<'a, Message, Renderer>>
for Element<'a, Message, Renderer>
where
- Renderer: 'a + self::Renderer,
+ Renderer: 'a + self::Renderer + row::Renderer,
Message: 'a,
{
fn from(
diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs
index e1374c82..a30b0e7d 100644
--- a/native/src/widget/pane_grid/content.rs
+++ b/native/src/widget/pane_grid/content.rs
@@ -1,16 +1,20 @@
+use crate::container;
use crate::layout;
use crate::pane_grid::{self, TitleBar};
-use crate::{Clipboard, Element, Event, Hasher, Layout, Point};
+use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size};
/// The content of a [`Pane`].
///
/// [`Pane`]: struct.Pane.html
-pub struct Content<'a, Message, Renderer> {
+pub struct Content<'a, Message, Renderer: container::Renderer> {
title_bar: Option<TitleBar<'a, Message, Renderer>>,
body: Element<'a, Message, Renderer>,
}
-impl<'a, Message, Renderer> Content<'a, Message, Renderer> {
+impl<'a, Message, Renderer> Content<'a, Message, Renderer>
+where
+ Renderer: container::Renderer,
+{
pub fn new(body: impl Into<Element<'a, Message, Renderer>>) -> Self {
Self {
title_bar: None,
@@ -29,7 +33,7 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> {
impl<'a, Message, Renderer> Content<'a, Message, Renderer>
where
- Renderer: pane_grid::Renderer,
+ Renderer: pane_grid::Renderer + container::Renderer,
{
pub fn draw(
&self,
@@ -38,13 +42,25 @@ where
layout: Layout<'_>,
cursor_position: Point,
) -> Renderer::Output {
- renderer.draw_pane(
- defaults,
- self.title_bar.as_ref(),
- &self.body,
- layout,
- cursor_position,
- )
+ if let Some(title_bar) = &self.title_bar {
+ let mut children = layout.children();
+ let title_bar_layout = children.next().unwrap();
+ let body_layout = children.next().unwrap();
+
+ renderer.draw_pane(
+ defaults,
+ Some((title_bar, title_bar_layout)),
+ (&self.body, body_layout),
+ cursor_position,
+ )
+ } else {
+ renderer.draw_pane(
+ defaults,
+ None,
+ (&self.body, layout),
+ cursor_position,
+ )
+ }
}
pub(crate) fn is_over_drag_target(
@@ -60,7 +76,34 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- self.body.layout(renderer, limits)
+ if let Some(title_bar) = &self.title_bar {
+ let max_size = limits.max();
+
+ let title_bar_layout = title_bar
+ .layout(renderer, &layout::Limits::new(Size::ZERO, max_size));
+
+ let title_bar_size = title_bar_layout.size();
+
+ let mut body_layout = self.body.layout(
+ renderer,
+ &layout::Limits::new(
+ Size::ZERO,
+ Size::new(
+ max_size.width,
+ max_size.height - title_bar_size.height,
+ ),
+ ),
+ );
+
+ body_layout.move_to(Point::new(0.0, title_bar_size.height));
+
+ layout::Node::with_children(
+ max_size,
+ vec![title_bar_layout, body_layout],
+ )
+ } else {
+ self.body.layout(renderer, limits)
+ }
}
pub(crate) fn on_event(
@@ -86,3 +129,13 @@ where
self.body.hash_layout(state);
}
}
+
+impl<'a, T, Message, Renderer> From<T> for Content<'a, Message, Renderer>
+where
+ T: Into<Element<'a, Message, Renderer>>,
+ Renderer: pane_grid::Renderer + container::Renderer,
+{
+ fn from(element: T) -> Self {
+ Self::new(element)
+ }
+}
diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs
index fa868a20..1fd06411 100644
--- a/native/src/widget/pane_grid/title_bar.rs
+++ b/native/src/widget/pane_grid/title_bar.rs
@@ -1,6 +1,119 @@
-use crate::Element;
+use crate::container;
+use crate::layout;
+use crate::pane_grid;
+use crate::{Element, Layout, Point, Size};
-pub struct TitleBar<'a, Message, Renderer> {
- title: String,
- buttons: Option<Element<'a, Message, Renderer>>,
+pub struct TitleBar<'a, Message, Renderer: container::Renderer> {
+ title: Element<'a, Message, Renderer>,
+ controls: Option<Element<'a, Message, Renderer>>,
+ padding: u16,
+ style: Renderer::Style,
+}
+
+impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer>
+where
+ Renderer: container::Renderer,
+{
+ pub fn new(title: impl Into<Element<'a, Message, Renderer>>) -> Self {
+ Self {
+ title: title.into(),
+ controls: None,
+ padding: 0,
+ style: Renderer::Style::default(),
+ }
+ }
+
+ pub fn controls(
+ mut self,
+ controls: impl Into<Element<'a, Message, Renderer>>,
+ ) -> Self {
+ self.controls = Some(controls.into());
+ self
+ }
+
+ /// Sets the padding of the [`TitleBar`].
+ ///
+ /// [`TitleBar`]: struct.TitleBar.html
+ pub fn padding(mut self, units: u16) -> Self {
+ self.padding = units;
+ self
+ }
+}
+
+impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer>
+where
+ Renderer: pane_grid::Renderer,
+{
+ pub fn draw(
+ &self,
+ renderer: &mut Renderer,
+ defaults: &Renderer::Defaults,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ ) -> Renderer::Output {
+ if let Some(controls) = &self.controls {
+ let mut children = layout.children();
+ let title_layout = children.next().unwrap();
+ let controls_layout = children.next().unwrap();
+
+ renderer.draw_title_bar(
+ defaults,
+ &self.style,
+ (&self.title, title_layout),
+ Some((controls, controls_layout)),
+ cursor_position,
+ )
+ } else {
+ renderer.draw_title_bar(
+ defaults,
+ &self.style,
+ (&self.title, layout),
+ None,
+ cursor_position,
+ )
+ }
+ }
+
+ pub(crate) fn layout(
+ &self,
+ renderer: &Renderer,
+ limits: &layout::Limits,
+ ) -> layout::Node {
+ let padding = f32::from(self.padding);
+ let limits = limits.pad(padding);
+
+ let mut node = if let Some(controls) = &self.controls {
+ let max_size = limits.max();
+
+ let title_layout = self
+ .title
+ .layout(renderer, &layout::Limits::new(Size::ZERO, max_size));
+
+ let title_size = title_layout.size();
+
+ let mut controls_layout = controls.layout(
+ renderer,
+ &layout::Limits::new(
+ Size::ZERO,
+ Size::new(
+ max_size.width - title_size.width,
+ max_size.height,
+ ),
+ ),
+ );
+
+ controls_layout.move_to(Point::new(title_size.width, 0.0));
+
+ layout::Node::with_children(
+ max_size,
+ vec![title_layout, controls_layout],
+ )
+ } else {
+ self.title.layout(renderer, &limits)
+ };
+
+ node.move_to(Point::new(padding, padding));
+
+ node
+ }
}