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

✨ Add Cupertino-style switch and buttons #106

Merged
merged 10 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ members = [
"examples/card",
"examples/color_picker",
"examples/cupertino/cupertino_spinner",
"examples/cupertino/cupertino_switch",
"examples/date_picker",
"examples/floating_element",
"examples/floating_element_anchors",
Expand Down
11 changes: 11 additions & 0 deletions examples/cupertino/cupertino_switch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "cupertino-switch"
version = "0.1.0"
authors = ["Brett Byler <[email protected]>"]
edition = "2021"
publish = false

[dependencies]
iced = { version = "0.8.0", features = [] }
iced_aw = { path = "../../../", features = ["cupertino"] }

7 changes: 7 additions & 0 deletions examples/cupertino/cupertino_switch/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SHELL := /bin/bash

run:
cargo run --package cupertino-switch

.ONESHELL:

19 changes: 19 additions & 0 deletions examples/cupertino/cupertino_switch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Cupertino Switch Example
=========================

An application that uses the `CupertinoSwitch` widget to draw a
switch.

The __[`main`]__ file contains all the code of the example.

You can run it with `cargo run`:

```bash
cargo run --package cupertino-switch

# Or
make run
```

[`main`]: src/main.rs

108 changes: 108 additions & 0 deletions examples/cupertino/cupertino_switch/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use iced::{alignment, Application, Color, Command, Element, executor, Length, Settings, Theme};
use iced::widget::{column, container, row, text};
use iced_aw::native::cupertino::cupertino_switch::CupertinoSwitch;

pub fn main() -> iced::Result {
Switch::run(Settings {
antialiasing: true,
..Settings::default()
})
}

enum Switch {
Loading,
LeftSwitchChanged(bool),
RightSwitchChanged(bool),
}

#[derive(Debug, Clone)]
enum Message {
LeftSwitchChanged(bool),
RightSwitchChanged(bool),
}

// `cargo fmt` becomes unreadable for this example, so switching off //
#[cfg_attr(rustfmt, rustfmt_skip)]
impl Application for Switch {
type Executor = executor::Default;
type Message = Message;
type Theme = Theme;
type Flags = ();

fn new(_flags: ()) -> (Self, Command<Message>) {
(Switch::Loading, Command::none())
}

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

fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::LeftSwitchChanged(value) => *self = Switch::LeftSwitchChanged(value),
Message::RightSwitchChanged(value) => *self = Switch::RightSwitchChanged(value),
}

Command::none()
}

fn view(&self) -> Element<Message> {
let toggle_1: CupertinoSwitch<Message> = CupertinoSwitch::new().on_changed(Some(Box::new(
Message::LeftSwitchChanged
)));

let toggle_2: CupertinoSwitch<Message> = CupertinoSwitch::new()
.value(false)
.on_changed(Some(Box::new(Message::RightSwitchChanged)));

let left_text: String = match self {
Switch::LeftSwitchChanged(v) => format!("Left Toggle State: {}", v),
_ => format!("Left Toggle State: {}", toggle_1.value),
};

let right_text: String = match self {
Switch::RightSwitchChanged(v) => format!("Right Toggle State: {}", v),
_ => format!("Right Toggle State: {}", toggle_2.value),
};

let content = row![
toggle_1,

container(column![
text(left_text)
.width(Length::Fill)
.size(25)
.horizontal_alignment(alignment::Horizontal::Center)
.vertical_alignment(alignment::Vertical::Center),

text(right_text)
.width(Length::Fill)
.size(25)
.horizontal_alignment(alignment::Horizontal::Center)
.vertical_alignment(alignment::Vertical::Center),
]).width(Length::Fill).center_y(),

toggle_2,
].spacing(100).align_items(alignment::Alignment::Center).width(Length::Shrink);

// No effect, but here for demonstrative purposes //
let style: fn(&iced::Theme) -> container::Appearance = |_theme| container::Appearance {
background: Some(Color::TRANSPARENT.into()),
..Default::default()
};
//

container(content)
.center_x()
.center_y()
.width(Length::Fill)
.height(Length::Fill)
.style(style)
.into()
}

fn theme(&self) -> Self::Theme {
Theme::Light
}
}

Binary file added images/showcase/cupertino/cupertino-switch.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions src/native/cupertino/cupertino_colours.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use iced_native::Color;

/// <https://flutter.github.io/assets-for-api-docs/assets/cupertino/cupertino_system_colors_1.png>
/// <https://flutter.github.io/assets-for-api-docs/assets/cupertino/cupertino_system_colors_2.png>
/// <https://flutter.github.io/assets-for-api-docs/assets/cupertino/cupertino_system_colors_3.png>
///
/// Because iced expects `r`, `g`, and `b` to be between 0 and 1, divide by 255 everywhere.
// System Colours //

