cargo: Update dependencies
This commit is contained in:
parent
8a46ef32c6
commit
004ebd5615
14 changed files with 521 additions and 366 deletions
676
Cargo.lock
generated
676
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
12
Cargo.toml
12
Cargo.toml
|
|
@ -22,25 +22,23 @@ libgweather = "4.0.0"
|
||||||
indexmap = "1.9.2"
|
indexmap = "1.9.2"
|
||||||
|
|
||||||
[dependencies.ashpd]
|
[dependencies.ashpd]
|
||||||
version = "0.4.0-alpha.1"
|
version = "0.4.0-alpha.3"
|
||||||
features = ["gtk4"]
|
features = ["gtk4"]
|
||||||
|
|
||||||
[dependencies.gtk]
|
[dependencies.gtk]
|
||||||
package = "gtk4"
|
package = "gtk4"
|
||||||
version = "0.5.5"
|
version = "0.6.0"
|
||||||
features = ["v4_10", "xml_validation"]
|
features = ["v4_10", "xml_validation"]
|
||||||
|
|
||||||
[dependencies.gio]
|
[dependencies.gio]
|
||||||
package = "gio"
|
package = "gio"
|
||||||
version = "0.16.3"
|
version = "0.17.0"
|
||||||
features = ["v2_74"]
|
features = ["v2_74"]
|
||||||
|
|
||||||
[dependencies.adw]
|
[dependencies.adw]
|
||||||
package = "libadwaita"
|
package = "libadwaita"
|
||||||
version = "0.2.0"
|
version = "0.3.1"
|
||||||
features = ["v1_2"]
|
features = ["v1_3"]
|
||||||
git = "https://gitlab.gnome.org/sophie-h/libadwaita-rs.git"
|
|
||||||
branch = "wip/sophie-h/swipeable"
|
|
||||||
|
|
||||||
[dependencies.gettext-rs]
|
[dependencies.gettext-rs]
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ mod imp {
|
||||||
// Overrides GObject vfuncs
|
// Overrides GObject vfuncs
|
||||||
impl ObjectImpl for LpApplication {
|
impl ObjectImpl for LpApplication {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
|
|
@ -66,14 +66,14 @@ mod imp {
|
||||||
// Overrides GApplication vfuncs
|
// Overrides GApplication vfuncs
|
||||||
impl ApplicationImpl for LpApplication {
|
impl ApplicationImpl for LpApplication {
|
||||||
fn activate(&self) {
|
fn activate(&self) {
|
||||||
let application = self.instance();
|
let application = self.obj();
|
||||||
let window = LpWindow::new(&*application);
|
let window = LpWindow::new(&*application);
|
||||||
window.present();
|
window.present();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles opening files from the command line or other applications
|
// Handles opening files from the command line or other applications
|
||||||
fn open(&self, files: &[gio::File], _hint: &str) {
|
fn open(&self, files: &[gio::File], _hint: &str) {
|
||||||
let application = self.instance();
|
let application = self.obj();
|
||||||
for file in files {
|
for file in files {
|
||||||
let Some(path) = file.path() else { log::error!("File has no path {}", file.uri()); return; };
|
let Some(path) = file.path() else { log::error!("File has no path {}", file.uri()); return; };
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ impl LpApplication {
|
||||||
.build(),
|
.build(),
|
||||||
];
|
];
|
||||||
|
|
||||||
self.add_action_entries(actions).unwrap();
|
self.add_action_entries(actions);
|
||||||
|
|
||||||
self.set_accels_for_action("app.help", &["F1"]);
|
self.set_accels_for_action("app.help", &["F1"]);
|
||||||
self.set_accels_for_action("app.quit", &["<Ctrl>Q"]);
|
self.set_accels_for_action("app.quit", &["<Ctrl>Q"]);
|
||||||
|
|
@ -220,10 +220,10 @@ impl LpApplication {
|
||||||
// an object and set all relevant properties very
|
// an object and set all relevant properties very
|
||||||
// easily in a way that's idiomatic to Rust.
|
// easily in a way that's idiomatic to Rust.
|
||||||
let about = adw::AboutWindow::builder()
|
let about = adw::AboutWindow::builder()
|
||||||
.application_name(&i18n("Loupe"))
|
.application_name(i18n("Loupe"))
|
||||||
.application_icon(config::APP_ID)
|
.application_icon(config::APP_ID)
|
||||||
.version(config::VERSION)
|
.version(config::VERSION)
|
||||||
.developer_name(&i18n("Christopher Davis"))
|
.developer_name(i18n("Christopher Davis"))
|
||||||
.website("https://gitlab.gnome.org/Incubator/loupe")
|
.website("https://gitlab.gnome.org/Incubator/loupe")
|
||||||
.issue_url("https://gitlab.gnome.org/Incubator/loupe/-/issues/new")
|
.issue_url("https://gitlab.gnome.org/Incubator/loupe/-/issues/new")
|
||||||
.developers(vec![
|
.developers(vec![
|
||||||
|
|
@ -235,7 +235,7 @@ impl LpApplication {
|
||||||
String::from("Jakub Steiner"),
|
String::from("Jakub Steiner"),
|
||||||
String::from("Tobias Bernard"),
|
String::from("Tobias Bernard"),
|
||||||
])
|
])
|
||||||
.copyright(&i18n("Copyright © 2020–2022 Christopher Davis et al."))
|
.copyright(i18n("Copyright © 2020–2022 Christopher Davis et al."))
|
||||||
.license_type(gtk::License::Gpl30)
|
.license_type(gtk::License::Gpl30)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl Default for LpFileModel {
|
impl Default for LpFileModel {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
glib::Object::new(&[])
|
glib::Object::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,8 +105,8 @@ impl LpFileModel {
|
||||||
.enumerate_children(
|
.enumerate_children(
|
||||||
&format!(
|
&format!(
|
||||||
"{},{}",
|
"{},{}",
|
||||||
*gio::FILE_ATTRIBUTE_STANDARD_NAME,
|
gio::FILE_ATTRIBUTE_STANDARD_NAME,
|
||||||
*gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
|
gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
|
||||||
),
|
),
|
||||||
gio::FileQueryInfoFlags::NONE,
|
gio::FileQueryInfoFlags::NONE,
|
||||||
gio::Cancellable::NONE,
|
gio::Cancellable::NONE,
|
||||||
|
|
@ -231,7 +231,7 @@ impl LpFileModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_image_file(file: &gio::File) -> bool {
|
fn is_image_file(file: &gio::File) -> bool {
|
||||||
let Ok(info) = util::query_attributes(file, vec![&gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE]) else {
|
let Ok(info) = util::query_attributes(file, vec![gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE]) else {
|
||||||
log::warn!("Could not query file info: {:?}", file.path());
|
log::warn!("Could not query file info: {:?}", file.path());
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl LpImageMetadata {
|
impl LpImageMetadata {
|
||||||
pub fn load(path: &Path) -> Self {
|
pub fn load(path: &Path) -> Self {
|
||||||
let obj = glib::Object::new::<Self>(&[]);
|
let obj = glib::Object::new::<Self>();
|
||||||
|
|
||||||
let metadata = ImageMetadata::load(path);
|
let metadata = ImageMetadata::load(path);
|
||||||
obj.imp().metadata.replace(metadata);
|
obj.imp().metadata.replace(metadata);
|
||||||
|
|
@ -34,7 +34,7 @@ impl LpImageMetadata {
|
||||||
|
|
||||||
impl From<ImageMetadata> for LpImageMetadata {
|
impl From<ImageMetadata> for LpImageMetadata {
|
||||||
fn from(metadata: ImageMetadata) -> Self {
|
fn from(metadata: ImageMetadata) -> Self {
|
||||||
let obj = glib::Object::new::<Self>(&[]);
|
let obj = glib::Object::new::<Self>();
|
||||||
|
|
||||||
obj.imp().metadata.replace(metadata);
|
obj.imp().metadata.replace(metadata);
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ impl From<ImageMetadata> for LpImageMetadata {
|
||||||
|
|
||||||
impl Default for LpImageMetadata {
|
impl Default for LpImageMetadata {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
glib::Object::new(&[])
|
glib::Object::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +90,6 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||||
//let obj = self.instance();
|
|
||||||
let metadata = self.metadata.borrow();
|
let metadata = self.metadata.borrow();
|
||||||
match pspec.name() {
|
match pspec.name() {
|
||||||
"has-information" => (!metadata.is_none()).to_value(),
|
"has-information" => (!metadata.is_none()).to_value(),
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@ mod deps {
|
||||||
}
|
}
|
||||||
|
|
||||||
use application::LpApplication;
|
use application::LpApplication;
|
||||||
|
use deps::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() -> glib::ExitCode {
|
||||||
pretty_env_logger::init_timed();
|
pretty_env_logger::init_timed();
|
||||||
|
|
||||||
setlocale(LocaleCategory::LcAll, "");
|
setlocale(LocaleCategory::LcAll, "");
|
||||||
|
|
@ -47,7 +48,5 @@ fn main() {
|
||||||
.expect("Could not load resources");
|
.expect("Could not load resources");
|
||||||
gio::resources_register(&res);
|
gio::resources_register(&res);
|
||||||
|
|
||||||
let app = LpApplication::new();
|
LpApplication::new().run()
|
||||||
let ret = app.run();
|
|
||||||
std::process::exit(ret);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot(&self, snapshot: &gdk::Snapshot, _width: f64, _height: f64) {
|
fn snapshot(&self, snapshot: &gdk::Snapshot, _width: f64, _height: f64) {
|
||||||
let paintable = self.instance();
|
let paintable = self.obj();
|
||||||
let width = paintable.intrinsic_width() as f64;
|
let width = paintable.intrinsic_width() as f64;
|
||||||
let height = paintable.intrinsic_height() as f64;
|
let height = paintable.intrinsic_height() as f64;
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl Thumbnail {
|
impl Thumbnail {
|
||||||
pub fn new(paintable: &impl glib::IsA<gdk::Paintable>) -> Self {
|
pub fn new(paintable: &impl glib::IsA<gdk::Paintable>) -> Self {
|
||||||
let object = glib::Object::new::<Self>(&[]);
|
let object = glib::Object::new::<Self>();
|
||||||
let imp = object.imp();
|
let imp = object.imp();
|
||||||
|
|
||||||
imp.image.set(paintable.clone().upcast()).unwrap();
|
imp.image.set(paintable.clone().upcast()).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use std::fmt::{Debug, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub fn get_file_display_name(file: &gio::File) -> Option<String> {
|
pub fn get_file_display_name(file: &gio::File) -> Option<String> {
|
||||||
let info = query_attributes(file, vec![&gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME]).ok()?;
|
let info = query_attributes(file, vec![gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME]).ok()?;
|
||||||
|
|
||||||
Some(info.display_name().to_string())
|
Some(info.display_name().to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -60,8 +60,8 @@ pub fn compare_by_name(file_a: &Path, file_b: &Path) -> std::cmp::Ordering {
|
||||||
|
|
||||||
static FILE_ATTRIBUTE_TRASH: Lazy<String> = Lazy::new(|| {
|
static FILE_ATTRIBUTE_TRASH: Lazy<String> = Lazy::new(|| {
|
||||||
[
|
[
|
||||||
*gio::FILE_ATTRIBUTE_STANDARD_NAME,
|
gio::FILE_ATTRIBUTE_STANDARD_NAME.as_str(),
|
||||||
*gio::FILE_ATTRIBUTE_TRASH_ORIG_PATH,
|
gio::FILE_ATTRIBUTE_TRASH_ORIG_PATH.as_str(),
|
||||||
]
|
]
|
||||||
.join(",")
|
.join(",")
|
||||||
});
|
});
|
||||||
|
|
@ -90,7 +90,7 @@ pub async fn untrash(path: &Path) -> anyhow::Result<()> {
|
||||||
let Some(file_info) = info.first()
|
let Some(file_info) = info.first()
|
||||||
else { break; };
|
else { break; };
|
||||||
|
|
||||||
let Some(original_path) = file_info.attribute_byte_string(&gio::FILE_ATTRIBUTE_TRASH_ORIG_PATH).as_ref().map(PathBuf::from)
|
let Some(original_path) = file_info.attribute_byte_string(gio::FILE_ATTRIBUTE_TRASH_ORIG_PATH).as_ref().map(PathBuf::from)
|
||||||
else { break; };
|
else { break; };
|
||||||
|
|
||||||
if original_path == path {
|
if original_path == path {
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
match pspec.name() {
|
match pspec.name() {
|
||||||
"file" => obj.file().to_value(),
|
"file" => obj.file().to_value(),
|
||||||
"path" => obj.path().to_variant().to_value(),
|
"path" => obj.path().to_variant().to_value(),
|
||||||
|
|
@ -194,7 +194,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
match pspec.name() {
|
match pspec.name() {
|
||||||
"rotation" => obj.set_rotation(value.get().unwrap()),
|
"rotation" => obj.set_rotation(value.get().unwrap()),
|
||||||
"mirrored" => obj.set_mirrored(value.get().unwrap()),
|
"mirrored" => obj.set_mirrored(value.get().unwrap()),
|
||||||
|
|
@ -210,7 +210,7 @@ mod imp {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
obj.set_hexpand(true);
|
obj.set_hexpand(true);
|
||||||
obj.set_vexpand(true);
|
obj.set_vexpand(true);
|
||||||
obj.set_overflow(gtk::Overflow::Hidden);
|
obj.set_overflow(gtk::Overflow::Hidden);
|
||||||
|
|
@ -224,7 +224,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispose(&self) {
|
fn dispose(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
// remove target fron zoom animation because it's property of this object
|
// remove target fron zoom animation because it's property of this object
|
||||||
obj.rotation_animation()
|
obj.rotation_animation()
|
||||||
|
|
@ -240,7 +240,7 @@ mod imp {
|
||||||
|
|
||||||
impl LpImage {
|
impl LpImage {
|
||||||
fn connect_controllers(&self) {
|
fn connect_controllers(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
// Needed vor having the current cursor position available
|
// Needed vor having the current cursor position available
|
||||||
let motion_controller = gtk::EventControllerMotion::new();
|
let motion_controller = gtk::EventControllerMotion::new();
|
||||||
|
|
@ -253,7 +253,7 @@ mod imp {
|
||||||
motion_controller.connect_leave(glib::clone!(@weak obj => move |_| {
|
motion_controller.connect_leave(glib::clone!(@weak obj => move |_| {
|
||||||
obj.imp().pointer_position.set(None);
|
obj.imp().pointer_position.set(None);
|
||||||
}));
|
}));
|
||||||
obj.add_controller(&motion_controller);
|
obj.add_controller(motion_controller);
|
||||||
|
|
||||||
// Zoom via scroll wheels etc
|
// Zoom via scroll wheels etc
|
||||||
let scroll_controller =
|
let scroll_controller =
|
||||||
|
|
@ -312,15 +312,15 @@ mod imp {
|
||||||
gtk::Inhibit(true)
|
gtk::Inhibit(true)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.add_controller(&scroll_controller);
|
obj.add_controller(scroll_controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect_gestures(&self) {
|
fn connect_gestures(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
// Double click for fullscreen (mouse/touchpad) or zoom (touch screen)
|
// Double click for fullscreen (mouse/touchpad) or zoom (touch screen)
|
||||||
let left_click_gesture = gtk::GestureClick::builder().button(1).build();
|
let left_click_gesture = gtk::GestureClick::builder().button(1).build();
|
||||||
obj.add_controller(&left_click_gesture);
|
obj.add_controller(left_click_gesture.clone());
|
||||||
left_click_gesture.connect_pressed(
|
left_click_gesture.connect_pressed(
|
||||||
glib::clone!(@weak obj => move |gesture, n_press, x, y| {
|
glib::clone!(@weak obj => move |gesture, n_press, x, y| {
|
||||||
// only handle double clicks
|
// only handle double clicks
|
||||||
|
|
@ -347,7 +347,7 @@ mod imp {
|
||||||
|
|
||||||
// Drag for moving image around
|
// Drag for moving image around
|
||||||
let drag_gesture = gtk::GestureDrag::new();
|
let drag_gesture = gtk::GestureDrag::new();
|
||||||
obj.add_controller(&drag_gesture);
|
obj.add_controller(drag_gesture.clone());
|
||||||
|
|
||||||
drag_gesture.connect_drag_begin(glib::clone!(@weak obj => move |gesture, _, _| {
|
drag_gesture.connect_drag_begin(glib::clone!(@weak obj => move |gesture, _, _| {
|
||||||
if obj.is_hscrollable() || obj.is_vscrollable() {
|
if obj.is_hscrollable() || obj.is_vscrollable() {
|
||||||
|
|
@ -378,7 +378,7 @@ mod imp {
|
||||||
|
|
||||||
// Rotate
|
// Rotate
|
||||||
let rotation_gesture = gtk::GestureRotate::new();
|
let rotation_gesture = gtk::GestureRotate::new();
|
||||||
obj.add_controller(&rotation_gesture);
|
obj.add_controller(rotation_gesture.clone());
|
||||||
|
|
||||||
rotation_gesture.connect_angle_changed(
|
rotation_gesture.connect_angle_changed(
|
||||||
glib::clone!(@weak obj => move |gesture, _, _| {
|
glib::clone!(@weak obj => move |gesture, _, _| {
|
||||||
|
|
@ -399,7 +399,7 @@ mod imp {
|
||||||
|
|
||||||
// Zoom
|
// Zoom
|
||||||
let zoom_gesture = gtk::GestureZoom::new();
|
let zoom_gesture = gtk::GestureZoom::new();
|
||||||
obj.add_controller(&zoom_gesture);
|
obj.add_controller(zoom_gesture.clone());
|
||||||
|
|
||||||
zoom_gesture.connect_begin(glib::clone!(@weak obj => move |gesture, _| {
|
zoom_gesture.connect_begin(glib::clone!(@weak obj => move |gesture, _| {
|
||||||
obj.imp()
|
obj.imp()
|
||||||
|
|
@ -448,7 +448,7 @@ mod imp {
|
||||||
impl WidgetImpl for LpImage {
|
impl WidgetImpl for LpImage {
|
||||||
// called when the widget size might have changed
|
// called when the widget size might have changed
|
||||||
fn size_allocate(&self, width: i32, height: i32, _baseline: i32) {
|
fn size_allocate(&self, width: i32, height: i32, _baseline: i32) {
|
||||||
let widget = self.instance();
|
let widget = self.obj();
|
||||||
|
|
||||||
// ensure there is an actual size change
|
// ensure there is an actual size change
|
||||||
if self.widget_dimensions.get() != (width, height) {
|
if self.widget_dimensions.get() != (width, height) {
|
||||||
|
|
@ -458,7 +458,7 @@ mod imp {
|
||||||
let best_fit_level = widget.zoom_level_best_fit();
|
let best_fit_level = widget.zoom_level_best_fit();
|
||||||
self.zoom.set(best_fit_level);
|
self.zoom.set(best_fit_level);
|
||||||
self.zoom_target.set(best_fit_level);
|
self.zoom_target.set(best_fit_level);
|
||||||
self.instance().zoom_animation().pause();
|
self.obj().zoom_animation().pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,7 +468,7 @@ mod imp {
|
||||||
// called when the widget content should be re-rendered
|
// called when the widget content should be re-rendered
|
||||||
fn snapshot(&self, snapshot: >k::Snapshot) {
|
fn snapshot(&self, snapshot: >k::Snapshot) {
|
||||||
if let Some(texture) = self.texture.borrow().as_ref() {
|
if let Some(texture) = self.texture.borrow().as_ref() {
|
||||||
let widget = self.instance();
|
let widget = self.obj();
|
||||||
let widget_width = widget.width() as f64;
|
let widget_width = widget.width() as f64;
|
||||||
let widget_height = widget.height() as f64;
|
let widget_height = widget.height() as f64;
|
||||||
|
|
||||||
|
|
@ -531,15 +531,16 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn measure(&self, orientation: gtk::Orientation, _for_size: i32) -> (i32, i32, i32, i32) {
|
fn measure(&self, orientation: gtk::Orientation, _for_size: i32) -> (i32, i32, i32, i32) {
|
||||||
let (image_width, image_height) = self.instance().image_size();
|
let (image_width, image_height) = self.obj().image_size();
|
||||||
|
|
||||||
if image_width > 0 && image_height > 0 {
|
if image_width > 0 && image_height > 0 {
|
||||||
if let Some(display) = gdk::Display::default() {
|
if let Some(display) = gdk::Display::default() {
|
||||||
if let Some(native) = self.instance().native() {
|
if let Some(native) = self.obj().native() {
|
||||||
let hidpi_scale = self.instance().scale_factor() as f64;
|
let hidpi_scale = self.obj().scale_factor() as f64;
|
||||||
|
|
||||||
// get monitor information
|
// get monitor information
|
||||||
let monitor = display.monitor_at_surface(&native.surface());
|
// TODO: Get rid of unwrap
|
||||||
|
let monitor = display.monitor_at_surface(&native.surface()).unwrap();
|
||||||
let monitor_geometry = monitor.geometry();
|
let monitor_geometry = monitor.geometry();
|
||||||
// TODO: Per documentation those dimensions should not be physical pixels.
|
// TODO: Per documentation those dimensions should not be physical pixels.
|
||||||
// But on Wayland they are physiscal pixels and on X11 not.
|
// But on Wayland they are physiscal pixels and on X11 not.
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
match pspec.name() {
|
match pspec.name() {
|
||||||
"image" => obj.image().to_value(),
|
"image" => obj.image().to_value(),
|
||||||
"error" => obj.error().to_value(),
|
"error" => obj.error().to_value(),
|
||||||
|
|
@ -96,7 +96,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
|
|
@ -127,7 +127,7 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl LpImagePage {
|
impl LpImagePage {
|
||||||
pub fn from_path(path: &Path) -> Self {
|
pub fn from_path(path: &Path) -> Self {
|
||||||
let obj = glib::Object::new::<Self>(&[]);
|
let obj = glib::Object::new::<Self>();
|
||||||
let path = path.to_path_buf();
|
let path = path.to_path_buf();
|
||||||
let file = gio::File::for_path(&path);
|
let file = gio::File::for_path(&path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn property(&self, _id: usize, psec: &glib::ParamSpec) -> glib::Value {
|
fn property(&self, _id: usize, psec: &glib::ParamSpec) -> glib::Value {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
match psec.name() {
|
match psec.name() {
|
||||||
"current-page" => obj.current_page().to_value(),
|
"current-page" => obj.current_page().to_value(),
|
||||||
"is-previous-available" => obj.is_previous_available().to_value(),
|
"is-previous-available" => obj.is_previous_available().to_value(),
|
||||||
|
|
@ -111,12 +111,12 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
// Manually mange widget layout, see `WidgetImpl` for details
|
// Manually mange widget layout, see `WidgetImpl` for details
|
||||||
obj.set_layout_manager(gtk::LayoutManager::NONE);
|
obj.set_layout_manager(None::<gtk::LayoutManager>);
|
||||||
|
|
||||||
obj.property_expression("current-page")
|
obj.property_expression("current-page")
|
||||||
.chain_property::<LpImagePage>("image")
|
.chain_property::<LpImagePage>("image")
|
||||||
|
|
@ -164,7 +164,7 @@ mod imp {
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.add_controller(&source);
|
obj.add_controller(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +188,7 @@ mod imp {
|
||||||
// take as minimum whatever is larger
|
// take as minimum whatever is larger
|
||||||
let min = i32::max(child_min, overlay1_min + overlay2_min);
|
let min = i32::max(child_min, overlay1_min + overlay2_min);
|
||||||
|
|
||||||
if let Some(page) = self.instance().current_page() {
|
if let Some(page) = self.obj().current_page() {
|
||||||
// measure `LpImage`
|
// measure `LpImage`
|
||||||
let (_, image_natural, _, _) = page.image().measure(orientation, for_size);
|
let (_, image_natural, _, _) = page.image().measure(orientation, for_size);
|
||||||
|
|
||||||
|
|
@ -575,7 +575,7 @@ impl LpImageView {
|
||||||
let pb = gdk_pixbuf::Pixbuf::from_file(path)?;
|
let pb = gdk_pixbuf::Pixbuf::from_file(path)?;
|
||||||
|
|
||||||
let setup = gtk::PageSetup::default();
|
let setup = gtk::PageSetup::default();
|
||||||
let page_size = gtk::PaperSize::new(Some(>k::PAPER_NAME_A4));
|
let page_size = gtk::PaperSize::new(Some(gtk::PAPER_NAME_A4));
|
||||||
setup.set_paper_size(&page_size);
|
setup.set_paper_size(&page_size);
|
||||||
operation.set_default_page_setup(Some(&setup));
|
operation.set_default_page_setup(Some(&setup));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
let prop_name = pspec.name();
|
let prop_name = pspec.name();
|
||||||
|
|
||||||
match prop_name {
|
match prop_name {
|
||||||
|
|
@ -126,7 +126,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
let prop_name = pspec.name();
|
let prop_name = pspec.name();
|
||||||
|
|
||||||
match prop_name {
|
match prop_name {
|
||||||
|
|
@ -136,7 +136,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
obj.action_set_enabled("properties.open-folder", false);
|
obj.action_set_enabled("properties.open-folder", false);
|
||||||
|
|
@ -254,10 +254,10 @@ impl LpPropertiesView {
|
||||||
if let Ok(info) = util::query_attributes_future(
|
if let Ok(info) = util::query_attributes_future(
|
||||||
&file,
|
&file,
|
||||||
vec![
|
vec![
|
||||||
&gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
||||||
&gio::FILE_ATTRIBUTE_STANDARD_SIZE,
|
gio::FILE_ATTRIBUTE_STANDARD_SIZE,
|
||||||
&gio::FILE_ATTRIBUTE_TIME_CREATED,
|
gio::FILE_ATTRIBUTE_TIME_CREATED,
|
||||||
&gio::FILE_ATTRIBUTE_TIME_MODIFIED,
|
gio::FILE_ATTRIBUTE_TIME_MODIFIED,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await {
|
.await {
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
match pspec.name() {
|
match pspec.name() {
|
||||||
"current-page" => obj.current_page().to_value(),
|
"current-page" => obj.current_page().to_value(),
|
||||||
name => unimplemented!("property {name}"),
|
name => unimplemented!("property {name}"),
|
||||||
|
|
@ -83,13 +83,13 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
self.instance().set_overflow(gtk::Overflow::Hidden);
|
self.obj().set_overflow(gtk::Overflow::Hidden);
|
||||||
|
|
||||||
let swipe_tracker = adw::SwipeTracker::builder()
|
let swipe_tracker = adw::SwipeTracker::builder()
|
||||||
.swipeable(&*self.instance())
|
.swipeable(&*self.obj())
|
||||||
.reversed(self.is_rtl())
|
.reversed(self.is_rtl())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
@ -135,7 +135,7 @@ mod imp {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
obj.add_controller(&scroll_controller);
|
obj.add_controller(scroll_controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,12 +155,12 @@ mod imp {
|
||||||
* (width as f32 + self.page_spacing(width));
|
* (width as f32 + self.page_spacing(width));
|
||||||
|
|
||||||
let transform = gsk::Transform::new().translate(&graphene::Point::new(x, 0.));
|
let transform = gsk::Transform::new().translate(&graphene::Point::new(x, 0.));
|
||||||
page.allocate(width, height, 0, Some(&transform));
|
page.allocate(width, height, 0, Some(transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn measure(&self, orientation: gtk::Orientation, for_size: i32) -> (i32, i32, i32, i32) {
|
fn measure(&self, orientation: gtk::Orientation, for_size: i32) -> (i32, i32, i32, i32) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
for page in self.pages.borrow().iter() {
|
for page in self.pages.borrow().iter() {
|
||||||
if Some(page) != obj.current_page().as_ref() {
|
if Some(page) != obj.current_page().as_ref() {
|
||||||
|
|
@ -185,18 +185,18 @@ mod imp {
|
||||||
|
|
||||||
impl SwipeableImpl for LpSlidingView {
|
impl SwipeableImpl for LpSlidingView {
|
||||||
fn progress(&self) -> f64 {
|
fn progress(&self) -> f64 {
|
||||||
self.instance().position()
|
self.obj().position()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn distance(&self) -> f64 {
|
fn distance(&self) -> f64 {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
let width = obj.allocation().width();
|
let width = obj.allocation().width();
|
||||||
|
|
||||||
width as f64 + self.page_spacing(width) as f64
|
width as f64 + self.page_spacing(width) as f64
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snap_points(&self) -> Vec<f64> {
|
fn snap_points(&self) -> Vec<f64> {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
(0..obj.n_pages())
|
(0..obj.n_pages())
|
||||||
.map(|i| i as f64 - obj.position_shift())
|
.map(|i| i as f64 - obj.position_shift())
|
||||||
|
|
@ -204,7 +204,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cancel_progress(&self) -> f64 {
|
fn cancel_progress(&self) -> f64 {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
let snap_points = self.snap_points();
|
let snap_points = self.snap_points();
|
||||||
|
|
||||||
if let (Some(min), Some(max)) = (snap_points.first(), snap_points.last()) {
|
if let (Some(min), Some(max)) = (snap_points.first(), snap_points.last()) {
|
||||||
|
|
@ -221,7 +221,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_rtl(&self) -> bool {
|
fn is_rtl(&self) -> bool {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
obj.direction() == gtk::TextDirection::Rtl
|
obj.direction() == gtk::TextDirection::Rtl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ mod imp {
|
||||||
|
|
||||||
impl ObjectImpl for LpWindow {
|
impl ObjectImpl for LpWindow {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.instance();
|
let obj = self.obj();
|
||||||
|
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
|
|
@ -337,8 +337,8 @@ mod imp {
|
||||||
let info = util::query_attributes(
|
let info = util::query_attributes(
|
||||||
&file,
|
&file,
|
||||||
vec![
|
vec![
|
||||||
&gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
gio::FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
||||||
&gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.expect("Could not query file info");
|
.expect("Could not query file info");
|
||||||
|
|
@ -427,7 +427,7 @@ impl LpWindow {
|
||||||
filter_store.append(&filter);
|
filter_store.append(&filter);
|
||||||
|
|
||||||
let chooser = gtk::FileDialog::builder()
|
let chooser = gtk::FileDialog::builder()
|
||||||
.title(&i18n("Open Image"))
|
.title(i18n("Open Image"))
|
||||||
.filters(&filter_store)
|
.filters(&filter_store)
|
||||||
.modal(true)
|
.modal(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -495,8 +495,8 @@ impl LpWindow {
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let toast = adw::Toast::builder()
|
let toast = adw::Toast::builder()
|
||||||
.title(&i18n("Image moved to trash"))
|
.title(i18n("Image moved to trash"))
|
||||||
.button_label(&i18n("Undo"))
|
.button_label(i18n("Undo"))
|
||||||
.build();
|
.build();
|
||||||
toast.connect_button_clicked(glib::clone!(@weak self as win => move |_| {
|
toast.connect_button_clicked(glib::clone!(@weak self as win => move |_| {
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
|
|
@ -514,7 +514,7 @@ impl LpWindow {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
self.imp().toast_overlay.add_toast(&toast);
|
self.imp().toast_overlay.add_toast(toast);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if Some(gio::IOErrorEnum::NotSupported) == err.kind::<gio::IOErrorEnum>() {
|
if Some(gio::IOErrorEnum::NotSupported) == err.kind::<gio::IOErrorEnum>() {
|
||||||
|
|
@ -537,8 +537,8 @@ impl LpWindow {
|
||||||
let dialog = adw::MessageDialog::builder()
|
let dialog = adw::MessageDialog::builder()
|
||||||
.modal(true)
|
.modal(true)
|
||||||
.transient_for(self)
|
.transient_for(self)
|
||||||
.heading(&i18n("Permanently Delete Image?"))
|
.heading(i18n("Permanently Delete Image?"))
|
||||||
.body(&i18n_f(
|
.body(i18n_f(
|
||||||
"The image “{}” can only be deleted permanently.",
|
"The image “{}” can only be deleted permanently.",
|
||||||
&[&PathBuf::from(&path.file_name().unwrap_or_default())
|
&[&PathBuf::from(&path.file_name().unwrap_or_default())
|
||||||
.display()
|
.display()
|
||||||
|
|
@ -549,7 +549,7 @@ impl LpWindow {
|
||||||
dialog.add_responses(&[("cancel", &i18n("Cancel")), ("delete", &i18n("Delete"))]);
|
dialog.add_responses(&[("cancel", &i18n("Cancel")), ("delete", &i18n("Delete"))]);
|
||||||
dialog.set_response_appearance("delete", adw::ResponseAppearance::Destructive);
|
dialog.set_response_appearance("delete", adw::ResponseAppearance::Destructive);
|
||||||
|
|
||||||
if "delete" == dialog.run_future().await {
|
if "delete" == dialog.choose_future().await {
|
||||||
let file = gio::File::for_path(path);
|
let file = gio::File::for_path(path);
|
||||||
let result = file.delete_future(glib::Priority::default()).await;
|
let result = file.delete_future(glib::Priority::default()).await;
|
||||||
|
|
||||||
|
|
@ -570,7 +570,7 @@ impl LpWindow {
|
||||||
let toast = adw::Toast::new(text.as_ref());
|
let toast = adw::Toast::new(text.as_ref());
|
||||||
toast.set_priority(priority);
|
toast.set_priority(priority);
|
||||||
|
|
||||||
imp.toast_overlay.add_toast(&toast);
|
imp.toast_overlay.add_toast(toast);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_image_from_path(&self, path: &Path) {
|
pub fn set_image_from_path(&self, path: &Path) {
|
||||||
|
|
@ -657,40 +657,6 @@ impl LpWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapted from https://gitlab.gnome.org/GNOME/eog/-/blob/master/src/eog-window.c:eog_window_obtain_desired_size
|
|
||||||
pub fn resize_from_dimensions(&self, img_width: i32, img_height: i32) {
|
|
||||||
let imp = self.imp();
|
|
||||||
let mut final_width = img_width;
|
|
||||||
let mut final_height = img_height;
|
|
||||||
|
|
||||||
let header_height = imp.headerbar.height();
|
|
||||||
|
|
||||||
// Ensure the window surface exists
|
|
||||||
if !self.is_realized() {
|
|
||||||
WidgetExt::realize(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
let display = gdk::Display::default().unwrap();
|
|
||||||
let monitor = display.monitor_at_surface(&self.native().unwrap().surface());
|
|
||||||
let monitor_geometry = monitor.geometry();
|
|
||||||
|
|
||||||
let monitor_width = monitor_geometry.width();
|
|
||||||
let monitor_height = monitor_geometry.height();
|
|
||||||
|
|
||||||
if img_width > monitor_width || img_height + header_height > monitor_height {
|
|
||||||
let width_factor = (monitor_width as f32 * 0.85) / img_width as f32;
|
|
||||||
let height_factor =
|
|
||||||
(monitor_height as f32 * 0.85 - header_height as f32) / img_height as f32;
|
|
||||||
let factor = width_factor.min(height_factor);
|
|
||||||
|
|
||||||
final_width = (final_width as f32 * factor).round() as i32;
|
|
||||||
final_height = (final_height as f32 * factor).round() as i32;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.set_default_size(final_width, final_height);
|
|
||||||
log::debug!("Window resized to {} x {}", final_width, final_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the LpWindow UI file we define a `gtk::Expression`s
|
// In the LpWindow UI file we define a `gtk::Expression`s
|
||||||
// that is a closure. This closure takes the current `gio::File`
|
// that is a closure. This closure takes the current `gio::File`
|
||||||
// and processes it to return a window title.
|
// and processes it to return a window title.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue