diff options
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | examples/pane_grid/Cargo.toml | 9 | ||||
-rw-r--r-- | examples/pane_grid/README.md | 18 | ||||
-rw-r--r-- | examples/pane_grid/src/main.rs | 202 |
4 files changed, 230 insertions, 0 deletions
@@ -45,6 +45,7 @@ members = [ "examples/geometry", "examples/integration", "examples/pokedex", + "examples/pane_grid", "examples/progress_bar", "examples/solar_system", "examples/stopwatch", diff --git a/examples/pane_grid/Cargo.toml b/examples/pane_grid/Cargo.toml new file mode 100644 index 00000000..3ed912ac --- /dev/null +++ b/examples/pane_grid/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "pane_grid" +version = "0.1.0" +authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] +edition = "2018" +publish = false + +[dependencies] +iced = { path = "../.." } diff --git a/examples/pane_grid/README.md b/examples/pane_grid/README.md new file mode 100644 index 00000000..4d9fc5b9 --- /dev/null +++ b/examples/pane_grid/README.md @@ -0,0 +1,18 @@ +## Counter + +The classic counter example explained in the [`README`](../../README.md). + +The __[`main`]__ file contains all the code of the example. + +<div align="center"> + <a href="https://gfycat.com/fairdeadcatbird"> + <img src="https://thumbs.gfycat.com/FairDeadCatbird-small.gif"> + </a> +</div> + +You can run it with `cargo run`: +``` +cargo run --package counter +``` + +[`main`]: src/main.rs diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs new file mode 100644 index 00000000..09969630 --- /dev/null +++ b/examples/pane_grid/src/main.rs @@ -0,0 +1,202 @@ +use iced::{ + button, pane_grid, scrollable, Align, Button, Column, Container, Element, + HorizontalAlignment, Length, PaneGrid, Sandbox, Scrollable, Settings, Text, +}; + +pub fn main() { + Example::run(Settings::default()) +} + +struct Example { + panes: pane_grid::State<Content>, + panes_created: usize, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + Split(pane_grid::Axis, pane_grid::Pane), + SplitFocused(pane_grid::Axis), + Dragged(pane_grid::DragEvent), + Resized(pane_grid::ResizeEvent), + Close(pane_grid::Pane), +} + +impl Sandbox for Example { + type Message = Message; + + fn new() -> Self { + let (panes, _) = pane_grid::State::new(Content::new(0)); + + Example { + panes, + panes_created: 1, + } + } + + fn title(&self) -> String { + String::from("Pane grid - Iced") + } + + fn update(&mut self, message: Message) { + match message { + Message::Split(axis, pane) => { + let _ = self.panes.split( + axis, + &pane, + Content::new(self.panes_created), + ); + + self.panes_created += 1; + } + Message::SplitFocused(axis) => { + if let Some(pane) = self.panes.active() { + let _ = self.panes.split( + axis, + &pane, + Content::new(self.panes_created), + ); + + self.panes_created += 1; + } + } + Message::Resized(pane_grid::ResizeEvent { split, ratio }) => { + self.panes.resize(&split, ratio); + } + Message::Dragged(pane_grid::DragEvent::Dropped { + pane, + target, + }) => { + self.panes.swap(&pane, &target); + } + Message::Dragged(_) => {} + Message::Close(pane) => { + let _ = self.panes.close(&pane); + } + } + } + + fn view(&mut self) -> Element<Message> { + let total_panes = self.panes.len(); + + let pane_grid = + PaneGrid::new(&mut self.panes, |pane, content, focus| { + content.view(pane, focus, total_panes) + }) + .width(Length::Fill) + .height(Length::Fill) + .spacing(5) + .on_drag(Message::Dragged) + .on_resize(Message::Resized); + + Column::new() + .width(Length::Fill) + .height(Length::Fill) + .padding(10) + .push(pane_grid) + .into() + } +} + +struct Content { + id: usize, + scroll: scrollable::State, + split_horizontally: button::State, + split_vertically: button::State, + close: button::State, +} + +impl Content { + fn new(id: usize) -> Self { + Content { + id, + scroll: scrollable::State::new(), + split_horizontally: button::State::new(), + split_vertically: button::State::new(), + close: button::State::new(), + } + } + fn view( + &mut self, + pane: pane_grid::Pane, + focus: Option<pane_grid::Focus>, + total_panes: usize, + ) -> Element<Message> { + let Content { + id, + scroll, + split_horizontally, + split_vertically, + close, + } = self; + + let button = |state, label, message| { + Button::new( + state, + Text::new(label) + .width(Length::Fill) + .horizontal_alignment(HorizontalAlignment::Center) + .size(16), + ) + .width(Length::Fill) + .on_press(message) + }; + + let mut controls = Column::new() + .spacing(5) + .max_width(150) + .push(button( + split_horizontally, + "Split horizontally", + Message::Split(pane_grid::Axis::Horizontal, pane), + )) + .push(button( + split_vertically, + "Split vertically", + Message::Split(pane_grid::Axis::Vertical, pane), + )); + + if total_panes > 1 { + controls = + controls.push(button(close, "Close", Message::Close(pane))); + } + + let content = Scrollable::new(scroll) + .width(Length::Fill) + .spacing(10) + .align_items(Align::Center) + .push(Text::new(format!("Pane {}", id)).size(30)) + .push(controls); + + Container::new(Column::new().padding(10).push(content)) + .width(Length::Fill) + .height(Length::Fill) + .center_y() + .style(style::Pane { + is_focused: focus.is_some(), + }) + .into() + } +} + +mod style { + use iced::{container, Background, Color}; + + pub struct Pane { + pub is_focused: bool, + } + + impl container::StyleSheet for Pane { + fn style(&self) -> container::Style { + container::Style { + background: Some(Background::Color(Color::WHITE)), + border_width: 1, + border_color: if self.is_focused { + Color::from_rgb8(0x25, 0x7A, 0xFD) + } else { + Color::BLACK + }, + ..Default::default() + } + } + } +} |