Merge remote-tracking branch 'origin/master' into feat/multi-window-support

# Conflicts:
#	examples/events/src/main.rs
#	glutin/src/application.rs
#	native/src/window.rs
#	winit/src/window.rs
This commit is contained in:
Bingus 2023-01-18 15:01:17 -08:00
commit 70d487ba20
No known key found for this signature in database
GPG key ID: 5F84D2AA40A9F170
57 changed files with 815 additions and 446 deletions

View file

@ -1,10 +0,0 @@
[package]
name = "cached"
version = "0.1.0"
authors = ["Nick Senger <dev@nsenger.com>"]
edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
iced_lazy = { path = "../../lazy" }

View file

@ -1,139 +0,0 @@
use iced::theme;
use iced::widget::{
button, column, horizontal_space, row, scrollable, text, text_input,
};
use iced::{Element, Length, Sandbox, Settings};
use iced_lazy::lazy;
use std::collections::HashSet;
pub fn main() -> iced::Result {
App::run(Settings::default())
}
struct App {
options: HashSet<String>,
input: String,
order: Order,
}
impl Default for App {
fn default() -> Self {
Self {
options: ["Foo", "Bar", "Baz", "Qux", "Corge", "Waldo", "Fred"]
.into_iter()
.map(ToString::to_string)
.collect(),
input: Default::default(),
order: Order::Ascending,
}
}
}
#[derive(Debug, Clone)]
enum Message {
InputChanged(String),
ToggleOrder,
DeleteOption(String),
AddOption(String),
}
impl Sandbox for App {
type Message = Message;
fn new() -> Self {
Self::default()
}
fn title(&self) -> String {
String::from("Cached - Iced")
}
fn update(&mut self, message: Message) {
match message {
Message::InputChanged(input) => {
self.input = input;
}
Message::ToggleOrder => {
self.order = match self.order {
Order::Ascending => Order::Descending,
Order::Descending => Order::Ascending,
}
}
Message::AddOption(option) => {
self.options.insert(option);
self.input.clear();
}
Message::DeleteOption(option) => {
self.options.remove(&option);
}
}
}
fn view(&self) -> Element<Message> {
let options = lazy((&self.order, self.options.len()), || {
let mut options: Vec<_> = self.options.iter().collect();
options.sort_by(|a, b| match self.order {
Order::Ascending => a.to_lowercase().cmp(&b.to_lowercase()),
Order::Descending => b.to_lowercase().cmp(&a.to_lowercase()),
});
column(
options
.into_iter()
.map(|option| {
row![
text(option),
horizontal_space(Length::Fill),
button("Delete")
.on_press(Message::DeleteOption(
option.to_string(),
),)
.style(theme::Button::Destructive)
]
.into()
})
.collect(),
)
.spacing(10)
});
column![
scrollable(options).height(Length::Fill),
row![
text_input(
"Add a new option",
&self.input,
Message::InputChanged,
)
.on_submit(Message::AddOption(self.input.clone())),
button(text(format!("Toggle Order ({})", self.order)))
.on_press(Message::ToggleOrder)
]
.spacing(10)
]
.spacing(20)
.padding(20)
.into()
}
}
#[derive(Debug, Hash)]
enum Order {
Ascending,
Descending,
}
impl std::fmt::Display for Order {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Ascending => "Ascending",
Self::Descending => "Descending",
}
)
}
}

View file

@ -6,5 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced = { path = "../..", features = ["debug"] }
iced_native = { path = "../../native" }

View file

