159 lines
4.3 KiB
Rust
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()
|
|
}
|