Mercurial > boomslang
annotate pyntnclick/widgets/filechooser.py @ 709:d279a7dd166a pyntnclick
Fix paging bug. Better widget spacing
author | Neil Muller <neil@dip.sun.ac.za> |
---|---|
date | Sun, 05 Aug 2012 13:53:21 +0200 |
parents | 6b8fa2248ee1 |
children | d4f97c8e0dbe |
rev | line source |
---|---|
707 | 1 # Display a paged lsit of files and directories |
2 # Allow moving up and down directory trees | |
3 | |
4 import os | |
5 | |
6 from pyntnclick.widgets.base import Box | |
7 from pyntnclick.widgets.text import TextButton, LabelWidget | |
8 | |
9 | |
10 class FileChooser(Box): | |
11 | |
12 def __init__(self, rect, gd, curdir, page_length=12, padding=2): | |
13 super(FileChooser, self).__init__(rect, gd) | |
14 self.page_length = page_length | |
15 self.page = 0 | |
16 self.curdir = os.path.realpath(os.path.normpath(curdir)) | |
17 self.selected = None | |
18 self.padding = padding | |
19 self.dirs = [] | |
20 self.files = [] | |
21 self.modal = True | |
22 self.prev_but = None | |
23 self.next_but = None | |
24 self.get_lists() | |
25 self.fill_page() | |
26 | |
27 def get_lists(self): | |
28 self.dirs = [] | |
29 self.files = [] | |
30 for entry in sorted(os.listdir(self.curdir)): | |
31 path = os.path.join(self.curdir, entry) | |
32 if os.path.isdir(path): | |
33 self.dirs.append(entry) | |
34 else: | |
35 self.files.append(entry) | |
36 | |
37 def _dir_button(self, entry): | |
38 widget = TextButton((0, 0), self.gd, entry + '/', | |
39 fontname=self.gd.constants.bold_font, | |
40 fontsize=10) | |
41 widget.add_callback('clicked', self.change_dir, entry) | |
42 return widget | |
43 | |
44 def _file_button(self, entry): | |
45 if entry == self.selected: | |
46 # highlight | |
47 widget = TextButton((0, 0), self.gd, entry, | |
48 fontsize=10, border=2, border_color='yellow') | |
49 else: | |
50 widget = TextButton((0, 0), self.gd, entry, fontsize=10) | |
51 self.add_callback('clicked', self.change_selection, entry) | |
52 return widget | |
53 | |
54 def fill_page(self): | |
55 for widget in self.children[:]: | |
56 self.remove(widget) | |
57 start_page = self.page * self.page_length | |
58 end_page = start_page + self.page_length | |
59 entries = self.dirs + self.files | |
60 top = self.rect.top + self.padding | |
61 left = self.rect.left + self.padding | |
62 # Add current directory at the top | |
63 widget = LabelWidget((0, 0), self.gd, self.curdir[-30:], color='black') | |
64 widget.rect.topleft = (left, top) | |
65 self.add(widget) | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
66 upbut = TextButton((left + 2 * self.padding + widget.rect.width, top), |
707 | 67 self.gd, u'\N{LEFTWARDS ARROW WITH HOOK}Back one level') |
68 upbut.add_callback('clicked', self.change_dir, os.pardir) | |
69 self.add(upbut) | |
70 top += max(widget.rect.height, upbut.rect.height) + 4 * self.padding | |
71 page_top = top | |
72 page_left = left | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
73 top += self.padding |
707 | 74 for entry in entries[start_page:end_page]: |
75 if entry in self.dirs: | |
76 widget = self._dir_button(entry) | |
77 else: | |
78 widget = self._file_button(entry) | |
79 widget.rect.topleft = (left, top) | |
80 self.add(widget) | |
81 top += widget.rect.height + self.padding | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
82 page_left = max(page_left, left + widget.rect.width + self.padding) |
707 | 83 # Add page list buttons |
84 if not self.prev_but: | |
85 self.prev_but = TextButton((0, 0), self.gd, u'\N{UPWARDS ARROW}') | |
86 self.prev_but.add_callback('clicked', self.change_page, -1) | |
87 self.prev_but.rect.topleft = (page_left, page_top) | |
88 if not self.next_but: | |
89 self.next_but = TextButton((0, 0), self.gd, u'\N{DOWNWARDS ARROW}') | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
90 self.next_but.add_callback('clicked', self.change_page, +1) |
707 | 91 page_top = max(top - self.next_but.rect.height, |
92 self.prev_but.rect.bottom + self.padding) | |
93 self.next_but.rect.topleft = (page_left, page_top) | |
94 if self.page > 0: | |
95 self.prev_but.enable() | |
96 else: | |
97 self.prev_but.disable() | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
98 if end_page + 1 < len(entries): |
707 | 99 self.next_but.enable() |
100 else: | |
101 self.next_but.disable() | |
102 self.add(self.next_but) | |
103 self.add(self.prev_but) | |
104 # Add OK and Cancel buttons | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
105 top = max(self.prev_but.rect.bottom + self.padding, |
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
106 top + 2 * self.padding) |
707 | 107 ok_but = TextButton((left, top), self.gd, 'OK') |
108 ok_but.add_callback('clicked', self.ok) | |
109 self.add(ok_but) | |
110 cancel_but = TextButton( | |
111 (left + ok_but.rect.width + 4 * self.padding, top), | |
112 self.gd, 'Cancel') | |
113 cancel_but.add_callback('clicked', self.cancel) | |
114 self.add(cancel_but) | |
115 | |
116 def change_page(self, ev, widget, change): | |
117 self.page += change | |
118 self.fill_page() | |
119 return True | |
120 | |
121 def change_dir(self, ev, widget, newdir): | |
122 """Change directory and refresh the widget.""" | |
123 self.curdir = os.path.normpath(os.path.join(self.curdir, newdir)) | |
124 self.page = 0 | |
125 self.selected = None | |
126 self.get_lists() | |
127 self.fill_page() | |
128 | |
129 def change_selection(self, ev, widget, entry): | |
130 """Update selection""" | |
131 self.selected = entry | |
132 | |
133 def cancel(self, ev, widget): | |
134 if hasattr(self.parent, 'paused'): | |
135 self.parent.paused = False | |
136 self.parent.remove(self) | |
137 self.selected = None | |
138 return True | |
139 | |
140 def ok(self, ev, widget): | |
141 if hasattr(self.parent, 'paused'): | |
142 self.parent.paused = False | |
143 self.parent.remove(self) | |
144 return True |