summaryrefslogtreecommitdiffstats
path: root/Tools/idle/MultiScrolledLists.py
blob: 6398b86dd384855837b159349ccaf635bf6d59bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# One or more ScrolledLists with HSeparators between them.
# There is a hierarchical relationship between them:
# the right list displays the substructure of the selected item
# in the left list.

from Tkinter import *
from WindowList import ListedToplevel
from Separator import HSeparator
from ScrolledList import ScrolledList

class MultiScrolledLists:

    def __init__(self, root, nlists=2):
        assert nlists >= 1
        self.root = root
        self.nlists = nlists
        self.path = []
        # create top
        self.top = top = ListedToplevel(root)
        top.protocol("WM_DELETE_WINDOW", self.close)
        top.bind("<Escape>", self.close)
        self.settitle()
        # create frames and separators in between
        self.frames = []
        self.separators = []
        last = top
        for i in range(nlists-1):
            sepa = HSeparator(last)
            self.separators.append(sepa)
            frame, last = sepa.parts()
            self.frames.append(frame)
        self.frames.append(last)
        # create labels and lists
        self.labels = []
        self.lists = []
        for i in range(nlists):
            frame = self.frames[i]
            label = Label(frame, text=self.subtitle(i),
                relief="groove", borderwidth=2)
            label.pack(fill="x")
            self.labels.append(label)
            list = ScrolledList(frame, width=self.width(i),
                height=self.height(i))
            self.lists.append(list)
            list.on_select = \
                lambda index, i=i, self=self: self.on_select(index, i)
            list.on_double = \
                lambda index, i=i, self=self: self.on_double(index, i)
        # fill leftmost list (rest get filled on demand)
        self.fill(0)
        # XXX one after_idle isn't enough; two are...
        top.after_idle(self.call_pack_propagate_1)

    def call_pack_propagate_1(self):
        self.top.after_idle(self.call_pack_propagate)

    def call_pack_propagate(self):
        for frame in self.frames:
            frame.pack_propagate(0)

    def close(self, event=None):
        self.top.destroy()

    def settitle(self):
        short = self.shorttitle()
        long = self.longtitle()
        if short and long:
            title = short + " - " + long
        elif short:
            title = short
        elif long:
            title = long
        else:
            title = "Untitled"
        icon = short or long or title
        self.top.wm_title(title)
        self.top.wm_iconname(icon)

    def longtitle(self):
        # override this
        return "Multi Scrolled Lists"

    def shorttitle(self):
        # override this
        return None

    def width(self, i):
        # override this
        return 20

    def height(self, i):
        # override this
        return 10

    def subtitle(self, i):
        # override this
        return "Column %d" % i

    def fill(self, i):
        for k in range(i, self.nlists):
            self.lists[k].clear()
            self.labels[k].configure(text=self.subtitle(k))
        list = self.lists[i]
        l = self.items(i)
        for s in l:
            list.append(s)

    def on_select(self, index, i):
        item = self.lists[i].get(index)
        del self.path[i:]
        self.path.append(item)
        if i+1 < self.nlists:
            self.fill(i+1)

    def items(self, i):
        # override this
        l = []
        for k in range(10):
            s = str(k)
            if i > 0:
                s = self.path[i-1] + "." + s
            l.append(s)
        return l

    def on_double(self, index, i):
        pass


def main():
    root = Tk()
    quit = Button(root, text="Exit", command=root.destroy)
    quit.pack()
    MultiScrolledLists(root, 4)
    root.mainloop()

if __name__ == "__main__":
    main()