blob: 9af50a7d6be8d1435bfd57a45e40796a7be2d78c [file] [log] [blame]
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001import FrameWork
Jack Jansen5a6fdcd2001-08-25 12:15:04 +00002from Carbon import Qd
3import Wbase, Wcontrols
4from Carbon import Ctl, Controls
Just van Rossum40f9b7b1999-01-30 22:39:17 +00005from types import *
6import Wapplication
7
8_arrowright = Qd.GetPicture(472)
9_arrowdown = Qd.GetPicture(473)
10
11
Just van Rossumd949b5c2000-04-09 19:45:08 +000012class PopupControl(Wcontrols.ControlWidget):
13
14 def __init__(self, possize, items=None, callback=None):
15 if items is None:
16 items = []
17 procID = Controls.popupMenuProc|Controls.popupFixedWidth|Controls.useWFont
18 Wcontrols.ControlWidget.__init__(self, possize, "", procID, callback, 0, 0, 0)
19 self._items = items[:]
20
21 def set(self, value):
22 self._control.SetControlValue(value+1)
23
24 def get(self):
25 return self._control.GetControlValue() - 1
26
27 def open(self):
28 self.menu = menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
29
30 for i in range(len(self._items)):
31 item = self._items[i]
32 if type(item) == StringType:
33 menuitemtext = object = item
34 elif type(item) == TupleType and len(item) == 2:
35 menuitemtext, object = item
36 self._items[i] = object
37 else:
38 raise Wbase.WidgetsError, "illegal itemlist for popup menu"
39 menuitem = FrameWork.MenuItem(menu, menuitemtext, None, None)
40
41 self._calcbounds()
42 self._control = Ctl.NewControl(self._parentwindow.wid,
43 self._bounds,
44 self._title,
45 1,
46 self._value,
47 self.menu.id,
48 self._max,
49 self._procID,
50 0)
51 self.SetPort()
52 self.enable(self._enabled)
53
54 def close(self):
55 self.menu.delete()
56 return Wcontrols.ControlWidget.close(self)
57
58 def click(self, point, modifiers):
59 if not self._enabled:
60 return
61 part = self._control.TrackControl(point, -1)
62 if part:
63 if self._callback:
64 Wbase.CallbackCall(self._callback, 0, self._items[self.get()])
65
Just van Rossum40f9b7b1999-01-30 22:39:17 +000066
67class PopupWidget(Wbase.ClickableWidget):
68
69 """Simple title-less popup widget. Should be 16x16 pixels.
70 Builds the menu items on the fly, good for dynamic popup menus."""
71
Just van Rossumd949b5c2000-04-09 19:45:08 +000072 def __init__(self, possize, items=None, callback=None):
73 Wbase.ClickableWidget.__init__(self, possize)
74 if items is None:
75 items = []
Just van Rossum40f9b7b1999-01-30 22:39:17 +000076 self._items = items
77 self._itemsdict = {}
78 self._callback = callback
79 self._enabled = 1
80
81 def close(self):
Just van Rossumd949b5c2000-04-09 19:45:08 +000082 Wbase.ClickableWidget.close(self)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000083 self._items = None
84 self._itemsdict = {}
85
86 def draw(self, visRgn = None):
87 if self._visible:
88 Qd.FrameRect(self._bounds)
89 Qd.EraseRect(Qd.InsetRect(self._bounds, 1, 1))
90 l, t, r, b = self._bounds
91 l = l + 2
92 t = t + 3
93 pictframe = (l, t, l + 10, t + 10)
94 Qd.DrawPicture(_arrowright, pictframe)
95
96 def click(self, point, modifiers):
97 if not self._enabled:
98 return
99 self.menu = FrameWork.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
100 self._additems(self._items, self.menu)
101 self.SetPort()
102 l, t, r, b = self._bounds
103 l, t = Qd.LocalToGlobal((l+1, t+1))
104 Wbase.SetCursor("arrow")
Jack Jansenafd0aa62001-01-29 13:29:47 +0000105 self.menu.menu.EnableMenuItem(0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000106 reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
107 if reply:
108 id = (reply & 0xffff0000) >> 16
109 item = reply & 0xffff
110 self._menu_callback(id, item)
111 self._emptymenu()
112
113 def set(self, items):
114 self._items = items
115
116 def get(self):
117 return self._items
118
119 def _additems(self, items, menu):
120 from FrameWork import SubMenu, MenuItem
121 menu_id = menu.id
122 for item in items:
123 if item == "-":
124 menu.addseparator()
125 continue
126 elif type(item) == ListType:
127 submenu = SubMenu(menu, item[0])
128 self._additems(item[1:], submenu)
129 continue
130 elif type(item) == StringType:
131 menuitemtext = object = item
132 elif type(item) == TupleType and len(item) == 2:
133 menuitemtext, object = item
134 else:
135 raise Wbase.WidgetsError, "illegal itemlist for popup menu"
136
137 if menuitemtext[:1] == '\0':
138 check = ord(menuitemtext[1])
139 menuitemtext = menuitemtext[2:]
140 else:
141 check = 0
142 menuitem = MenuItem(menu, menuitemtext, None, None)
143 if check:
144 menuitem.check(1)
145 self._itemsdict[(menu_id, menuitem.item)] = object
146
147 def _emptymenu(self):
148 menus = self._parentwindow.parent.menubar.menus
149 for id, item in self._itemsdict.keys():
150 if menus.has_key(id):
151 self.menu = menus[id]
152 self.menu.delete()
153 self._itemsdict = {}
154
155 def _menu_callback(self, id, item):
156 thing = self._itemsdict[(id, item)]
157 if callable(thing):
158 thing()
159 elif self._callback:
160 Wbase.CallbackCall(self._callback, 0, thing)
161
162
163class PopupMenu(PopupWidget):
164
165 """Simple title-less popup widget. Should be 16x16 pixels.
166 Prebuilds the menu items, good for static (non changing) popup menus."""
167
168 def open(self):
169 self._calcbounds()
170 self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
171 self._additems(self._items, self.menu)
172
173 def close(self):
174 self._emptymenu()
175 Wbase.Widget.close(self)
176 self._items = None
177 self._itemsdict = {}
178 self.menu = None
179
180 def set(self, items):
181 if self._itemsdict:
182 self._emptymenu()
183 self.menu = Wapplication.Menu(self._parentwindow.parent.menubar, 'Foo', -1)
184 self._items = items
185 self._additems(self._items, self.menu)
186
187 def click(self, point, modifiers):
188 if not self._enabled:
189 return
190 self.SetPort()
191 l, t, r, b = self._bounds
192 l, t = Qd.LocalToGlobal((l+1, t+1))
193 Wbase.SetCursor("arrow")
Jack Jansenafd0aa62001-01-29 13:29:47 +0000194 self.menu.menu.EnableMenuItem(0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000195 reply = self.menu.menu.PopUpMenuSelect(t, l, 1)
196 if reply:
197 id = (reply & 0xffff0000) >> 16
198 item = reply & 0xffff
199 self._menu_callback(id, item)
200
201
202class FontMenu(PopupMenu):
203
204 """A font popup menu."""
205
206 menu = None
207
208 def __init__(self, possize, callback):
209 PopupMenu.__init__(self, possize)
210 _makefontmenu()
211 self._callback = callback
212 self._enabled = 1
213
214 def open(self):
215 self._calcbounds()
216
217 def close(self):
218 del self._callback
219
220 def set(self):
221 raise Wbase.WidgetsError, "can't change font menu widget"
222
223 def _menu_callback(self, id, item):
224 fontname = self.menu.menu.GetMenuItemText(item)
225 if self._callback:
226 Wbase.CallbackCall(self._callback, 0, fontname)
227
228 def click(self, point, modifiers):
229 if not self._enabled:
230 return
231 _makefontmenu()
232 return PopupMenu.click(self, point, modifiers)
233
234
235def _makefontmenu():
236 """helper for font menu"""
237 if FontMenu.menu is not None:
238 return
239 import W
240 FontMenu.menu = Wapplication.Menu(W.getapplication().menubar, 'Foo', -1)
241 W.SetCursor('watch')
Jack Jansen565e9562001-01-29 15:18:46 +0000242 for i in range(FontMenu.menu.menu.CountMenuItems(), 0, -1):
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000243 FontMenu.menu.menu.DeleteMenuItem(i)
244 FontMenu.menu.menu.AppendResMenu('FOND')
245
246
247def _getfontlist():
Jack Jansen5a6fdcd2001-08-25 12:15:04 +0000248 from Carbon import Res
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000249 fontnames = []
250 for i in range(1, Res.CountResources('FOND') + 1):
251 r = Res.GetIndResource('FOND', i)
252 fontnames.append(r.GetResInfo()[2])
253 return fontnames