Cleanup UI-loading code
- Functions to separate concerns - Comments
This commit is contained in:
parent
db7ca71905
commit
92db45bb28
@ -12,6 +12,7 @@ use i_slint_backend_winit::{
|
|||||||
|
|
||||||
slint::include_modules!();
|
slint::include_modules!();
|
||||||
|
|
||||||
|
/// Derive temperature unit symbol for the configured units
|
||||||
fn unit_symbol(units: &str) -> char {
|
fn unit_symbol(units: &str) -> char {
|
||||||
match units {
|
match units {
|
||||||
"metric" => 'C',
|
"metric" => 'C',
|
||||||
@ -21,58 +22,6 @@ fn unit_symbol(units: &str) -> char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_popup(resp: &WeatherResponse, cfg: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Closure that adjusts winit WindowAttributes before Slint creates the window.
|
|
||||||
let window_attrs = |attrs: WindowAttributes| {
|
|
||||||
// Mark the X11 window as a DOCK so the WM treats it as a top bar/panel.
|
|
||||||
attrs.with_x11_window_type(vec![WindowType::Dock])
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build a Slint backend that applies this attribute hook to all windows.
|
|
||||||
let backend = Backend::builder()
|
|
||||||
.with_window_attributes_hook(window_attrs) // Register the hook
|
|
||||||
.build()?; // Construct backend
|
|
||||||
|
|
||||||
// Activate this customized backend for all Slint window creation and events.
|
|
||||||
slint::platform::set_platform(Box::new(backend))?;
|
|
||||||
|
|
||||||
let ui = MainWindow::new()?;
|
|
||||||
|
|
||||||
let city = resp.name.clone().unwrap_or_else(|| "Unknown".into());
|
|
||||||
let country = resp
|
|
||||||
.sys
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|s| s.country.clone())
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let (weather_main, weather_description, icon_code) = resp.weather.first().map_or_else(
|
|
||||||
|| ("N/A".into(), "N/A".into(), String::new()),
|
|
||||||
|w| (w.main.clone(), w.description.clone(), w.icon.clone()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let temp = resp.main.as_ref().and_then(|m| m.temp).unwrap_or(0.0);
|
|
||||||
let temperature = format!("{temp:.1}");
|
|
||||||
|
|
||||||
let unit_symbol = unit_symbol(cfg.query_params.units.as_str());
|
|
||||||
|
|
||||||
ui.set_city(SharedString::from(city));
|
|
||||||
ui.set_country(SharedString::from(country));
|
|
||||||
ui.set_weather_main(SharedString::from(weather_main));
|
|
||||||
ui.set_weather_description(SharedString::from(weather_description));
|
|
||||||
ui.set_weather_icon(SharedString::from(icon_to_nerd_font(&icon_code)));
|
|
||||||
ui.set_temperature(SharedString::from(temperature));
|
|
||||||
ui.set_unit(SharedString::from(unit_symbol));
|
|
||||||
|
|
||||||
#[allow(clippy::cast_precision_loss)]
|
|
||||||
ui.window().set_size(LogicalSize::new(300.0, 124.0));
|
|
||||||
|
|
||||||
// Position the window (bar) at the top-left.
|
|
||||||
ui.window().set_position(LogicalPosition::new(0.0, 0.0));
|
|
||||||
|
|
||||||
ui.run()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert OWM icon codes (e.g. "01d", "09n") to Nerd Font weather glyphs.
|
/// Convert OWM icon codes (e.g. "01d", "09n") to Nerd Font weather glyphs.
|
||||||
fn icon_to_nerd_font(code: &str) -> String {
|
fn icon_to_nerd_font(code: &str) -> String {
|
||||||
match code {
|
match code {
|
||||||
@ -90,3 +39,68 @@ fn icon_to_nerd_font(code: &str) -> String {
|
|||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set Slint properties from weather data
|
||||||
|
fn set_ui_props(ui: &MainWindow, resp: &WeatherResponse, cfg: &Config) {
|
||||||
|
// Extract data
|
||||||
|
let city = resp.name.clone().unwrap_or_else(|| "Unknown".into());
|
||||||
|
let country = resp
|
||||||
|
.sys
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|s| s.country.clone())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let (weather_main, weather_description, icon_code) = resp.weather.first().map_or_else(
|
||||||
|
|| ("N/A".into(), "N/A".into(), String::new()),
|
||||||
|
|w| (w.main.clone(), w.description.clone(), w.icon.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let temp = resp.main.as_ref().and_then(|m| m.temp).unwrap_or(0.0);
|
||||||
|
let temperature = format!("{temp:.1}");
|
||||||
|
|
||||||
|
let unit = unit_symbol(cfg.query_params.units.as_str());
|
||||||
|
|
||||||
|
// Set UI elements
|
||||||
|
ui.set_city(SharedString::from(city));
|
||||||
|
ui.set_country(SharedString::from(country));
|
||||||
|
ui.set_weather_main(SharedString::from(weather_main));
|
||||||
|
ui.set_weather_description(SharedString::from(weather_description));
|
||||||
|
ui.set_weather_icon(SharedString::from(icon_to_nerd_font(&icon_code)));
|
||||||
|
ui.set_temperature(SharedString::from(temperature));
|
||||||
|
ui.set_unit(SharedString::from(unit));
|
||||||
|
|
||||||
|
// Window size (width, height): pixels
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
ui.window().set_size(LogicalSize::new(300.0, 124.0));
|
||||||
|
|
||||||
|
// Window position (x,y): pixels
|
||||||
|
ui.window().set_position(LogicalPosition::new(1610.0, 32.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create and show the Window UI
|
||||||
|
pub fn show_popup(resp: &WeatherResponse, cfg: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// Closure that adjusts winit WindowAttributes before Slint creates the window.
|
||||||
|
let window_attrs = |attrs: WindowAttributes| {
|
||||||
|
// Mark the X11 window as a DOCK so the WM doesn't treat it as a normal window
|
||||||
|
attrs.with_x11_window_type(vec![WindowType::Dock])
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build a Slint backend that applies this attribute hook to all windows.
|
||||||
|
let backend = Backend::builder()
|
||||||
|
.with_window_attributes_hook(window_attrs) // Register the hook
|
||||||
|
.build()?; // Construct backend
|
||||||
|
|
||||||
|
// Activate this customized backend for all Slint window creation and events.
|
||||||
|
slint::platform::set_platform(Box::new(backend))?;
|
||||||
|
|
||||||
|
// Create window
|
||||||
|
let ui = MainWindow::new()?;
|
||||||
|
|
||||||
|
// Send the weather data to the UI as properties
|
||||||
|
set_ui_props(&ui, resp, cfg);
|
||||||
|
|
||||||
|
// Run the UI
|
||||||
|
ui.run()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user