Mercurial > boomslang
annotate pyntnclick/widgets/filechooser.py @ 710:d4f97c8e0dbe pyntnclick
Fix selection display
author | Neil Muller <neil@dip.sun.ac.za> |
---|---|
date | Sun, 05 Aug 2012 14:00:04 +0200 |
parents | d279a7dd166a |
children | f33dd2093f77 |
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, | |
710 | 48 fontsize=10, border=2, color='yellow') |
707 | 49 else: |
710 | 50 widget = TextButton((0, 0), self.gd, entry, border=0, |
51 fontsize=10) | |
52 widget.add_callback('clicked', self.change_selection, entry) | |
707 | 53 return widget |
54 | |
55 def fill_page(self): | |
56 for widget in self.children[:]: | |
57 self.remove(widget) | |
58 start_page = self.page * self.page_length | |
59 end_page = start_page + self.page_length | |
60 entries = self.dirs + self.files | |
61 top = self.rect.top + self.padding | |
62 left = self.rect.left + self.padding | |
63 # Add current directory at the top | |
64 widget = LabelWidget((0, 0), self.gd, self.curdir[-30:], color='black') | |
65 widget.rect.topleft = (left, top) | |
66 self.add(widget) | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
67 upbut = TextButton((left + 2 * self.padding + widget.rect.width, top), |
707 | 68 self.gd, u'\N{LEFTWARDS ARROW WITH HOOK}Back one level') |
69 upbut.add_callback('clicked', self.change_dir, os.pardir) | |
70 self.add(upbut) | |
71 top += max(widget.rect.height, upbut.rect.height) + 4 * self.padding | |
72 page_top = top | |
73 page_left = left | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
74 top += self.padding |
707 | 75 for entry in entries[start_page:end_page]: |
76 if entry in self.dirs: | |
77 widget = self._dir_button(entry) | |
78 else: | |
79 widget = self._file_button(entry) | |
80 widget.rect.topleft = (left, top) | |
81 self.add(widget) | |
82 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
|
83 page_left = max(page_left, left + widget.rect.width + self.padding) |
707 | 84 # Add page list buttons |
85 if not self.prev_but: | |
86 self.prev_but = TextButton((0, 0), self.gd, u'\N{UPWARDS ARROW}') | |
87 self.prev_but.add_callback('clicked', self.change_page, -1) | |
88 self.prev_but.rect.topleft = (page_left, page_top) | |
89 if not self.next_but: | |
90 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
|
91 self.next_but.add_callback('clicked', self.change_page, +1) |
707 | 92 page_top = max(top - self.next_but.rect.height, |
93 self.prev_but.rect.bottom + self.padding) | |
94 self.next_but.rect.topleft = (page_left, page_top) | |
95 if self.page > 0: | |
96 self.prev_but.enable() | |
97 else: | |
98 self.prev_but.disable() | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
99 if end_page + 1 < len(entries): |
707 | 100 self.next_but.enable() |
101 else: | |
102 self.next_but.disable() | |
103 self.add(self.next_but) | |
104 self.add(self.prev_but) | |
105 # Add OK and Cancel buttons | |
709
d279a7dd166a
Fix paging bug. Better widget spacing
Neil Muller <neil@dip.sun.ac.za>
parents:
707
diff
changeset
|
106 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
|
107 top + 2 * self.padding) |
707 | 108 ok_but = TextButton((left, top), self.gd, 'OK') |
109 ok_but.add_callback('clicked', self.ok) | |
110 self.add(ok_but) | |
111 cancel_but = TextButton( | |
112 (left + ok_but.rect.width + 4 * self.padding, top), | |
113 self.gd, 'Cancel') | |
114 cancel_but.add_callback('clicked', self.cancel) | |
115 self.add(cancel_but) | |
116 | |
117 def change_page(self, ev, widget, change): | |
118 self.page += change | |
119 self.fill_page() | |
120 return True | |
121 | |
122 def change_dir(self, ev, widget, newdir): | |
123 """Change directory and refresh the widget.""" | |
124 self.curdir = os.path.normpath(os.path.join(self.curdir, newdir)) | |
125 self.page = 0 | |
126 self.selected = None | |
127 self.get_lists() | |
128 self.fill_page() | |
129 | |
130 def change_selection(self, ev, widget, entry): | |
131 """Update selection""" | |
132 self.selected = entry | |
710 | 133 self.fill_page() |
707 | 134 |
135 def cancel(self, ev, widget): | |
136 if hasattr(self.parent, 'paused'): | |
137 self.parent.paused = False | |
138 self.parent.remove(self) | |
139 self.selected = None | |
140 return True | |
141 | |
142 def ok(self, ev, widget): | |
143 if hasattr(self.parent, 'paused'): | |
144 self.parent.paused = False | |
145 self.parent.remove(self) | |
146 return True |