summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2012-01-11 16:16:29 +0100
committerhut <hut@lavabit.com>2012-01-11 17:05:57 +0100
commit98bca305d5e053ccd624073e2c2ecac50640106f (patch)
tree27ad408563e3cd942326cb80401c705fda60951a
parent0374f709574d3db79887b86ca4486d65f5eb1c01 (diff)
downloadranger-98bca305d5e053ccd624073e2c2ecac50640106f.tar.gz
gui.colorschemes: more efficient color_at
-rw-r--r--ranger/ext/cached_function.py27
-rw-r--r--ranger/gui/colorscheme.py42
-rw-r--r--ranger/gui/curses_shortcuts.py3
-rw-r--r--ranger/gui/widgets/browsercolumn.py12
-rw-r--r--ranger/gui/widgets/taskview.py12
5 files changed, 56 insertions, 40 deletions
diff --git a/ranger/ext/cached_function.py b/ranger/ext/cached_function.py
new file mode 100644
index 00000000..00068583
--- /dev/null
+++ b/ranger/ext/cached_function.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2012  Roman Zimbelmann <romanz@lavabit.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+def cached_function(fnc):
+  cache = {}
+  def inner_cached_function(self, *args):
+    try:
+      return cache[args]
+    except:
+      value = fnc(self, *args)
+      cache[args] = value
+      return value
+  inner_cached_function._cache = cache
+  return inner_cached_function
+
diff --git a/ranger/gui/colorscheme.py b/ranger/gui/colorscheme.py
index bc5a67a5..cc72d6a8 100644
--- a/ranger/gui/colorscheme.py
+++ b/ranger/gui/colorscheme.py
@@ -46,6 +46,8 @@ from ranger.gui.color import get_color
 from ranger.gui.context import Context
 from ranger.core.helper import allow_access_to_confdir
 from ranger.core.shared import SettingsAware
+from ranger.ext.cached_function import cached_function
+from ranger.ext.iter_tools import flatten
 
 # ColorScheme is not SettingsAware but it will gain access
 # to the settings during the initialization.  We can't import
@@ -60,9 +62,6 @@ class ColorScheme(SettingsAware):
 	which fits to the given keys.
 	"""
 
-	def __init__(self):
-		self.cache = {}
-
 	def get(self, *keys):
 		"""
 		Returns the (fg, bg, attr) for the given keys.
