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!();
|
||||
|
||||
/// Derive temperature unit symbol for the configured units
|
||||
fn unit_symbol(units: &str) -> char {
|
||||
match units {
|
||||
"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.
|
||||
fn icon_to_nerd_font(code: &str) -> String {
|
||||
match code {
|
||||
@ -90,3 +39,68 @@ fn icon_to_nerd_font(code: &str) -> String {
|
||||
}
|
||||
.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