[meld] Use gtkrc-set symbolic colours for most drawing
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] Use gtkrc-set symbolic colours for most drawing
- Date: Tue, 4 Sep 2012 20:32:10 +0000 (UTC)
commit 4c909343e2d384bc28f0241e2dc732a3ccec1e3f
Author: Kai Willadsen <kai willadsen gmail com>
Date: Mon Jan 2 06:48:37 2012 +1000
Use gtkrc-set symbolic colours for most drawing
This patch series moves Meld towards retreiving drawing colours from
a gtkrc set rather than from our preferences. This change should improve
themeability over the long term, though there may be some regressions.
While gtkrc is not GTK3-friendly, this should also make it somewhat
easier to forward port to the new themeing mechanics.
Treeview colours are still hard-coded.
Makefile | 2 +
bin/meld | 1 +
data/gtkrc | 18 +++++++++++
meld/diffmap.py | 16 +++++-----
meld/dirdiff.py | 40 ++++++++++++++++++------
meld/filediff.py | 85 +++++++++++++++++++++++++++-----------------------
meld/linkmap.py | 4 +-
meld/meldwindow.py | 1 +
meld/misc.py | 3 ++
meld/paths.py | 6 +++
meld/preferences.py | 5 ---
11 files changed, 117 insertions(+), 64 deletions(-)
---
diff --git a/Makefile b/Makefile
index 2dd6e7a..6cb6b9f 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,8 @@ install: $(addsuffix .install,$(SPECIALS)) meld.desktop
$(DESTDIR)$(sharedir)/applications
$(PYTHON) -c 'import compileall; compileall.compile_dir("$(DESTDIR)$(libdir_)",10,"$(libdir_)")'
$(PYTHON) -O -c 'import compileall; compileall.compile_dir("$(DESTDIR)$(libdir_)",10,"$(libdir_)")'
+ install -m 644 data/gtkrc \
+ $(DESTDIR)$(sharedir_)
install -m 644 \
data/ui/*.ui \
$(DESTDIR)$(sharedir_)/ui
diff --git a/bin/meld b/bin/meld
index 6cb7a7b..07fa0ea 100755
--- a/bin/meld
+++ b/bin/meld
@@ -130,6 +130,7 @@ except (ImportError, AssertionError) as e:
gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
+gtk.rc_parse(meld.paths.share_dir("gtkrc"))
def main():
import meld.meldapp
diff --git a/data/gtkrc b/data/gtkrc
new file mode 100644
index 0000000..78d845f
--- /dev/null
+++ b/data/gtkrc
@@ -0,0 +1,18 @@
+
+style "meld-color-scheme"
+{
+ color["insert-bg"] = "DarkSeaGreen1"
+ color["insert-outline"] = shade(0.8, @insert-bg)
+ color["delete-bg"] = "White"
+ color["delete-outline"] = shade(0.8, @delete-bg)
+ color["replace-bg"] = "#ddeeff"
+ color["replace-outline"] = shade(0.8, @replace-bg)
+ color["conflict-bg"] = "Pink"
+ color["conflict-outline"] = shade(0.8, @conflict-bg)
+ color["error-bg"] = "#fce94f"
+ color["error-outline"] = shade(0.8, @error-bg)
+ color["inline-bg"] = "LightSteelBlue2"
+ color["inline-fg"] = "Red"
+ color["current-line-highlight"] = "#ffff00"
+}
+widget "meldapp.*" style : lowest "meld-color-scheme"
diff --git a/meld/diffmap.py b/meld/diffmap.py
index 609138b..403690d 100644
--- a/meld/diffmap.py
+++ b/meld/diffmap.py
@@ -41,9 +41,8 @@ class DiffMap(gtk.DrawingArea):
self._h_offset = 0
self._scroll_y = 0
self._scroll_height = 0
- self.ctab = {}
- def setup(self, scrollbar, change_chunk_fn, colour_map):
+ def setup(self, scrollbar, change_chunk_fn, color_map):
for (o, h) in self._handlers:
o.disconnect(h)
@@ -63,7 +62,11 @@ class DiffMap(gtk.DrawingArea):
(self._scrolladj, adj_change_hid),
(self._scrolladj, adj_val_hid)]
self._difffunc = change_chunk_fn
- self.ctab = colour_map
+ self.set_color_scheme(color_map)
+ self.queue_draw()
+
+ def set_color_scheme(self, color_map):
+ self.fill_colors, self.line_colors = color_map
self.queue_draw()
def on_scrollbar_style_set(self, scrollbar, previous_style):
@@ -102,20 +105,17 @@ class DiffMap(gtk.DrawingArea):
context.rectangle(x0 - 3, -1, x1 + 6, height + 1)
context.clip()
- darken = lambda color: [x * 0.8 for x in color]
-
tagged_diffs = collections.defaultdict(list)
for c, y0, y1 in self._difffunc():
tagged_diffs[c].append((y0, y1))
for tag, diffs in tagged_diffs.iteritems():
- color = self.ctab[tag]
- context.set_source_rgb(*color)
+ context.set_source_color(self.fill_colors[tag])
for y0, y1 in diffs:
y0, y1 = round(y0 * height) - 0.5, round(y1 * height) - 0.5
context.rectangle(x0, y0, x1, y1 - y0)
context.fill_preserve()
- context.set_source_rgb(*darken(color))
+ context.set_source_color(self.line_colors[tag])
context.stroke()
page_color = (0., 0., 0., 0.1)
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index 04e87b4..556315e 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -212,7 +212,6 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
tree.STATE_ERROR: "error",
tree.STATE_EMPTY: None,
tree.STATE_MODIFIED: "replace",
- tree.STATE_CONFLICT: "conflict",
tree.STATE_MISSING: "delete",
}
@@ -263,6 +262,10 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
self.map_widgets_into_lists(["treeview", "fileentry", "scrolledwindow",
"diffmap", "linkmap", "msgarea_mgr",
"vbox"])
+
+ self.widget.connect("style-set", self.on_style_set)
+ self.widget.ensure_style()
+
self.set_num_panes(num_panes)
self.focus_in_events = []
self.focus_out_events = []
@@ -300,6 +303,31 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
action_name = self.state_actions[s][1]
self.actiongroup.get_action(action_name).set_active(True)
+ def on_style_set(self, widget, prev_style):
+ style = widget.get_style()
+
+ lookup = lambda color_id, default: style.lookup_color(color_id) or \
+ gtk.gdk.color_parse(default)
+
+ self.fill_colors = {"insert" : lookup("insert-bg", "DarkSeaGreen1"),
+ "delete" : lookup("delete-bg", "White"),
+ "replace" : lookup("replace-bg", "#ddeeff"),
+ "error" : lookup("error-bg", "#fce94f")}
+ self.line_colors = {"insert" : lookup("insert-outline", "#77f077"),
+ "delete" : lookup("delete-outline", "Grey"),
+ "replace" : lookup("replace-outline", "#8bbff3"),
+ "error" : lookup("error-outline", "#edd400")}
+
+ for diffmap in self.diffmap:
+ diffmap.set_color_scheme([self.fill_colors, self.line_colors])
+ self.queue_draw()
+
+ def queue_draw(self):
+ for treeview in self.treeview:
+ treeview.queue_draw()
+ for diffmap in self.diffmap:
+ diffmap.queue_draw()
+
def on_custom_filter_menu_toggled(self, item):
if item.get_active():
self.custom_popup.connect("deactivate",
@@ -1087,18 +1115,10 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
self.treeview[i].set_model(self.model)
self.model.connect("row-deleted", self.on_treemodel_row_deleted)
- colour_map = {
- "conflict": (1.0, 0.75294117647058822, 0.79607843137254897),
- "error": (0.9882352941176, 0.9137254901960, 0.30980392156862),
- "insert": (0.75686274509803919, 1.0, 0.75686274509803919),
- "replace": (0.8666666666666667, 0.93333333333333335, 1.0),
- "delete": (1.0, 1.0, 1.0),
- }
-
for (w, i) in zip(self.diffmap, (0, n - 1)):
scroll = self.scrolledwindow[i].get_vscrollbar()
idx = 1 if i else 0
- w.setup(scroll, self.get_state_traversal(idx), colour_map)
+ w.setup(scroll, self.get_state_traversal(idx), [self.fill_colors, self.line_colors])
toshow = self.scrolledwindow[:n] + self.fileentry[:n]
toshow += self.linkmap[:n-1] + self.diffmap[:n]
diff --git a/meld/filediff.py b/meld/filediff.py
index 1c2724d..f04a3ee 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -178,28 +178,10 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
self.in_nested_textview_gutter_expose = False
self._inline_cache = set()
self._cached_match = CachedSequenceMatcher()
- self.anim_source_id = []
- self.animating_chunks = []
+ self.anim_source_id = [None for buf in self.textbuffer]
+ self.animating_chunks = [[] for buf in self.textbuffer]
for buf in self.textbuffer:
- buf.create_tag("inline", background=self.prefs.color_inline_bg,
- foreground=self.prefs.color_inline_fg)
- self.anim_source_id.append(None)
- self.animating_chunks.append([])
-
- def parse_to_cairo(color_spec):
- c = gtk.gdk.color_parse(color_spec)
- return tuple([x / 65535. for x in (c.red, c.green, c.blue)])
-
- self.fill_colors = {"insert" : parse_to_cairo(self.prefs.color_delete_bg),
- "delete" : parse_to_cairo(self.prefs.color_delete_bg),
- "conflict" : parse_to_cairo(self.prefs.color_conflict_bg),
- "replace" : parse_to_cairo(self.prefs.color_replace_bg)}
-
- darken = lambda color: tuple([x * 0.8 for x in color])
- self.line_colors = {"insert" : darken(self.fill_colors["insert"]),
- "delete" : darken(self.fill_colors["delete"]),
- "conflict" : darken(self.fill_colors["conflict"]),
- "replace" : darken(self.fill_colors["replace"])}
+ buf.create_tag("inline")
actions = (
("MakePatch", None, _("Format as patch..."), None, _("Create a patch using differences between files"), self.make_patch),
@@ -233,6 +215,10 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
self.actiongroup.add_actions(actions)
self.actiongroup.add_toggle_actions(toggle_actions)
self.findbar = findbar.FindBar(self.table)
+
+ self.widget.connect("style-set", self.on_style_set)
+ self.widget.ensure_style()
+
self.set_num_panes(num_panes)
gobject.idle_add( lambda *args: self.load_font()) # hack around Bug 316730
gnomeglade.connect_signal_handlers(self)
@@ -258,6 +244,33 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
self.emit("action-mode-changed", mode)
keymask = property(get_keymask, set_keymask)
+ def on_style_set(self, widget, prev_style):
+ style = widget.get_style()
+
+ lookup = lambda color_id, default: style.lookup_color(color_id) or \
+ gtk.gdk.color_parse(default)
+
+ for buf in self.textbuffer:
+ tag = buf.get_tag_table().lookup("inline")
+ tag.props.background = lookup("inline-bg", "LightSteelBlue2")
+ tag.props.foreground = lookup("inline-fg", "Red")
+
+ self.fill_colors = {"insert" : lookup("insert-bg", "DarkSeaGreen1"),
+ "delete" : lookup("insert-bg", "DarkSeaGreen1"),
+ "conflict": lookup("conflict-bg", "Pink"),
+ "replace" : lookup("replace-bg", "#ddeeff")}
+ self.line_colors = {"insert" : lookup("insert-outline", "#77f077"),
+ "delete" : lookup("insert-outline", "#77f077"),
+ "conflict": lookup("conflict-outline", "#f0768b"),
+ "replace" : lookup("replace-outline", "#8bbff3")}
+
+ for diffmap in self.diffmap:
+ diffmap.set_color_scheme([self.fill_colors, self.line_colors])
+
+ self.highlight_color = lookup("highlight-bg", "#ffff00")
+
+ self.queue_draw()
+
def on_focus_change(self):
self.keymask = 0
@@ -1212,21 +1225,22 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
context.rectangle(-0.5, ypos0 - 0.5, width + 1, ypos1 - ypos0)
if change[1] != change[2]:
- context.set_source_rgb(*self.fill_colors[change[0]])
+ context.set_source_color(self.fill_colors[change[0]])
context.fill_preserve()
if self.linediffer.locate_chunk(pane, change[1])[0] == self.cursor.chunk:
context.set_source_rgba(1.0, 1.0, 1.0, 0.5)
context.fill_preserve()
- context.set_source_rgb(*self.line_colors[change[0]])
+ context.set_source_color(self.line_colors[change[0]])
context.stroke()
if textview.is_focus() and self.cursor.line is not None:
it = self.textbuffer[pane].get_iter_at_line(self.cursor.line)
ypos, line_height = self.textview[pane].get_line_yrange(it)
- context.set_source_rgba(1, 1, 0, .25)
context.rectangle(0, ypos - visible.y, width, line_height)
- context.fill()
+ context.clip()
+ context.set_source_color(self.highlight_color)
+ context.paint_with_alpha(0.25)
current_time = glib.get_current_time()
new_anim_chunks = []
@@ -1532,16 +1546,9 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
yield c[0], y0 / max_y, (y + h) / max_y
return coords_by_chunk
- colour_map = {
- "conflict": (1.0, 0.75294117647058822, 0.79607843137254897),
- "insert": (0.75686274509803919, 1.0, 0.75686274509803919),
- "replace": (0.8666666666666667, 0.93333333333333335, 1.0),
- "delete": (0.75686274509803919, 1.0, 0.75686274509803919)
- }
-
for (w, i) in zip(self.diffmap, (0, self.num_panes - 1)):
scroll = self.scrolledwindow[i].get_vscrollbar()
- w.setup(scroll, coords_iter(i), colour_map)
+ w.setup(scroll, coords_iter(i), [self.fill_colors, self.line_colors])
for (w, i) in zip(self.linkmap, (0, self.num_panes - 2)):
w.associate(self, self.textview[i], self.textview[i + 1])
@@ -1599,8 +1606,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
mark1 = b1.create_mark(None, new_end, True)
# FIXME: If the inserted chunk ends up being an insert chunk, then
# this animation is not visible; this happens often in three-way diffs
- rgba0 = self.fill_colors['insert'] + (1.0,)
- rgba1 = self.fill_colors['insert'] + (0.0,)
+ rgba0 = misc.gdk_to_cairo_color(self.fill_colors['insert']) + (1.0,)
+ rgba1 = misc.gdk_to_cairo_color(self.fill_colors['insert']) + (0.0,)
anim = TextviewLineAnimation(mark0, mark1, rgba0, rgba1, 0.5)
self.animating_chunks[dst].append(anim)
@@ -1619,8 +1626,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
mark1 = b1.create_mark(None, new_end, True)
# FIXME: If the inserted chunk ends up being an insert chunk, then
# this animation is not visible; this happens often in three-way diffs
- rgba0 = self.fill_colors['insert'] + (1.0,)
- rgba1 = self.fill_colors['insert'] + (0.0,)
+ rgba0 = misc.gdk_to_cairo_color(self.fill_colors['insert']) + (1.0,)
+ rgba1 = misc.gdk_to_cairo_color(self.fill_colors['insert']) + (0.0,)
anim = TextviewLineAnimation(mark0, mark1, rgba0, rgba1, 0.5)
self.animating_chunks[dst].append(anim)
@@ -1633,8 +1640,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
mark0 = b0.create_mark(None, it, True)
mark1 = b0.create_mark(None, it, True)
# TODO: Need a more specific colour here; conflict is wrong
- rgba0 = self.fill_colors['conflict'] + (1.0,)
- rgba1 = self.fill_colors['conflict'] + (0.0,)
+ rgba0 = misc.gdk_to_cairo_color(self.fill_colors['conflict']) + (1.0,)
+ rgba1 = misc.gdk_to_cairo_color(self.fill_colors['conflict']) + (0.0,)
anim = TextviewLineAnimation(mark0, mark1, rgba0, rgba1, 0.5)
self.animating_chunks[src].append(anim)
diff --git a/meld/linkmap.py b/meld/linkmap.py
index 3c5b9ef..d37f844 100644
--- a/meld/linkmap.py
+++ b/meld/linkmap.py
@@ -213,7 +213,7 @@ class LinkMap(gtk.DrawingArea):
x_steps[0], f1 - 0.5)
context.close_path()
- context.set_source_rgb(*self.fill_colors[c[0]])
+ context.set_source_color(self.fill_colors[c[0]])
context.fill_preserve()
chunk_idx = self.filediff.linediffer.locate_chunk(left, c[1])[0]
@@ -221,7 +221,7 @@ class LinkMap(gtk.DrawingArea):
context.set_source_rgba(1.0, 1.0, 1.0, 0.5)
context.fill_preserve()
- context.set_source_rgb(*self.line_colors[c[0]])
+ context.set_source_color(self.line_colors[c[0]])
context.stroke()
if culled:
diff --git a/meld/meldwindow.py b/meld/meldwindow.py
index 1bffda0..c3263cc 100644
--- a/meld/meldwindow.py
+++ b/meld/meldwindow.py
@@ -126,6 +126,7 @@ class MeldWindow(gnomeglade.Component):
def __init__(self):
gladefile = paths.ui_dir("meldapp.ui")
gnomeglade.Component.__init__(self, gladefile, "meldapp")
+ self.widget.set_name("meldapp")
actions = (
("FileMenu", None, _("_File")),
diff --git a/meld/misc.py b/meld/misc.py
index 05b8dbd..f35bbc2 100644
--- a/meld/misc.py
+++ b/meld/misc.py
@@ -135,6 +135,9 @@ def make_tool_button_widget(label):
hbox.show_all()
return hbox
+def gdk_to_cairo_color(color):
+ return (color.red / 65535., color.green / 65535., color.blue / 65535.)
+
def all_equal(alist):
"""Return true if all members of the list are equal to the first.
diff --git a/meld/paths.py b/meld/paths.py
index ab20ca3..60ae44a 100644
--- a/meld/paths.py
+++ b/meld/paths.py
@@ -35,6 +35,12 @@ def locale_dir(*args): # i18n files
def help_dir(*args): # help
return os.path.join(_help_dir, *args)
+def share_dir(*args):
+ if os.path.exists(os.path.join(_share_dir, "data")):
+ return os.path.join(_share_dir, "data", *args)
+ else:
+ return os.path.join(_share_dir, *args)
+
def ui_dir(*args):
if os.path.exists(os.path.join(_share_dir, "data")):
return os.path.join(_share_dir, "data", "ui", *args)
diff --git a/meld/preferences.py b/meld/preferences.py
index f339858..6d681b8 100644
--- a/meld/preferences.py
+++ b/meld/preferences.py
@@ -223,11 +223,6 @@ class MeldPreferences(prefs.Preferences):
"text_codecs": prefs.Value(prefs.STRING, "utf8 latin1"),
"ignore_symlinks": prefs.Value(prefs.BOOL,0),
"vc_console_visible": prefs.Value(prefs.BOOL, 0),
- "color_delete_bg" : prefs.Value(prefs.STRING, "DarkSeaGreen1"),
- "color_replace_bg" : prefs.Value(prefs.STRING, "#ddeeff"),
- "color_conflict_bg" : prefs.Value(prefs.STRING, "Pink"),
- "color_inline_bg" : prefs.Value(prefs.STRING, "LightSteelBlue2"),
- "color_inline_fg" : prefs.Value(prefs.STRING, "Red"),
"filters" : prefs.Value(prefs.STRING,
#TRANSLATORS: translate this string ONLY to the first "\t", leave it and the following parts intact
_("Backups\t1\t#*# .#* ~* *~ *.{orig,bak,swp}\n") + \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]