[Rust] iced: ๋ ์ด์์ - Stack
0.13 ๋ฒ์ ๊ธฐ์ค์ด๋ค.
Stack ์ปดํฌ๋ํธ
Stack ์ปดํฌ๋ํธ๋ ์ด๋ฆ ๊ทธ๋๋ก ์ปดํฌ๋ํธ๋ฅผ ์์์ฌ๋ฆฌ๋ ์ญํ ์ ํ๋ ์์ ฏ์ด๋ค.
์์ ์์๋๋ก ์ธต์ธต์ด ์์์ฌ๋ฆฐ๋ค.
์๋ฅผ ๋ค์ด, ์ด ์ฝ๋๋ ๋ฐฐ๊ฒฝ์ ๋จผ์ ๋นจ๊ฐ์์ ํฌ๊ฒ ๊น๊ณ , ๊ทธ ์์ stack์ผ๋ก ์ด๋ก์, ํ๋์์ ๊น๋ค.
๋ฑ ์ ์ํ ์์๋๋ก ๊น๊ณ ๋ณด๋ ๊ฒ์ด๋ค.
๊ทธ๋ ๊ฒ ๋๋ ค๋ณด๋ฉด
์๋ํ๋๋ก ๋ํ๋ ๊ฒ์ด๋ค.
์์ฒ๋ผ ๋ญ๊ฐ๋ฅผ ์ค์ฒฉ์์ผ์ ํํํ ๋ ์ ์ฉํ๋ค.
์์ ์ฝ๋
use iced::widget::{container, stack, text};
use iced::{Background, Color, Element, Length, Settings, Size};
pub struct MainApp {}
#[derive(Debug, Clone)]
pub enum Message {}
impl MainApp {
pub fn new() -> Self {
let app = Self {};
app
}
pub fn theme(&self) -> iced::Theme {
iced::Theme::Dracula
}
pub fn update(&mut self, message: Message) {
match message {}
}
pub fn view(&self) -> Element<Message> {
let content = container(stack![
container(text("c"))
.width(Length::Fill)
.height(Length::Fill)
.style(|_| {
let mut style = container::Style::default();
style.background = Some(Background::Color(Color::from_rgb8(0, 255, 0)));
style
})
.width(Length::Fixed(250.0))
.height(Length::Fixed(250.0)),
container(text("d"))
.width(Length::Fill)
.height(Length::Fill)
.style(|_| {
let mut style = container::Style::default();
style.background = Some(Background::Color(Color::from_rgb8(0, 0, 255)));
style
})
.width(Length::Fixed(200.0))
.height(Length::Fixed(200.0)),
])
.width(Length::Fixed(300.0))
.height(Length::Fixed(300.0))
.style(|_| {
let mut style = container::Style::default();
style.background = Some(Background::Color(Color::from_rgb8(255, 0, 0)));
style
})
.into();
content
}
}
impl Default for MainApp {
fn default() -> Self {
Self::new()
}
}
fn main() -> iced::Result {
let setting = Settings::default();
iced::application("test", MainApp::update, MainApp::view)
.settings(setting)
.resizable(false)
.window_size(Size::new(600.0, 600.0))
.theme(MainApp::theme)
.run()
}์์ฉ: Modal ๊ตฌํ
๊ธฐ๋ณธ ์ฐฝ ์์ ์์ ์ฐฝ์ ๋์ฐ๋๊ฑธ ๋ณดํต ๋ชจ๋ฌ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
Stack์ ํํ ์์ฉ๋ก ์ค ํ๋๊ฐ ์ด๋ ๊ฒ ์ค์ฒฉ๋ ์์ ฏ์ ํ์ํ๋ ๊ฒ์ด๋ค๋ณด๋, ๋ชจ๋ฌ ๊ฐ์๊ฑธ ๊ตฌํํ ๋๋ Stack์ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
๋จผ์ ๋ชจ๋ฌ์ ํ์ฌ ํ์ํ๋ ์ํ์ธ์ง์ ๋ํ ์ํ๊ฐ์ด ํ์ํ๋ค.

