Tried to make things more stateless and RefCell usage for robust
- Use object properties to control the action enabled/disabled
- Borrow model RefCell for only one line or use .replace()
- Don't pass models around and borrow as short as possible instead
Fixes#20
This stops the overlay controls to overlap for very small
window sizes and properties opened.
LpImageView already does custom measure and overlay is it's
direct child. So added it here.
Fixes#32
Give LpImage a native with that should feel nice.
When opening a new window with a new image the window size
is determined by LpImage's natural width.
The image size and EXIF data is loaded before the image such
that the window can be shown in the right dimension while
loading the actual image.
- Fixes image cannot be opened when directory unreadable
- Avoids bugs with wrong images being selected for an instant.
Mostly important for adjusting the window size to image.
- Basis for prioritizing loading the important image first
If only 1/4 of a zoom step zoomed in, assume best-fit.
This helps with floating point precision when zooming in and
out again. It also removes akward other minimal zoom steps.
This change centralizes part of the best-fit detection.
Makes dragging an image out of Loupe work in most cases.
There seems to be an issue with dragging from flatpak to host.
Removing the png from the provider seems to avoid gdk crashes
but not 100% sure that was the cause.
Add shortcuts
- F9 Image properties
- F10 Main menu
- Ctrl +/- for zoom
- Ctrl 0 for best fit
- Ctrl [Shift] R for rotate
- Escape to leave fullscrenen
Updated help overlay accordingly.
Zoom via
- Scroll event controller
- Zoom gesture
- Overlay buttons
- Fixed zoom level shortcuts (1=100%, 2=200%)
Scrolling via
- Scrolled window
- Drag gesture
Changes
- Implement best-fit via calculating a zoom level
- Gesture for carousel no longer working because of scrolled window
- Split control overlays into two to not steal inputs in area between
Closes#17
With https://gitlab.gnome.org/GNOME/libadwaita/-/merge_requests/652
merged
we no longer crash when loading files from the same directory.
Now that we don't crash, we've exposed a logic error: we were
changing the state of the carousel while scrolling through it,
which ends with the carousel in a weird state.
This commit delays clearing and refilling the carousel until
after the `page-changed` signal is emitted.
This is for easier debugging in case a panic happens -
instead of dealing with "thread <unnamed> paniced...", etc.,
we get a name relevant to our context.
`parse_svg_file_future()` is called in a cancellable async
block. This means that after it's called it can be cancelled,
which drops the receiver. When we fetch the metadata, we try
sending the result to the dropped receiver.
This is expected behavior in this case - the receiver
being gone at the time of sending the metadata is perfectly
valid. However, previously we would cause the thread to panic.
This didn't break anything but made for scary log message.
Since this is expected behavior we can use `_` to tell the
compiler that we don't care about the outcome of sending.
This is valid in this instance because we will only get an
error if the receiver is gone.
Implement a properties sidebar. In order to prevent
the UI from freezing, we use futures to load and cancel
loading file information. We also make use of
`gdk_pixbuf` and `svg_metadata` in order to get the file's
metadata before the file fully loads, meaning there's
little to no delay between changing files and seeing
the metadata for large images.
The properties widget uses expressions and
properties to avoid glue code for setting each label,
allowing us to have a clean separation between UI
and data.
The GFile is more useful for other data. The window can
use expressions to calculate an appropriate title, so
we no longer need to call `set_title()` or connect to
a signal manually.
This commit also adjusts the `uri()` and `print()`
functions to use `active_file()`
Allan Day's latest mockups have the fullscreen icon on the bottom
left of the image. This commit moves the icon there, using a
GtkExpression for the icon name.
Previously we used `prev_index` everywhere, which could
get confusing - it's not really the "previous" index
until we've moved. So, only `page_changed_cb ()` refers
to it as `prev_index`. Everywhere else it's called
`current_model_index`.
In accordance with this change, we can get rid
of a call to `current_page()` and `index_of()`
since we already know the index of the current page.
Due to the latest refactoring passes, it was possible
for the model to be borrowed twice when navigating
to a file. This commit makes model an argument
to update_action_state() so we don't need to acquire
another borrow. We have the model already in all cases
where we use update_action_state().
These functions required iterating to find the
index of a file and then adding one to it.
We can be smarter, using an index we already
have and adding or subtracting where appropriate.
Rework the model loading to not care about the edges.
Now we only care about where we are in the model and
the number of buffer pages. This algorithm handles
the edges without special casing.
Previously we loaded images synchronously and manually
changed `LpImage`. This could cause freezes when loading
large images and SVGs. We also had no proper feedback for
when a corrupted or unsupported image was loaded.
This commit introduces a major rework to how we handle
images and the gallery. It introduces a swipeable gallery
that loads files asynchronously via a new widget: LpImagePage.
LpImagePage owns the file and information related to the file,
and on creation it spawns a future that either loads an error
page when it can't load something (file deleted, corrupted, or
unsupported) or the actual image via LpImage. LpImagePage
now holds the right-click popover and the associated gestures.
The gestures needed to be moved to LpImagePage in order to
rework LpImageView's overlay - instead of having an overlay
child that's a box with a few buttons, we now have the buttons
as individual overlay children. This could cause them
to overlap each other at certain sizes, but it's required
in order to allow input to reach the carousel below.
Right now this comes with a few regressions:
* Occasionally input gets blocked across the applications. It's
hard to tell if this is caused by swipes or right clicking. This
input issue can cause a crash - no Rust backtrace, so a debugger
is needed.
* The "current" page doesn't seem to be properly loaded by the
time `set_image_from_file ()` finishes, so we need to rework
resizing from image dimensions
* We need to re-implement loading different directories and
files within directories
There also seems to be an issue on touchscreens, swiping between
images on a touchscreen causes responsiveness issues not present
when swiping on a touchpad. My guess is that it's related to
the long press gesture.