/// System Blue
#[must_use]
pub fn system_blue(alpha: f32) -> Color { Color::from_rgba(0.0 / 255.0, 122.0 / 255.0, 1.0, alpha) }

/// System Green
#[must_use]
pub fn system_green(alpha: f32) -> Color { Color::from_rgba(52.0 / 255.0, 199.0 / 255.0, 89.0 / 255.0, alpha) }

/// System Indigo
#[must_use]
pub fn system_indigo(alpha: f32) -> Color { Color::from_rgba(88.0 / 255.0, 86.0 / 255.0, 214.0 / 255.0, alpha) }

/// System Orange
#[must_use]
pub fn system_orange(alpha: f32) -> Color { Color::from_rgba(1.0, 149.0 / 255.0, 0.0 / 255.0, alpha) }

/// System Pink
#[must_use]
pub fn system_pink(alpha: f32) -> Color { Color::from_rgba(1.0, 45.0 / 255.0, 85.0 / 255.0, alpha) }

/// System Purple
#[must_use]
pub fn system_purple(alpha: f32) -> Color { Color::from_rgba(175.0 / 255.0, 82.0 / 255.0, 222.0 / 255.0, alpha) }

/// System Red
#[must_use]
pub fn system_red(alpha: f32) -> Color { Color::from_rgba(1.0, 59.0 / 255.0, 48.0 / 255.0, alpha) }

/// System Teal
#[must_use]
pub fn system_teal(alpha: f32) -> Color { Color::from_rgba(90.0 / 255.0, 200.0 / 255.0, 250.0 / 255.0, alpha) }

/// System Yellow
#[must_use]
pub fn system_yellow(alpha: f32) -> Color { Color::from_rgba(1.0, 204.0 / 255.0, 0.0 / 255.0, alpha) }
//

/// Secondary System Fill
#[must_use]
pub fn secondary_system_fill() -> Color { Color::from_rgb(209.0 / 255.0, 209.0 / 255.0, 214.0 / 255.0) }

14 changes: 9 additions & 5 deletions src/native/cupertino/cupertino_spinner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,20 @@ impl Default for CupertinoSpinner {

impl CupertinoSpinner {
/// Creates a new [`CupertinoSpinner`] widget.
#[must_use]
pub fn new() -> Self {
Self::default()
}

/// Sets the width of the [`CupertinoSpinner`](CupertinoSpinner).
#[must_use]
pub fn width(mut self, width: Length) -> Self {
self.width = width;
self
}

/// Sets the height of the [`CupertinoSpinner`](CupertinoSpinner).
#[must_use]
pub fn height(mut self, height: Length) -> Self {
self.height = height;
self
Expand All @@ -79,6 +82,7 @@ impl CupertinoSpinner {
/// Sets the radius of the [`CupertinoSpinner`](CupertinoSpinner).
/// NOTE: While you _can_ tweak the radius, the scale may be all out of whack if not using a
/// number close to the default of `20.0`.
#[must_use]
pub fn radius(mut self, radius: f32) -> Self {
self.radius = radius;
self
Expand Down Expand Up @@ -116,16 +120,16 @@ where B: Backend {
let radius = self.radius;
let width = radius / 5.0;

let mut hands: Vec<(Path, _)> = vec!();
let mut hands: Vec<(Path, _)> = vec![];

for i in 0..HAND_COUNT {
for alpha in &ALPHAS {
hands.push((
Path::line(Point::new(0.0, radius / 3.0), Point::new(0.0, radius / 1.5)),
move || -> Stroke {
// The `60.0` is to shift the original black to dark grey //
gen_stroke(
width,
Color::from_rgba(0.0, 0.0, 0.0, ALPHAS[i] as f32 / (60.0 + 147.0))
Color::from_rgba(0.0, 0.0, 0.0, f32::from(*alpha) / (60.0 + 147.0))
)
},
))
Expand Down Expand Up @@ -161,7 +165,7 @@ where B: Backend {
now: time::OffsetDateTime::now_local().unwrap_or_else(
|_| time::OffsetDateTime::now_utc()
),
spinner: Default::default(),
spinner: Cache::default(),
})
}

Expand Down Expand Up @@ -212,7 +216,7 @@ fn gen_stroke(width: f32, color: Color) -> Stroke<'static> {
const K: f32 = PI * 2.0;

fn hand_rotation(n: u16, total: u16) -> f32 {
let turns = n as f32 / total as f32;
let turns = f32::from(n) / f32::from(total);

K * turns
}
Expand Down
Loading