summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2009-11-27 17:57:29 +0100
committerhut <hut@lavabit.com>2009-11-27 17:57:29 +0100
commitdd7a4f636fcc3c68b061d5af265aeaf38f70e45b (patch)
tree86792251ad3cb4a8580b18600941a1d888a67147
parent3ea48208992acbcd97eaecb23a958d35684b0317 (diff)
downloadranger-dd7a4f636fcc3c68b061d5af265aeaf38f70e45b.tar.gz
scrolling & stuff
-rw-r--r--ranger/command.py3
-rw-r--r--ranger/directory.py42
-rw-r--r--ranger/environment.py22
-rw-r--r--ranger/fm.py18
-rw-r--r--ranger/keys.py19
-rw-r--r--ranger/options.py6
-rw-r--r--ranger/ui.py3
-rw-r--r--ranger/wdisplay.py75
8 files changed, 150 insertions, 38 deletions
diff --git a/ranger/command.py b/ranger/command.py
index bd11dd70..f8c9f146 100644
--- a/ranger/command.py
+++ b/ranger/command.py
@@ -8,6 +8,9 @@ class CommandList():
 		self.dummies_in_paths = False
 		self.dummy_object = CommandDummy
 
+	# We need to know when to clear the keybuffer (when a wrong key is pressed)
+	# and when to wait for the rest of the key combination. For "gg" we
+	# will assign "g" to a dummy which tells the program not to do the latter.
 	def rebuild_paths(self):
 		paths = self.paths
 
diff --git a/ranger/directory.py b/ranger/directory.py
index 6f468b0a..57df2e13 100644
--- a/ranger/directory.py
+++ b/ranger/directory.py
@@ -18,8 +18,9 @@ class Directory(ranger.fsobject.FSObject):
 		self.filter = None
 		self.pointed_index = None
 		self.pointed_file = None
-		self.index = None
+		self.scroll_begin = 0
 		self.show_hidden = False
+		self.old_show_hidden = self.show_hidden
 	
 	def set_filter(self, string):
 		self.filter = string
@@ -34,20 +35,30 @@ class Directory(ranger.fsobject.FSObject):
 		self.content_loaded = True
 
 		if self.exists and self.runnable:
-			basenames = listdir(self.path)
-			mapped = map(lambda name: join(self.path, name), basenames)
-			self.filenames = list(mapped)
+			filenames = []
+			for fname in listdir(self.path):
+				if not self.show_hidden and fname[0] == '.':
+					continue
+				if isinstance(self.filter, str) and self.filter in fname:
+					continue
+				filenames.append(join(self.path, fname))
+#			basenames = listdir(self.path)
+#			mapped = map(lambda name: join(self.path, name), basenames)
+			self.scroll_offset = 0
+			self.filenames = filenames
 			self.infostring = ' %d' % len(self.filenames) # update the infostring
-			self.files = []
+			files = []
 			for name in self.filenames:
-				if isinstance(self.filter, str) and self.filter in name: continue
-				if basename(name)[0] == '.': continue
 				if isdir(name):
 					f = Directory(name)
 				else:
 					f = file.File(name)
 				f.load()
-				self.files.append(f)
+				files.append(f)
+
+			files.sort(key = lambda x: x.basename)
+			self.files = files
+
 			if len(self.files) > 0:
 				self.pointed_index = 0
 				self.pointed_file = self.files[0]
@@ -73,6 +84,16 @@ class Directory(ranger.fsobject.FSObject):
 		self.fix_pointer()
 		return self.pointed_file
 
+	def move_pointer_to_file_path(self, path):
+		self.load_content_once()
+		i = 0
+		for f in self.files:
+			if f.path == path:
+				self.move_pointer(absolute = i)
+				return
+			i += 1
+
+
 	def fix_pointer(self):
 		i = self.pointed_index
 		if i >= len(self.files): i = len(self.files) - 1
@@ -91,6 +112,11 @@ class Directory(ranger.fsobject.FSObject):
 		self.stop_if_frozen()
 		if self.load_content_once(): return True
 
+		if self.old_show_hidden != self.show_hidden:
+			self.old_show_hidden = self.show_hidden
+			self.load_content()
+			return True
+
 		import os
 		real_mtime = os.stat(self.path).st_mtime
 		cached_mtime = self.stat.st_mtime
diff --git a/ranger/environment.py b/ranger/environment.py
index faa3b9dc..d5678695 100644
--- a/ranger/environment.py
+++ b/ranger/environment.py
@@ -28,7 +28,10 @@ class Environment():
 			except IndexError:
 				return None
 		else:
-			return self.cf
+			try:
+				return self.directories[self.cf.path]
+			except KeyError:
+				return self.cf
 	
 	def get_directory(self, path):
 		import os
