mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Keyboard controls for image popup
This commit is contained in:
parent
20bcb4f416
commit
7b7d2d44b1
@ -59,6 +59,7 @@ class ImagePopup:
|
|||||||
self._container = E.div(
|
self._container = E.div(
|
||||||
style=f'display:none; position:absolute; left:0; top: 0; z-index: {MODAL_Z_INDEX}; width: 100vw; height: 100vh; padding: 0; margin: 0; border-width: 0; box-sizing: border-box',
|
style=f'display:none; position:absolute; left:0; top: 0; z-index: {MODAL_Z_INDEX}; width: 100vw; height: 100vh; padding: 0; margin: 0; border-width: 0; box-sizing: border-box',
|
||||||
id=self.container_id, tabindex='0', class_='calibre-image-popup',
|
id=self.container_id, tabindex='0', class_='calibre-image-popup',
|
||||||
|
onkeydown=self.onkeydown,
|
||||||
E.div(
|
E.div(
|
||||||
style='position: fixed; top: 0; left: 0; text-align: right; width: 100%; font-size: 200%; padding: 0.25ex; box-sizing: border-box; display: flex; justify-content: space-between',
|
style='position: fixed; top: 0; left: 0; text-align: right; width: 100%; font-size: 200%; padding: 0.25ex; box-sizing: border-box; display: flex; justify-content: space-between',
|
||||||
E.a(
|
E.a(
|
||||||
@ -80,6 +81,76 @@ class ImagePopup:
|
|||||||
window.addEventListener('resize', debounce(self.resize_canvas, 250))
|
window.addEventListener('resize', debounce(self.resize_canvas, 250))
|
||||||
return self._container
|
return self._container
|
||||||
|
|
||||||
|
def onkeydown(self, ev):
|
||||||
|
ev.preventDefault(), ev.stopPropagation()
|
||||||
|
console.log(ev.key)
|
||||||
|
if ev.key is ' ':
|
||||||
|
return self.toggle_fit_to_window()
|
||||||
|
if ev.key is 'Escape':
|
||||||
|
return self.hide_container()
|
||||||
|
if ev.key is 'ArrowDown':
|
||||||
|
return self.scroll_down((window.innerHeight - 10) if ev.getModifierState("Control") else 10)
|
||||||
|
if ev.key is 'PageDown':
|
||||||
|
return self.scroll_down(window.innerHeight-10)
|
||||||
|
if ev.key is 'ArrowUp':
|
||||||
|
return self.scroll_up((window.innerHeight - 10) if ev.getModifierState("Control") else 10)
|
||||||
|
if ev.key is 'PageUp':
|
||||||
|
return self.scroll_up(window.innerHeight-10)
|
||||||
|
if ev.key is 'ArrowLeft':
|
||||||
|
return self.scroll_left((window.innerWidth - 10) if ev.getModifierState("Control") else 10)
|
||||||
|
if ev.key is 'ArrowRight':
|
||||||
|
return self.scroll_right((window.innerWidth - 10) if ev.getModifierState("Control") else 10)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vertical_max_bounce_distance(self):
|
||||||
|
return Math.min(60, window.innerHeight / 2)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def horizontal_max_bounce_distance(self):
|
||||||
|
return Math.min(60, window.innerWidth / 2)
|
||||||
|
|
||||||
|
def scroll_down(self, amt):
|
||||||
|
if self.img_ok and not self.fit_to_window:
|
||||||
|
canvas_height = self.canvas_height
|
||||||
|
if self.img.height <= canvas_height:
|
||||||
|
return
|
||||||
|
miny = canvas_height - self.img.height - self.vertical_max_bounce_distance
|
||||||
|
y = Math.max(self.y - amt, miny)
|
||||||
|
if y is not self.y:
|
||||||
|
self.y = y
|
||||||
|
self.update_canvas()
|
||||||
|
|
||||||
|
def scroll_up(self, amt):
|
||||||
|
if self.img_ok and not self.fit_to_window:
|
||||||
|
canvas_height = self.canvas_height
|
||||||
|
if self.img.height <= canvas_height:
|
||||||
|
return
|
||||||
|
y = Math.min(self.y + amt, self.vertical_max_bounce_distance)
|
||||||
|
if y is not self.y:
|
||||||
|
self.y = y
|
||||||
|
self.update_canvas()
|
||||||
|
|
||||||
|
def scroll_right(self, amt):
|
||||||
|
if self.img_ok and not self.fit_to_window:
|
||||||
|
canvas_width = self.canvas_width
|
||||||
|
if self.img.width <= canvas_width:
|
||||||
|
return
|
||||||
|
minx = canvas_width - self.img.width - self.horizontal_max_bounce_distance
|
||||||
|
x = Math.max(self.x - amt, minx)
|
||||||
|
if x is not self.x:
|
||||||
|
self.x = x
|
||||||
|
self.update_canvas()
|
||||||
|
|
||||||
|
def scroll_left(self, amt):
|
||||||
|
if self.img_ok and not self.fit_to_window:
|
||||||
|
canvas_width = self.canvas_width
|
||||||
|
if self.img.width <= canvas_width:
|
||||||
|
return
|
||||||
|
x = Math.min(self.x + amt, self.horizontal_max_bounce_distance)
|
||||||
|
if x is not self.x:
|
||||||
|
self.x = x
|
||||||
|
self.update_canvas()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def canvas(self):
|
def canvas(self):
|
||||||
return self.container.getElementsByTagName('canvas')[0]
|
return self.container.getElementsByTagName('canvas')[0]
|
||||||
@ -123,18 +194,26 @@ class ImagePopup:
|
|||||||
self.img.addEventListener('load', self.image_loaded)
|
self.img.addEventListener('load', self.image_loaded)
|
||||||
self.img.addEventListener('error', self.image_failed)
|
self.img.addEventListener('error', self.image_failed)
|
||||||
self.img_loading = True
|
self.img_loading = True
|
||||||
self.img_ok = True
|
self.x = self.y = 0
|
||||||
|
self.img_ok = False
|
||||||
self.fit_to_window = True
|
self.fit_to_window = True
|
||||||
self.img.src = url
|
self.img.src = url
|
||||||
self.show_container()
|
self.show_container()
|
||||||
self.resize_canvas()
|
self.resize_canvas()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def canvas_width(self):
|
||||||
|
return self.canvas.width / Math.max(1, window.devicePixelRatio)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def canvas_height(self):
|
||||||
|
return self.canvas.height / Math.max(1, window.devicePixelRatio)
|
||||||
|
|
||||||
def update_canvas(self):
|
def update_canvas(self):
|
||||||
canvas = self.canvas
|
canvas = self.canvas
|
||||||
ctx = canvas.getContext('2d')
|
ctx = canvas.getContext('2d')
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
dpr = Math.max(1, window.devicePixelRatio)
|
canvas_width, canvas_height = self.canvas_width, self.canvas_height
|
||||||
canvas_width, canvas_height = canvas.width / dpr, canvas.height / dpr
|
|
||||||
|
|
||||||
def draw_centered_text(text):
|
def draw_centered_text(text):
|
||||||
tm = ctx.measureText(text)
|
tm = ctx.measureText(text)
|
||||||
@ -160,7 +239,7 @@ class ImagePopup:
|
|||||||
draw_full_image_fit_to_canvas()
|
draw_full_image_fit_to_canvas()
|
||||||
return
|
return
|
||||||
|
|
||||||
ctx.drawImage(self.img, 0, 0)
|
ctx.drawImage(self.img, self.x, self.y)
|
||||||
|
|
||||||
def toggle_fit_to_window(self):
|
def toggle_fit_to_window(self):
|
||||||
self.fit_to_window ^= True
|
self.fit_to_window ^= True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user