1 #----------------------------------------------------------------------
3 # Purpose: Generic popup control
5 # Author: Gerrit van Dyk
10 # License: wxWindows license
11 #----------------------------------------------------------------------
12 # 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
14 # o 2.5 compatability update.
18 from wx
.lib
.buttons
import GenButtonEvent
21 class PopButton(wx
.PyControl
):
22 def __init__(self
,*_args
,**_kwargs
):
23 apply(wx
.PyControl
.__init
__,(self
,) + _args
,_kwargs
)
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
)
35 def InitColours(self
):
36 faceClr
= wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_BTNFACE
)
37 self
.faceDnClr
= faceClr
38 self
.SetBackgroundColour(faceClr
)
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
)
47 evt
= GenButtonEvent(wx
.wxEVT_COMMAND_BUTTON_CLICKED
, self
.GetId())
48 evt
.SetIsDown(not self
.up
)
49 evt
.SetButtonObj(self
)
50 evt
.SetEventObject(self
)
51 self
.GetEventHandler().ProcessEvent(evt
)
53 def OnEraseBackground(self
, event
):
56 def OnLeftDown(self
, event
):
57 if not self
.IsEnabled():
62 self
.GetParent().textCtrl
.SetFocus()
66 def OnLeftUp(self
, event
):
67 if not self
.IsEnabled():
78 def OnMotion(self
, event
):
79 if not self
.IsEnabled():
81 if event
.LeftIsDown():
83 x
,y
= event
.GetPosition()
84 w
,h
= self
.GetClientSize()
85 if self
.up
and x
<w
and x
>=0 and y
<h
and y
>=0:
89 if not self
.up
and (x
<0 or y
<0 or x
>=w
or y
>=h
):
95 def DrawBezel(self
, dc
, x1
, y1
, x2
, y2
):
96 # draw the upper left sides
98 dc
.SetPen(self
.highlightPen
)
100 dc
.SetPen(self
.shadowPen
)
102 dc
.DrawLine((x1
+i
, y1
), (x1
+i
, y2
-i
))
103 dc
.DrawLine((x1
, y1
+i
), (x2
-i
, y1
+i
))
105 # draw the lower right sides
107 dc
.SetPen(self
.shadowPen
)
109 dc
.SetPen(self
.highlightPen
)
111 dc
.DrawLine((x1
+i
, y2
-i
), (x2
+1, y2
-i
))
112 dc
.DrawLine((x2
-i
, y1
+i
), (x2
-i
, y2
))
114 def DrawArrow(self
,dc
):
115 w
, h
= self
.GetSize()
118 dc
.SetPen(self
.highlightPen
)
119 dc
.DrawLine((mx
-5,my
-5), (mx
+5,my
-5))
120 dc
.DrawLine((mx
-5,my
-5), (mx
,my
+5))
121 dc
.SetPen(self
.shadowPen
)
122 dc
.DrawLine((mx
+4,my
-5), (mx
,my
+5))
123 dc
.SetPen(self
.blackPen
)
124 dc
.DrawLine((mx
+5,my
-5), (mx
,my
+5))
126 def OnPaint(self
, event
):
127 width
, height
= self
.GetClientSize()
131 dc
= wx
.BufferedPaintDC(self
)
133 dc
.SetBackground(wx
.Brush(self
.GetBackgroundColour(), wx
.SOLID
))
135 dc
.SetBackground(wx
.Brush(self
.faceDnClr
, wx
.SOLID
))
137 self
.DrawBezel(dc
, x1
, y1
, x2
, y2
)
141 #---------------------------------------------------------------------------
144 # Tried to use wxPopupWindow but the control misbehaves on MSW
145 class wxPopupDialog(wx
.Dialog
):
146 def __init__(self
,parent
,content
= None):
147 wx
.Dialog
.__init
__(self
,parent
,-1,'', style
= wx
.BORDER_SIMPLE|wx
.STAY_ON_TOP
)
150 self
.win
= wx
.Window(self
,-1,pos
= (0,0),style
= 0)
153 self
.SetContent(content
)
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())
163 pos
= self
.ctrl
.ClientToScreen( (0,0) )
164 dSize
= wx
.GetDisplaySize()
165 selfSize
= self
.GetSize()
166 tcSize
= self
.ctrl
.GetSize()
168 pos
.x
-= (selfSize
.width
- tcSize
.width
) / 2
169 if pos
.x
+ selfSize
.width
> dSize
.width
:
170 pos
.x
= dSize
.width
- selfSize
.width
174 pos
.y
+= tcSize
.height
175 if pos
.y
+ selfSize
.height
> dSize
.height
:
176 pos
.y
= dSize
.height
- selfSize
.height
182 self
.ctrl
.FormatContent()
187 #---------------------------------------------------------------------------
190 class wxPopupControl(wx
.PyControl
):
191 def __init__(self
,*_args
,**_kwargs
):
192 if _kwargs
.has_key('value'):
194 apply(wx
.PyControl
.__init
__,(self
,) + _args
,_kwargs
)
196 self
.textCtrl
= wx
.TextCtrl(self
,-1,'',pos
= (0,0))
197 self
.bCtrl
= PopButton(self
,-1)
202 self
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
203 self
.bCtrl
.Bind(wx
.EVT_BUTTON
, self
.OnButton
, self
.bCtrl
)
204 # embedded control should get focus on TAB keypress
205 self
.Bind(wx
.EVT_SET_FOCUS
, self
.OnFocus
)
207 def OnFocus(self
,evt
):
208 self
.textCtrl
.SetFocus()
211 def OnSize(self
,evt
):
212 w
,h
= self
.GetClientSize()
213 self
.textCtrl
.SetDimensions(0,0,w
-17,h
)
214 self
.bCtrl
.SetDimensions(w
-17,0,17,h
)
216 def OnButton(self
,evt
):
219 self
.pop
= wxPopupDialog(self
,self
.content
)
222 print 'No Content to pop'
226 def Enable(self
,flag
):
227 wx
.PyControl
.Enable(self
,flag
)
228 self
.textCtrl
.Enable(flag
)
229 self
.bCtrl
.Enable(flag
)
231 def SetPopupContent(self
,content
):
233 self
.content
= content
234 self
.content
.Show(False)
236 self
.pop
.SetContent(content
)
238 def FormatContent(self
):
245 def SetValue(self
,value
):
246 self
.textCtrl
.SetValue(value
)
249 return self
.textCtrl
.GetValue()
253 wxPopupCtrl
= wxPopupControl