Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widget Operations #1399

Merged
merged 11 commits into from
Aug 5, 2022
52 changes: 36 additions & 16 deletions examples/scrollable/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use iced::executor;
use iced::widget::{
button, column, container, horizontal_rule, progress_bar, radio,
scrollable, text, vertical_space, Row,
};
use iced::{Element, Length, Sandbox, Settings, Theme};
use iced::{Application, Command, Element, Length, Settings, Theme};

pub fn main() -> iced::Result {
ScrollableDemo::run(Settings::default())
Expand All @@ -21,43 +22,57 @@ enum Message {
Scrolled(usize, f32),
}

impl Sandbox for ScrollableDemo {
impl Application for ScrollableDemo {
type Message = Message;

fn new() -> Self {
ScrollableDemo {
theme: Default::default(),
variants: Variant::all(),
}
type Theme = Theme;
type Executor = executor::Default;
type Flags = ();

fn new(_flags: Self::Flags) -> (Self, Command<Message>) {
(
ScrollableDemo {
theme: Default::default(),
variants: Variant::all(),
},
Command::none(),
)
}

fn title(&self) -> String {
String::from("Scrollable - Iced")
}

fn update(&mut self, message: Message) {
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::ThemeChanged(theme) => self.theme = theme,
Message::ThemeChanged(theme) => {
self.theme = theme;

Command::none()
}
Message::ScrollToTop(i) => {
if let Some(variant) = self.variants.get_mut(i) {
// TODO
// variant.scrollable.snap_to(0.0);

variant.latest_offset = 0.0;

scrollable::snap_to(Variant::id(i), 0.0)
} else {
Command::none()
}
}
Message::ScrollToBottom(i) => {
if let Some(variant) = self.variants.get_mut(i) {
// TODO
// variant.scrollable.snap_to(1.0);

variant.latest_offset = 1.0;

scrollable::snap_to(Variant::id(i), 1.0)
} else {
Command::none()
}
}
Message::Scrolled(i, offset) => {
if let Some(variant) = self.variants.get_mut(i) {
variant.latest_offset = offset;
}

Command::none()
}
}
}
Expand Down Expand Up @@ -136,6 +151,7 @@ impl Sandbox for ScrollableDemo {
);

let mut scrollable = scrollable(contents)
.id(Variant::id(i))
.height(Length::Fill)
.on_scroll(move |offset| Message::Scrolled(i, offset));

Expand Down Expand Up @@ -228,4 +244,8 @@ impl Variant {
},
]
}

pub fn id(i: usize) -> scrollable::Id {
scrollable::Id::new(format!("scrollable-{}", i))
}
}
1 change: 1 addition & 0 deletions examples/todos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ publish = false
iced = { path = "../..", features = ["async-std", "debug"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
lazy_static = "1.4"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
async-std = "1.0"
Expand Down
85 changes: 74 additions & 11 deletions examples/todos/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
use iced::alignment::{self, Alignment};
use iced::event::{self, Event};
use iced::keyboard;
use iced::subscription;
use iced::theme::{self, Theme};
use iced::widget::{
button, checkbox, column, container, row, scrollable, text, text_input,
Text,
self, button, checkbox, column, container, row, scrollable, text,
text_input, Text,
};
use iced::window;
use iced::{Application, Element};
use iced::{Color, Command, Font, Length, Settings};
use iced::{Color, Command, Font, Length, Settings, Subscription};

use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};

lazy_static! {
static ref INPUT_ID: text_input::Id = text_input::Id::unique();
}

pub fn main() -> iced::Result {
Todos::run(Settings {
window: window::Settings {
Expand Down Expand Up @@ -42,6 +51,7 @@ enum Message {
CreateTask,
FilterChanged(Filter),
TaskMessage(usize, TaskMessage),
TabPressed { shift: bool },
}

impl Application for Todos {
Expand Down Expand Up @@ -84,14 +94,16 @@ impl Application for Todos {
_ => {}
}

Command::none()
text_input::focus(INPUT_ID.clone())
}
Todos::Loaded(state) => {
let mut saved = false;

match message {
let command = match message {
Message::InputChanged(value) => {
state.input_value = value;

Command::none()
}
Message::CreateTask => {
if !state.input_value.is_empty() {
Expand All @@ -100,30 +112,56 @@ impl Application for Todos {
.push(Task::new(state.input_value.clone()));
state.input_value.clear();
}

Command::none()
}
Message::FilterChanged(filter) => {
state.filter = filter;

Command::none()
}
Message::TaskMessage(i, TaskMessage::Delete) => {
state.tasks.remove(i);

Command::none()
}
Message::TaskMessage(i, task_message) => {
if let Some(task) = state.tasks.get_mut(i) {
let should_focus =
matches!(task_message, TaskMessage::Edit);

task.update(task_message);

if should_focus {
text_input::focus(Task::text_input_id(i))
} else {
Command::none()
}
} else {
Command::none()
}
}
Message::Saved(_) => {
state.saving = false;
saved = true;

Command::none()
}
_ => {}
}
Message::TabPressed { shift } => {
if shift {
widget::focus_previous()
} else {
widget::focus_next()
}
}
_ => Command::none(),
};

if !saved {
state.dirty = true;
}

if state.dirty && !state.saving {
let save = if state.dirty && !state.saving {
state.dirty = false;
state.saving = true;

Expand All @@ -138,7 +176,9 @@ impl Application for Todos {
)
} else {
Command::none()
}
};

Command::batch(vec![command, save])
}
}
}
Expand All @@ -163,6 +203,7 @@ impl Application for Todos {
input_value,
Message::InputChanged,
)
.id(INPUT_ID.clone())
.padding(15)
.size(30)
.on_submit(Message::CreateTask);
Expand All @@ -178,12 +219,13 @@ impl Application for Todos {
.enumerate()
.filter(|(_, task)| filter.matches(task))
.map(|(i, task)| {
task.view().map(move |message| {
task.view(i).map(move |message| {
Message::TaskMessage(i, message)
})
})
.collect(),
)
.spacing(10)
.into()
} else {
empty_message(match filter {
Expand All @@ -209,6 +251,22 @@ impl Application for Todos {
}
}
}

fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, status| match (event, status) {
(
Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,
modifiers,
..
}),
event::Status::Ignored,
) => Some(Message::TabPressed {
shift: modifiers.shift(),
}),
_ => None,
})
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -242,6 +300,10 @@ pub enum TaskMessage {
}

impl Task {
fn text_input_id(i: usize) -> text_input::Id {
text_input::Id::new(format!("task-{}", i))
}

fn new(description: String) -> Self {
Task {
description,
Expand Down Expand Up @@ -270,7 +332,7 @@ impl Task {
}
}

fn view(&self) -> Element<TaskMessage> {
fn view(&self, i: usize) -> Element<TaskMessage> {
match &self.state {
TaskState::Idle => {
let checkbox = checkbox(
Expand All @@ -297,6 +359,7 @@ impl Task {
&self.description,
TaskMessage::DescriptionEdited,
)
.id(Self::text_input_id(i))
.on_submit(TaskMessage::FinishEdition)
.padding(10);

Expand Down
6 changes: 2 additions & 4 deletions examples/tour/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ impl<'a> Step {
.map(Element::from)
.collect()
)
.spacing(10)
]
.padding(20)
.spacing(10);
Expand Down Expand Up @@ -594,10 +595,7 @@ fn ferris<'a>(width: u16) -> Container<'a, StepMessage> {
if cfg!(target_arch = "wasm32") {
image("tour/images/ferris.png")
} else {
image(format!(
"{}/../../tour/images/ferris.png",
env!("CARGO_MANIFEST_DIR")
))
image(format!("{}/images/ferris.png", env!("CARGO_MANIFEST_DIR")))
}
.width(Length::Units(width)),
)
Expand Down
1 change: 1 addition & 0 deletions examples/websocket/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ publish = false
iced = { path = "../..", features = ["tokio", "debug"] }
iced_native = { path = "../../native" }
iced_futures = { path = "../../futures" }
lazy_static = "1.4"

[dependencies.async-tungstenite]
version = "0.16"
Expand Down
Loading