@ -1,11 +1,12 @@
use iced::alignment;
use iced::executor;
use iced::widget::{button, checkbox, container, text, Column};
use iced::window;
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
Theme,
};
use iced_native::{window, Event};
use iced_native::Event;
pub fn main() -> iced::Result {
Events::run(Settings {
@ -18,14 +19,13 @@ pub fn main() -> iced::Result {
struct Events {
last: Vec<iced_native::Event>,
enabled: bool,
should_exit: bool,
}
#[derive(Debug, Clone)]
enum Message {
EventOccurred(iced_native::Event),
Toggled(bool),
Exit,
Exit(window::Id),
}
impl Application for Events {
@ -50,31 +50,29 @@ impl Application for Events {
if self.last.len() > 5 {
let _ = self.last.remove(0);
}
Command::none()
}
Message::EventOccurred(event) => {
if let Event::Window(_, window::Event::CloseRequested) = event {
self.should_exit = true;
if let Event::Window(id, window::Event::CloseRequested) = event {
window::close(id)
} else {
Command::none()
}
}
Message::Toggled(enabled) => {
self.enabled = enabled;
}
Message::Exit => {
self.should_exit = true;
}
};
Command::none()
Command::none()
}
Message::Exit(id) => window::close(id),
}
}
fn subscription(&self) -> Subscription<Message> {
iced_native::subscription::events().map(Message::EventOccurred)
}
fn should_exit(&self) -> bool {
self.should_exit
}
fn view(&self) -> Element<Message> {
let events = Column::with_children(
self.last

View file

@ -1,5 +1,7 @@
use iced::executor;
use iced::widget::{button, column, container};
use iced::{Alignment, Element, Length, Sandbox, Settings};
use iced::window;
use iced::{Alignment, Application, Command, Element, Length, Settings, Theme};
pub fn main() -> iced::Result {
Exit::run(Settings::default())
@ -8,7 +10,6 @@ pub fn main() -> iced::Result {
#[derive(Default)]
struct Exit {
show_confirm: bool,
exit: bool,
}
#[derive(Debug, Clone, Copy)]
@ -17,28 +18,27 @@ enum Message {
Exit,
}
impl Sandbox for Exit {
impl Application for Exit {
type Executor = executor::Default;
type Message = Message;
type Theme = Theme;
type Flags = ();
fn new() -> Self {
Self::default()
fn new(_flags: ()) -> (Self, Command<Message>) {
(Self::default(), Command::none())
}
fn title(&self) -> String {
String::from("Exit - Iced")
}
fn should_exit(&self) -> bool {
self.exit
}
fn update(&mut self, message: Message) {
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::Confirm => {
self.exit = true;
}
Message::Confirm => window::close(),
Message::Exit => {
self.show_confirm = true;
Command::none()
}
}
}

View file

@ -1,18 +1,21 @@
use iced::theme;
use iced::widget::{
button, column, horizontal_space, row, scrollable, text, text_input,
button, column, horizontal_space, pick_list, row, scrollable, text,
text_input,
};
use iced::{Element, Length, Sandbox, Settings};
use iced_lazy::lazy;
use std::collections::HashSet;
use std::hash::Hash;
pub fn main() -> iced::Result {
App::run(Settings::default())
}
struct App {
options: HashSet<String>,
version: u8,
items: HashSet<Item>,
input: String,
order: Order,
}
@ -20,9 +23,10 @@ struct App {
impl Default for App {
fn default() -> Self {
Self {
options: ["Foo", "Bar", "Baz", "Qux", "Corge", "Waldo", "Fred"]
version: 0,
items: ["Foo", "Bar", "Baz", "Qux", "Corge", "Waldo", "Fred"]
.into_iter()
.map(ToString::to_string)
.map(From::from)
.collect(),
input: Default::default(),
order: Order::Ascending,
@ -30,12 +34,92 @@ impl Default for App {
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
enum Color {
#[default]
Black,
Red,
Orange,
Yellow,
Green,
Blue,
Purple,
}
impl Color {
const ALL: &[Color] = &[
Color::Black,
Color::Red,
Color::Orange,
Color::Yellow,
Color::Green,
Color::Blue,
Color::Purple,
];
}
impl std::fmt::Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Black => "Black",
Self::Red => "Red",
Self::Orange => "Orange",
Self::Yellow => "Yellow",
Self::Green => "Green",
Self::Blue => "Blue",
Self::Purple => "Purple",
})
}
}
impl From<Color> for iced::Color {
fn from(value: Color) -> Self {
match value {
Color::Black => iced::Color::from_rgb8(0, 0, 0),
Color::Red => iced::Color::from_rgb8(220, 50, 47),
Color::Orange => iced::Color::from_rgb8(203, 75, 22),
Color::Yellow => iced::Color::from_rgb8(181, 137, 0),
Color::Green => iced::Color::from_rgb8(133, 153, 0),
Color::Blue => iced::Color::from_rgb8(38, 139, 210),
Color::Purple => iced::Color::from_rgb8(108, 113, 196),
}
}
}
#[derive(Clone, Debug, Eq)]
struct Item {
name: String,
color: Color,
}
impl Hash for Item {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl PartialEq for Item {
fn eq(&self, other: &Self) -> bool {
self.name.eq(&other.name)
}
}
impl From<&str> for Item {
fn from(s: &str) -> Self {
Self {
name: s.to_owned(),
color: Default::default(),
}
}
}
#[derive(Debug, Clone)]
enum Message {
InputChanged(String),
ToggleOrder,
DeleteOption(String),
AddOption(String),
DeleteItem(Item),
AddItem(String),
ItemColorChanged(Item, Color),
}
impl Sandbox for App {
@ -46,7 +130,7 @@ impl Sandbox for App {
}
fn title(&self) -> String {
String::from("Cached - Iced")
String::from("Lazy - Iced")
}
fn update(&mut self, message: Message) {
@ -55,43 +139,71 @@ impl Sandbox for App {
self.input = input;
}
Message::ToggleOrder => {
self.version = self.version.wrapping_add(1);
self.order = match self.order {
Order::Ascending => Order::Descending,
Order::Descending => Order::Ascending,
}
}
Message::AddOption(option) => {
self.options.insert(option);
Message::AddItem(name) => {
self.version = self.version.wrapping_add(1);
self.items.insert(name.as_str().into());
self.input.clear();
}
Message::DeleteOption(option) => {
self.options.remove(&option);
Message::DeleteItem(item) => {
self.version = self.version.wrapping_add(1);
self.items.remove(&item);
}
Message::ItemColorChanged(item, color) => {
self.version = self.version.wrapping_add(1);
if self.items.remove(&item) {
self.items.insert(Item {
name: item.name,
color,
});
}
}
}
}
fn view(&self) -> Element<Message> {
let options = lazy((&self.order, self.options.len()), || {
let mut options: Vec<_> = self.options.iter().collect();
let options = lazy(self.version, |_| {
let mut items: Vec<_> = self.items.iter().cloned().collect();
options.sort_by(|a, b| match self.order {
Order::Ascending => a.to_lowercase().cmp(&b.to_lowercase()),
Order::Descending => b.to_lowercase().cmp(&a.to_lowercase()),
items.sort_by(|a, b| match self.order {
Order::Ascending => {
a.name.to_lowercase().cmp(&b.name.to_lowercase())
}
Order::Descending => {
b.name.to_lowercase().cmp(&a.name.to_lowercase())
}
});
column(
options
items
.into_iter()
.map(|option| {
.map(|item| {
let button = button("Delete")
.on_press(Message::DeleteItem(item.clone()))
.style(theme::Button::Destructive);
row![
text(option),
text(&item.name)
.style(theme::Text::Color(item.color.into())),
horizontal_space(Length::Fill),
button("Delete")
.on_press(Message::DeleteOption(
option.to_string(),
),)
.style(theme::Button::Destructive)
pick_list(
Color::ALL,
Some(item.color),
move |color| {
Message::ItemColorChanged(
item.clone(),
color,
)
}
),
button
]
.spacing(20)
.into()
})
.collect(),
@ -107,7 +219,7 @@ impl Sandbox for App {
&self.input,
Message::InputChanged,
)
.on_submit(Message::AddOption(self.input.clone())),
.on_submit(Message::AddItem(self.input.clone())),
button(text(format!("Toggle Order ({})", self.order)))
.on_press(Message::ToggleOrder)
]

View file

@ -9,7 +9,6 @@
use iced::application;
use iced::executor;
use iced::theme::{self, Theme};
use iced::time;
use iced::widget::canvas;
use iced::widget::canvas::gradient::{self, Gradient};
use iced::widget::canvas::stroke::{self, Stroke};
@ -90,7 +89,7 @@ impl Application for SolarSystem {
}
fn subscription(&self) -> Subscription<Message> {
time::every(time::Duration::from_millis(10)).map(Message::Tick)
window::frames().map(Message::Tick)
}
}