]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/popupctl.py
More agressive cleanup. Now also removes temp items that are created
[wxWidgets.git] / wxPython / wx / lib / popupctl.py
1 #----------------------------------------------------------------------
2 # Name:         popup
3 # Purpose:      Generic popup control
4 #
5 # Author:       Gerrit van Dyk
6 #
7 # Created:      2002/11/20
8 # Version:      0.1
9 # RCS-ID:       $Id$
10 # License:      wxWindows license
11 #----------------------------------------------------------------------
12 # 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
13 #
14 # o 2.5 compatability update.
15 #
16 # 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
17 #
18 # o wxPopupDialog -> PopupDialog
19 # o wxPopupControl -> PopupControl
20 #
21
22 import  wx
23 from wx.lib.buttons import GenButtonEvent
24
25
26 class PopButton(wx.PyControl):
27     def __init__(self,*_args,**_kwargs):
28         apply(wx.PyControl.__init__,(self,) + _args,_kwargs)
29
30         self.up = True
31         self.didDown = False
32
33         self.InitColours()
34
35         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
36         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
37         self.Bind(wx.EVT_MOTION, self.OnMotion)
38         self.Bind(wx.EVT_PAINT, self.OnPaint)
39
40     def InitColours(self):
41         faceClr = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNFACE)
42         self.faceDnClr = faceClr
43         self.SetBackgroundColour(faceClr)
44
45         shadowClr    = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW)
46         highlightClr = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT)
47         self.shadowPen    = wx.Pen(shadowClr, 1, wx.SOLID)
48         self.highlightPen = wx.Pen(highlightClr, 1, wx.SOLID)
49         self.blackPen     = wx.Pen(wx.BLACK, 1, wx.SOLID)
50
51     def Notify(self):
52         evt = GenButtonEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
53         evt.SetIsDown(not self.up)
54         evt.SetButtonObj(self)
55         evt.SetEventObject(self)
56         self.GetEventHandler().ProcessEvent(evt)
57
58     def OnEraseBackground(self, event):
59         pass
60
61     def OnLeftDown(self, event):
62         if not self.IsEnabled():
63             return
64         self.didDown = True
65         self.up = False
66         self.CaptureMouse()
67         self.GetParent().textCtrl.SetFocus()
68         self.Refresh()
69         event.Skip()
70
71     def OnLeftUp(self, event):
72         if not self.IsEnabled():
73             return
74         if self.didDown:
75             self.ReleaseMouse()
76             if not self.up:
77                 self.Notify()
78             self.up = True
79             self.Refresh()
80             self.didDown = False
81         event.Skip()
82
83     def OnMotion(self, event):
84         if not self.IsEnabled():
85             return
86         if event.LeftIsDown():
87             if self.didDown:
88                 x,y = event.GetPosition()
89                 w,h = self.GetClientSize()
90                 if self.up and x<w and x>=0 and y<h and y>=0:
91                     self.up = False
92                     self.Refresh()
93                     return
94                 if not self.up and (x<0 or y<0 or x>=w or y>=h):
95                     self.up = True
96                     self.Refresh()
97                     return
98         event.Skip()
99
100     def DrawBezel(self, dc, x1, y1, x2, y2):
101         # draw the upper left sides
102         if self.up:
103             dc.SetPen(self.highlightPen)
104         else:
105             dc.SetPen(self.shadowPen)
106         for i in range(2):
107             dc.DrawLine((x1+i, y1), (x1+i, y2-i))
108             dc.DrawLine((x1, y1+i), (x2-i, y1+i))
109
110         # draw the lower right sides
111         if self.up:
112             dc.SetPen(self.shadowPen)
113         else:
114             dc.SetPen(self.highlightPen)
115         for i in range(2):
116             dc.DrawLine((x1+i, y2-i), (x2+1, y2-i))
117             dc.DrawLine((x2-i, y1+i), (x2-i, y2))
118
119     def DrawArrow(self,dc):
120         w, h = self.GetSize()
121         mx = w / 2
122         my = h / 2
123         dc.SetPen(self.highlightPen)
124         dc.DrawLine((mx-5,my-5), (mx+5,my-5))
125         dc.DrawLine((mx-5,my-5), (mx,my+5))
126         dc.SetPen(self.shadowPen)
127         dc.DrawLine((mx+4,my-5), (mx,my+5))
128         dc.SetPen(self.blackPen)
129         dc.DrawLine((mx+5,my-5), (mx,my+5))
130
131     def OnPaint(self, event):
132         width, height = self.GetClientSize()
133         x1 = y1 = 0
134         x2 = width - 1
135         y2 = height - 1
136         dc = wx.BufferedPaintDC(self)
137         if self.up:
138             dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
139         else:
140             dc.SetBackground(wx.Brush(self.faceDnClr, wx.SOLID))
141         dc.Clear()
142         self.DrawBezel(dc, x1, y1, x2, y2)
143         self.DrawArrow(dc)
144
145
146 #---------------------------------------------------------------------------
147
148
149 # Tried to use wxPopupWindow but the control misbehaves on MSW
150 class PopupDialog(wx.Dialog):
151     def __init__(self,parent,content = None):
152         wx.Dialog.__init__(self,parent,-1,'', style = wx.BORDER_SIMPLE|wx.STAY_ON_TOP)
153
154         self.ctrl = parent
155         self.win = wx.Window(self,-1,pos = (0,0),style = 0)
156
157         if content:
158             self.SetContent(content)
159
160     def SetContent(self,content):
161         self.content = content
162         self.content.Reparent(self.win)
163         self.content.Show(True)
164         self.win.SetClientSize(self.content.GetSize())
165         self.SetSize(self.win.GetSize())
166
167     def Display(self):
168         pos = self.ctrl.ClientToScreen( (0,0) )
169         dSize = wx.GetDisplaySize()
170         selfSize = self.GetSize()
171         tcSize = self.ctrl.GetSize()
172
173         pos.x -= (selfSize.width - tcSize.width) / 2
174         if pos.x + selfSize.width > dSize.width:
175             pos.x = dSize.width - selfSize.width
176         if pos.x < 0:
177             pos.x = 0
178
179         pos.y += tcSize.height
180         if pos.y + selfSize.height > dSize.height:
181             pos.y = dSize.height - selfSize.height
182         if pos.y < 0:
183             pos.y = 0
184
185         self.Move(pos)
186
187         self.ctrl.FormatContent()
188
189         self.ShowModal()
190
191
192 #---------------------------------------------------------------------------
193
194
195 class PopupControl(wx.PyControl):
196     def __init__(self,*_args,**_kwargs):
197         if _kwargs.has_key('value'):
198             del _kwargs['value']
199         apply(wx.PyControl.__init__,(self,) + _args,_kwargs)
200
201         self.textCtrl = wx.TextCtrl(self,-1,'',pos = (0,0))
202         self.bCtrl = PopButton(self,-1)
203         self.pop = None
204         self.content = None
205         self.OnSize(None)
206
207         self.Bind(wx.EVT_SIZE, self.OnSize)
208         self.bCtrl.Bind(wx.EVT_BUTTON, self.OnButton, self.bCtrl)
209         # embedded control should get focus on TAB keypress
210         self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
211
212     def OnFocus(self,evt):
213         self.textCtrl.SetFocus()
214         evt.Skip()
215
216     def OnSize(self,evt):
217         w,h = self.GetClientSize()
218         self.textCtrl.SetDimensions(0,0,w-17,h)
219         self.bCtrl.SetDimensions(w-17,0,17,h)
220
221     def OnButton(self,evt):
222         if not self.pop:
223             if self.content:
224                 self.pop = PopupDialog(self,self.content)
225                 del self.content
226             else:
227                 print 'No Content to pop'
228         if self.pop:
229             self.pop.Display()
230
231     def Enable(self,flag):
232         wx.PyControl.Enable(self,flag)
233         self.textCtrl.Enable(flag)
234         self.bCtrl.Enable(flag)
235
236     def SetPopupContent(self,content):
237         if not self.pop:
238             self.content = content
239             self.content.Show(False)
240         else:
241             self.pop.SetContent(content)
242
243     def FormatContent(self):
244         pass
245
246     def PopDown(self):
247         if self.pop:
248             self.pop.EndModal(1)
249
250     def SetValue(self,value):
251         self.textCtrl.SetValue(value)
252
253     def GetValue(self):
254         return self.textCtrl.GetValue()
255
256
257 # an alias
258 PopupCtrl = PopupControl