@@ -39,6 +42,20 @@ class Environment():
 			self.directories[path] = Directory(path)
 			return self.directories[path]
 
+	def assign_correct_cursor_positions(self):
+		# Assign correct cursor positions for subdirectories
+		from ranger.debug import log
+
+		last_path = None
+		for path in reversed(self.pathway):
+			if not last_path:
+				last_path = path.path
+				continue
+
+			log(( path.path, last_path ))
+			path.move_pointer_to_file_path(last_path)
+			last_path = path.path
+
 	def enter_dir(self, path):
 		# get the absolute path
 		path = os.path.normpath(os.path.join(self.path, path))
@@ -62,10 +79,11 @@ class Environment():
 			currentpath = '/'
 			for dir in path.split('/'):
 				currentpath = os.path.join(currentpath, dir)
-#			debug.log(currentpath)
 				pathway.append(self.get_directory(currentpath))
 			self.pathway = tuple(pathway)
 
+		self.assign_correct_cursor_positions()
+
 		# set the current file.
 		self.cf = self.pwd.pointed_file
 		return True
diff --git a/ranger/fm.py b/ranger/fm.py
index 48541f0c..141414b0 100644
--- a/ranger/fm.py
+++ b/ranger/fm.py
@@ -1,11 +1,3 @@
-import sys
-#LOGFILE = '/tmp/errorlog'
-#f = open(LOGFILE, 'a')
-#f.write(str(tuple(sys.path)) + "\n")
-#f.close()
-#import code.ui, code.debug, code.file, code.directory, code.fstype
-
-
 class FM():
 	def __init__(self, environment):
 		self.env = environment
@@ -19,7 +11,6 @@ class FM():
 		import time
 		while 1:
 			try:
-				self.env.pwd.load_content_if_outdated()
 				self.ui.draw()
 				key = self.ui.get_next_key()
 				self.ui.press(key, self)
@@ -29,6 +20,9 @@ class FM():
 			except:
 				raise
 
+	def resize(self):
+		self.ui.resize()
+
 	def exit(self):
 		raise SystemExit()
 
@@ -49,9 +43,13 @@ class FM():
 	def move_pointer(self, relative = 0, absolute = None):
 		self.env.cf = self.env.pwd.move_pointer(relative, absolute)
 
-	def move_pointer_by_screensize(self, relative = 0):
+	def move_pointer_by_pages(self, relative = 0):
 		self.env.cf = self.env.pwd.move_pointer(
 				relative = int(relative * self.env.termsize[0]))
 
 	def redraw(self):
 		self.ui.redraw()
+
+	def toggle_boolean_option(self, string):
+		if isinstance(self.env.opt[string], bool):
+			self.env.opt[string] ^= True
diff --git a/ranger/keys.py b/ranger/keys.py
index fe885278..b120c507 100644
--- a/ranger/keys.py
+++ b/ranger/keys.py
@@ -1,6 +1,7 @@
 def initialize_commands(command_list):
 	from ranger.fm import FM
 	from curses.ascii import ctrl
+	import curses
 
 	cl = command_list
 	
@@ -12,21 +13,29 @@ def initialize_commands(command_list):
 	# * a tuple of integers
 
 	def move(relative = 0, absolute = None):
-		return lambda fm: fm.move_pointer(relative = relative, absolute = absolute)
+		return lambda fm: fm.move_pointer(
+				relative = relative, absolute = absolute)
 
-	def move_screens(n):
-		return lambda fm: fm.move_pointer_by_screensize(n)
+	def move_pages(n):
+		return lambda fm: fm.move_pointer_by_pages(n)
+
+	def toggle_option(string):
+		return lambda fm: fm.toggle_boolean_option(string)
 
 	cl.bind(FM.move_left, 'h', 195, 'back')
 	cl.bind(FM.move_right, 'l', 'forward')
 	cl.bind(move( relative = 1 ), 'j')
-	cl.bind(move_screens( 0.5 ), 'J')
+	cl.bind(move_pages( 0.5 ), 'J')
 	cl.bind(move( relative = -1 ), 'k')
-	cl.bind(move_screens( -0.5 ), 'K')
+	cl.bind(move_pages( -0.5 ), 'K')
 	cl.bind(move( absolute = 0 ), 'gg')
 	cl.bind(move( absolute = -1 ), 'G')
+
+	cl.bind(toggle_option('show_hidden'), 'th')
+
 	cl.bind(FM.exit, 'q', ctrl('D'), 'ZZ')
 	cl.bind(FM.redraw, ctrl('L'))
+	cl.bind(FM.resize, curses.KEY_RESIZE)
 
 	cl.rebuild_paths()
 
