Mark partial hint matches

This commit is contained in:
Florian Bruhin 2014-04-21 15:45:29 +02:00
parent d7b87e09c9
commit c2aa9517ea
2 changed files with 35 additions and 14 deletions

View File

@ -18,6 +18,7 @@
"""A HintManager to draw hints over links.""" """A HintManager to draw hints over links."""
import math import math
from collections import namedtuple
from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtCore import pyqtSignal, QObject
@ -25,6 +26,9 @@ import qutebrowser.config.config as config
from qutebrowser.utils.keyparser import KeyParser from qutebrowser.utils.keyparser import KeyParser
ElemTuple = namedtuple('ElemTuple', 'elem, label')
class HintKeyParser(KeyParser): class HintKeyParser(KeyParser):
"""KeyParser for hints. """KeyParser for hints.
@ -63,8 +67,7 @@ class HintManager(QObject):
Attributes: Attributes:
_frame: The QWebFrame to use. _frame: The QWebFrame to use.
_elems: The elements we're hinting currently. _elems: A mapping from keystrings to (elem, label) namedtuples.
_labels: The label elements.
Signals: Signals:
hint_strings_updated: Emitted when the possible hint strings changed. hint_strings_updated: Emitted when the possible hint strings changed.
@ -106,8 +109,7 @@ class HintManager(QObject):
""" """
super().__init__(frame) super().__init__(frame)
self._frame = frame self._frame = frame
self._elems = [] self._elems = {}
self._labels = []
def _hint_strings(self, elems): def _hint_strings(self, elems):
"""Calculate the hint strings for elems. """Calculate the hint strings for elems.
@ -204,6 +206,9 @@ class HintManager(QObject):
Args: Args:
elem: The QWebElement to use. elem: The QWebElement to use.
string: The hint string to print. string: The hint string to print.
Return:
The newly created label elment
""" """
rect = elem.geometry() rect = elem.geometry()
css = HintManager.HINT_CSS.format(left=rect.x(), top=rect.y(), css = HintManager.HINT_CSS.format(left=rect.x(), top=rect.y(),
@ -211,7 +216,7 @@ class HintManager(QObject):
doc = self._frame.documentElement() doc = self._frame.documentElement()
doc.appendInside('<span class="qutehint" style="{}">{}</span>'.format( doc.appendInside('<span class="qutehint" style="{}">{}</span>'.format(
css, string)) css, string))
self._labels.append(doc.lastChild()) return doc.lastChild()
def start(self, mode="all"): def start(self, mode="all"):
"""Start hinting. """Start hinting.
@ -221,6 +226,7 @@ class HintManager(QObject):
""" """
selector = HintManager.SELECTORS[mode] selector = HintManager.SELECTORS[mode]
elems = self._frame.findAllElements(selector) elems = self._frame.findAllElements(selector)
visible_elems = []
for e in elems: for e in elems:
rect = e.geometry() rect = e.geometry()
if (not rect.isValid()) and rect.x() == 0: if (not rect.isValid()) and rect.x() == 0:
@ -231,24 +237,35 @@ class HintManager(QObject):
if not framegeom.contains(rect): if not framegeom.contains(rect):
# out of screen # out of screen
continue continue
self._elems.append(e) visible_elems.append(e)
strings = self._hint_strings(self._elems) strings = self._hint_strings(visible_elems)
for e, string in zip(self._elems, strings): for e, string in zip(visible_elems, strings):
self._draw_label(e, string) label = self._draw_label(e, string)
self._elems[string] = ElemTuple(e, label)
self.hint_strings_updated.emit(strings) self.hint_strings_updated.emit(strings)
self.set_mode.emit("hint") self.set_mode.emit("hint")
def stop(self): def stop(self):
"""Stop hinting.""" """Stop hinting."""
for e in self._labels: for elem in self._elems:
e.removeFromDocument() elem.label.removeFromDocument()
self._elems = None self._elems = {}
self._labels = []
self.set_mode.emit("normal") self.set_mode.emit("normal")
def handle_partial_key(self, keystr): def handle_partial_key(self, keystr):
"""Handle a new partial keypress.""" """Handle a new partial keypress."""
raise NotImplementedError delete = []
for (string, elems) in self._elems.items():
if string.startswith(keystr):
matched = string[:len(keystr)]
rest = string[len(keystr):]
elems.label.setInnerXml('<font color="{}">{}</font>{}'.format(
config.get("colors", "hints.fg.match"), matched, rest))
else:
elems.label.removeFromDocument()
delete.append(string)
for key in delete:
del self._elems[key]
def fire(self, keystr): def fire(self, keystr):
"""Fire a completed hint.""" """Fire a completed hint."""

View File

@ -478,6 +478,10 @@ DATA = OrderedDict([
SettingValue(types.CssColor, "black"), SettingValue(types.CssColor, "black"),
"Font color for hints."), "Font color for hints."),
('hints.fg.match',
SettingValue(types.CssColor, "green"),
"Font color for the matched part of hints."),
('hints.bg', ('hints.bg',
SettingValue(types.CssColor, "-webkit-gradient(linear, left top, " SettingValue(types.CssColor, "-webkit-gradient(linear, left top, "
"left bottom, color-stop(0%,#FFF785), " "left bottom, color-stop(0%,#FFF785), "