๊ทธ๋ฆฌ๊ณ ๋น์ฐํ ๋ชจ๋ฌ์ ์ผ๊ณ ๋๋ ์ด๋ฒคํธ์ ๋ํด์๋ ํธ๋ค๋ง์ด ๋์ด์ผํ๋ค.
stack ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋จํ ๋ณด์ผ๋ฌํ๋ ์ดํธ๋ฅผ ๋ง๋ค์๋ค.
์ด๋ฌ๋ฉด ๊ธฐ์กด ์์ ฏ์ ์ ๋ถ ๋ฐ๋ฅ์ ๊น๊ณ , ๋ชจ๋ฌ์ ์์ ๊น๋ ํํ๋ก ๊ตฌ์ฑ์ด ๋๋ค.
view์์๋ ์ด๋ฐ ์์ผ๋ก ํด์, show_modal์ด ์ผ์ ธ์์ผ๋ฉด ๋ฐฉ๊ธ ์ ์ํ ๋ณด์ผ๋ฌํ๋ ์ดํธ ๊ธฐ๋ฐ์ผ๋ก ๋ชจ๋ฌ ๋ทฐ๋ฅผ ์ค์ฒฉํด์ ๋์ฐ๊ณ , ์๋๋ฉด ๊ทธ๋ฅ ๋ชจ๋ฌ ์๋์ฑ๋ก ํ์ํ๋๋ก ํ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฒํผ์ผ๋ก ๋ชจ๋ฌ์ ์ผ๊ณ , ๋ชจ๋ฌ ๋ฐ์ ๋๋ฅด๋ฉด ๋ชจ๋ฌ์ด ๊บผ์ง๋๋ก ํ๋ค.
๊ทธ๋ ๊ฒ ์คํํด๋ณด๋ฉด

์๋ํ๋๋ก ๋์ํ ๊ฒ์ด๋ค.
์๋๋ ์ ์ฒด ์์ ์ฝ๋๋ค.
use iced::widget::{button, center, container, mouse_area, opaque, stack, text};
use iced::{Color, Element, Length, Settings, Size};
pub fn create_modal<'a, Message>(
base: impl Into<Element<'a, Message>>,
content: impl Into<Element<'a, Message>>,
on_blur: Message,
) -> Element<'a, Message>
where
Message: Clone + 'a,
{
stack![
base.into(),
opaque(
mouse_area(center(opaque(content)).style(|_theme| {
container::Style {
background: Some(
Color {
a: 0.8,
..Color::BLACK
}
.into(),
),
..container::Style::default()
}
}))
.on_press(on_blur)
)
]
.into()
}
pub struct MainApp {
show_modal: bool,
}
#[derive(Debug, Clone)]
pub enum Message {
OpenModal,
CloseModal,
}
impl MainApp {
pub fn new() -> Self {
let app = Self { show_modal: false };
app
}
pub fn theme(&self) -> iced::Theme {
iced::Theme::Dracula
}
pub fn update(&mut self, message: Message) {
match message {
Message::OpenModal => {
self.show_modal = !self.show_modal;
}
Message::CloseModal => {
self.show_modal = false;
}
}
}
pub fn view(&self) -> Element<Message> {
let content = container(button(text("Foo").size(12)).on_press(Message::OpenModal))
.width(Length::Fill)
.height(Length::Fill)
.into();
if self.show_modal {
let modal_view = container(text("Bar").size(24))
.width(250)
.padding(10)
.style(container::rounded_box);
create_modal(content, modal_view, Message::CloseModal)
} else {
content
}
}
}
impl Default for MainApp {
fn default() -> Self {
Self::new()
}
}
fn main() -> iced::Result {
let setting = Settings::default();
iced::application("test", MainApp::update, MainApp::view)
.settings(setting)
.resizable(false)
.window_size(Size::new(200.0, 200.0))
.theme(MainApp::theme)
.run()
}