From 9d2f05b516edf2492c67a9a624582882a78c785a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 16 Apr 2020 13:25:56 +0530 Subject: [PATCH] Viewer: Allow double clicking or long tapping on images to view then in a new window. Fixes #1872759 [E-book viewer: double clicking on image to evoke "View image" window.](https://bugs.launchpad.net/calibre/+bug/1872759) --- manual/viewer.rst | 8 ++++++++ src/pyj/read_book/flow_mode.pyj | 9 --------- src/pyj/read_book/iframe.pyj | 27 ++++++++++++++++++++++++++- src/pyj/read_book/view.pyj | 4 ++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/manual/viewer.rst b/manual/viewer.rst index 8697e31421..84cae31bf4 100644 --- a/manual/viewer.rst +++ b/manual/viewer.rst @@ -137,6 +137,14 @@ right clicking and selecting :guilabel:`Copy` to copy to the clipboard. The cop material can be pasted into another application as plain text and images. +Zooming in on images +---------------------------- + +You can zoom in to show an image at full size in a separate window by either +double clicking or long tapping on it. You can also right click on it and +choose :guilabel:`View Image`. + + Non re-flowable content -------------------------- diff --git a/src/pyj/read_book/flow_mode.pyj b/src/pyj/read_book/flow_mode.pyj index 2320483cd2..c12e2b86e4 100644 --- a/src/pyj/read_book/flow_mode.pyj +++ b/src/pyj/read_book/flow_mode.pyj @@ -2,8 +2,6 @@ # License: GPL v3 Copyright: 2016, Kovid Goyal from __python__ import bound_methods, hash_literals -from select import word_at_point - from dom import set_css from read_book.globals import current_spine_item, get_boss from read_book.settings import opts @@ -429,13 +427,6 @@ def handle_gesture(gesture): scroll_by_page(-1) elif gesture.type is 'next-page': scroll_by_page(1) - elif gesture.type is 'long-tap': - r = word_at_point(gesture.viewport_x, gesture.viewport_y) - if r: - s = document.getSelection() - s.removeAllRanges() - s.addRange(r) - get_boss().send_message('lookup_word', word=str(r)) anchor_funcs = { diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index 6da7e615eb..227c0db712 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -6,7 +6,7 @@ import traceback from gettext import gettext as _ from select import ( extend_selection_after_scroll, selection_extents, selection_extents_at_point, - set_selections_extents_to + set_selections_extents_to, word_at_point ) from fs_images import fix_fullscreen_svg_images @@ -261,9 +261,23 @@ class IframeBoss: self.send_message('show_chrome') elif gesture.type is 'pinch': self.send_message('bump_font_size', increase=gesture.direction is 'out') + elif gesture.type is 'long-tap': + self.handle_long_tap(gesture) else: self._handle_gesture(gesture) + def handle_long_tap(self, gesture): + elements = get_elements(gesture.viewport_x, gesture.viewport_y) + if elements.img: + self.send_message('view_image', calibre_src=elements.img) + return + r = word_at_point(gesture.viewport_x, gesture.viewport_y) + if r: + s = document.getSelection() + s.removeAllRanges() + s.addRange(r) + self.send_message('lookup_word', word=str(r)) + def gesture_from_margin(self, data): self.handle_gesture(data.gesture) @@ -363,6 +377,8 @@ class IframeBoss: def content_loaded_stage2(self): reset_find_caches() self.connect_links() + if runtime.is_standalone_viewer: + self.listen_for_image_double_clicks() self.content_ready = True # this is the loading styles used to suppress scrollbars during load # added in unserialize_html @@ -543,6 +559,15 @@ class IframeBoss: for a in document.body.querySelectorAll('a[target]'): a.removeAttribute('target') + def listen_for_image_double_clicks(self): + for img in document.querySelectorAll('img, image'): + img.addEventListener('dblclick', self.image_double_clicked, {'passive': True}) + + def image_double_clicked(self, ev): + img = ev.currentTarget + if img.dataset.calibreSrc: + self.send_message('view_image', calibre_src=img.dataset.calibreSrc) + def link_activated(self, evt): link_attr = 'data-' + self.book.manifest.link_uid try: diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index 4409b5b69c..3ec5668696 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -269,6 +269,10 @@ class View: if ui_operations.copy_selection: ui_operations.copy_selection(data.text) , + 'view_image': def(data): + if ui_operations.view_image: + ui_operations.view_image(data.calibre_src) + , } entry_point = None if runtime.is_standalone_viewer else 'read_book.iframe' if runtime.is_standalone_viewer: