Skip to content

Commit

Permalink
feat: add build_pattern for iced_layershell (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
Decodetalkers authored Dec 3, 2024
1 parent a08d676 commit d0eac93
Show file tree
Hide file tree
Showing 9 changed files with 2,367 additions and 2 deletions.
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions iced_examples/counter_mulit_pattern/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "counter_multi_pattern"
authors.workspace = true
edition.workspace = true
version.workspace = true
license.workspace = true
repository.workspace = true
description.workspace = true
keywords.workspace = true
readme.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
iced.workspace = true
iced_runtime.workspace = true
iced_layershell.workspace = true
tracing-subscriber.workspace = true
273 changes: 273 additions & 0 deletions iced_examples/counter_mulit_pattern/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
use std::collections::HashMap;

use iced::widget::{button, column, container, row, text, text_input};
use iced::window::Id;
use iced::{event, Alignment, Element, Event, Length, Task as Command};
use iced_layershell::actions::{IcedNewMenuSettings, MenuDirection};
use iced_runtime::window::Action as WindowAction;
use iced_runtime::{task, Action};

use iced_layershell::build_pattern::{daemon, MainSettings};
use iced_layershell::reexport::{Anchor, KeyboardInteractivity, Layer, NewLayerShellSettings};
use iced_layershell::settings::{LayerShellSettings, StartMode};
use iced_layershell::{to_layer_message, LayerSingleton};

pub fn main() -> Result<(), iced_layershell::Error> {
tracing_subscriber::fmt().init();
daemon(
Counter::namespace,
Counter::update,
Counter::view,
Counter::id_info,
Counter::set_id_info,
Counter::remove_id,
)
.subscription(Counter::subscription)
.settings(MainSettings {
layer_settings: LayerShellSettings {
size: Some((0, 400)),
exclusive_zone: 400,
anchor: Anchor::Bottom | Anchor::Left | Anchor::Right,
start_mode: StartMode::AllScreens,
..Default::default()
},
..Default::default()
})
.run_with(|| Counter::new("Hello"))
}

#[derive(Debug, Default)]
struct Counter {
value: i32,
text: String,
ids: HashMap<iced::window::Id, WindowInfo>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, LayerSingleton)]
enum WindowInfo {
#[singleton]
Left,
#[singleton]
Right,
PopUp,
}

#[derive(Debug, Clone, Copy)]
enum WindowDirection {
Top(Id),
Left(Id),
Right(Id),
Bottom(Id),
}

#[to_layer_message(multi, info_name = "WindowInfo")]
#[derive(Debug, Clone)]
enum Message {
IncrementPressed,
DecrementPressed,
NewWindowLeft,
NewWindowRight,
Close(Id),
TextInput(String),
Direction(WindowDirection),
IcedEvent(Event),
}

impl Counter {
fn window_id(&self, info: &WindowInfo) -> Option<&iced::window::Id> {
for (k, v) in self.ids.iter() {
if info == v {
return Some(k);
}
}
None
}
}

