-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add filmstrip option in thumbnail mode #336
base: master
Are you sure you want to change the base?
Conversation
This is golden! It adds exactly what I was missing from vimiv; a synchronized list, displaying all images opened from multiple directories, in thumbnail view next to image view. Thank you very much for this work! You are right, code speaks louder than words. In #299 I though I meant to integrate this view directly into the library, which would have not solved the initial problem of #299. This implementation is somewhat similarly to what I meant. But I did not expect it to be that "easily" integrable. I have only three things minor things to add:
|
I have noted a inconsistency in the synchronisation between thumbnail and image mode. I.e. in image mode we see image A while thumbnail listing mode shows image B as active. Reproduce
Expected Behaviour
Actual Behaviour
NoteSynchronisation is respored after switching to the next image |
Thanks a lot for your detailed comments! Glad you like the general idea.
EDIT: I think I misunderstood, the expected synchronization would be to select the correct image in the listview, not in image mode, right? |
I am very sorry for the long delay with answering and that I have not worked on #325.
|
Absolutely no worries, I am also currently rather busy and will probably not find the time to work on this in the next few weeks unfortunately.
|
|
When in icon mode, the regular thumbnail view is shown, i.e. it is shown instead of the image with a grid of thumbnails. When in list mode, a single column of thumbnails is displayed at the right of the current image. The background is rendered semi-transparent.
It is now possible to also show the basename of the thumbnail element in thumbnail mode as well as hiding the pixmap. For each of the two we have four options: - always show (default for pixmap) - always hide - show only in icon mode - show only in list mode (default for text)
Instead of using an alpha factor we reduce lightness and saturation. This keeps the effect of unfocusing seperate from alpha which is required for the listview.
The width is now the maximum of the icon size or the current text width. The height is now the sum of the visible content, i.e. icon and text. In addition, the icon is no longer perfectly centered in case text is visible in the bottom, precisely to account for the text.
The new bindings `gf` and `gF` enter filmstrip mode (and open the current image in image mode). In addition the `gt` binding now forces entering thumbnail mode in "icon" mode.
Equivalent to the library, they scroll in addition to opening the current thumbnail in image mode. This is especially useful in "filmstrip" mode.
The constructor for a thumbnail item slightly changed.
This essentially reverts cd2f570 but we keep a new style option `thumbnail.font` for the thumnbail font to allow customizing the size.
`zi`/`zI` show/hide the icon. `zn`/`zN` show/hide the name.
This better reflects the gf related bindings and keeps the naming consistent.
This allows running chains which depend on a new mode, like the new `gF` binding.
Instead of setting "when the elements are visible" we now set "what is visible in each mode". This now leaves us with the two settings `thumbnail.display_icon` and `thumbnail.display_filmstrip`. Each of them has the valid options `icon`, `name` and `both`. This has a few advantages compared to the previous implementation: - It is not possible to show nothing. - It is easy to toggle through the valid options. In addition, the logic checking if a specific element is visible in the current mode has been put into properties to simplify this in each part of the code.
When running :set thumbnail.filmstrip! or :set thumbnail.filmstrip false it seems logical to hide the filmstrip when not in thumbnail mode. Entering thumbnail mode seems a bit of a stretch as we never auto-enter modes.
7961f62
to
52a8095
Compare
All right, this took a while but finally there is some more progress 😊
In addition to all this, the settings have changed in the behaviour, i.e. we now set "what is visible in mode x" and not "when is x visible". This has a few advantages as described in 86219bd. Mainly, it is now possible to jump through the different display options. This is currently bound to With all the changes, I hope I didn't break anything. Any additional feedback is more than welcome as always 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for you late-evening shift, I like a lot what you have done 👍
I have gone through you changed. While I did not understand every single line (esp. QT related things), I have still added a few comments. Two of them indicate bugs which happen only when you use rather long file names. I hope I have described everything well enough, I you do not understand something, let me know.
Additionally, I think we have a little mess with the naming of all these modes/view. I.e. we have thumbnail mode, icon mode, list mode, filmstrip view, (grid mode) as well as combinations with other modes (image mode + filmstrip view).
I presume that this can be rather confusing for users (at least it is for me). While from the code base, icon mode and filmstrip mode are similar (both depend on the thumbnail mode) they are in practice different things. I do rather see the filmstrip mode as an additional view of image mode instead of a view of thumbnail mode.
I think a layer of abstraction would here be appropriate; Image mode has like three views:
- Normal (like image mode before this PR)
- Filmstrip open (filmstrip open but image mode activated)
- Filmstrip active (filmstrip open and active)
Image mode is entered using gi. From there, one can toggle between Normal and Filmstrip open view using tab. From any mode (/view) Filmstrip active can be accessed using gf. When using gi from any mode, we get to Image Normal or Image Filmstrip open depending on the toggle of filmstrip (i.e. depending on thumbnail.filmstrip
).
Thumbnail mode would be equivalent to how it was before this PR (with the exception of the option to display the image name).
As said, while this change may not make sense from the POV of the code base, I belief it improves the user experience. Let me know what you think.
ViewOption, | ||
"thumbnail.display_filmstrip", | ||
ViewOption.Both, | ||
desc=f"Which element(s) to display in icon view, one of {_view_options}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: Which element(s) to display in filmstrip view
|
||
_view_options = quotedjoin(option.value for option in ViewOption) | ||
|
||
display_icon = EnumSetting( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setting display_icon is a bit ambiguously named, how about display_grid?
@@ -56,12 +56,10 @@ def __init__(self, *colors: str, font: str = DEFAULT_FONT): | |||
self.check_valid_color(color) | |||
self[f"base{i:02x}"] = color | |||
# Fill in all default values | |||
self["font"] = font | |||
self["font"] = self["thumbnail.font"] = font |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing thumbnail.font
via styles works, but why do you set self["thumbnail.font"] = font
but why do you not do it for e.g. statusbar.font
or library.font
?
@@ -39,7 +39,6 @@ | |||
"statusbar.message_border": "2px solid", | |||
"statusbar.padding": "4", | |||
# Thumbnail | |||
"thumbnail.font": "{font}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand the full styles stack, but I have the feeling that this line should not be removed 🤔
if api.modes.current() != api.modes.THUMBNAIL: | ||
self.hide() | ||
self._update_geometry() | ||
self.rescale_items() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to call self._update_geometry()
after calling self.rescale_items()
. Else the width of the cell gets not updated adequately.
This happens e.g. when in icon view you display the icon + name and the name is much wider than the image and in filmstrip mode you only display the icon.
width = self.iconSize().width() | ||
if self.name_visible(): | ||
height += self.text_size.height() | ||
width = max(width, self.text_size.width()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would prefers if in filmstrip view the width is bounded to the width of the image and not the max of image with and text width.
This has the advantage zooming in/out has direct effect on the width of the filmstrip. Also, we do not get any unnecessary overlay of the filmstrip over the image view when there are only some images with long names.
Obviously, this causes the name to get clipped, which is not so nice. But I would still prefer to have it this way.
I.e. something like
if self.name_visible():
height += self.text_size.height()
width = max(width, self.text_size.width()) if (self.viewMode() == self.IconMode or width == 0) else width
api.signals.all_images_cleared.connect(self.clear) | ||
api.signals.new_image_opened.connect(self._select_path) | ||
api.signals.new_images_opened.connect(self._on_new_images_opened) | ||
api.settings.thumbnail.size.changed.connect(self._on_size_changed) | ||
api.settings.thumbnail.filmstrip.changed.connect(self._on_view_changed) | ||
api.settings.thumbnail.display_icon.changed.connect(self.rescale_items) | ||
api.settings.thumbnail.display_filmstrip.changed.connect(self.rescale_items) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only calling self.rescale_items()
upon change of thumbnail.display_icon
and thumbnail.display_filmstrip
respectively, is not enough. Calling self._update_geometry()
is also required. Else, the width of the cells are not updated correctly. This happens e.g. when in icon view you display the icon + name and the name is much wider than the image and in filmstrip mode you only display the icon.
As code speaks louder than works, here is a draft PR for what I meant with using thumbnail mode for the described listview in #299.
Thumbnail mode can now also be shown at the right of the current image as a simple list similar to the filmstrip used by other programs. In addition, the display of thumbnail mode can now be any combination of icon and text, with the default being icon-only in icon view, and icon + text in list view. The view mode is switched by the
thumbnail.listview
boolean setting. Toggling is currently bound to the<tab>
key. Showing the icon is changed using thethumbnail.display_pixmap
setting (should probably be renamed todisplay_icon
). Showing the text is changed using thethumbnail.display_text
setting. Each of these two setting can have one of the following options:What do you think of the general concept @jcjgraf ?
In case we go for this, I see some more todos: