diff --git a/imgsrc/srv/chevron-down.svg b/imgsrc/srv/chevron-down.svg
new file mode 100644
index 0000000000..8177dc9bac
--- /dev/null
+++ b/imgsrc/srv/chevron-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/imgsrc/srv/chevron-up.svg b/imgsrc/srv/chevron-up.svg
new file mode 100644
index 0000000000..563a644984
--- /dev/null
+++ b/imgsrc/srv/chevron-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/pyj/complete.pyj b/src/pyj/complete.pyj
index 5bfc245961..0a6cdf31e4 100644
--- a/src/pyj/complete.pyj
+++ b/src/pyj/complete.pyj
@@ -65,7 +65,7 @@ class EditWithComplete:
self.completion_popup.set_all_items(items)
-def create_search_bar(action, name, tooltip=None, placeholder=None, button=None, history_size=100):
+def create_search_bar(action, name, tooltip=None, placeholder=None, button=None, history_size=100, associated_widgets=None):
parent = E.div(style="display:flex")
ewc = EditWithComplete(name, parent=parent, tooltip=tooltip, placeholder=placeholder, input_type='search')
parent.lastChild.style.width = '100%'
@@ -94,6 +94,9 @@ def create_search_bar(action, name, tooltip=None, placeholder=None, button=None,
if button:
ewc.add_associated_widget(button)
button.addEventListener('click', trigger)
+ if associated_widgets is not None:
+ for w in associated_widgets:
+ ewc.add_associated_widget(w)
return parent
# }}}
diff --git a/src/pyj/read_book/overlay.pyj b/src/pyj/read_book/overlay.pyj
index fe4b5197a9..86e7285256 100644
--- a/src/pyj/read_book/overlay.pyj
+++ b/src/pyj/read_book/overlay.pyj
@@ -156,7 +156,7 @@ class MainOverlay:
),
E.ul(
- ac(_('Search'), _('Search for text in this book'), None, 'search'),
+ ac(_('Search'), _('Search for text in this book'), self.overlay.show_search, 'search'),
ac(_('Go to'), _('Go to a specific location in the book'), self.overlay.show_goto, 'chevron-right'),
),
@@ -349,6 +349,10 @@ class Overlay:
self.panels.push(TOCOverlay(self, create_goto_panel, _('Go to…')))
self.show_current_panel()
+ def show_search(self):
+ self.hide()
+ self.view.show_search()
+
def show_prefs(self):
self.panels = [PrefsOverlay(self)]
self.show_current_panel()
diff --git a/src/pyj/read_book/search.pyj b/src/pyj/read_book/search.pyj
index 9857eeb0b7..d22f674799 100644
--- a/src/pyj/read_book/search.pyj
+++ b/src/pyj/read_book/search.pyj
@@ -2,10 +2,49 @@
# License: GPL v3 Copyright: 2017, Kovid Goyal
from __python__ import hash_literals, bound_methods
+from complete import create_search_bar
+from dom import add_extra_css, build_rule, svgicon
+from keycodes import get_key
+from elementmaker import E
+from gettext import gettext as _
+from book_list.theme import get_color
+
+CLASS_NAME = 'book-search-container'
+
+add_extra_css(def():
+ sel = '.' + CLASS_NAME
+ style = build_rule(sel, text_align='right')
+ sel += ' > div '
+ style += build_rule(sel, display='inline-flex', pointer_events='auto', background_color=get_color('window-background'), padding='1ex')
+ return style
+)
+
+
class SearchOverlay:
def __init__(self, view):
self.view = view
+ c = self.container
+ c.classList.add(CLASS_NAME)
+ next_button = E.div(class_='simple-link', svgicon('chevron-down'), title=_('Next match'))
+ prev_button = E.div(class_='simple-link', svgicon('chevron-up'), title=_('Previous match'))
+ prev_button.addEventListener('click', def(ev): self.find_previous();)
+ # We cannot use simple link for the close button as it causes the
+ # button to remain red when the search panel is re-opened
+ close_button = E.div(style='cursor:pointer', svgicon('close'), title=_('Close search bar'))
+ close_button.addEventListener('click', def(ev): window.setTimeout(self.hide, 0);)
+ c.appendChild(E.div(
+ svgicon('search'), '\xa0',
+ create_search_bar(self.find_next, 'search-in-book', placeholder=_('Search') + '…', button=next_button, associated_widgets=[prev_button, close_button]),
+ '\xa0', next_button, '\xa0', prev_button, '\xa0', close_button
+ ))
+ c.firstChild.addEventListener('keydown', self.onkeydown)
+
+ def onkeydown(self, event):
+ k = get_key(event)
+ if k is 'escape':
+ self.hide()
+ event.preventDefault(), event.stopPropagation()
@property
def container(self):
@@ -13,3 +52,14 @@ class SearchOverlay:
def hide(self):
self.container.style.display = 'none'
+
+ def show(self):
+ c = self.container
+ c.style.display = 'block'
+ c.querySelector('input').focus()
+
+ def find_next(self):
+ pass
+
+ def find_previous(self):
+ pass
diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj
index 4a5384de0b..374e3b9420 100644
--- a/src/pyj/read_book/view.pyj
+++ b/src/pyj/read_book/view.pyj
@@ -68,7 +68,7 @@ class View:
E.div(style='height:{}px; width:100%; padding: 0'.format(sd.get('margin_bottom', 20)), id='book-bottom-margin'),
),
right_margin,
- E.div(style='position: absolute; top:0; left:0; width: 100%; display:none', id='book-search-overlay'), # search overlay
+ E.div(style='position: absolute; top:0; left:0; width: 100%; pointer-events:none; display:none', id='book-search-overlay'), # search overlay
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='book-overlay'), # main overlay
)
)
@@ -127,6 +127,10 @@ class View:
self.search_overlay.hide()
self.overlay.show()
+ def show_search(self):
+ self.overlay.hide()
+ self.search_overlay.show()
+
def set_margins(self):
no_margins = self.currently_showing.name is self.book.manifest.title_page_name
sd = get_session_data()