about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2009-12-31 17:13:12 +0100
committerhut <hut@lavabit.com>2009-12-31 17:13:12 +0100
commit42fd36907c9d9e4c68634e35e7b5de2c91c9164e (patch)
treea8cb1799eacb31ecfc73c768978097c5288a7677
parent9cce9fab0792ee0ac17ad4355d9af9274159f294 (diff)
downloadranger-42fd36907c9d9e4c68634e35e7b5de2c91c9164e.tar.gz
optimized drawing of widgets (broke notify widget)
-rw-r--r--ranger/gui/defaultui.py3
-rw-r--r--ranger/gui/displayable.py47
-rw-r--r--ranger/gui/ui.py4
-rw-r--r--ranger/gui/widgets/browsercolumn.py36
-rw-r--r--ranger/gui/widgets/console.py1
-rw-r--r--ranger/gui/widgets/statusbar.py33
6 files changed, 90 insertions, 34 deletions
diff --git a/ranger/gui/defaultui.py b/ranger/gui/defaultui.py
index 540d088d..3985b1cc 100644
--- a/ranger/gui/defaultui.py
+++ b/ranger/gui/defaultui.py
@@ -42,6 +42,7 @@ class DefaultUI(UI):
 
 		# Create the pager
 		self.pager = Pager(self.win)
+		self.pager.visible = False
 		self.add_child(self.pager)
 
 	def update_size(self):
@@ -119,8 +120,6 @@ class DefaultUI(UI):
 			self.titlebar.throbber = type(self.titlebar).throbber
 		else:
 			self.titlebar.throbber = string
-	
-#		self.win.addnstr(0, self.env.termsize[1]-1, string, 1)
 
 	def hint(self, text=None):
 		self.status.override = text
diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py
index 315d2f7b..c5e1dbac 100644
--- a/ranger/gui/displayable.py
+++ b/ranger/gui/displayable.py
@@ -2,6 +2,7 @@ from ranger.shared import FileManagerAware, EnvironmentAware, SettingsAware
 from ranger import log
 import _curses
 
+
 class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 	"""
 	Displayables are objects which are displayed on the screen.
@@ -32,6 +33,9 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 	Modifiable:
 		focused -- Focused objects receive press() calls.
 		visible -- Visible objects receive draw() and finalize() calls
+		need_redraw -- Should the widget be redrawn? This variable may
+			be set at various places in the script and should eventually be
+			handled (and unset) in the draw() method.
 	
 	Read-Only: (i.e. reccomended not to change manually)
 		win -- the own curses window object
@@ -49,14 +53,18 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 		if settings is not None:
 			self.settings = settings
 
+		self.need_redraw = True
 		self.focused = False
 		self.visible = True
 		self.x = 0
 		self.y = 0
 		self.wid = 0
 		self.hei = 0
+		self.paryx = (0, 0)
 		self.parent = None
 
+		self._old_visible = self.visible
+
 		if win is not None:
 			if isinstance(self, UI):
 				self.win = win
@@ -110,7 +118,8 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 		Displayable.color(self, 'reset')
 
 	def draw(self):
-		"""Draw the object. Called on every main iteration.
+		"""
+		Draw the object. Called on every main iteration if visible.
 		Containers should call draw() on their contained objects here.
 		Override this!
 		"""
@@ -142,13 +151,13 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 
 	def poke(self):
 		"""Called before drawing, even if invisible"""
-	
-	def draw(self):
-		"""Draw displayable.  Called on every main iteration if the object
-		is visible.  Override this!
-		"""
-		pass
+		if self._old_visible != self.visible:
+			self._old_visible = self.visible
+			self.need_redraw = True
 
+			if not self.visible:
+				self.win.erase()
+	
 	def finalize(self):
 		"""Called after every displayable is done drawing.
 		Override this!
@@ -184,7 +193,13 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 			if y + hei > maxy:
 				raise OutOfBoundsException("Y out of bounds!")
 
+		window_is_cleared = False
+
 		if hei != self.hei or wid != self.wid:
+			#log("resizing " + str(self))
+			self.win.erase()
+			self.need_redraw = True
+			window_is_cleared = True
 			try:
 				self.win.resize(hei, wid)
 			except:
@@ -199,17 +214,24 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware):
 
 			self.hei, self.wid = self.win.getmaxyx()
 
-		if do_move or y != self.y or x != self.x:
-			log("moving " + self.__class__.__name__)
+		if do_move or y != self.paryx[0] or x != self.paryx[1]:
+			if not window_is_cleared:
+				self.win.erase()
+				self.need_redraw = True
+			#log("moving " + str(self))
 			try:
 				self.win.mvderwin(y, x)
 			except:
 				pass
 
-			self.y, self.x = self.win.getparyx()
+			self.paryx = self.win.getparyx()
+			self.y, self.x = self.paryx
 			if self.parent:
 				self.y += self.parent.y
 				self.x += self.parent.x
+	
+	def __str__(self):
+		return self.__class__.__name__
 
 class DisplayableContainer(Displayable):
 	"""
