blob: 92119365770540d8e5c57673f95f359a581892a3 [file] [log] [blame]
Guido van Rossume6fae1c1998-10-15 23:27:08 +00001from Tkinter import *
2
3class ScrolledList:
Tim Peters70c43782001-01-17 08:48:39 +00004
Guido van Rossumac1cb161999-03-10 05:10:49 +00005 default = "(None)"
Guido van Rossum504b0bf1999-01-02 21:28:54 +00006
Guido van Rossume6fae1c1998-10-15 23:27:08 +00007 def __init__(self, master, **options):
8 # Create top frame, with scrollbar and listbox
9 self.master = master
10 self.frame = frame = Frame(master)
11 self.frame.pack(fill="both", expand=1)
12 self.vbar = vbar = Scrollbar(frame, name="vbar")
13 self.vbar.pack(side="right", fill="y")
Guido van Rossumac1cb161999-03-10 05:10:49 +000014 self.listbox = listbox = Listbox(frame, exportselection=0,
15 background="white")
Guido van Rossume6fae1c1998-10-15 23:27:08 +000016 if options:
17 listbox.configure(options)
18 listbox.pack(expand=1, fill="both")
19 # Tie listbox and scrollbar together
20 vbar["command"] = listbox.yview
21 listbox["yscrollcommand"] = vbar.set
22 # Bind events to the list box
23 listbox.bind("<ButtonRelease-1>", self.click_event)
Guido van Rossum504b0bf1999-01-02 21:28:54 +000024 listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
Guido van Rossume6fae1c1998-10-15 23:27:08 +000025 listbox.bind("<ButtonPress-3>", self.popup_event)
26 listbox.bind("<Key-Up>", self.up_event)
27 listbox.bind("<Key-Down>", self.down_event)
Guido van Rossumac1cb161999-03-10 05:10:49 +000028 # Mark as empty
29 self.clear()
Guido van Rossum504b0bf1999-01-02 21:28:54 +000030
Guido van Rossum95ef4981998-10-16 16:10:09 +000031 def close(self):
32 self.frame.destroy()
Guido van Rossum504b0bf1999-01-02 21:28:54 +000033
Guido van Rossume6fae1c1998-10-15 23:27:08 +000034 def clear(self):
35 self.listbox.delete(0, "end")
Guido van Rossumac1cb161999-03-10 05:10:49 +000036 self.empty = 1
37 self.listbox.insert("end", self.default)
Guido van Rossum504b0bf1999-01-02 21:28:54 +000038
Guido van Rossume6fae1c1998-10-15 23:27:08 +000039 def append(self, item):
Guido van Rossumac1cb161999-03-10 05:10:49 +000040 if self.empty:
41 self.listbox.delete(0, "end")
42 self.empty = 0
Guido van Rossume6fae1c1998-10-15 23:27:08 +000043 self.listbox.insert("end", str(item))
Guido van Rossum504b0bf1999-01-02 21:28:54 +000044
Guido van Rossume6fae1c1998-10-15 23:27:08 +000045 def get(self, index):
46 return self.listbox.get(index)
47
48 def click_event(self, event):
49 self.listbox.activate("@%d,%d" % (event.x, event.y))
50 index = self.listbox.index("active")
51 self.select(index)
52 self.on_select(index)
53 return "break"
54
55 def double_click_event(self, event):
56 index = self.listbox.index("active")
57 self.select(index)
58 self.on_double(index)
59 return "break"
Guido van Rossum504b0bf1999-01-02 21:28:54 +000060
Guido van Rossume6fae1c1998-10-15 23:27:08 +000061 menu = None
Guido van Rossum504b0bf1999-01-02 21:28:54 +000062
Guido van Rossume6fae1c1998-10-15 23:27:08 +000063 def popup_event(self, event):
64 if not self.menu:
65 self.make_menu()
66 menu = self.menu
67 self.listbox.activate("@%d,%d" % (event.x, event.y))
68 index = self.listbox.index("active")
69 self.select(index)
70 menu.tk_popup(event.x_root, event.y_root)
71
72 def make_menu(self):
73 menu = Menu(self.listbox, tearoff=0)
74 self.menu = menu
75 self.fill_menu()
Guido van Rossum504b0bf1999-01-02 21:28:54 +000076
Guido van Rossume6fae1c1998-10-15 23:27:08 +000077 def up_event(self, event):
78 index = self.listbox.index("active")
79 if self.listbox.selection_includes(index):
80 index = index - 1
81 else:
82 index = self.listbox.size() - 1
83 if index < 0:
84 self.listbox.bell()
85 else:
86 self.select(index)
87 self.on_select(index)
88 return "break"
Guido van Rossum504b0bf1999-01-02 21:28:54 +000089
Guido van Rossume6fae1c1998-10-15 23:27:08 +000090 def down_event(self, event):
91 index = self.listbox.index("active")
92 if self.listbox.selection_includes(index):
93 index = index + 1
94 else:
95 index = 0
96 if index >= self.listbox.size():
97 self.listbox.bell()
98 else:
99 self.select(index)
100 self.on_select(index)
101 return "break"
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000102
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000103 def select(self, index):
104 self.listbox.focus_set()
105 self.listbox.activate(index)
106 self.listbox.selection_clear(0, "end")
107 self.listbox.selection_set(index)
108 self.listbox.see(index)
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000109
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000110 # Methods to override for specific actions
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000111
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000112 def fill_menu(self):
113 pass
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000114
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000115 def on_select(self, index):
116 pass
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000117
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000118 def on_double(self, index):
119 pass
120
121
122def test():
123 root = Tk()
124 root.protocol("WM_DELETE_WINDOW", root.destroy)
125 class MyScrolledList(ScrolledList):
126 def fill_menu(self): self.menu.add_command(label="pass")
127 def on_select(self, index): print "select", self.get(index)
128 def on_double(self, index): print "double", self.get(index)
129 s = MyScrolledList(root)
130 for i in range(30):
131 s.append("item %02d" % i)
132 return root
133
134def main():
135 root = test()
136 root.mainloop()
137
138if __name__ == '__main__':
139 main()