@@ -70,33 +69,28 @@ class ColorScheme(SettingsAware):
 		Using this function rather than use() will cache all
 		colors for faster access.
 		"""
-		keys = frozenset(keys)
-		try:
-			return self.cache[keys]
-
-		except KeyError:
-			context = Context(keys)
-
-			# add custom error messages for broken colorschemes
-			color = self.use(context)
-			if self.settings.colorscheme_overlay:
-				result = self.settings.colorscheme_overlay(context, *color)
-				assert isinstance(result, (tuple, list)), \
-						"Your colorscheme overlay doesn't return a tuple!"
-				assert all(isinstance(val, int) for val in result), \
-						"Your colorscheme overlay doesn't return a tuple"\
-						" containing 3 integers!"
-				color = result
-			self.cache[keys] = color
-			return color
-
+		context = Context(keys)
+
+		# add custom error messages for broken colorschemes
+		color = self.use(context)
+		if self.settings.colorscheme_overlay:
+			result = self.settings.colorscheme_overlay(context, *color)
+			assert isinstance(result, (tuple, list)), \
+					"Your colorscheme overlay doesn't return a tuple!"
+			assert all(isinstance(val, int) for val in result), \
+					"Your colorscheme overlay doesn't return a tuple"\
+					" containing 3 integers!"
+			color = result
+		return color
+
+	@cached_function
 	def get_attr(self, *keys):
 		"""
 		Returns the curses attribute for the specified keys
 
 		Ready to use for curses.setattr()
 		"""
-		fg, bg, attr = self.get(*keys)
+		fg, bg, attr = self.get(*flatten(keys))
 		return attr | color_pair(get_color(fg, bg))
 
 	def use(self, context):
diff --git a/ranger/gui/curses_shortcuts.py b/ranger/gui/curses_shortcuts.py
index 10a159a1..a383ab4c 100644
--- a/ranger/gui/curses_shortcuts.py
+++ b/ranger/gui/curses_shortcuts.py
@@ -17,7 +17,6 @@
 import curses
 import _curses
 
-from ranger.ext.iter_tools import flatten
 from ranger.gui.color import get_color
 from ranger.core.shared import SettingsAware
 
@@ -63,7 +62,6 @@ class CursesShortcuts(SettingsAware):
 
 	def color(self, *keys):
 		"""Change the colors from now on."""
-		keys = flatten(keys)
 		attr = self.settings.colorscheme.get_attr(*keys)
 		try:
 			self.win.attrset(attr)
@@ -72,7 +70,6 @@ class CursesShortcuts(SettingsAware):
 
 	def color_at(self, y, x, wid, *keys):
 		"""Change the colors at the specified position"""
-		keys = flatten(keys)
 		attr = self.settings.colorscheme.get_attr(*keys)
 		try:
 			self.win.chgat(y, x, wid, attr)
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index b6b745aa..e9c08439 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -178,7 +178,7 @@ class BrowserColumn(Pager):
 		self.win.move(0, 0)
 
 		if not self.target.content_loaded:
-			self.color(base_color)
+			self.color(tuple(base_color))
 			self.addnstr("...", self.wid)
 			self.color_reset()
 			return
@@ -187,13 +187,13 @@ class BrowserColumn(Pager):
 			base_color.append('main_column')
 
 		if not self.target.accessible:
-			self.color(base_color, 'error')
+			self.color(tuple(base_color + ['error']))
 			self.addnstr("not accessible", self.wid)
 			self.color_reset()
 			return
 
 		if self.target.empty():
-			self.color(base_color, 'empty')
+			self.color(tuple(base_color + ['empty']))
 			self.addnstr("empty", self.wid)
 			self.color_reset()
 			return
@@ -289,15 +289,15 @@ class BrowserColumn(Pager):
 				if x > 0:
 					self.addstr(line, x, infostring)
 
-			self.color_at(line, 0, self.wid, this_color)
+			self.color_at(line, 0, self.wid, tuple(this_color))
 			if bad_info_color:
 				start, wid = bad_info_color
-				self.color_at(line, start, wid, this_color, 'badinfo')
+				self.color_at(line, start, wid, tuple(this_color), 'badinfo')
 
 			if (self.main_column or self.settings.display_tags_in_all_columns) \
 					and tagged and self.wid > 2:
 				this_color.append('tag_marker')
-				self.color_at(line, 0, len(tagged_marker), this_color)
+				self.color_at(line, 0, len(tagged_marker), tuple(this_color))
 
 			self.color_reset()
 
diff --git a/ranger/gui/widgets/taskview.py b/ranger/gui/widgets/taskview.py
index c4476b9c..a3f8e314 100644
--- a/ranger/gui/widgets/taskview.py
+++ b/ranger/gui/widgets/taskview.py
@@ -17,8 +17,6 @@
 The TaskView allows you to modify what the loader is doing.
 """
 
-from collections import deque
-
 from . import Widget
 from ranger.ext.accumulator import Accumulator
 
@@ -31,7 +29,7 @@ class TaskView(Widget, Accumulator):
 		self.scroll_begin = 0
 
 	def draw(self):
-		base_clr = deque()
+		base_clr = []
 		base_clr.append('in_taskview')
 		lst = self.get_list()
 
@@ -48,7 +46,7 @@ class TaskView(Widget, Accumulator):
 				return
 
 			self.addstr(0, 0, "Task View")
-			self.color_at(0, 0, self.wid, base_clr, 'title')
+			self.color_at(0, 0, self.wid, tuple(base_clr), 'title')
 
 			if lst:
 				for i in range(self.hei - 1):
@@ -59,19 +57,19 @@ class TaskView(Widget, Accumulator):
 						break
 
 					y = i + 1
-					clr = deque(base_clr)
+					clr = list(base_clr)
 
 					if self.pointer == i:
 						clr.append('selected')
 
 					descr = obj.get_description()
 					self.addstr(y, 0, descr, self.wid)
-					self.color_at(y, 0, self.wid, clr)
+					self.color_at(y, 0, self.wid, tuple(clr))
 
 			else:
 				if self.hei > 1:
 					self.addstr(1, 0, "No task in the queue.")
-					self.color_at(1, 0, self.wid, base_clr, 'error')
+					self.color_at(1, 0, self.wid, tuple(base_clr), 'error')
 
 			self.color_reset()