@@ -245,15 +267,20 @@ class DisplayableContainer(Displayable):
 
 	def poke(self):
 		"""Recursively called on objects in container"""
+		Displayable.poke(self)
 		for displayable in self.container:
 			displayable.poke()
 
 	def draw(self):
 		"""Recursively called on visible objects in container"""
 		for displayable in self.container:
+			if self.need_redraw:
+				displayable.need_redraw = True
 			if displayable.visible:
 				displayable.draw()
 
+		self.need_redraw = False
+
 	def finalize(self):
 		"""Recursively called on visible objects in container"""
 		for displayable in self.container:
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index e609b72d..31ddf61a 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -146,9 +146,11 @@ class UI(DisplayableContainer):
 
 	def redraw_window(self):
 		"""Redraw the window. This only calls self.win.redrawwin()."""
+		self.win.erase()
 		self.win.redrawwin()
 		self.win.refresh()
 		self.win.redrawwin()
+		self.need_redraw = True
 
 	def update_size(self):
 		"""Update self.env.termsize.
@@ -158,7 +160,7 @@ class UI(DisplayableContainer):
 
 	def draw(self):
 		"""Erase the window, then draw all objects in the container"""
-		self.win.erase()
+		self.win.touchwin()
 		DisplayableContainer.draw(self)
 		self.win.refresh()
 
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 055c9843..5427d958 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -11,6 +11,9 @@ class BrowserColumn(Pager, Widget):
 	postpone_drawing = False
 	tagged_marker = '*'
 
+	old_dir = None
+	old_cf = None
+
 	def __init__(self, win, level):
 		Pager.__init__(self, win)
 		Widget.__init__(self, win)
@@ -65,6 +68,7 @@ class BrowserColumn(Pager, Widget):
 		return True
 
 	def poke(self):
+		Widget.poke(self)
 		self.target = self.env.at_level(self.level)
 
 	def draw(self):
@@ -72,15 +76,26 @@ class BrowserColumn(Pager, Widget):
 		from ranger.fsobject.file import File
 		from ranger.fsobject.directory import Directory
 
-#		self.pager.visible = False
-		if self.target is None:
-			pass
-		elif type(self.target) == File:
-			Pager.open(self)
-			self._draw_file()
-		elif type(self.target) == Directory:
-			self._draw_directory()
-			Widget.draw(self)
+		if self.target != self.old_dir:
+			self.need_redraw = True
+			self.old_dir = self.target
+
+		if isinstance(self.target, Directory) \
+				and self.target.pointed_obj != self.old_cf:
+			self.need_redraw = True
+			self.old_cf = self.target.pointed_obj
+
+		if self.need_redraw:
+			self.win.erase()
+			if self.target is None:
+				pass
+			elif type(self.target) == File:
+				Pager.open(self)
+				self._draw_file()
+			elif type(self.target) == Directory:
+				self._draw_directory()
+				Widget.draw(self)
+			self.need_redraw = False
 
 	def _preview_this_file(self, target):
 		return target.document and not self.settings.preview_files
@@ -278,3 +293,6 @@ class BrowserColumn(Pager, Widget):
 		if self.target.scroll_begin == old_value:
 			self.target.move(relative = relative)
 			self.target.scroll_begin += relative
+	
+	def __str__(self):
+		return self.__class__.__name__ + ' at level ' + str(self.level)
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 22b9831d..11b83417 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -43,6 +43,7 @@ class Console(Widget):
 		if self.mode is None:
 			return
 		
+		self.win.erase()
 		self.addstr(0, 0, self.prompt)
 		self.addstr(self.line)
 
diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py
index b5f3bdce..94e62d0b 100644
--- a/ranger/gui/widgets/statusbar.py
+++ b/ranger/gui/widgets/statusbar.py
@@ -23,7 +23,6 @@ class StatusBar(Widget):
 
 	old_cf = None
 	old_mtime = None
-	old_wid = None
 	result = None
 
 	def __init__(self, win, column=None):
@@ -39,18 +38,28 @@ class StatusBar(Widget):
 
 		if self.override and isinstance(self.override, str):
 			self._draw_message()
-		else:
-			try:
-				mtime = self.env.cf.stat.st_mtime
-			except:
-				mtime = -1
-			if not self.result or self.old_cf != self.env.cf or \
-					mtime != self.old_mtime or self.old_wid != self.wid:
-				self.old_mtime = mtime
-				self.old_cf = self.env.cf
-				self.old_wid = self.wid
-				self._calc_bar()
+			return
+
+		try:
+			mtime = self.env.cf.stat.st_mtime
+		except:
+			mtime = -1
+
+		if not self.result:
+			self.need_redraw = True
+
+		if self.old_cf != self.env.cf:
+			self.old_cf = self.env.cf
+			self.need_redraw = True
+
+		if self.old_mtime != mtime:
+			self.old_mtime = mtime
+			self.need_redraw = True
+
+		if self.need_redraw:
+			self.need_redraw = False
 
+			self._calc_bar()
 			self._print_result(self.result)
 	
 	def _calc_bar(self):