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