Merge branch 'master' into feat/multi-window-support
This commit is contained in:
commit
e09b4e24dd
331 changed files with 12085 additions and 3976 deletions
|
|
@ -6,18 +6,26 @@ edition = "2021"
|
|||
publish = false
|
||||
|
||||
[dependencies]
|
||||
iced = { path = "../..", features = ["async-std", "debug"] }
|
||||
iced.workspace = true
|
||||
iced.features = ["async-std", "debug"]
|
||||
|
||||
once_cell.workspace = true
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
once_cell = "1.15"
|
||||
uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
async-std = "1.0"
|
||||
async-std.workspace = true
|
||||
directories-next = "2.0"
|
||||
tracing-subscriber = "0.3"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
web-sys = { version = "0.3", features = ["Window", "Storage"] }
|
||||
wasm-timer = "0.2"
|
||||
iced.workspace = true
|
||||
iced.features = ["debug", "webgl"]
|
||||
|
||||
uuid = { version = "1.0", features = ["js"] }
|
||||
web-sys = { workspace = true, features = ["Window", "Storage"] }
|
||||
wasm-timer.workspace = true
|
||||
|
||||
[package.metadata.deb]
|
||||
assets = [
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input,
|
|||
All the example code is located in the __[`main`]__ file.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://gfycat.com/littlesanehalicore">
|
||||
<img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="400px">
|
||||
<a href="https://iced.rs/examples/todos.mp4">
|
||||
<img src="https://iced.rs/examples/todos.gif">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
@ -14,7 +14,14 @@ You can run the native version with `cargo run`:
|
|||
```
|
||||
cargo run --package todos
|
||||
```
|
||||
We have not yet implemented a `LocalStorage` version of the auto-save feature. Therefore, it does not work on web _yet_!
|
||||
|
||||
The web version can be run with [`trunk`]:
|
||||
|
||||
```
|
||||
cd examples/todos
|
||||
trunk serve
|
||||
```
|
||||
|
||||
[`main`]: src/main.rs
|
||||
[TodoMVC]: http://todomvc.com/
|
||||
[`trunk`]: https://trunkrs.dev/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
use iced::alignment::{self, Alignment};
|
||||
use iced::event::{self, Event};
|
||||
use iced::font::{self, Font};
|
||||
use iced::keyboard::{self, KeyCode, Modifiers};
|
||||
use iced::subscription;
|
||||
use iced::keyboard;
|
||||
use iced::theme::{self, Theme};
|
||||
use iced::widget::{
|
||||
self, button, checkbox, column, container, row, scrollable, text,
|
||||
text_input, Text,
|
||||
self, button, checkbox, column, container, keyed_column, row, scrollable,
|
||||
text, text_input, Text,
|
||||
};
|
||||
use iced::window;
|
||||
use iced::{Application, Element};
|
||||
|
|
@ -14,10 +12,14 @@ use iced::{Color, Command, Length, Settings, Subscription};
|
|||
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
static INPUT_ID: Lazy<text_input::Id> = Lazy::new(text_input::Id::unique);
|
||||
|
||||
pub fn main() -> iced::Result {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
Todos::run(Settings {
|
||||
window: window::Settings {
|
||||
size: (500, 800),
|
||||
|
|
@ -222,17 +224,19 @@ impl Application for Todos {
|
|||
tasks.iter().filter(|task| filter.matches(task));
|
||||
|
||||
let tasks: Element<_> = if filtered_tasks.count() > 0 {
|
||||
column(
|
||||
keyed_column(
|
||||
tasks
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, task)| filter.matches(task))
|
||||
.map(|(i, task)| {
|
||||
task.view(i).map(move |message| {
|
||||
Message::TaskMessage(i, message)
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
(
|
||||
task.id,
|
||||
task.view(i).map(move |message| {
|
||||
Message::TaskMessage(i, message)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.spacing(10)
|
||||
.into()
|
||||
|
|
@ -262,39 +266,27 @@ 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,
|
||||
..
|
||||
keyboard::on_key_press(|key_code, modifiers| {
|
||||
match (key_code, modifiers) {
|
||||
(keyboard::KeyCode::Tab, _) => Some(Message::TabPressed {
|
||||
shift: modifiers.shift(),
|
||||
}),
|
||||
event::Status::Ignored,
|
||||
) => Some(Message::TabPressed {
|
||||
shift: modifiers.shift(),
|
||||
}),
|
||||
(
|
||||
Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code,
|
||||
modifiers: Modifiers::SHIFT,
|
||||
}),
|
||||
event::Status::Ignored,
|
||||
) => match key_code {
|
||||
KeyCode::Up => {
|
||||
(keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => {
|
||||
Some(Message::ToggleFullscreen(window::Mode::Fullscreen))
|
||||
}
|
||||
KeyCode::Down => {
|
||||
(keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => {
|
||||
Some(Message::ToggleFullscreen(window::Mode::Windowed))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct Task {
|
||||
#[serde(default = "Uuid::new_v4")]
|
||||
id: Uuid,
|
||||
description: String,
|
||||
completed: bool,
|
||||
|
||||
|
|
@ -330,6 +322,7 @@ impl Task {
|
|||
|
||||
fn new(description: String) -> Self {
|
||||
Task {
|
||||
id: Uuid::new_v4(),
|
||||
description,
|
||||
completed: false,
|
||||
state: TaskState::Idle,
|
||||
|
|
@ -422,8 +415,7 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element<Message> {
|
|||
|
||||
row![
|
||||
text(format!(
|
||||
"{} {} left",
|
||||
tasks_left,
|
||||
"{tasks_left} {} left",
|
||||
if tasks_left == 1 { "task" } else { "tasks" }
|
||||
))
|
||||
.width(Length::Fill),
|
||||
|
|
@ -451,7 +443,7 @@ pub enum Filter {
|
|||
}
|
||||
|
||||
impl Filter {
|
||||
fn matches(&self, task: &Task) -> bool {
|
||||
fn matches(self, task: &Task) -> bool {
|
||||
match self {
|
||||
Filter::All => true,
|
||||
Filter::Active => !task.completed,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue