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.
16 # 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
18 # o wxPopupDialog -> PopupDialog
19 # o wxPopupControl -> PopupControl
23 from wx
.lib
.buttons
import GenButtonEvent
26 class PopButton(wx
.PyControl
):
27 def __init__(self
,*_args
,**_kwargs
):
28 apply(wx
.PyControl
.__init
__,(self
,) + _args
,_kwargs
)
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
)
40 def InitColours(self
):
41 faceClr
= wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_BTNFACE
)
42 self
.faceDnClr
= faceClr
43 self
.SetBackgroundColour(faceClr
)
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
)
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
)
58 def OnEraseBackground(self
, event
):
61 def OnLeftDown(self
, event
):
62 if not self
.IsEnabled():
67 self
.GetParent().textCtrl
.SetFocus()
71 def OnLeftUp(self
, event
):
72 if not self
.IsEnabled():
83 def OnMotion(self
, event
):
84 if not self
.IsEnabled():
86 if event
.LeftIsDown():
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:
94 if not self
.up
and (x
<0 or y
<0 or x
>=w
or y
>=h
):
100 def DrawBezel(self
, dc
, x1
, y1
, x2
, y2
):
101 # draw the upper left sides
103 dc
.SetPen(self
.highlightPen
)
105 dc
.SetPen(self
.shadowPen
)
107 dc
.DrawLine((x1
+i
, y1
), (x1
+i
, y2
-i
))
108 dc
.DrawLine((x1
, y1
+i
), (x2
-i
, y1
+i
))
110 # draw the lower right sides
112 dc
.SetPen(self
.shadowPen
)
114 dc
.SetPen(self
.highlightPen
)
116 dc
.DrawLine((x1
+i
, y2
-i
), (x2
+1, y2
-i
))
117 dc
.DrawLine((x2
-i
, y1
+i
), (x2
-i
, y2
))
119 def DrawArrow(self
,dc
):
120 w
, h
= self
.GetSize()
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))
131 def OnPaint(self
, event
):
132 width
, height
= self
.GetClientSize()
136 dc
= wx
.BufferedPaintDC(self
)
138 dc
.SetBackground(wx
.Brush(self
.GetBackgroundColour(), wx
.SOLID
))
140 dc
.SetBackground(wx
.Brush(self
.faceDnClr
, wx
.SOLID
))
142 self
.DrawBezel(dc
, x1
, y1
, x2
, y2
)
146 #---------------------------------------------------------------------------
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
)
155 self
.win
= wx
.Window(self
,-1,pos
= (0,0),style
= 0)
158 self
.SetContent(content
)
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())
168 pos
= self
.ctrl
.ClientToScreen( (0,0) )
169 dSize
= wx
.GetDisplaySize()
170 selfSize
= self
.GetSize()
171 tcSize
= self
.ctrl
.GetSize()
173 pos
.x
-= (selfSize
.width
- tcSize
.width
) / 2
174 if pos
.x
+ selfSize
.width
> dSize
.width
:
175 pos
.x
= dSize
.width
- selfSize
.width
179 pos
.y
+= tcSize
.height
180 if pos
.y
+ selfSize
.height
> dSize
.height
:
181 pos
.y
= dSize
.height
- selfSize
.height
187 self
.ctrl
.FormatContent()
192 #---------------------------------------------------------------------------
195 class PopupControl(wx
.PyControl
):
196 def __init__(self
,*_args
,**_kwargs
):
197 if _kwargs
.has_key('value'):
199 apply(wx
.PyControl
.__init
__,(self
,) + _args
,_kwargs
)
201 self
.textCtrl
= wx
.TextCtrl(self
,-1,'',pos
= (0,0))
202 self
.bCtrl
= PopButton(self
,-1)
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
)
212 def OnFocus(self
,evt
):
213 self
.textCtrl
.SetFocus()
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
)
221 def OnButton(self
,evt
):
224 self
.pop
= PopupDialog(self
,self
.content
)
227 print 'No Content to pop'
231 def Enable(self
,flag
):
232 wx
.PyControl
.Enable(self
,flag
)
233 self
.textCtrl
.Enable(flag
)
234 self
.bCtrl
.Enable(flag
)
236 def SetPopupContent(self
,content
):
238 self
.content
= content
239 self
.content
.Show(False)
241 self
.pop
.SetContent(content
)
243 def FormatContent(self
):
250 def SetValue(self
,value
):
251 self
.textCtrl
.SetValue(value
)
254 return self
.textCtrl
.GetValue()
258 PopupCtrl
= PopupControl