diff options
author | hut <hut@lavabit.com> | 2009-12-11 22:30:07 +0100 |
---|---|---|
committer | hut <hut@lavabit.com> | 2009-12-11 22:30:07 +0100 |
commit | d88232a386dbc2153aa12bea7f30c9c53c414010 (patch) | |
tree | 2f6f93ff6769e7fdc829a910f25513c9645d7333 | |
parent | 3de15ddd7fb0151e5f43f0b8e7d06bd76568e235 (diff) | |
download | ranger-d88232a386dbc2153aa12bea7f30c9c53c414010.tar.gz |
Reorganization of gui/widget hierarchy and directory structure
-rw-r--r-- | ranger/actions.py | 8 | ||||
-rw-r--r-- | ranger/applications.py | 4 | ||||
-rw-r--r-- | ranger/defaults/keys.py | 22 | ||||
-rw-r--r-- | ranger/environment.py | 3 | ||||
-rw-r--r-- | ranger/fm.py | 7 | ||||
-rw-r--r-- | ranger/gui/color.py | 3 | ||||
-rw-r--r-- | ranger/gui/defaultui.py | 36 | ||||
-rw-r--r-- | ranger/gui/displayable.py | 167 | ||||
-rw-r--r-- | ranger/gui/mouse_event.py | 16 | ||||
-rw-r--r-- | ranger/gui/ui.py | 140 | ||||
-rw-r--r-- | ranger/gui/widget.py | 74 | ||||
-rw-r--r-- | ranger/gui/widgets/__init__.py | 0 | ||||
-rw-r--r-- | ranger/gui/widgets/console.py (renamed from ranger/gui/wconsole.py) | 38 | ||||
-rw-r--r-- | ranger/gui/widgets/filelist.py (renamed from ranger/gui/wdisplay.py) | 40 | ||||
-rw-r--r-- | ranger/gui/widgets/titlebar.py (renamed from ranger/gui/wtitlebar.py) | 29 | ||||
-rw-r--r-- | ranger/main.py | 6 | ||||
-rw-r--r-- | test/tc_directory.py | 2 |
17 files changed, 348 insertions, 247 deletions
diff --git a/ranger/actions.py b/ranger/actions.py index 54a88b11..a36b0c56 100644 --- a/ranger/actions.py +++ b/ranger/actions.py @@ -20,7 +20,7 @@ class Actions(EnvironmentAware, SettingsAware): raise SystemExit() def resize(self): - self.ui.resize() + self.ui.update_size() def exit(self): raise SystemExit() @@ -57,7 +57,7 @@ class Actions(EnvironmentAware, SettingsAware): self.env.history_go(relative) def handle_mouse(self): - self.ui.handle_mouse(self) + self.ui.handle_mouse() def execute_file(self, files, app = '', flags = '', mode = 0): if type(files) not in (list, tuple): @@ -78,7 +78,7 @@ class Actions(EnvironmentAware, SettingsAware): self.execute_file(self.env.cf, app = 'editor') def open_console(self, mode = ':'): - if self.ui.can('open_console'): + if hasattr(self.ui, 'open_console'): self.ui.open_console(mode) def move_pointer(self, relative = 0, absolute = None): @@ -89,7 +89,7 @@ class Actions(EnvironmentAware, SettingsAware): relative = int(relative * self.env.termsize[0])) def scroll(self, relative): - if self.ui.can('scroll'): + if hasattr(self.ui, 'scroll'): self.ui.scroll(relative) self.env.cf = self.env.pwd.pointed_file diff --git a/ranger/applications.py b/ranger/applications.py index 99a40e93..85dc50f5 100644 --- a/ranger/applications.py +++ b/ranger/applications.py @@ -50,8 +50,8 @@ def run(*args, **kw): return process else: - if fm.ui is not None: fm.ui.exit() + if fm.ui: fm.ui.destroy() p = Popen(args, **popen_kw) waitpid_no_intr(p.pid) - if fm.ui is not None: fm.ui.initialize() + if fm.ui: fm.ui.initialize() return p diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py index 2f623bca..5edae929 100644 --- a/ranger/defaults/keys.py +++ b/ranger/defaults/keys.py @@ -90,7 +90,7 @@ def initialize_commands(command_list): def initialize_console_commands(command_list): from ranger.actions import Actions as do - from ranger.gui.wconsole import WConsole + from ranger.gui.widgets.console import Console def bind(fnc, *keys): command_list.bind(fnc, *keys) @@ -107,18 +107,18 @@ def initialize_console_commands(command_list): c = curry # movement - bind(c(WConsole.move, relative = -1), curses.KEY_LEFT, ctrl('b')) - bind(c(WConsole.move, relative = 1), curses.KEY_RIGHT, ctrl('f')) - bind(c(WConsole.move, absolute = 0), curses.KEY_HOME, ctrl('a')) - bind(c(WConsole.move, absolute = -1), curses.KEY_END, ctrl('e')) - bind(c(WConsole.delete, 0), curses.KEY_DC, ctrl('d')) - bind(c(WConsole.delete, -1), curses.KEY_BACKSPACE, 127, ctrl('h')) - bind(c(WConsole.delete_rest, -1), ctrl('U')) - bind(c(WConsole.delete_rest, 1), ctrl('K')) + bind(c(Console.move, relative = -1), curses.KEY_LEFT, ctrl('b')) + bind(c(Console.move, relative = 1), curses.KEY_RIGHT, ctrl('f')) + bind(c(Console.move, absolute = 0), curses.KEY_HOME, ctrl('a')) + bind(c(Console.move, absolute = -1), curses.KEY_END, ctrl('e')) + bind(c(Console.delete, 0), curses.KEY_DC, ctrl('d')) + bind(c(Console.delete, -1), curses.KEY_BACKSPACE, 127, ctrl('h')) + bind(c(Console.delete_rest, -1), ctrl('U')) + bind(c(Console.delete_rest, 1), ctrl('K')) # system functions - bind(c(WConsole.close), ESC, ctrl('C')) - bind(WConsole.execute, curses.KEY_ENTER, ctrl('j')) + bind(c(Console.close), ESC, ctrl('C')) + bind(Console.execute, curses.KEY_ENTER, ctrl('j')) bind(c_fm(do.redraw), ctrl('L')) bind(c_fm(do.resize), curses.KEY_RESIZE) diff --git a/ranger/environment.py b/ranger/environment.py index d7097fc8..9e2c2877 100644 --- a/ranger/environment.py +++ b/ranger/environment.py @@ -15,7 +15,8 @@ class Environment(SettingsAware): self.cf = None # current file self.keybuffer = KeyBuffer() self.copy = None - self.termsize = (24, 80) + self.termsize = None +# self.termsize = (24, 80) self.history = History(self.settings.max_history_size) from ranger.shared import EnvironmentAware diff --git a/ranger/fm.py b/ranger/fm.py index cdcfb8d7..dd74342f 100644 --- a/ranger/fm.py +++ b/ranger/fm.py @@ -3,6 +3,7 @@ from ranger.container import Bookmarks from ranger import __version__ USAGE = '''%s [options] [path/filename]''' +CTRL_C = 3 class FM(Actions): def __init__(self, ui = None, bookmarks = None): @@ -35,8 +36,10 @@ class FM(Actions): try: self.bookmarks.reload_if_outdated() self.ui.draw() + self.ui.finalize() + key = self.ui.get_next_key() - self.ui.press(key, self) + self.ui.handle_key(key) gc_tick += 1 if gc_tick > 10: @@ -44,4 +47,4 @@ class FM(Actions): self.env.garbage_collect() except KeyboardInterrupt: - self.ui.press(3, self) + self.ui.handle_key(CTRL_C, self) diff --git a/ranger/gui/color.py b/ranger/gui/color.py index 214383ee..1318ab6f 100644 --- a/ranger/gui/color.py +++ b/ranger/gui/color.py @@ -1,9 +1,10 @@ +"""Contains abbreviations to curses' color/attribute constants.""" import curses COLOR_PAIRS = {10: 0} def get_color(fg, bg): - import curses + """Returns the color pair for the given fg/bg combination.""" c = bg+2 + 9*(fg + 2) diff --git a/ranger/gui/defaultui.py b/ranger/gui/defaultui.py index 547f20ff..8d9f7ded 100644 --- a/ranger/gui/defaultui.py +++ b/ranger/gui/defaultui.py @@ -4,28 +4,29 @@ RATIO = ( 0.15, 0.15, 0.4, 0.3 ) from ranger.gui.ui import UI as SuperClass class DefaultUI(SuperClass): def setup(self): - from ranger.gui.wdisplay import WDisplay - from ranger.gui.wtitlebar import WTitleBar - from ranger.gui.wconsole import WConsole - self.titlebar = WTitleBar(self.win, self.colorscheme) - self.add_widget(self.titlebar) + from ranger.gui.widgets.filelist import FileList + from ranger.gui.widgets.titlebar import TitleBar + from ranger.gui.widgets.console import Console + self.titlebar = TitleBar(self.win) + self.add_obj(self.titlebar) self.displays = [ - WDisplay(self.win, self.colorscheme, -2), - WDisplay(self.win, self.colorscheme, -1), - WDisplay(self.win, self.colorscheme, 0), - WDisplay(self.win, self.colorscheme, 1) ] + FileList(self.win, -2), + FileList(self.win, -1), + FileList(self.win, 0), + FileList(self.win, 1) ] self.main_display = self.displays[2] self.displays[2].display_infostring = True self.displays[2].main_display = True for disp in self.displays: - self.add_widget(disp) + self.add_obj(disp) - self.console = WConsole(self.win, self.colorscheme) - self.add_widget(self.console) + self.console = Console(self.win) + self.add_obj(self.console) - def resize(self): - SuperClass.resize(self) + def update_size(self): + """resize all widgets""" + SuperClass.update_size(self) y, x = self.win.getmaxyx() leftborder = 0 @@ -34,16 +35,15 @@ class DefaultUI(SuperClass): for ratio in RATIO: wid = int(ratio * x) try: - self.displays[i].setdim(1, leftborder, y-2, wid - 1) + self.displays[i].resize(1, leftborder, y-2, wid - 1) except KeyError: pass leftborder += wid i += 1 - self.titlebar.setdim(0, 0, 1, x) - self.console.setdim(y-1, 0, 1, x) + self.titlebar.resize(0, 0, 1, x) + self.console.resize(y-1, 0, 1, x) - # ---specials--- def open_console(self, mode): if self.console.open(mode): self.console.on_close = self.close_console diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py new file mode 100644 index 00000000..4ac8c3fc --- /dev/null +++ b/ranger/gui/displayable.py @@ -0,0 +1,167 @@ +from ranger.shared import FileManagerAware, EnvironmentAware, SettingsAware + +class Displayable(EnvironmentAware, FileManagerAware, SettingsAware): + focused = False + visible = True + win = None + colorscheme = None + + def __init__(self, win): + self.resize(0, 0, 0, 0) + self.colorscheme = self.env.settings.colorscheme + + if win is not None: + self.win = win + + def __nonzero__(self): + """Always True""" + return True + + def color(self, keylist = None, *keys): + """Change the colors from now on.""" + keys = combine(keylist, keys) + self.win.attrset(self.colorscheme.get_attr(*keys)) + + def color_at(self, y, x, wid, keylist = None, *keys): + """Change the colors at the specified position""" + keys = combine(keylist, keys) + self.win.chgat(y, x, wid, self.colorscheme.get_attr(*keys)) + + def color_reset(self): + """Change the colors to the default colors""" + Displayable.color(self, 'reset') + + def draw(self): + """Draw the object. Called on every main iteration. +Containers should call draw() on their contained objects here. +Override this!""" + + def destroy(self): + """Called when the object is destroyed. +Override this!""" + + def contains_point(self, y, x): + """Test if the point lies within the boundaries of this object""" + return (x >= self.x and x < self.x + self.wid) and \ + (y >= self.y and y < self.y + self.hei) + + def click(self, event): + """Called when a mouse key is pressed and self.focused is True. +Override this!""" + pass + + def press(self, key): + """Called when a key is pressed and self.focused is True. +Override this!""" + pass + + def draw(self): + """Draw displayable. Called on every main iteration. +Override this!""" + pass + + def finalize(self): + """Called after every displayable is done drawing. +Override this!""" + pass + + def resize(self, y, x, hei=None, wid=None): + """Resize the widget""" + try: + maxy, maxx = self.env.termsize + except TypeError: + pass + else: + wid = wid or maxx - x + hei = hei or maxy - y + + if x + wid > maxx and y + hei > maxy: + raise OutOfBoundsException("X and Y out of bounds!") + + if x + wid > maxx: + raise OutOfBoundsException("X out of bounds!") + + if y + hei > maxy: + raise OutOfBoundsException("Y out of bounds!") + + self.x = x + self.y = y + self.wid = wid + self.hei = hei + + +class DisplayableContainer(Displayable): + container = None + def __init__(self, win): + Displayable.__init__(self, win) + self.container = [] + + def draw(self): + """Recursively called on objects in container""" + for displayable in self.container: + if displayable.visible: + displayable.draw() + + def finalize(self): + """Recursively called on objects in container""" + for displayable in self.container: + if displayable.visible: + displayable.finalize() + + def get_focused_obj(self): + """Finds a focused displayable object in the container.""" + for displayable in self.container: + if displayable.focused: + return displayable + try: + obj = displayable.get_focused_obj() + except AttributeError: + pass + else: + if obj is not None: + return obj + return None + + def press(self, key): + """Recursively called on objects in container""" + focused_obj = self.get_focused_obj() + + if focused_obj: + focused_obj.press(key) + return True + return False + + def click(self, event): + """Recursively called on objects in container""" + focused_obj = self.get_focused_obj() + if focused_obj: + focused_obj.press(key) + return True + return False + + def add_obj(self, obj): + self.container.append(obj) + + def destroy(self): + """Recursively called on objects in container""" + for displayable in self.container: + displayable.destroy() + +# def resize(self): +# """Recursively called on objects in container""" +# for displayable in container: +# displayable.resize() + +class OutOfBoundsException(Exception): + pass + +def combine(seq, tup): + """Add seq and tup. Ensures that the result is a tuple.""" + try: + if isinstance(seq, str): raise TypeError + return tuple(tuple(seq) + tup) + except TypeError: + try: + return tuple((seq, ) + tup) + except: + return () diff --git a/ranger/gui/mouse_event.py b/ranger/gui/mouse_event.py new file mode 100644 index 00000000..fa25f5f0 --- /dev/null +++ b/ranger/gui/mouse_event.py @@ -0,0 +1,16 @@ +class MouseEvent(object): + import curses + PRESSED = [ 0, + curses.BUTTON1_PRESSED, + curses.BUTTON2_PRESSED, + curses.BUTTON3_PRESSED, + curses.BUTTON4_PRESSED ] + + def __init__(self, getmouse): + _, self.x, self.y, _, self.bstate = getmouse + + def pressed(self, n): + try: + return (self.bstate & MouseEvent.PRESSED[n]) != 0 + except: + return False diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index c7c10cfe..8abd39df 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -1,26 +1,11 @@ import curses -class MouseEvent(object): - import curses - PRESSED = [ 0, - curses.BUTTON1_PRESSED, - curses.BUTTON2_PRESSED, - curses.BUTTON3_PRESSED, - curses.BUTTON4_PRESSED ] - - def __init__(self, getmouse): - _, self.x, self.y, _, self.bstate = getmouse - - def pressed(self, n): - try: - return (self.bstate & MouseEvent.PRESSED[n]) != 0 - except: - return False - -from ranger.shared import EnvironmentAware, SettingsAware +from .displayable import DisplayableContainer +from .mouse_event import MouseEvent from ranger.container import CommandList -class UI(EnvironmentAware, SettingsAware): +class UI(DisplayableContainer): + is_set_up = False def __init__(self, commandlist = None): import os os.environ['ESCDELAY'] = '25' # don't know a cleaner way @@ -30,13 +15,12 @@ class UI(EnvironmentAware, SettingsAware): self.settings.keys.initialize_commands(self.commandlist) else: self.commandlist = commandlist - self.colorscheme = self.env.settings.colorscheme - self.is_set_up = False self.win = curses.initscr() - self.widgets = [] + DisplayableContainer.__init__(self, None) def initialize(self): + """initialize curses, then call setup (at the first time) and resize.""" self.win.leaveok(0) self.win.keypad(1) @@ -46,6 +30,7 @@ class UI(EnvironmentAware, SettingsAware): curses.curs_set(0) curses.start_color() curses.use_default_colors() + curses.mouseinterval(0) mask = curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION avail, old = curses.mousemask(mask) @@ -54,63 +39,37 @@ class UI(EnvironmentAware, SettingsAware): if not self.is_set_up: self.is_set_up = True self.setup() - self.resize() - - def exit(self): - from ranger import log - log("exiting ui!") - self.win.keypad(0) - curses.nocbreak() - curses.echo() - curses.curs_set(1) - curses.mousemask(0) - curses.endwin() + self.update_size() - def handle_mouse(self, fm): + def handle_mouse(self): + """Handles mouse input""" try: event = MouseEvent(curses.getmouse()) except: return + from ranger import log + log(str(event.bstate)) + if event.pressed(1) or event.pressed(3): - for widg in self.widgets: - if widg.contains_point(event.y, event.x): - widg.click(event, fm) + for displayable in self.container: + if displayable.contains_point(event.y, event.x): + displayable.click(event) break - if event.pressed(4) or event.pressed(2) or event.bstate & 134217728: +# if event.pressed(4) or event.pressed(2) or event.bstate & 134217728: + if event.pressed(4) or event.pressed(2): if event.pressed(4): - fm.scroll(relative = -3) + self.fm.scroll(relative = -3) else: - fm.scroll(relative = 3) + self.fm.scroll(relative = 3) - def can(self, attr): - return hasattr(self, attr) - - def setup(self): - pass - - def resize(self): - self.env.termsize = self.win.getmaxyx() - - def redraw(self): - self.win.redrawwin() - self.win.refresh() - self.win.redrawwin() - - def add_widget(self, widg): - self.widgets.append(widg) - - def feed_env(self, env): - self.env = env - - def press(self, key, fm): + def handle_key(self, key): + """Handles key input""" self.env.key_append(key) - for widg in self.widgets: - if widg.focused: - widg.press(key, fm, self.env) - return + if DisplayableContainer.press(self, key): + return try: cmd = self.commandlist.paths[tuple(self.env.keybuffer)] @@ -121,21 +80,48 @@ class UI(EnvironmentAware, SettingsAware): if cmd == self.commandlist.dummy_object: return - cmd.execute(fm) + cmd.execute(self.fm) self.env.key_clear() - def draw(self): - self.win.erase() - for widg in self.widgets: - widg.feed_env(self.env) - if widg.visible: - widg.draw() - for widg in self.widgets: - if widg.visible: - widg.finalize() - self.win.refresh() - def get_next_key(self): + """Waits for key input and returns the pressed key""" key = self.win.getch() curses.flushinp() return key + + def setup(self): + """Called after an initialize() call. +Override this!""" + + def redraw(self): + """Redraw the window. This only calls self.win.redrawwin().""" + self.win.redrawwin() + self.win.refresh() + self.win.redrawwin() + + def update_size(self): + """Update self.env.termsize. +Extend this method to resize all widgets!""" + self.env.termsize = self.win.getmaxyx() + + def draw(self): + """Erase the window, then draw all objects in the container""" + self.win.erase() + DisplayableContainer.draw(self) + + def finalize(self): + """Finalize every object in container and refresh the window""" + DisplayableContainer.finalize(self) + self.win.refresh() + + def destroy(self): + """Destroy all widgets and turn off curses""" +# DisplayableContainer.destroy(self) + from ranger import log + log("exiting ui!") + self.win.keypad(0) + curses.nocbreak() + curses.echo() + curses.curs_set(1) +# curses.mousemask(0) + curses.endwin() diff --git a/ranger/gui/widget.py b/ranger/gui/widget.py deleted file mode 100644 index 093eee14..00000000 --- a/ranger/gui/widget.py +++ /dev/null @@ -1,74 +0,0 @@ - -class OutOfBoundsException(Exception): - pass - -def combine(keylist, keys): - if type(keylist) in (list, tuple): - return tuple(tuple(keylist) + keys) - else: - return tuple((keylist, ) + keys) - -from ranger.shared import SettingsAware -class Widget(SettingsAware): - def __init__(self, win, _): - self.win = win - self.focused = False - self.colorscheme = self.settings.colorscheme - self.visible = True - self.setdim(0, 0, 0, 0) - - def color(self, keylist = None, *keys): - keys = combine(keylist, keys) - self.win.attrset(self.colorscheme.get_attr(*keys)) - - def color_at(self, y, x, wid, keylist = None, *keys): - keys = combine(keylist, keys) - self.win.chgat(y, x, wid, self.colorscheme.get_attr(*keys)) - - def color_reset(self): - Widget.color(self, 'reset') - - def setdim(self, y, x, hei=None, wid=None): - maxy, maxx = self.win.getmaxyx() - - wid = wid or maxx - x - hei = hei or maxy - y - - if x + wid > maxx and y + hei > maxy: - raise OutOfBoundsException("X and Y out of bounds!") - - if x + wid > maxx: - raise OutOfBoundsException("X out of bounds!") - - if y + hei > maxy: - raise OutOfBoundsException("Y out of bounds!") - - self.x = x - self.y = y - self.wid = wid - self.hei = hei - - def contains_point(self, y, x): - return (x >= self.x and x < self.x + self.wid) and \ - (y >= self.y and y < self.y + self.hei) - - def feed_env(self, env): - pass - - def feed(self): - pass - - def click(self, event, fm): - pass - - def press(self, key, fm): - pass - - def draw(self): - pass - - def finalize(self): - pass - - def destroy(self): - pass diff --git a/ranger/gui/widgets/__init__.py b/ranger/gui/widgets/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ranger/gui/widgets/__init__.py diff --git a/ranger/gui/wconsole.py b/ranger/gui/widgets/console.py index 581745b4..ab37d628 100644 --- a/ranger/gui/wconsole.py +++ b/ranger/gui/widgets/console.py @@ -1,13 +1,15 @@ -from ranger.gui.widget import Widget as SuperClass +"""The Console widget implements a vim-like console for entering commands, +searching and executing files.""" +from ..displayable import Displayable import curses CONSOLE_MODES = tuple(':@/?>!') -CONSOLE_MODES_DICTIONARY = { '@': 'open with: ' } +CONSOLE_PROMPTS = { '@': 'open with: ' } -class WConsole(SuperClass): - def __init__(self, win, colorscheme): +class Console(Displayable): + def __init__(self, win): from ranger.container import CommandList - SuperClass.__init__(self, win, colorscheme) + Displayable.__init__(self, win) self.mode = None self.visible = False self.commandlist = CommandList() @@ -16,12 +18,12 @@ class WConsole(SuperClass): self.clear() self.prompt = None self.execute_funcs = { - ':': WConsole.execute_command, - '@': WConsole.execute_openwith_quick, - '/': WConsole.execute_search, - '?': WConsole.execute_search, - '>': WConsole.execute_noreturn, - '!': WConsole.execute_openwith } + ':': Console.execute_command, + '@': Console.execute_openwith_quick, + '/': Console.execute_search, + '?': Console.execute_search, + '>': Console.execute_noreturn, + '!': Console.execute_openwith } def feed_env(self, env): self.cf = env.cf @@ -44,7 +46,7 @@ class WConsole(SuperClass): self.last_cursor_mode = curses.curs_set(1) self.mode = mode try: - self.prompt = CONSOLE_MODES_DICTIONARY[self.mode] + self.prompt = CONSOLE_PROMPTS[self.mode] except KeyError: self.prompt = self.mode self.focused = True @@ -62,22 +64,20 @@ class WConsole(SuperClass): self.pos = 0 self.line = '' - def press(self, key, fm, env): + def press(self, key): from curses.ascii import ctrl, ESC -# from ranger.helper import log -# log(key) try: - cmd = self.commandlist.paths[env.keybuffer] + cmd = self.commandlist.paths[self.env.keybuffer] except KeyError: - env.key_clear() + self.env.key_clear() return if cmd == self.commandlist.dummy_object: return - cmd.execute(self, fm) - env.key_clear() + cmd.execute(self, self.fm) + self.env.key_clear() def type_key(self, key): if isinstance(key, int): diff --git a/ranger/gui/wdisplay.py b/ranger/gui/widgets/filelist.py index c7e78b8e..493dae24 100644 --- a/ranger/gui/wdisplay.py +++ b/ranger/gui/widgets/filelist.py @@ -1,17 +1,17 @@ -from ranger.gui.widget import Widget as SuperClass +"""The FileList widget displays the contents of a directory or file.""" +from ..displayable import Displayable -class WDisplay(SuperClass): - def __init__(self, win, colorscheme, level): - SuperClass.__init__(self, win, colorscheme) +class FileList(Displayable): + main_display = False + display_infostring = False + scroll_begin = 0 + + def __init__(self, win, level): + Displayable.__init__(self, win) 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) - - def click(self, event, fm): + def click(self, event): + """Handle a MouseEvent""" from ranger.fsobject.fsobject import T_DIRECTORY if self.target is None: @@ -22,25 +22,28 @@ class WDisplay(SuperClass): if event.pressed(1): if not self.main_display: - fm.enter_dir(self.target.path) + self.fm.enter_dir(self.target.path) if index < len(self.target): - fm.move_pointer(absolute = index) + self.fm.move_pointer(absolute = index) elif event.pressed(3): try: clicked_file = self.target[index] - fm.enter_dir(clicked_file.path) + self.fm.enter_dir(clicked_file.path) except: pass else: if self.level > 0: - fm.move_right() + self.fm.move_right() def draw(self): + """Call either draw_file() or draw_directory()""" from ranger.fsobject.file import File from ranger.fsobject.directory import Directory + self.target = self.env.at_level(self.level) + if self.target is None: pass elif type(self.target) == File: @@ -51,6 +54,7 @@ class WDisplay(SuperClass): self.win.addnstr(self.y, self.x, "unknown type.", self.wid) def draw_file(self): + """Draw a preview of the file, if the settings allow it""" if not self.target.accessible: self.win.addnstr(self.y, self.x, "not accessible", self.wid) return @@ -66,8 +70,8 @@ class WDisplay(SuperClass): pass def draw_directory(self): + """Draw the contents of a directory""" from ranger.fsobject.directory import Directory - import curses import stat self.target.use() @@ -135,6 +139,7 @@ class WDisplay(SuperClass): self.color_reset() def get_scroll_begin(self): + """Determines scroll_begin (the position of the first displayed file)""" offset = self.settings.scroll_offset dirsize = len(self.target) winsize = self.hei @@ -173,6 +178,7 @@ class WDisplay(SuperClass): return original def set_scroll_begin(self): + """Updates the scroll_begin value""" self.scroll_begin = self.get_scroll_begin() self.target.scroll_begin = self.scroll_begin @@ -187,5 +193,3 @@ class WDisplay(SuperClass): if self.target.scroll_begin == old_value: self.target.move_pointer(relative = relative) self.target.scroll_begin += relative - - diff --git a/ranger/gui/wtitlebar.py b/ranger/gui/widgets/titlebar.py index 65ed2e33..4ec48766 100644 --- a/ranger/gui/wtitlebar.py +++ b/ranger/gui/widgets/titlebar.py @@ -1,24 +1,18 @@ -from ranger.gui.widget import Widget as SuperClass +"""The TitleBar widget displays the current path and some other useful +information.""" -class WTitleBar(SuperClass): - def feed_env(self, env): - self.pathway = env.pathway - self.cf = env.cf - self.keybuffer = env.keybuffer +from ..displayable import Displayable +class TitleBar(Displayable): def draw(self): import curses, socket, os self.win.move(self.y, self.x) - try: - self.color('in_titlebar', 'hostname') - string = os.getenv('LOGNAME') + '@' + socket.gethostname() - self.win.addnstr(string, self.wid) - except: - raise - pass + self.color('in_titlebar', 'hostname') + string = os.getenv('LOGNAME') + '@' + socket.gethostname() + self.win.addnstr(string, self.wid) - for path in self.pathway: + for path in self.env.pathway: currentx = self.win.getyx()[1] if path.islink: @@ -27,14 +21,14 @@ class WTitleBar(SuperClass): self.color('in_titlebar', 'directory') self.win.addnstr(path.basename + '/', max(self.wid - currentx, 0)) - if self.cf is not None: + if self.env.cf is not None: currentx = self.win.getyx()[1] self.color('in_titlebar', 'file') - self.win.addnstr(self.cf.basename, max(self.wid - currentx, 0)) + self.win.addnstr(self.env.cf.basename, max(self.wid - currentx, 0)) self.color('in_titlebar', 'keybuffer') - kb = str(self.keybuffer) + kb = str(self.env.keybuffer) if self.wid + self.x - currentx > len(kb): self.win.addstr( self.y, @@ -42,4 +36,3 @@ class WTitleBar(SuperClass): kb) self.color_reset() - diff --git a/ranger/main.py b/ranger/main.py index 48297a7c..b6af145d 100644 --- a/ranger/main.py +++ b/ranger/main.py @@ -69,11 +69,15 @@ def main(): # Run the file manager my_ui.initialize() my_fm.loop() + +# except: +# from ranger import log +# log(str(sys.exc_info())) finally: # Finish, clean up if 'my_ui' in vars(): - my_ui.exit() + my_ui.destroy() if args.cd_after_exit: try: sys.__stderr__.write(env.pwd.path) diff --git a/test/tc_directory.py b/test/tc_directory.py index 92a4f01c..434d282f 100644 --- a/test/tc_directory.py +++ b/test/tc_directory.py @@ -10,7 +10,7 @@ from ranger.fsobject.directory import Directory from os.path import realpath, join, dirname TESTDIR = realpath(join(dirname(__file__), 'testdir')) TESTFILE = join(TESTDIR, 'testfile5234148') -NONEXISTANT_DIR = '/this/directory/will/most/certainly/not/exist' +NONEXISTANT_DIR = join(TESTDIR, 'nonexistant') import unittest class Test1(unittest.TestCase): |