OpenWeatherWidget/widget/src/show_popup.rs

159 lines
4.3 KiB
Rust

use iced::{
Alignment, Font, Length, Point, Settings, Size, Task,
alignment::{Horizontal, Vertical},
font::Family,
widget::{Column, Row, Space, Text, column, row},
window,
};
#[derive(Debug, Clone)]
enum Message {}
struct WeatherPopup {
city: String,
country: String,
weather_main: String,
weather_description: String,
icon_code: String,
temperature: String,
unit: char,
}
impl WeatherPopup {
fn new(
city: String,
country: String,
weather_main: String,
weather_description: String,
icon_code: String,
temperature: String,
unit: char,
) -> Self {
Self {
city,
country,
weather_main,
weather_description,
icon_code,
temperature,
unit,
}
}
fn update(&mut self, _message: Message) -> Task<Message> {
Task::none()
}
fn view(&self) -> iced::Element<Message> {
let default_font = "IosevkaTermSlab Nerd Font Mono";
column![
// City and country
Row::with_children(vec![
Text::new(format!("{}, {}", self.city, self.country))
.font(Font {
family: Family::Name(default_font),
..Font::DEFAULT
})
.size(16)
.into(),
])
.width(Length::Fill),
// Weather icon and temperature
Row::with_children(vec![
Text::new(icon_to_nerd_font(&self.icon_code))
.font(Font {
family: Family::Name(default_font),
..Font::DEFAULT
})
.align_x(Horizontal::Left)
.size(40)
.into(),
Space::with_width(Length::Fill).into(),
Text::new(format!("{}°{}", self.temperature, self.unit))
.font(Font {
family: Family::Name(default_font),
..Font::DEFAULT
})
.size(32)
.into(),
])
.width(Length::Fill),
// Weather description
Row::with_children(vec![
Text::new(format!(
"{} - {}",
self.weather_main, self.weather_description
))
.font(Font {
family: Family::Name(default_font),
..Font::DEFAULT
})
.size(16)
.into(),
])
.width(Length::Fill),
]
.spacing(10)
.padding(20)
.align_x(Horizontal::Center)
.into()
}
}
pub fn show_popup(
city: String,
country: String,
weather_main: String,
weather_description: String,
icon_code: String,
temperature: String,
unit: char,
) -> iced::Result {
iced::application(
"Weather Popup", // Title
WeatherPopup::update,
WeatherPopup::view,
)
.window(window::Settings {
size: Size {
width: 300.,
height: 150.,
},
position: window::Position::Specific(Point { x: 20., y: 20. }),
decorations: false,
..window::Settings::default()
})
.run_with(move || {
(
WeatherPopup::new(
city,
country,
weather_main,
weather_description,
icon_code,
temperature,
unit,
),
Task::none(),
)
})
}
/// Convert OWM icon codes (e.g. "01d", "09n") to Nerd Font weather glyphs.
fn icon_to_nerd_font(code: &str) -> String {
match code {
"01d" => "", // clear day
"01n" => "", // clear night
"02d" | "02n" => "", // few clouds
"03d" | "03n" => "", // scattered clouds
"04d" | "04n" => "", // broken clouds
"09d" | "09n" => "", // shower rain
"10d" | "10n" => "", // rain
"11d" | "11n" => "", // thunderstorm
"13d" | "13n" => "", // snow
"50d" | "50n" => "", // mist
_ => "",
}
.into()
}