From 5d63ddfc036ed9b4e59063f59a1b22cfaf1b7641 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 3 Aug 2020 21:46:01 +0530 Subject: [PATCH] Make the edit panel smaller --- src/pyj/read_book/highlights.pyj | 43 +++++++------------- src/pyj/read_book/selection_bar.pyj | 61 ++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/pyj/read_book/highlights.pyj b/src/pyj/read_book/highlights.pyj index 09e4c6a5c6..df10cf09c8 100644 --- a/src/pyj/read_book/highlights.pyj +++ b/src/pyj/read_book/highlights.pyj @@ -121,9 +121,6 @@ class EditNotesAndColors: # {{{ self.initial_style = current_style self.is_dark_theme = is_dark_theme - def separator(): - return E.hr(style='width: 100%; border-top: solid 1px; margin: auto; margin-top: 2ex; margin-bottom: 2ex') - def finish(): close_editor(True) @@ -137,50 +134,38 @@ class EditNotesAndColors: # {{{ elif ev.key is 'Enter' and ev.ctrlKey: finish() + remove_button = create_button(_('Remove style'), 'trash', self.remove_custom_color, _('Remove this custom highlight style')) + remove_button.classList.add('remove-custom-color') + c = E.div( - style=f'background: {get_color("window-background")}; margin: auto; text-align: center; padding: 2rem;', + style=f'background: {get_color("window-background")}; margin: auto; text-align: center; padding: 1ex;', 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: 90%; margin: 1ex', + placeholder=_('Add notes for this highlight. Double click or long tap on a highlight to read its notes.'), + rows='10', spellcheck='true', style='resize: none; width: 90%;', 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({ICON_SIZE} * 10); margin: auto', + style=f'display: flex; flex-wrap: wrap; width: 100%; justify-content: center', ), E.div( - style='width: 100%; margin: auto; margin-top: 2ex; display: flex; justify-content: space-between; align-items: center', + style='width: 100%; display: flex; justify-content: space-between', E.div( - E.label(_('New color:'), ' ', E.input(type='color', onchange=self.add_custom_color)) + create_button(_('Cancel'), 'close', abort, _('Abort') + ' [Esc]'), + E.span('\xa0'), + remove_button ), - E.div( - E.a(_('Remove color'), class_='simple-link remove-custom-color', onclick=self.remove_custom_color), - ), - ), - - separator(), - - E.div( - style='width: 100%; margin: auto; display: flex; justify-content: space-between', - create_button(_('Cancel'), 'close', abort, _('Abort') + ' [Esc]'), create_button(_('Finish'), 'check', finish, _('Finish editing highlight') + ' [Ctrl+Enter]', True), ) ) self.container_id = c.id container.appendChild(c) - container.style.maxWidth = '50rem' + container.style.maxWidth = '40rem' container.style.width = '90%' self.seen_colors = {} custom_highlight_styles = get_session_data().get('custom_highlight_styles') @@ -189,10 +174,10 @@ class EditNotesAndColors: # {{{ for raw in all_builtin_styles(): self.add_color(HighlightStyle(raw)) if not c.querySelector('.current-swatch'): - self.add_color(self.initial_style) + self.add_color(self.initial_style, True) self.set_visibility_of_remove_button() - self.notes_edit.focus() + window.setTimeout(self.notes_edit.focus.bind(self.notes_edit), 0) def set_visibility_of_remove_button(self): c = self.container diff --git a/src/pyj/read_book/selection_bar.pyj b/src/pyj/read_book/selection_bar.pyj index 9a1b59c8e5..2398f3b406 100644 --- a/src/pyj/read_book/selection_bar.pyj +++ b/src/pyj/read_book/selection_bar.pyj @@ -22,6 +22,15 @@ def get_margins(): } +def map_boundaries(cs): + margins = get_margins() + + def map_boundary(x): + return {'x': (x.x or 0) + margins.left, 'y': (x.y or 0) + margins.top, 'height': x.height or 0, 'onscreen': x.onscreen} + + return map_boundary(cs.start), map_boundary(cs.end) + + def map_to_iframe_coords(point, margins): point.x -= margins.left point.y -= margins.top @@ -235,11 +244,8 @@ class SelectionBar: 'left: 0; top: 0; display: flex; flex-direction: column;' )) - editor_div = E.div(id=self.editor_id, style='pointer-events: auto') - container.appendChild(E.div( - editor_div, - style='width: 100%; height: 100%; position: absolute; display: flex;' - 'align-items: center; justify-content: center; pointer-events: none')) + editor_div = E.div(id=self.editor_id, style='position: absolute') + container.appendChild(editor_div) editor_div.addEventListener('click', self.editor_container_clicked, {'passive': False}) # bar and handles markup {{{ @@ -508,6 +514,7 @@ class SelectionBar: return if self.state is EDITING: self.show() + self.place_editor() return self.left_handle.style.display = 'none' self.right_handle.style.display = 'none' @@ -519,15 +526,9 @@ class SelectionBar: if not cs.start.onscreen and not cs.end.onscreen: return self.hide() - margins = get_margins() - - def map_boundary(x): - return {'x': (x.x or 0) + margins.left, 'y': (x.y or 0) + margins.top, 'height': x.height or 0, 'onscreen': x.onscreen} - self.show() self.bar.style.display = self.left_handle.style.display = self.right_handle.style.display = 'block' - start = map_boundary(cs.start) - end = map_boundary(cs.end) + start, end = map_boundaries(cs) bar = self.build_bar(cs.annot_id) end_after_start = start.y < end.y or (start.y is end.y and start.x < end.x) bar_height = bar.offsetHeight @@ -562,9 +563,6 @@ class SelectionBar: # horizontal position left = end.x - bar_width // 2 - if cs.drag_mouse_position.x?: - mouse = map_boundary(cs.drag_mouse_position) - left = mouse.x - bar_width // 2 left = max(limits.left, min(left, limits.right)) bar.style.left = left + 'px' lh, rh = left_handle.getBoundingClientRect(), right_handle.getBoundingClientRect() @@ -611,6 +609,39 @@ class SelectionBar: self.state = EDITING self.current_editor = EditNotesAndColors( container, self.view.current_color_scheme.is_dark_theme, notes, highlight_style, self.hide_editor) + self.place_editor() + + def place_editor(self): + if self.current_editor is None: + return + ed = self.editor + cs = self.view.currently_showing.selection + start, end = map_boundaries(cs) + if not start.onscreen and not end.onscreen: + return + width, height = ed.offsetWidth, ed.offsetHeight + if not start.onscreen: + start = end + if not end.onscreen: + end = start + top, bottom = v'[start, end]' if start.y <= end.y else v'[end, start]' + container = self.container + space_above, space_below = top.y, container.offsetHeight - (bottom.y + bottom.height) + if height <= min(space_above, space_below): + put_above = space_above < space_below + else: + put_above = space_above > space_below + if put_above: + y = max(0, top.y - height) + else: + y = bottom.y + bottom.height + if y + height > container.offsetHeight: + y = container.offsetHeight - height + x = max(0, end.x - width // 2) + if x + width > container.offsetWidth: + x = container.offsetWidth - width + ed.style.left = x + 'px' + ed.style.top = y + 'px' def hide_editor(self, apply): pass # TODO: Implement this