desktop: Use Arc+Mutex for PathOrUrlField.value

This allows modifying it asynchronously.
This commit is contained in:
Kamil Jarosz 2024-08-08 01:41:34 +02:00 committed by TÖRÖK Attila
parent d487d3f1aa
commit 8755dd95cc
1 changed files with 19 additions and 9 deletions

View File

@ -2,13 +2,13 @@ use crate::gui::text;
use crate::util::pick_file;
use egui::{TextEdit, Ui};
use std::path::Path;
use std::sync::Weak;
use std::sync::{Arc, Mutex, MutexGuard, Weak};
use unic_langid::LanguageIdentifier;
use url::Url;
pub struct PathOrUrlField {
window: Weak<winit::window::Window>,
value: String,
value: Arc<Mutex<String>>,
result: Option<Url>,
hint: &'static str,
}
@ -24,7 +24,7 @@ impl PathOrUrlField {
if let Ok(path) = default.to_file_path() {
return Self {
window,
value: path.to_string_lossy().to_string(),
value: Arc::new(Mutex::new(path.to_string_lossy().to_string())),
result: Some(default),
hint,
};
@ -33,7 +33,7 @@ impl PathOrUrlField {
return Self {
window,
value: default.to_string(),
value: Arc::new(Mutex::new(default.to_string())),
result: Some(default),
hint,
};
@ -41,12 +41,16 @@ impl PathOrUrlField {
Self {
window,
value: "".to_string(),
value: Arc::new(Mutex::new("".to_string())),
result: None,
hint,
}
}
fn lock_value(value: &Arc<Mutex<String>>) -> MutexGuard<'_, String> {
value.lock().expect("Non-poisoned value")
}
pub fn ui(&mut self, locale: &LanguageIdentifier, ui: &mut Ui) -> &mut Self {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
if ui.button(text(locale, "browse")).clicked() {
@ -61,12 +65,16 @@ impl PathOrUrlField {
});
if let Some(path) = pick_file(true, dir, self.window.upgrade()) {
self.value = path.to_string_lossy().to_string();
let mut value_lock = Self::lock_value(&self.value);
*value_lock = path.to_string_lossy().to_string();
}
}
let mut value_locked = Self::lock_value(&self.value);
let mut value = value_locked.clone();
ui.add_sized(
ui.available_size(),
TextEdit::singleline(&mut self.value)
TextEdit::singleline(&mut value)
.hint_text(self.hint)
.text_color_opt(if self.result.is_none() {
Some(ui.style().visuals.error_fg_color)
@ -74,13 +82,15 @@ impl PathOrUrlField {
None
}),
);
*value_locked = value;
});
let path = Path::new(&self.value);
let value = Self::lock_value(&self.value).clone();
let path = Path::new(&value);
self.result = if path.is_file() {
Url::from_file_path(path).ok()
} else {
Url::parse(&self.value).ok()
Url::parse(&value).ok()
};
self