Merge branch 'master' into feature/overlay

This commit is contained in:
Héctor Ramón Jiménez 2020-07-10 01:25:49 +02:00
commit ce8cb228ef
13 changed files with 872 additions and 125 deletions

View file

@ -9,30 +9,34 @@
//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.1/examples/pane_grid
//! [`PaneGrid`]: struct.PaneGrid.html
mod axis;
mod configuration;
mod content;
mod direction;
mod node;
mod pane;
mod split;
mod state;
mod title_bar;
pub use axis::Axis;
pub use configuration::Configuration;
pub use content::Content;
pub use direction::Direction;
pub use node::Node;
pub use pane::Pane;
pub use split::Split;
pub use state::{Focus, State};
pub use title_bar::TitleBar;
use crate::{
keyboard, layout, mouse, Clipboard, Element, Event, Hasher, Layout, Length,
Point, Rectangle, Size, Widget,
container, keyboard, layout, mouse, row, text, Clipboard, Element, Event,
Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget,
};
/// A collection of panes distributed using either vertical or horizontal splits
/// to completely fill the space available.
///
/// [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish)
/// [![Pane grid - Iced](https://thumbs.gfycat.com/FrailFreshAiredaleterrier-small.gif)](https://gfycat.com/frailfreshairedaleterrier)
///
/// This distribution of space is common in tiling window managers (like
/// [`awesome`](https://awesomewm.org/), [`i3`](https://i3wm.org/), or even
@ -70,10 +74,10 @@ use crate::{
///
/// let pane_grid =
/// PaneGrid::new(&mut state, |pane, state, focus| {
/// match state {
/// pane_grid::Content::new(match state {
/// PaneState::SomePane => Text::new("This is some pane"),
/// PaneState::AnotherKindOfPane => Text::new("This is another kind of pane"),
/// }.into()
/// })
/// })
/// .on_drag(Message::PaneDragged)
/// .on_resize(10, Message::PaneResized);
@ -82,10 +86,9 @@ 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: self::Renderer> {
state: &'a mut state::Internal,
pressed_modifiers: &'a mut keyboard::ModifiersState,
elements: Vec<(Pane, Element<'a, Message, Renderer>)>,
elements: Vec<(Pane, Content<'a, Message, Renderer>)>,
width: Length,
height: Length,
spacing: u16,
@ -95,7 +98,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: self::Renderer,
{
/// Creates a [`PaneGrid`] with the given [`State`] and view function.
///
/// The view function will be called to display each [`Pane`] present in the
@ -110,7 +116,7 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
Pane,
&'a mut T,
Option<Focus>,
) -> Element<'a, Message, Renderer>,
) -> Content<'a, Message, Renderer>,
) -> Self {
let elements = {
let action = state.internal.action();
@ -136,7 +142,6 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
Self {
state: &mut state.internal,
pressed_modifiers: &mut state.modifiers,
elements,
width: Length::Fill,
height: Length::Fill,
@ -177,8 +182,7 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
/// Sets the modifier keys of the [`PaneGrid`].
///
/// The modifier keys will need to be pressed to trigger dragging, and key
/// events.
/// The modifier keys will need to be pressed to trigger key events.
///
/// The default modifier key is `Ctrl`.
///
@ -194,8 +198,6 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
/// Enables the drag and drop interactions of the [`PaneGrid`], which will
/// use the provided function to produce messages.
///
/// Panes can be dragged using `Modifier keys + Left click`.
///
/// [`PaneGrid`]: struct.PaneGrid.html
pub fn on_drag<F>(mut self, f: F) -> Self
where
@ -248,7 +250,12 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
self.on_key_press = Some(Box::new(f));
self
}
}
impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer>
where
Renderer: self::Renderer,
{
fn click_pane(
&mut self,
layout: Layout<'_>,
@ -260,16 +267,24 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
|(_, layout)| layout.bounds().contains(cursor_position),
);
if let Some(((pane, _), _)) = clicked_region.next() {
if let Some(((pane, content), layout)) = clicked_region.next() {
match &self.on_drag {
Some(on_drag)
if self.pressed_modifiers.matches(self.modifier_keys) =>
{
self.state.pick_pane(pane);
Some(on_drag) => {
if content.can_be_picked_at(layout, cursor_position) {
let pane_position = layout.position();
messages.push(on_drag(DragEvent::Picked { pane: *pane }));
let origin = cursor_position
- Vector::new(pane_position.x, pane_position.y);
self.state.pick_pane(pane, origin);
messages
.push(on_drag(DragEvent::Picked { pane: *pane }));
} else {
self.state.focus(pane);
}
}
_ => {
None => {
self.state.focus(pane);
}
}
@ -390,7 +405,7 @@ pub struct KeyPressEvent {
impl<'a, Message, Renderer> Widget<'a, Message, Renderer>
for PaneGrid<'a, Message, Renderer>
where
Renderer: self::Renderer,
Renderer: self::Renderer + container::Renderer,
{
fn width(&self) -> Length {
self.width
@ -485,7 +500,7 @@ where
}
}
mouse::Event::ButtonReleased(mouse::Button::Left) => {
if let Some(pane) = self.state.picked_pane() {
if let Some((pane, _)) = self.state.picked_pane() {
self.state.focus(&pane);
if let Some(on_drag) = &self.on_drag {
@ -540,9 +555,6 @@ where
}
}
}
keyboard::Event::ModifiersChanged(modifiers) => {
*self.pressed_modifiers = modifiers;
}
_ => {}
}
}
@ -553,7 +565,7 @@ where
{
self.elements.iter_mut().zip(layout.children()).for_each(
|((_, pane), layout)| {
pane.widget.on_event(
pane.on_event(
event.clone(),
layout,
cursor_position,
@ -600,7 +612,8 @@ where
})
.map(|(_, axis)| axis);
renderer.draw(
self::Renderer::draw(
renderer,
defaults,
&self.elements,
self.state.picked_pane(),
@ -632,7 +645,9 @@ where
///
/// [`PaneGrid`]: struct.PaneGrid.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer + Sized {
pub trait Renderer:
crate::Renderer + container::Renderer + text::Renderer + Sized
{
/// Draws a [`PaneGrid`].
///
/// It receives:
@ -648,18 +663,62 @@ pub trait Renderer: crate::Renderer + Sized {
fn draw<Message>(
&mut self,
defaults: &Self::Defaults,
content: &[(Pane, Element<'_, Message, Self>)],
dragging: Option<Pane>,
content: &[(Pane, Content<'_, Message, Self>)],
dragging: Option<(Pane, Point)>,
resizing: Option<Axis>,
layout: Layout<'_>,
cursor_position: Point,
) -> Self::Output;
/// Draws a [`Pane`].
///
/// It receives:
/// - the [`TitleBar`] of the [`Pane`], if any
/// - the [`Content`] of the [`Pane`]
/// - the [`Layout`] of the [`Pane`] and its elements
/// - the cursor position
///
/// [`Pane`]: struct.Pane.html
/// [`Layout`]: ../layout/struct.Layout.html
fn draw_pane<Message>(
&mut self,
defaults: &Self::Defaults,
bounds: Rectangle,
style: &Self::Style,
title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>,
body: (&Element<'_, Message, Self>, Layout<'_>),
cursor_position: Point,
) -> Self::Output;
/// Draws a [`TitleBar`].
///
/// It receives:
/// - the bounds, style of the [`TitleBar`]
/// - the style of the [`TitleBar`]
/// - the title of the [`TitleBar`] with its size, font, and bounds
/// - the controls of the [`TitleBar`] with their [`Layout`+, if any
/// - the cursor position
///
/// [`TitleBar`]: struct.TitleBar.html
/// [`Layout`]: ../layout/struct.Layout.html
fn draw_title_bar<Message>(
&mut self,
defaults: &Self::Defaults,
bounds: Rectangle,
style: &Self::Style,
title: &str,
title_size: u16,
title_font: Self::Font,
title_bounds: Rectangle,
controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>,
cursor_position: Point,
) -> Self::Output;
}
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(