From 1ce8b68de66db56626940e5e62377335258f0e60 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 2 Aug 2020 21:39:29 +0530 Subject: [PATCH] Remove the create_annotation module The entire UI is being removed since all operations will be performed via the selection bar --- src/calibre/gui2/viewer/highlights.py | 8 +- src/pyj/read_book/create_annotation.pyj | 708 ------------------------ src/pyj/read_book/overlay.pyj | 8 +- src/pyj/read_book/selection_bar.pyj | 20 +- src/pyj/read_book/shortcuts.pyj | 8 +- src/pyj/read_book/view.pyj | 20 +- 6 files changed, 21 insertions(+), 751 deletions(-) delete mode 100644 src/pyj/read_book/create_annotation.pyj diff --git a/src/calibre/gui2/viewer/highlights.py b/src/calibre/gui2/viewer/highlights.py index 80edc7e87a..3240e42cbe 100644 --- a/src/calibre/gui2/viewer/highlights.py +++ b/src/calibre/gui2/viewer/highlights.py @@ -285,13 +285,10 @@ class HighlightsPanel(QWidget): b.clicked.connect(target) return b - self.add_button = button('plus.png', _('Add'), _('Create a new highlight'), self.add_highlight) self.edit_button = button('edit_input.png', _('Edit'), _('Edit the selected highlight'), self.edit_highlight) self.remove_button = button('trash.png', _('Remove'), _('Remove the selected highlights'), self.remove_highlight) - h.addWidget(self.add_button), h.addWidget(self.edit_button), h.addWidget(self.remove_button) - self.export_button = button('save.png', _('Export'), _('Export all highlights'), self.export) - l.addWidget(self.export_button) + h.addWidget(self.edit_button), h.addWidget(self.remove_button), h.addWidget(self.export_button) self.notes_display = nd = NotesDisplay(self) nd.notes_edited.connect(self.notes_edited) @@ -356,9 +353,6 @@ class HighlightsPanel(QWidget): for h in highlights: self.request_highlight_action.emit(h['uuid'], 'delete') - def add_highlight(self): - self.request_highlight_action.emit(None, 'create') - def export(self): hl = list(self.highlights.all_highlights) if not hl: diff --git a/src/pyj/read_book/create_annotation.pyj b/src/pyj/read_book/create_annotation.pyj deleted file mode 100644 index b2acc425c6..0000000000 --- a/src/pyj/read_book/create_annotation.pyj +++ /dev/null @@ -1,708 +0,0 @@ -# vim:fileencoding=utf-8 -# License: GPL v3 Copyright: 2020, Kovid Goyal -from __python__ import bound_methods, hash_literals - -from elementmaker import E -from gettext import gettext as _ -from uuid import short_uuid - -from book_list.globals import get_session_data -from book_list.theme import cached_color_to_rgba, get_color -from dom import clear, ensure_id, svgicon, unique_id -from modals import error_dialog, question_dialog -from read_book.globals import ui_operations -from read_book.shortcuts import shortcut_for_key_event -from widgets import create_button - - -WAITING_FOR_CLICK = 1 -WAITING_FOR_DRAG = 2 -DRAGGING_LEFT = 3 -DRAGGING_RIGHT = 4 - -dark_fg = '#111' -light_fg = '#eee' -builtin_highlight_colors = { - '#fce2ae': dark_fg, - '#b6ffea': dark_fg, - '#ffb3b3': dark_fg, - '#ffdcf7': dark_fg, - '#cae8d5': dark_fg, - - '#204051': light_fg, - '#3b6978': light_fg, - '#2b580c': light_fg, - '#512b58': light_fg, -} -default_highlight_color = '#fce2ae' - - -def default_highlight_style(): - return { - 'background-color': default_highlight_color, - 'color': builtin_highlight_colors[default_highlight_color] - } - - -def selection_handle(invert, style): - ans = svgicon('selection-handle') - use = ans.querySelector('use') - use.style.stroke = style['color'] - use.style.fill = style['background-color'] - s = ans.style - if invert: - s.transform = 'scaleX(-1)' - s.position = 'absolute' - s.boxSizing = 'border-box' - s.touchAction = 'none' - return ans - - -def map_from_iframe_coords(point): - l = document.getElementById('book-left-margin') - point.x += l.offsetWidth - t = document.getElementById('book-top-margin') - point.y += t.offsetHeight - return point - - -def map_to_iframe_coords(point): - l = document.getElementById('book-left-margin') - point.x -= l.offsetWidth - t = document.getElementById('book-top-margin') - point.y -= t.offsetHeight - return point - - -BAR_SIZE = 32 -DRAG_SCROLL_ZONE_MIN_HEIGHT = 10 - - -def create_bar(): - style = f'min-height: 1px; min-width: 1px; max-height: {BAR_SIZE}px; height: {BAR_SIZE}px' - ans = E.div( - id=unique_id('annot-bar'), - style=f'height: {BAR_SIZE}px; max-height: {BAR_SIZE}px; width: 100vw; display: flex; justify-content: space-between;', - E.div(style=style), E.div(style=style), E.div(style=style), - ) - return ans - - -class EditNotesAndColors: # {{{ - - def __init__(self, container, hide_middle, accept, current_notes, current_style): - self.initial_style = current_style - def separator(): - return E.hr(style='max-width: 80em; width: 80vw; border-top: solid 1px; margin: auto; margin-top: 2ex; margin-bottom: 2ex') - - def finish(): - hide_middle() - accept() - - def handle_keypress(ev): - ev.stopPropagation() - if ev.key is 'Escape': - hide_middle() - elif ev.key is 'Enter' and ev.ctrlKey: - finish() - - c = E.div( - style=f'background: {get_color("window-background")}; margin: auto; padding: 1rem', - onclick=def(ev): ev.stopPropagation();, - id=unique_id(), - E.h3(_('Add notes for this highlight')), - E.textarea( - current_notes or '', - rows='10', spellcheck='true', style='resize: none; width: 80vw; max-width: 80em; margin: 1ex', - onkeydown=handle_keypress, - ), - E.div( - style='margin: 1ex; font-size: smaller', - _('Double click or long tap on a highlight to see its notes') - ), - - separator(), - - E.h3(_('Choose the color for this highlight'), style='margin-bottom: 2ex'), - E.div( - class_='color-block', - style=f'display: flex; flex-wrap: wrap; max-width: calc({BAR_SIZE}px * 8); margin: auto', - ), - E.div( - style='max-width: 80em; width: 80vw; margin: auto; margin-top: 2ex; display: flex; justify-content: space-between; align-items: center', - E.div( - E.label(_('New color:'), ' ', E.input(type='color', onchange=self.add_custom_color)) - ), - E.div( - E.a(_('Remove color'), class_='simple-link remove-custom-color', onclick=self.remove_custom_color), - ), - ), - - separator(), - - E.div( - style='max-width: 80em; width: 80vw; margin: auto; display: flex; justify-content: space-between', - create_button(_('Adjust selection'), 'arrows-h', hide_middle, _('Accept changes and then adjust the selected text') + ' [Esc]'), - create_button(_('Finish'), 'check', finish, _('Finish editing highlight') + ' [Ctrl+Enter]', True), - ) - - ) - self.container_id = c.id - container.appendChild(c) - self.seen_colors = {} - custom_highlight_colors = get_session_data().get('custom_highlight_colors') - for bg in custom_highlight_colors: - self.add_color(bg).classList.add('custom-color') - for bg in builtin_highlight_colors: - self.add_color(bg) - if not c.querySelector('.current-swatch'): - self.add_color(self.initial_style['background-color']) - - self.set_visibility_of_remove_button() - self.notes_edit.focus() - - def set_visibility_of_remove_button(self): - c = self.container - item = c.querySelector('.current-swatch.custom-color') - visibility = 'unset' if item else 'hidden' - c.querySelector('.remove-custom-color').style.visibility = visibility - - def add_color(self, bg, at_start): - if self.seen_colors[bg]: - return - self.seen_colors[bg] = True - ic = svgicon('swatch', BAR_SIZE, BAR_SIZE) - ic.classList.add('simple-link') - is_current = bg.lower() is self.initial_style['background-color'].lower() - sqbg = get_color('window-background2') if is_current else 'unset' - ic.querySelector('use').style.fill = bg - item = E.div( - ic, style=f'padding: 4px; background-color: {sqbg}; margin: 4px', - onclick=self.change_color - ) - if is_current: - item.classList.add('current-swatch') - item.dataset.bg = bg - parent = self.container.getElementsByClassName('color-block')[0] - if at_start: - parent.insertBefore(item, parent.firstChild) - else: - parent.appendChild(item) - return item - - def add_custom_color(self): - bg = self.container.querySelector('input[type=color]').value - item = self.add_color(bg, True) - item.classList.add('custom-color') - self.make_swatch_current(item) - sd = get_session_data() - custom_highlight_colors = sd.get('custom_highlight_colors') - custom_highlight_colors.unshift(bg) - sd.set('custom_highlight_colors', custom_highlight_colors) - - def remove_custom_color(self): - item = self.container.getElementsByClassName('current-swatch')[0] - bg = item.dataset.bg - p = item.parentNode - p.removeChild(item) - self.make_swatch_current(p.firstChild) - sd = get_session_data() - custom_highlight_colors = sd.get('custom_highlight_colors') - idx = custom_highlight_colors.indexOf(bg) - if idx > -1: - custom_highlight_colors.splice(idx, 1) - sd.set('custom_highlight_colors', custom_highlight_colors) - - @property - def container(self): - return document.getElementById(self.container_id) - - @property - def notes_edit(self): - return self.container.getElementsByTagName('textarea')[0] - - def change_color(self, evt): - evt.stopPropagation() - self.make_swatch_current(evt.currentTarget) - - def make_swatch_current(self, item): - for child in item.parentNode.childNodes: - child.style.backgroundColor = 'unset' - child.classList.remove('current-swatch') - item.style.backgroundColor = get_color('window-background2') - item.classList.add('current-swatch') - self.notes_edit.focus() - self.set_visibility_of_remove_button() - - @property - def current_notes(self): - return self.notes_edit.value or '' - - @property - def current_style(self): - bg = self.container.getElementsByClassName('current-swatch')[0].dataset.bg - fg = builtin_highlight_colors[bg] - if not fg: - rgba = cached_color_to_rgba(bg) - is_dark = max(rgba[0], rgba[1], rgba[2]) < 115 - fg = light_fg if is_dark else dark_fg - return {'background-color': bg, 'color': fg} -# }}} - - -class CreateAnnotation: # {{{ - - container_id = 'create-annotation-overlay' - - def __init__(self, view): - self.view = view - self.active_touch = None - self.drag_scroll_timer = None - self.last_drag_scroll_at = -100000 - self.editing_annot_uuid = None - self.current_notes = '' - self.annotations_manager = self.view.annotations_manager - self.state = WAITING_FOR_CLICK - self.left_line_height = self.right_line_height = 8 - self.in_flow_mode = False - container = self.container - container.style.flexDirection = 'column' - container.style.justifyContent = 'space-between' - self.position_in_handle = {'x': 0, 'y': 0} - - def button(name, bar, icon, tt, action): - cb = svgicon(icon, bar.style.height, bar.style.height, tt) - cb.setAttribute('title', tt) - cb.style.backgroundColor = get_color('window-background') - cb.style.boxSizing = 'border-box' - cb.style.padding = '2px' - cb.style.border = 'solid 2px currentColor' - cb.style.borderRadius = '4px' - cb.style.marginLeft = '0.5rem' - cb.style.marginRight = '0.5rem' - cb.classList.add('simple-link') - cb.classList.add('adjust-button') - cb.classList.add(f'button-{name}') - cb.addEventListener('click', def(ev): - ev.preventDefault(), ev.stopPropagation() - action() - ) - bar.appendChild(cb) - return cb - - tb = create_bar() - container.appendChild(tb) - button('close', tb.firstChild, 'close', _('Cancel creation of highlight') + ' [Esc]', self.hide) - button('up', tb.firstChild.nextSibling, 'chevron-up', _('Scroll up') + ' [Up]', self.button_scroll.bind(None, True)) - button('copy', tb.lastChild, 'copy', _('Copy to clipboard'), self.copy_to_clipboard) - button('finish', tb.lastChild, 'check', _('Finish creation of highlight') + ' [Enter]', self.accept) - - middle = E.div(id=unique_id('middle'), style='display: none; text-align: center; z-index: 90000') - self.middle_id = middle.id - container.appendChild(middle) - - bb = create_bar() - container.appendChild(bb) - button('remove', bb.firstChild, 'trash', _('Remove this highlight'), self.delete_highlight) - button('down', bb.firstChild.nextSibling, 'chevron-down', _('Scroll down') + ' [Down]', self.button_scroll) - button('edit', bb.lastChild, 'pencil', _('Edit notes and change highlight color') + ' [e]', self.edit_notes_and_colors) - - sd = get_session_data() - style = sd.get('highlight_style') or default_highlight_style() - if not style['background-color'] or not style['color']: - style = default_highlight_style() - self.current_highlight_style = style - - lh = selection_handle(False, style) - self.left_handle_id = ensure_id(lh, 'handle') - lh.addEventListener('mousedown', self.mousedown_on_handle, {'passive': False}) - lh.addEventListener('touchstart', self.touchstart_on_handle, {'passive': False}) - container.appendChild(lh) - rh = selection_handle(True, style) - self.right_handle_id = ensure_id(rh, 'handle') - rh.addEventListener('mousedown', self.mousedown_on_handle, {'passive': False}) - rh.addEventListener('touchstart', self.touchstart_on_handle, {'passive': False}) - container.appendChild(rh) - - container.addEventListener('click', self.container_clicked, {'passive': False}) - container.addEventListener('mouseup', self.mouseup_on_container, {'passive': False}) - container.addEventListener('mousemove', self.mousemove_on_container, {'passive': False}) - container.addEventListener('touchmove', self.touchmove_on_container, {'passive': False}) - container.addEventListener('touchend', self.touchend_on_container, {'passive': False}) - container.addEventListener('touchcancel', self.touchend_on_container, {'passive': False}) - container.addEventListener('keydown', self.on_keydown, {'passive': False}) - - def copy_to_clipboard(self): - ui_operations.copy_selection(self.view.currently_showing.selection.text or '') - - @property - def middle(self): - return document.getElementById(self.middle_id) - - def edit_notes_and_colors(self): - if self.editor: - return - current_notes = self.current_notes - if not current_notes and self.editing_annot_uuid: - current_notes = self.annotations_manager.notes_for_highlight(self.editing_annot_uuid) - current_style = self.current_highlight_style - self.show_middle(self.editing_done) - container = self.middle - clear(container) - self.editor = EditNotesAndColors(container, self.hide_middle, self.accept, current_notes, current_style) - - def editing_done(self): - self.current_notes = self.editor.current_notes - new_highlight_style = self.editor.current_style - self.editor = None - if self.current_highlight_style['background-color'] is not new_highlight_style['background_color']: - self.current_highlight_style = new_highlight_style - self.send_message('set-highlight-style', style=self.current_highlight_style) - get_session_data().set('highlight_style', self.current_highlight_style) - self.update_handle_colors() - return True - - def update_handle_colors(self): - fill = self.current_highlight_style['background-color'] - stroke = self.view.current_color_scheme.foreground - for handle in (self.left_handle, self.right_handle): - use = handle.querySelector('use') - use.style.stroke = stroke - use.style.fill = fill - - def show_middle(self, pre_close_callback): - self.pre_middle_close_callback = pre_close_callback - for h in (self.left_handle, self.right_handle): - h.style.visibility = 'hidden' - for button in self.container.querySelectorAll('.adjust-button'): - button.style.visibility = 'hidden' - self.middle.style.display = 'block' - - def hide_middle(self): - m = self.middle - if m.style.display is not 'none': - if self.pre_middle_close_callback: - if not self.pre_middle_close_callback(): - return - self.pre_middle_close_callback = None - for button in self.container.querySelectorAll('.adjust-button'): - button.style.visibility = 'unset' - for h in (self.left_handle, self.right_handle): - h.style.visibility = 'unset' - m.style.display = 'none' - self.container.focus() - - def accept(self): - s = self.current_highlight_style - style = '' - for k in Object.keys(self.current_highlight_style): - style += f'{k}: {s[k]}; ' - self.send_message( - 'apply-highlight', style=style, uuid=short_uuid(), existing=self.editing_annot_uuid - ) - self.hide() - - def quick_create(self): - s = self.current_highlight_style - style = '' - for k in Object.keys(self.current_highlight_style): - style += f'{k}: {s[k]}; ' - self.send_message( - 'apply-highlight', style=style, uuid=short_uuid() - ) - - def on_keydown(self, ev): - ev.stopPropagation(), ev.preventDefault() - if ev.key is 'Enter': - return self.accept() - if ev.key is 'e' or ev.key is 'E': - return self.edit_notes_and_colors() - sc_name = shortcut_for_key_event(ev, self.view.keyboard_shortcut_map) - if sc_name is 'show_chrome': - self.hide() - elif sc_name in ('up', 'down', 'pageup', 'pagedown'): - backwards = 'up' in sc_name - if 'page' in sc_name or not self.in_flow_mode: - self.paged_scroll(backwards) - else: - self.send_drag_scroll_message(backwards, 'left' if backwards else 'right', False) - elif sc_name in ('left', 'right'): - if self.in_flow_mode: - self.send_message('perp-scroll', backwards=bool(sc_name is 'left')) - else: - self.paged_scroll(sc_name is 'left') - - def container_clicked(self, ev): - ev.stopPropagation(), ev.preventDefault() - if self.middle.style.display is not 'none': - self.hide_middle() - self.accept() - return - if self.state is WAITING_FOR_CLICK: - pt = map_to_iframe_coords({'x': ev.clientX, 'y': ev.clientY}) - self.send_message('position-handles-at-point', x=pt.x, y=pt.y) - - def start_handle_drag(self, ev, q): - if q is self.left_handle_id: - self.state = DRAGGING_LEFT - handle = self.left_handle - elif q is self.right_handle_id: - self.state = DRAGGING_RIGHT - handle = self.right_handle - r = handle.getBoundingClientRect() - self.position_in_handle.x = Math.round(ev.clientX - r.left) - self.position_in_handle.y = Math.round(ev.clientY - r.top) - - def mousedown_on_handle(self, ev): - ev.stopPropagation(), ev.preventDefault() - if self.state is WAITING_FOR_CLICK: - return - self.start_handle_drag(ev, ev.currentTarget.id) - - def touchstart_on_handle(self, ev): - ev.stopPropagation(), ev.preventDefault() - if self.state is WAITING_FOR_CLICK: - return - for touch in ev.changedTouches: - self.active_touch = touch.identifier - self.start_handle_drag(touch, ev.currentTarget.id) - break - - def button_scroll(self, backwards): - if self.in_flow_mode: - self.send_drag_scroll_message(backwards, 'left' if backwards else 'right', False) - else: - self.paged_scroll(backwards) - - def paged_scroll(self, backwards): - self.send_message('paged-scroll', backwards=backwards) - - def run_drag_scroll(self, mouse_y, top, bottom): - backwards = mouse_y <= top - self.do_one_drag_scroll(backwards, top - mouse_y if backwards else mouse_y - bottom) - - def do_one_drag_scroll(self, backwards, distance_from_boundary): - window.clearTimeout(self.drag_scroll_timer) - self.drag_scroll_timer = None - if self.state not in (DRAGGING_RIGHT, DRAGGING_LEFT): - return - sd = get_session_data() - interval = 1000/sd.get('lines_per_sec_smooth') if self.in_flow_mode else 1200 - self.drag_scroll_timer = window.setTimeout(self.do_one_drag_scroll.bind(None, backwards, distance_from_boundary), interval) - now = window.performance.now() - if now - self.last_drag_scroll_at > interval: - self.send_drag_scroll_message(backwards, 'left' if self.state is DRAGGING_LEFT else 'right', True) - self.last_drag_scroll_at = now - - def send_drag_scroll_message(self, backwards, handle, extend_selection): - self.send_message( - 'drag-scroll', backwards=backwards, handle=handle, extents=self.current_handle_position, - extend_selection=extend_selection) - - def end_drag_scroll(self): - if self.drag_scroll_timer is not None: - window.clearTimeout(self.drag_scroll_timer) - self.drag_scroll_timer = None - self.last_drag_scroll_at = -10000 - - def mouseup_on_container(self, ev): - if self.state in (DRAGGING_RIGHT, DRAGGING_LEFT): - self.state = WAITING_FOR_DRAG - self.end_drag_scroll() - ev.preventDefault(), ev.stopPropagation() - - def touchend_on_container(self, ev): - if self.state in (DRAGGING_RIGHT, DRAGGING_LEFT): - ev.preventDefault(), ev.stopPropagation() - for touch in ev.changedTouches: - if touch.identifier is self.active_touch: - self.active_touch = None - self.state = WAITING_FOR_DRAG - self.end_drag_scroll() - return - - def handle_moved(self, ev): - handle = self.left_handle if self.state is DRAGGING_LEFT else self.right_handle - s = handle.style - s.left = (ev.clientX - self.position_in_handle.x) + 'px' - s.top = (ev.clientY - self.position_in_handle.y) + 'px' - pos = self.current_handle_position - pos.start = map_to_iframe_coords(pos.start) - pos.end = map_to_iframe_coords(pos.end) - self.send_message('set-selection', extents=pos) - c = self.container - rect = c.getBoundingClientRect() - t = document.getElementById('book-top-margin').offsetHeight - top = rect.top + max(t, DRAG_SCROLL_ZONE_MIN_HEIGHT) - t = document.getElementById('book-bottom-margin').offsetHeight - bottom = rect.bottom - max(t, DRAG_SCROLL_ZONE_MIN_HEIGHT) - if ev.clientY < top or ev.clientY > bottom: - self.run_drag_scroll(ev.clientY, top, bottom) - else: - self.end_drag_scroll() - - def mousemove_on_container(self, ev): - if self.state not in (DRAGGING_RIGHT, DRAGGING_LEFT): - return - ev.stopPropagation(), ev.preventDefault() - self.handle_moved(ev) - - def touchmove_on_container(self, ev): - if self.state not in (DRAGGING_RIGHT, DRAGGING_LEFT): - return - ev.stopPropagation(), ev.preventDefault() - for touch in ev.changedTouches: - if touch.identifier is self.active_touch: - self.handle_moved(touch) - return - - @property - def container(self): - return document.getElementById(self.container_id) - - @property - def left_handle(self): - return document.getElementById(self.left_handle_id) - - @property - def right_handle(self): - return document.getElementById(self.right_handle_id) - - @property - def is_visible(self): - return self.container.style.display is not 'none' - - @property - def current_handle_position(self): - lh, rh = self.left_handle, self.right_handle - lbr, rbr = self.left_handle.getBoundingClientRect(), self.right_handle.getBoundingClientRect() - return { - 'start': { - 'onscreen': lh.style.display is not 'none', - 'x': Math.round(lbr.right), 'y': Math.round(lbr.bottom - self.left_line_height // 2) - }, - 'end': { - 'onscreen': rh.style.display is not 'none', - 'x': Math.round(rbr.left), 'y': Math.round(rbr.bottom - self.right_line_height // 2) - } - } - - def show(self): - self.middle.style.display = 'none' - c = self.container - c.style.display = 'flex' - c.focus() - self.update_handle_colors() - self.view.selection_bar.hide() - - def hide(self): - if self.is_visible: - self.container.style.display = 'none' - self.view.focus_iframe() - self.send_message('set-highlight-style', style=None) - self.view.selection_bar.update_position() - - def send_message(self, type, **kw): - self.view.iframe_wrapper.send_message('annotations', type=type, **kw) - - def initiate_create_annotation(self, start_in_notes_edit): - self.send_message('create', start_in_notes_edit=v'!!start_in_notes_edit') - - def edit_highlight(self, uuid): - self.send_message('edit-highlight', uuid=uuid) - self.show() - - def remove_highlight(self, uuid): - self.send_message('remove-highlight', uuid=uuid) - self.annotations_manager.delete_highlight(uuid) - self.hide() - - def delete_highlight(self): - uuid = self.editing_annot_uuid - question_dialog(_('Are you sure?'), _('Are you sure you want to delete this highlight permanently?'), - def (yes): - if yes: - self.remove_highlight(uuid) if uuid else self.hide() - ) - - def handle_message(self, msg): - if msg.type is 'create-annotation': - self.editing_annot_uuid = msg.existing or None - self.current_notes = '' - if self.editing_annot_uuid: - self.current_notes = self.annotations_manager.notes_for_highlight(self.editing_annot_uuid) or '' - hs = self.annotations_manager.style_for_highlight(self.editing_annot_uuid) - if hs: - self.current_highlight_style = hs - get_session_data().set('highlight_style', self.current_highlight_style) - if not self.is_visible: - self.view.hide_overlays() - self.state = WAITING_FOR_CLICK - self.show() - self.hide_handles() - if msg.extents and not msg.extents.start.is_empty: - self.place_handles(msg.extents) - self.in_flow_mode = msg.in_flow_mode - self.send_message('set-highlight-style', style=self.current_highlight_style) - if msg.start_in_notes_edit: - self.edit_notes_and_colors() - elif msg.type is 'position-handles': - if self.state is WAITING_FOR_CLICK: - self.place_handles(msg.extents) - self.editing_annot_uuid = msg.existing or None - if self.editing_annot_uuid: - self.current_notes = self.annotations_manager.notes_for_highlight(self.editing_annot_uuid) or '' - elif msg.type is 'scrolled': - self.place_handles_after_scroll(msg.extents, msg.handle, msg.extended) - elif msg.type is 'update-handles': - self.place_handles(msg.extents) - elif msg.type is 'highlight-applied': - if not msg.ok: - return error_dialog( - _('Highlighting failed'), - _('Failed to apply highlighting, try adjusting extent of highlight') - ) - self.annotations_manager.add_highlight(msg, self.current_highlight_style, self.current_notes) - else: - print('Ignoring annotations message with unknown type:', msg.type) - - def hide_handles(self): - self.left_handle.style.display = 'none' - self.right_handle.style.display = 'none' - - def place_single_handle(self, handle, data): - map_from_iframe_coords(data) - s = handle.style - s.display = 'block' if data.onscreen else 'none' - height = data.height * 3 - width = data.height * 2 - s.width = f'{width}px' - s.height = f'{height}px' - bottom = data.y + data.height - top = bottom - height - s.top = f'{top}px' - if handle.id is self.left_handle_id: - s.left = (data.x - width) + 'px' - else: - s.left = data.x + 'px' - - def place_handles(self, extents): - self.place_single_handle(self.left_handle, extents.start) - self.place_single_handle(self.right_handle, extents.end) - self.state = WAITING_FOR_DRAG - self.left_line_height = extents.start.height - self.right_line_height = extents.end.height - - def place_handles_after_scroll(self, extents, handle, extended): - if extended: - if handle is 'right': - h = self.left_handle - data = extents.start - else: - h = self.right_handle - data = extents.end - self.place_single_handle(h, data) - else: - self.place_single_handle(self.left_handle, extents.start) - self.place_single_handle(self.right_handle, extents.end) -# }}} diff --git a/src/pyj/read_book/overlay.pyj b/src/pyj/read_book/overlay.pyj index 0203e8510b..8dfb53e96f 100644 --- a/src/pyj/read_book/overlay.pyj +++ b/src/pyj/read_book/overlay.pyj @@ -316,17 +316,12 @@ class MainOverlay: # {{{ actions_div.appendChild(E.ul(*full_screen_actions)) no_selection_bar = not sd.get('show_selection_bar') - if no_selection_bar: - highlight_action = ac(_('Highlight'), _('Highlight text in the book'), - def(): self.overlay.hide(), self.overlay.view.initiate_create_annotation();, 'highlight') - if runtime.is_standalone_viewer: if no_selection_bar: actions_div.appendChild(E.ul( ac(_('Lookup/search word'), _('Lookup or search for the currently selected word'), def(): self.overlay.hide(), ui_operations.toggle_lookup(True);, 'library') )) - actions_div.lastChild.appendChild(highlight_action) actions_div.lastChild.appendChild( ac(_('Browse highlights'), _('Browse all highlights'), def(): self.overlay.hide(), ui_operations.toggle_highlights();, 'image') @@ -355,8 +350,7 @@ class MainOverlay: # {{{ def(): self.overlay.hide(), ui_operations.quit();, 'remove'), )) else: - if no_selection_bar: - actions_div.appendChild(E.ul(highlight_action)) + pass container.appendChild(set_css(E.div(class_=MAIN_OVERLAY_TS_CLASS, # top section onclick=def (evt):evt.stopPropagation();, diff --git a/src/pyj/read_book/selection_bar.pyj b/src/pyj/read_book/selection_bar.pyj index e2644060ac..800e6949ff 100644 --- a/src/pyj/read_book/selection_bar.pyj +++ b/src/pyj/read_book/selection_bar.pyj @@ -156,7 +156,7 @@ def all_actions(): 'copy': a('copy', _('Copy to clipboard'), 'copy_to_clipboard'), 'lookup': a('library', _('Lookup/search selected word'), 'lookup'), 'quick_highlight': a('highlight', _('Quick highlight in current color'), 'quick_highlight'), - 'highlight': a('highlight', _('Highlight selection in notes mode'), 'create_highlight'), + 'highlight': a('highlight', _('Highlight selection'), 'create_highlight'), 'search_net': a('search', _('Search for selection on the net'), 'internet_search'), 'remove_highlight': a('trash', _('Remove this highlight'), 'remove_highlight', True), 'clear': a('close', _('Clear selection'), 'clear_selection'), @@ -617,20 +617,27 @@ class SelectionBar: self.hide() def create_highlight(self): - self.view.initiate_create_annotation(True) + pass # TODO: Implement this def quick_highlight(self): cs = self.view.currently_showing.selection if cs.text: + # TODO: Implement this if cs.annot_id: - self.view.initiate_create_annotation(True) + pass else: - self.view.create_annotation.quick_create() + pass def remove_highlight(self): annot_id = self.view.currently_showing.selection.annot_id if annot_id: - self.view.create_annotation.remove_highlight(annot_id) + self.remove_highlight_with_id(annot_id) + + def remove_highlight_with_id(self, annot_id): + pass # TODO: Implement this + + def edit_highlight(self, annot_id): + pass # TODO: Implement this # }}} # Interact with iframe {{{ @@ -638,4 +645,7 @@ class SelectionBar: def send_message(self, type, **kw): self.view.iframe_wrapper.send_message('annotations', type=type, **kw) + def handle_message(self, data): + pass # TODO: Implement this + # }}} diff --git a/src/pyj/read_book/shortcuts.pyj b/src/pyj/read_book/shortcuts.pyj index 4e8050c25d..fa943efaad 100644 --- a/src/pyj/read_book/shortcuts.pyj +++ b/src/pyj/read_book/shortcuts.pyj @@ -328,12 +328,6 @@ def shortcuts_definition(): _('Auto scroll slower'), ), - 'create_annotation': desc( - "Ctrl+h", - 'ui', - _('Create a highlight'), - ), - } return ans @@ -396,7 +390,7 @@ def add_standalone_viewer_shortcuts(): ) sc['toggle_highlights'] = desc( - "Ctrl+Alt+h", + "Ctrl+h", 'ui', _('Toggle the highlights panel') ) diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index 803219207a..a8199b50c9 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -14,7 +14,6 @@ from iframe_comm import IframeWrapper from modals import error_dialog, warning_dialog from read_book.annotations import AnnotationsManager from read_book.content_popup import ContentPopupOverlay -from read_book.create_annotation import CreateAnnotation from read_book.globals import ( current_book, rtl_page_progression, runtime, set_current_spine_item, ui_operations @@ -243,7 +242,6 @@ class View: E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='book-content-popup-overlay'), # content popup overlay E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; overflow: auto; display:none', id='book-overlay'), # main overlay E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='controls-help-overlay'), # controls help overlay - E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none; overflow: hidden', id=CreateAnnotation.container_id, tabindex='0'), # create annotation overlay ) ), E.div( @@ -312,7 +310,6 @@ class View: self.currently_showing = {'selection': {'empty': True}} self.book_scrollbar.apply_visibility() self.annotations_manager = AnnotationsManager(self) - self.create_annotation = CreateAnnotation(self) @property def iframe(self): @@ -332,7 +329,7 @@ class View: self.set_scrollbar_visibility(not sd.get('book_scrollbar')) def on_annotations_message(self, data): - self.create_annotation.handle_message(data) + self.selection_bar.handle_message(data) def left_margin_clicked(self, event): if event.button is 0: @@ -451,8 +448,6 @@ class View: ui_operations.toggle_bookmarks() elif data.name is 'toggle_highlights': ui_operations.toggle_highlights() - elif data.name is 'create_annotation': - self.initiate_create_annotation() elif data.name is 'new_bookmark': ui_operations.new_bookmark() elif data.name is 'toggle_inspector': @@ -626,7 +621,6 @@ class View: self.search_overlay.hide() self.content_popup_overlay.hide() self.reference_mode_overlay.style.display = 'none' - self.create_annotation.hide() self.focus_iframe() def focus_iframe(self): @@ -1249,26 +1243,18 @@ class View: else: self.show_name(sr.file_name, initial_position={'type':'search_result', 'search_result':sr, 'replace_history':True}) - def initiate_create_annotation(self, start_in_notes_edit): - self.create_annotation.initiate_create_annotation(start_in_notes_edit) - def highlight_action(self, uuid, which): - if self.create_annotation.is_visible: - return - if which is 'create': - self.initiate_create_annotation(False) - return spine = self.book.manifest.spine spine_index = self.annotations_manager.spine_index_for_highlight(uuid, spine) if spine_index < 0 or spine_index >= spine.length: return if which is 'edit': if self.currently_showing.spine_index is spine_index: - self.create_annotation.edit_highlight(uuid) + self.selection_bar.edit_highlight(uuid) else: self.show_name(spine[spine_index], initial_position={'type':'edit_annotation', 'uuid': uuid, 'replace_history':True}) elif which is 'delete': - self.create_annotation.remove_highlight(uuid) + self.selection_bar.remove_highlight_with_id(uuid) elif which is 'goto': cfi = self.annotations_manager.cfi_for_highlight(uuid, spine_index) if cfi: