[gedit-plugins] [commander] Use overlay for entry
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit-plugins] [commander] Use overlay for entry
- Date: Thu, 4 Sep 2014 16:59:17 +0000 (UTC)
commit 48a9b7c453eefe367bae75bb14c6699361a10d23
Author: Jesse van den Kieboom <jessevdk gmail com>
Date: Thu Sep 4 15:06:40 2014 +0200
[commander] Use overlay for entry
plugins/commander/commander/entry.py | 346 ++++++++++++----------
plugins/commander/commander/info.py | 7 +-
plugins/commander/commander/windowactivatable.py | 2 +-
3 files changed, 193 insertions(+), 162 deletions(-)
---
diff --git a/plugins/commander/commander/entry.py b/plugins/commander/commander/entry.py
index faf27b4..710fb70 100644
--- a/plugins/commander/commander/entry.py
+++ b/plugins/commander/commander/entry.py
@@ -40,25 +40,49 @@ from info import Info
from xml.sax import saxutils
import traceback
-class Entry(Gtk.EventBox):
+class Entry(Gtk.Box):
__gtype_name__ = "CommanderEntry"
+ def remove(self):
+ self._reveal.set_reveal_child(False)
+
def __init__(self, view):
- Gtk.EventBox.__init__(self)
+ Gtk.Box.__init__(self)
+
self._view = view
- self.set_visible_window(False)
+ self._history = History(os.path.join(GLib.get_user_config_dir(), 'gedit/commander/history'))
+ self._history_prefix = None
- hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 3)
- hbox.show()
- hbox.set_border_width(3)
+ self._prompt_text = None
+ self._accel_group = None
- # context for the view
- self._entry = Gtk.Entry()
- self._entry.set_has_frame(False)
- self._entry.set_name('gedit-commander-entry')
- self._entry.show()
+ self._wait_timeout = 0
+ self._info_window = None
+
+ self._suspended = None
+
+ self._handlers = [
+ [0, Gdk.KEY_Up, self._on_history_move, -1],
+ [0, Gdk.KEY_Down, self._on_history_move, 1],
+ [None, Gdk.KEY_Return, self._on_execute, None],
+ [None, Gdk.KEY_KP_Enter, self._on_execute, None],
+ [0, Gdk.KEY_Tab, self._on_complete, None],
+ [0, Gdk.KEY_ISO_Left_Tab, self._on_complete, None]
+ ]
+
+ self._re_complete = re.compile('("((?:\\\\"|[^"])*)"?|\'((?:\\\\\'|[^\'])*)\'?|[^\s]+)')
+ self._command_state = commands.Commands.State()
+ self._build_ui()
+ self._setup_keybindings()
+
+ self._attach()
+
+ def view(self):
+ return self._view
+
+ def _setup_keybindings(self):
css = Gtk.CssProvider()
css.load_from_data(bytes("""
@binding-set terminal-like-bindings {
@@ -85,125 +109,144 @@ GtkEntry#gedit-commander-entry {
}
""", 'utf-8'))
- # FIXME: remove hardcopy of 600 (GTK_STYLE_PROVIDER_PRIORITY_APPLICATION)
- # https://bugzilla.gnome.org/show_bug.cgi?id=646860
- self._entry.get_style_context().add_provider(css, 600)
+ self._entry.get_style_context().add_provider(css, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
- self._prompt_label = Gtk.Label(label='<b>>>></b>', use_markup=True)
- self._prompt_label.show()
+ def _find_overlay(self, view):
+ parent = view.get_parent()
- self._entry.connect('focus-out-event', self.on_entry_focus_out)
- self._entry.connect('key-press-event', self.on_entry_key_press)
+ while not isinstance(parent, Gtk.Overlay):
+ parent = parent.get_parent()
- self._history = History(os.path.join(GLib.get_user_config_dir(), 'gedit/commander/history'))
- self._prompt = None
+ return parent
- self._accel_group = None
+ def _build_ui(self):
+ self.set_orientation(Gtk.Orientation.HORIZONTAL)
+ self.set_spacing(6)
- hbox.pack_start(self._prompt_label, False, False, 0)
- hbox.pack_start(self._entry, True, True, 0)
+ self._overlay = self._find_overlay(self._view)
- self.copy_style_from_view()
- self.view_style_updated_id = self._view.connect('style-updated', self.on_view_style_updated)
+ self._prompt_label = Gtk.Label(label='<b>>>></b>', use_markup=True)
+ self._prompt_label.set_margin_top(3)
+ self._prompt_label.set_margin_bottom(3)
+ self._prompt_label.set_margin_start(3)
- self.add(hbox)
- self.attach()
- self._entry.grab_focus()
+ self._prompt_label.show()
+ self.add(self._prompt_label)
- self._wait_timeout = 0
- self._info_window = None
+ self._entry = Gtk.Entry()
+ self._entry.set_has_frame(False)
+ self._entry.set_name('gedit-commander-entry')
+ self._entry.set_hexpand(True)
+ self._entry.set_margin_top(3)
+ self._entry.set_margin_bottom(3)
+ self._entry.set_margin_end(3)
- self.connect('destroy', self.on_destroy)
- self.connect_after('size-allocate', self.on_size_allocate)
- self.view_draw_id = self._view.connect_after('draw', self.on_draw)
+ self._entry.connect('focus-out-event', self._on_entry_focus_out)
+ self._entry.connect('key-press-event', self._on_entry_key_press)
- self._history_prefix = None
- self._suspended = None
- self._handlers = [
- [0, Gdk.KEY_Up, self.on_history_move, -1],
- [0, Gdk.KEY_Down, self.on_history_move, 1],
- [None, Gdk.KEY_Return, self.on_execute, None],
- [None, Gdk.KEY_KP_Enter, self.on_execute, None],
- [0, Gdk.KEY_Tab, self.on_complete, None],
- [0, Gdk.KEY_ISO_Left_Tab, self.on_complete, None]
- ]
+ self._entry.show()
+ self.add(self._entry)
- self._re_complete = re.compile('("((?:\\\\"|[^"])*)"?|\'((?:\\\\\'|[^\'])*)\'?|[^\s]+)')
- self._command_state = commands.Commands.State()
+ self._copy_style_from_view()
+ self._view_style_updated_id = self._view.connect('style-updated', self._on_view_style_updated)
- def on_view_style_updated(self, widget):
- self.copy_style_from_view()
+ def _on_view_style_updated(self, widget):
+ self._copy_style_from_view()
- def get_border_color(self):
- color = self.get_background_color().copy()
- color.red = 1 - color.red
- color.green = 1 - color.green
- color.blue = 1 - color.blue
- color.alpha = 0.5
+ @property
+ def _border_color(self):
+ style = self._view.get_buffer().get_style_scheme().get_style('right-margin')
+
+ if style.props.foreground_set:
+ color = Gdk.RGBA()
+ color.parse(style.props.foreground)
+ else:
+ color = self.background_color.copy()
+ color.red = 1 - color.red
+ color.green = 1 - color.green
+ color.blue = 1 - color.blue
+ color.alpha = 0.5
return color
- def get_background_color(self):
+ @property
+ def background_color(self):
context = self._view.get_style_context()
- return context.get_background_color(Gtk.StateFlags.NORMAL)
-
- def get_foreground_color(self):
+
+ context.save()
+
+ context.add_class('bottom')
+ ret = context.get_background_color(Gtk.StateFlags.NORMAL)
+
+ context.restore()
+
+ return ret
+
+ @property
+ def foreground_color(self):
context = self._view.get_style_context()
- return context.get_color(Gtk.StateFlags.NORMAL)
- def get_font(self):
+ context.save()
+
+ context.add_class('bottom')
+ ret = context.get_color(Gtk.StateFlags.NORMAL)
+
+ context.restore()
+
+ return ret
+
+ @property
+ def font(self):
context = self._view.get_style_context()
return context.get_font(Gtk.StateFlags.NORMAL)
- def copy_style_from_view(self, widget=None):
- if widget != None:
- context = self._view.get_style_context()
- font = context.get_font(Gtk.StateFlags.NORMAL)
+ def _copy_style_from_view(self):
+ font = self.font
+ fg = self.foreground_color
+ bg = self.background_color
- widget.override_color(Gtk.StateFlags.NORMAL, self.get_foreground_color())
- widget.override_font(self.get_font())
- else:
- if self._entry:
- self.copy_style_from_view(self._entry)
+ cursor = Gdk.RGBA.from_color(self._view.style_get_property('cursor-color'))
+ second = Gdk.RGBA.from_color(self._view.style_get_property('secondary-cursor-color'))
- if self._prompt_label:
- self.copy_style_from_view(self._prompt_label)
+ for widget in (self, self._entry, self._prompt_label):
+ widget.override_color(Gtk.StateFlags.NORMAL, fg)
+ widget.override_color(Gtk.StateFlags.SELECTED, bg)
- def view(self):
- return self._view
+ widget.override_background_color(Gtk.StateFlags.NORMAL, bg)
+ widget.override_background_color(Gtk.StateFlags.SELECTED, fg)
- def on_size_allocate(self, widget, alloc):
- alloc = self.get_allocation()
- self._view.set_border_window_size(Gtk.TextWindowType.BOTTOM, alloc.height)
+ widget.override_font(font)
+ widget.override_cursor(cursor, second)
- win = self._view.get_window(Gtk.TextWindowType.BOTTOM)
- self.set_size_request(win.get_width(), -1)
+ def _attach(self):
+ reveal = Gtk.Revealer()
+ reveal.add(self)
+ self.show()
- # NOTE: we need to do this explicitly somehow, otherwise the window
- # size will not be updated unless something else happens, not exactly
- # sure what. This might be caused by the multi notebook, or custom
- # animation layouting?
- self._view.get_parent().resize_children()
+ reveal.set_transition_type(Gtk.RevealerTransitionType.SLIDE_UP)
+ reveal.set_transition_duration(200)
- def attach(self):
- # Attach ourselves in the text view, and position just above the
- # text window
- win = self._view.get_window(Gtk.TextWindowType.TEXT)
- alloc = self.get_allocation()
+ reveal.set_valign(Gtk.Align.END)
+ reveal.set_halign(Gtk.Align.FILL)
- self._view.set_border_window_size(Gtk.TextWindowType.BOTTOM, max(alloc.height, 1))
- self._view.add_child_in_window(self, Gtk.TextWindowType.BOTTOM, 0, 0)
+ self._overlay.add_overlay(reveal)
+ reveal.show()
- win = self._view.get_window(Gtk.TextWindowType.BOTTOM)
+ reveal.set_reveal_child(True)
+ self._reveal = reveal
- self.show()
- self.set_size_request(win.get_width(), -1)
+ reveal.connect('notify::child-revealed', self._on_child_revealed)
+ self._entry.grab_focus()
- def on_entry_focus_out(self, widget, evnt):
- if self._entry.get_sensitive():
+ def _on_child_revealed(self, widget, spec):
+ if not self._reveal.get_child_revealed():
self.destroy()
- def on_entry_key_press(self, widget, evnt):
+ def _on_entry_focus_out(self, widget, evnt):
+ if self._entry.get_sensitive():
+ self._reveal.set_reveal_child(False)
+
+ def _on_entry_key_press(self, widget, evnt):
state = evnt.state & Gtk.accelerator_get_default_mod_mask()
text = self._entry.get_text()
@@ -223,15 +266,15 @@ GtkEntry#gedit-commander-entry {
self._entry.set_editable(True)
self._accel_group = None
- self.prompt()
+ self._prompt()
elif text:
self._entry.set_text('')
elif self._command_state:
self._command_state.clear()
- self.prompt()
+ self._prompt()
else:
self._view.grab_focus()
- self.destroy()
+ self._reveal.set_reveal_child(False)
return True
@@ -248,12 +291,12 @@ GtkEntry#gedit-commander-entry {
self._accel_group = accel
self._entry.set_text('')
self._entry.set_editable(False)
- self.prompt()
+ self._prompt()
return True
elif isinstance(accel, commands.accel_group.AccelCallback):
self._entry.set_editable(True)
- self.run_command(lambda: accel.activate(self._command_state, self))
+ self._run_command(lambda: accel.activate(self._command_state, self))
return True
if not self._entry.get_editable():
@@ -269,7 +312,7 @@ GtkEntry#gedit-commander-entry {
self._history_prefix = None
return False
- def on_history_move(self, direction, modifier):
+ def _on_history_move(self, direction, modifier):
pos = self._entry.get_position()
self._history.update(self._entry.get_text())
@@ -293,8 +336,8 @@ GtkEntry#gedit-commander-entry {
return True
- def prompt(self, pr=''):
- self._prompt = pr
+ def _prompt(self, pr=''):
+ self._prompt_text = pr
if self._accel_group != None:
pr = '<i>%s</i>' % (saxutils.escape(self._accel_group.full_name()),)
@@ -306,34 +349,34 @@ GtkEntry#gedit-commander-entry {
self._prompt_label.set_markup('<b>>>></b>%s' % pr)
- def make_info(self):
+ def _make_info(self):
if self._info_window == None:
self._info_window = Info(self)
self._info_window.show()
- self._info_window.connect('destroy', self.on_info_window_destroy)
+ self._info_window.connect('destroy', self._on_info_window_destroy)
- def on_info_window_destroy(self, widget):
+ def _on_info_window_destroy(self, widget):
self._info_window = None
def info_show(self, text='', use_markup=False):
- self.make_info()
+ self._make_info()
self._info_window.add_lines(text, use_markup)
def info_status(self, text):
- self.make_info()
+ self._make_info()
self._info_window.status(text)
- def info_add_action(self, stock, callback, data=None):
- self.make_info()
+ def _info_add_action(self, stock, callback, data=None):
+ self._make_info()
return self._info_window.add_action(stock, callback, data)
- def command_history_done(self):
+ def _command_history_done(self):
self._history.add(self._entry.get_text())
self._history_prefix = None
self._entry.set_text('')
- def on_wait_cancel(self):
+ def _on_wait_cancel(self):
if self._suspended:
self._suspended.resume()
@@ -346,7 +389,7 @@ GtkEntry#gedit-commander-entry {
self._entry.set_sensitive(True)
def _show_wait_cancel(self):
- self._cancel_button = self.info_add_action(Gtk.STOCK_STOP, self.on_wait_cancel)
+ self._cancel_button = self._info_add_action(Gtk.STOCK_STOP, self._on_wait_cancel)
self.info_status('<i>Waiting to finish...</i>')
self._wait_timeout = 0
@@ -357,7 +400,7 @@ GtkEntry#gedit-commander-entry {
if match.group(i) != None:
return [match.group(i), match.start(i), match.end(i)]
- def on_suspend_resume(self):
+ def _on_suspend_resume(self):
if self._wait_timeout:
GLib.source_remove(self._wait_timeout)
self._wait_timeout = 0
@@ -367,40 +410,29 @@ GtkEntry#gedit-commander-entry {
self.info_status(None)
self._entry.set_sensitive(True)
- self.command_history_done()
+ self._command_history_done()
if self._entry.props.has_focus or (self._info_window and not self._info_window.empty()):
self._entry.grab_focus()
- self.on_execute(None, 0)
-
- def ellipsize(self, s, size):
- if len(s) <= size:
- return s
-
- mid = (size - 4) / 2
- return s[:mid] + '...' + s[-mid:]
+ self._on_execute(None, 0)
- def destroy(self):
- self.hide()
- Gtk.EventBox.destroy(self)
-
- def run_command(self, cb):
+ def _run_command(self, cb):
self._suspended = None
try:
ret = cb()
except Exception as e:
- self.command_history_done()
+ self._command_history_done()
self._command_state.clear()
- self.prompt()
+ self._prompt()
# Show error in info
self.info_show('<b><span color="#f66">Error:</span></b> ' + saxutils.escape(str(e)), True)
if not isinstance(e, commands.exceptions.Execute):
- self.info_show(self.format_trace(), False)
+ self.info_show(self._format_trace(), False)
return None
@@ -409,26 +441,26 @@ GtkEntry#gedit-commander-entry {
if ret == mod.Result.SUSPEND:
# Wait for it...
self._suspended = ret
- ret.register(self.on_suspend_resume)
+ ret.register(self._on_suspend_resume)
self._wait_timeout = GLib.timeout_add(500, self._show_wait_cancel)
self._entry.set_sensitive(False)
else:
- self.command_history_done()
- self.prompt('')
+ self._command_history_done()
+ self._prompt('')
if ret == mod.Result.PROMPT:
- self.prompt(ret.prompt)
- elif (ret == None or ret == mod.HIDE) and not self._prompt and (not self._info_window or
self._info_window.empty()):
+ self._prompt(ret.prompt)
+ elif (ret == None or ret == mod.HIDE) and not self._prompt_text and (not self._info_window or
self._info_window.empty()):
self._command_state.clear()
self._view.grab_focus()
- self.destroy()
+ self._reveal.set_reveal_child(False)
else:
self._entry.grab_focus()
return ret
- def format_trace(self):
+ def _format_trace(self):
tp, val, tb = sys.exc_info()
origtb = tb
@@ -455,7 +487,7 @@ GtkEntry#gedit-commander-entry {
return r
- def on_execute(self, dummy, modifier):
+ def _on_execute(self, dummy, modifier):
if self._info_window and not self._suspended:
self._info_window.destroy()
@@ -471,11 +503,11 @@ GtkEntry#gedit-commander-entry {
self._entry.set_text('')
return
- self.run_command(lambda: commands.Commands().execute(self._command_state, text, words, wordsstr,
self, modifier))
+ self._run_command(lambda: commands.Commands().execute(self._command_state, text, words, wordsstr,
self, modifier))
return True
- def on_complete(self, dummy, modifier):
+ def _on_complete(self, dummy, modifier):
# First split all the text in words
text = self._entry.get_text()
pos = self._entry.get_position()
@@ -650,32 +682,30 @@ GtkEntry#gedit-commander-entry {
return True
- def on_draw(self, widget, ct):
- win = widget.get_window(Gtk.TextWindowType.BOTTOM)
-
- if not Gtk.cairo_should_draw_window(ct, win):
- return False
+ def do_draw(self, ctx):
+ ret = Gtk.Box.do_draw(self, ctx)
- Gtk.cairo_transform_to_window(ct, widget, win)
+ col = self._border_color
- color = self.get_border_color()
- width = win.get_width()
+ ctx.set_line_width(1)
+ ctx.set_source_rgba(col.red, col.green, col.blue, col.alpha)
- ct.set_source_rgba(color.red, color.green, color.blue, color.alpha)
- ct.move_to(0, 0)
- ct.line_to(width, 0)
- ct.stroke()
+ ctx.move_to(0, 0)
+ ctx.line_to(self.get_allocated_width(), 0)
+ ctx.stroke()
- return False
+ return ret
- def on_destroy(self, widget):
- self._view.set_border_window_size(Gtk.TextWindowType.BOTTOM, 0)
- self._view.disconnect(self.view_style_updated_id)
- self._view.disconnect(self.view_draw_id)
+ def do_destroy(self):
+ self._view.disconnect(self._view_style_updated_id)
if self._info_window:
self._info_window.destroy()
self._history.save()
+ self._view = None
+
+ Gtk.Box.do_destroy(self)
+
# vi:ex:ts=4:et
diff --git a/plugins/commander/commander/info.py b/plugins/commander/commander/info.py
index 569e339..02a20f0 100644
--- a/plugins/commander/commander/info.py
+++ b/plugins/commander/commander/info.py
@@ -45,9 +45,9 @@ class Info(TransparentWindow):
self._text = Gtk.TextView()
- font = self._entry.get_font()
- fgcolor = self._entry.get_foreground_color()
- bgcolor = self.background_color()
+ font = self._entry.font
+ fgcolor = self._entry.foreground_color
+ bgcolor = self.background_color
self._text.override_font(font)
self._text.override_color(Gtk.StateFlags.NORMAL, fgcolor)
@@ -345,6 +345,7 @@ class Info(TransparentWindow):
ct.line_to(w - 0.5, h)
+ @property
def background_color(self):
color = self._entry.get_background_color().copy()
color.alpha = 0.9
diff --git a/plugins/commander/commander/windowactivatable.py
b/plugins/commander/commander/windowactivatable.py
index a064cf9..915a94c 100644
--- a/plugins/commander/commander/windowactivatable.py
+++ b/plugins/commander/commander/windowactivatable.py
@@ -71,7 +71,7 @@ class CommanderWindowActivatable(GObject.Object, Gedit.WindowActivatable):
self._entry.grab_focus()
self._view = view
elif self._entry:
- self._entry.destroy()
+ self._entry.remove()
self._view = None
action.set_state(GLib.Variant.new_boolean(active))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]