impl Counter {
fn new(text: &str) -> (Self, Command<Message>) {
(
Self {
value: 0,
text: text.to_string(),
ids: HashMap::new(),
},
Command::none(),
)
}

fn id_info(&self, id: iced::window::Id) -> Option<WindowInfo> {
self.ids.get(&id).cloned()
}

fn set_id_info(&mut self, id: iced::window::Id, info: WindowInfo) {
self.ids.insert(id, info);
}

fn remove_id(&mut self, id: iced::window::Id) {
self.ids.remove(&id);
}

fn namespace(&self) -> String {
String::from("Counter - Iced")
}

fn subscription(&self) -> iced::Subscription<Message> {
event::listen().map(Message::IcedEvent)
}

fn update(&mut self, message: Message) -> Command<Message> {
use iced::keyboard;
use iced::keyboard::key::Named;
use iced::Event;
match message {
Message::IcedEvent(event) => {
match event {
Event::Keyboard(keyboard::Event::KeyPressed {
key: keyboard::Key::Named(Named::Escape),
..
}) => {
if let Some(id) = self.window_id(&WindowInfo::Left) {
return iced_runtime::task::effect(Action::Window(
WindowAction::Close(*id),
));
}
}
Event::Mouse(iced::mouse::Event::ButtonPressed(iced::mouse::Button::Right)) => {
return Command::done(Message::NewMenu {
settings: IcedNewMenuSettings {
size: (100, 100),
direction: MenuDirection::Up,
},
info: WindowInfo::PopUp,
});
}
_ => {}
}
Command::none()
}
Message::IncrementPressed => {
self.value += 1;
Command::none()
}
Message::DecrementPressed => {
self.value -= 1;
Command::none()
}
Message::TextInput(text) => {
self.text = text;
Command::none()
}
Message::Direction(direction) => match direction {
WindowDirection::Left(id) => Command::done(Message::AnchorSizeChange {
id,
anchor: Anchor::Top | Anchor::Left | Anchor::Bottom,
size: (400, 0),
}),
WindowDirection::Right(id) => Command::done(Message::AnchorSizeChange {
id,
anchor: Anchor::Top | Anchor::Right | Anchor::Bottom,
size: (400, 0),
}),
WindowDirection::Bottom(id) => Command::done(Message::AnchorSizeChange {
id,
anchor: Anchor::Left | Anchor::Right | Anchor::Bottom,
size: (0, 400),
}),
WindowDirection::Top(id) => Command::done(Message::AnchorSizeChange {
id,
anchor: Anchor::Left | Anchor::Right | Anchor::Top,
size: (0, 400),
}),
},
Message::NewWindowLeft => Command::done(Message::NewLayerShell {
settings: NewLayerShellSettings {
size: Some((100, 100)),
exclusive_zone: None,
anchor: Anchor::Left | Anchor::Bottom,
layer: Layer::Top,
margin: None,
keyboard_interactivity: KeyboardInteractivity::Exclusive,
use_last_output: false,
..Default::default()
},
info: WindowInfo::Left,
}),
Message::NewWindowRight => Command::done(Message::NewLayerShell {
settings: NewLayerShellSettings {
size: Some((100, 100)),
exclusive_zone: None,
anchor: Anchor::Right | Anchor::Bottom,
layer: Layer::Top,
margin: None,
keyboard_interactivity: KeyboardInteractivity::Exclusive,
use_last_output: false,
..Default::default()
},
info: WindowInfo::Right,
}),
Message::Close(id) => task::effect(Action::Window(WindowAction::Close(id))),
_ => unreachable!(),
}
}

fn view(&self, id: iced::window::Id) -> Element<Message> {
if let Some(WindowInfo::Left) = self.id_info(id) {
return button("close left").on_press(Message::Close(id)).into();
}
if let Some(WindowInfo::Right) = self.id_info(id) {
return button("close right").on_press(Message::Close(id)).into();
}
if let Some(WindowInfo::PopUp) = self.id_info(id) {
return container(button("close PopUp").on_press(Message::Close(id)))
.center_x(Length::Fill)
.center_y(Length::Fill)
.style(|_theme| container::Style {
background: Some(iced::Color::new(0., 0.5, 0.7, 0.6).into()),
..Default::default()
})
//.style(Container::Custom(Box::new(BlackMenu)))
.width(Length::Fill)
.height(Length::Fill)
.into();
}
let center = column![
button("Increment").on_press(Message::IncrementPressed),
button("Decrement").on_press(Message::DecrementPressed),
text(self.value).size(50),
button("newwindowLeft").on_press(Message::NewWindowLeft),
button("newwindowRight").on_press(Message::NewWindowRight),
]
.align_x(Alignment::Center)
.padding(20)
.width(Length::Fill)
.height(Length::Fill);
row![
button("left")
.on_press(Message::Direction(WindowDirection::Left(id)))
.height(Length::Fill),
column![
button("top")
.on_press(Message::Direction(WindowDirection::Top(id)))
.width(Length::Fill),
center,
text_input("hello", &self.text)
.on_input(Message::TextInput)
.padding(10),
button("bottom")
.on_press(Message::Direction(WindowDirection::Bottom(id)))
.width(Length::Fill),
]
.width(Length::Fill),
button("right")
.on_press(Message::Direction(WindowDirection::Right(id)))
.height(Length::Fill),
]
.padding(20)
.spacing(10)
//.align_items(Alignment::Center)
.width(Length::Fill)
.height(Length::Fill)
.into()
}
}
17 changes: 17 additions & 0 deletions iced_examples/counter_pattern/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "counter_pattern"
authors.workspace = true
edition.workspace = true
version.workspace = true
license.workspace = true
repository.workspace = true
description.workspace = true
keywords.workspace = true
readme.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
iced.workspace = true
iced_runtime.workspace = true
iced_layershell.workspace = true
Loading

0 comments on commit d0eac93

Please sign in to comment.