diff --git a/ranger/options.py b/ranger/options.py
index f2a7d1ae..50957c8a 100644
--- a/ranger/options.py
+++ b/ranger/options.py
@@ -1,5 +1,7 @@
 def get():
-	return []
+	""" to be implemented. read the options from a file. """
+	pass
 
 def dummy():
-	return { 'show hidden': False }
+	""" provide a way of getting options until get() is implemented """
+	return { 'show_hidden': False, 'scroll_offset': 2 }
diff --git a/ranger/ui.py b/ranger/ui.py
index 308e5e14..9e8acb73 100644
--- a/ranger/ui.py
+++ b/ranger/ui.py
@@ -38,7 +38,7 @@ class UI():
 
 	def press(self, key, fm):
 		self.env.key_append(key)
-		log(self.env.keybuffer)
+#		log(self.env.keybuffer)
 
 		try:
 			cmd = self.commandlist.paths[self.env.keybuffer]
@@ -58,7 +58,6 @@ class UI():
 		curses.endwin()
 
 	def draw(self):
-		from ranger.debug import log
 		self.win.erase()
 		for widg in self.widgets:
 			widg.feed_env(self.env)
diff --git a/ranger/wdisplay.py b/ranger/wdisplay.py
index 3d74ef63..d0962149 100644
--- a/ranger/wdisplay.py
+++ b/ranger/wdisplay.py
@@ -1,4 +1,5 @@
 import ranger.widget
+from ranger.debug import log
 import curses
 
 class WDisplay(ranger.widget.Widget):
@@ -7,9 +8,12 @@ class WDisplay(ranger.widget.Widget):
 		self.level = level
 		self.main_display = False
 		self.display_infostring = False
+		self.scroll_begin = 0
 
 	def feed_env(self, env):
 		self.target = env.at_level(self.level)
+		self.show_hidden = env.opt['show_hidden']
+		self.scroll_offset = env.opt['scroll_offset']
 
 	def draw(self):
 		from ranger.file import File
@@ -31,26 +35,79 @@ class WDisplay(ranger.widget.Widget):
 		self.win.addnstr(self.y, self.x, "this is a file.", self.wid)
 
 	def draw_directory(self):
-		self.target.load_content_once()
+		self.target.show_hidden = self.show_hidden
+		self.target.load_content_if_outdated()
 		main_display = self.main_display
+
 		if not self.target.accessible:
 			self.win.addnstr(self.y, self.x, "not accessible", self.wid)
 			return
-		for i in range(self.hei):
-			try:
-				drawed = self.target[i]
-			except IndexError:
-				break
-			invert = main_display and i == self.target.pointed_index
+
+		self.set_scroll_begin()
+
+		for line in range(self.hei):
+			i = line + self.scroll_begin
+			# last file reached?
+			try: drawed = self.target[i]
+			except IndexError: break
+
+			invert = i == self.target.pointed_index
 			if invert:
 				self.win.attrset(curses.A_REVERSE)
-			self.win.addnstr(self.y + i, self.x, drawed.basename, self.wid)
+
+			if self.main_display:
+				self.win.addnstr(
+						self.y + line,
+						self.x + 1,
+						' ' + drawed.basename + ' ',
+						self.wid - 2)
+			else:
+				self.win.addnstr(
+						self.y + line,
+						self.x,
+						drawed.basename,
+						self.wid)
+
 			if self.display_infostring and drawed.infostring:
 				info = drawed.infostring
 				x = self.x + self.wid - 1 - len(info)
 				if x > self.x:
-					self.win.addstr(self.y + i, x, str(info) + '')
+					self.win.addstr(self.y + line, x, str(info) + ' ')
 			if invert:
 				self.win.attrset(curses.A_NORMAL)
 
+	def get_scroll_begin(self):
+		offset = self.scroll_offset
+		dirsize = len(self.target)
+		winsize = self.hei
+		halfwinsize = winsize // 2
+		index = self.target.pointed_index or 0
+		original = self.target.scroll_begin
+		projected = index - original
+
+		upper_limit = winsize - 1 - offset
+		lower_limit = offset
+
+		if dirsize < winsize:
+			return 0
+
+		if halfwinsize < offset:
+			return min( dirsize - winsize, max( 0, index - halfwinsize ))
+
+		if projected < upper_limit and projected > lower_limit:
+			return original
+
+		if projected > upper_limit:
+			return min( dirsize - winsize,
+					original + (projected - upper_limit))
+
+		if projected < upper_limit:
+			return max( 0,
+					original - (lower_limit - projected))
+		
+		return original
+
+	def set_scroll_begin(self):
+		self.scroll_begin = self.get_scroll_begin()
+		self.target.scroll_begin = self.scroll_begin