1 #----------------------------------------------------------------------
3 # Purpose: Generic popup control
5 # Author: Gerrit van Dyk
10 # License: wxWindows license
11 #----------------------------------------------------------------------
13 from wxPython
.wx
import *
14 from wxPython
.lib
.buttons
import wxGenButtonEvent
17 class PopButton(wxPyControl
):
18 def __init__(self
,*_args
,**_kwargs
):
19 apply(wxPyControl
.__init
__,(self
,) + _args
,_kwargs
)
26 EVT_LEFT_DOWN(self
, self
.OnLeftDown
)
27 EVT_LEFT_UP(self
, self
.OnLeftUp
)
28 EVT_MOTION(self
, self
.OnMotion
)
29 EVT_PAINT(self
, self
.OnPaint
)
31 def InitColours(self
):
32 faceClr
= wxSystemSettings_GetColour(wxSYS_COLOUR_BTNFACE
)
33 self
.faceDnClr
= faceClr
34 self
.SetBackgroundColour(faceClr
)
36 shadowClr
= wxSystemSettings_GetColour(wxSYS_COLOUR_BTNSHADOW
)
37 highlightClr
= wxSystemSettings_GetColour(wxSYS_COLOUR_BTNHIGHLIGHT
)
38 self
.shadowPen
= wxPen(shadowClr
, 1, wxSOLID
)
39 self
.highlightPen
= wxPen(highlightClr
, 1, wxSOLID
)
40 self
.blackPen
= wxPen(wxBLACK
, 1, wxSOLID
)
43 evt
= wxGenButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED
, self
.GetId())
44 evt
.SetIsDown(not self
.up
)
45 evt
.SetButtonObj(self
)
46 evt
.SetEventObject(self
)
47 self
.GetEventHandler().ProcessEvent(evt
)
49 def OnEraseBackground(self
, event
):
52 def OnLeftDown(self
, event
):
53 if not self
.IsEnabled():
58 self
.GetParent().textCtrl
.SetFocus()
62 def OnLeftUp(self
, event
):
63 if not self
.IsEnabled():
74 def OnMotion(self
, event
):
75 if not self
.IsEnabled():
77 if event
.LeftIsDown():
79 x
,y
= event
.GetPositionTuple()
80 w
,h
= self
.GetClientSizeTuple()
81 if self
.up
and x
<w
and x
>=0 and y
<h
and y
>=0:
85 if not self
.up
and (x
<0 or y
<0 or x
>=w
or y
>=h
):
91 def DrawBezel(self
, dc
, x1
, y1
, x2
, y2
):
92 # draw the upper left sides
94 dc
.SetPen(self
.highlightPen
)
96 dc
.SetPen(self
.shadowPen
)
98 dc
.DrawLine((x1
+i
, y1
), (x1
+i
, y2
-i
))
99 dc
.DrawLine((x1
, y1
+i
), (x2
-i
, y1
+i
))
101 # draw the lower right sides
103 dc
.SetPen(self
.shadowPen
)
105 dc
.SetPen(self
.highlightPen
)
107 dc
.DrawLine((x1
+i
, y2
-i
), (x2
+1, y2
-i
))
108 dc
.DrawLine((x2
-i
, y1
+i
), (x2
-i
, y2
))
110 def DrawArrow(self
,dc
):
111 size
= self
.GetSize()
114 dc
.SetPen(self
.highlightPen
)
115 dc
.DrawLine((mx
-5,my
-5), (mx
+5,my
-5))
116 dc
.DrawLine((mx
-5,my
-5), (mx
,my
+5))
117 dc
.SetPen(self
.shadowPen
)
118 dc
.DrawLine((mx
+4,my
-5), (mx
,my
+5))
119 dc
.SetPen(self
.blackPen
)
120 dc
.DrawLine((mx
+5,my
-5), (mx
,my
+5))
122 def OnPaint(self
, event
):
123 width
, height
= self
.GetClientSizeTuple()
127 dc
= wxBufferedPaintDC(self
)
129 dc
.SetBackground(wxBrush(self
.GetBackgroundColour(), wxSOLID
))
131 dc
.SetBackground(wxBrush(self
.faceDnClr
, wxSOLID
))
133 self
.DrawBezel(dc
, x1
, y1
, x2
, y2
)
137 #---------------------------------------------------------------------------
140 # Tried to use wxPopupWindow but the control misbehaves on MSW
141 class wxPopupDialog(wxDialog
):
142 def __init__(self
,parent
,content
= None):
143 wxDialog
.__init
__(self
,parent
,-1,'', style
= wxBORDER_SIMPLE|wxSTAY_ON_TOP
)
146 self
.win
= wxWindow(self
,-1,pos
= wxPoint(0,0),style
= 0)
149 self
.SetContent(content
)
151 def SetContent(self
,content
):
152 self
.content
= content
153 self
.content
.Reparent(self
.win
)
154 self
.content
.Show(True)
155 self
.win
.SetClientSize(self
.content
.GetSize())
156 self
.SetSize(self
.win
.GetSize())
159 pos
= self
.ctrl
.ClientToScreen( (0,0) )
160 dSize
= wxGetDisplaySize()
161 selfSize
= self
.GetSize()
162 tcSize
= self
.ctrl
.GetSize()
164 pos
.x
-= (selfSize
.width
- tcSize
.width
) / 2
165 if pos
.x
+ selfSize
.width
> dSize
.width
:
166 pos
.x
= dSize
.width
- selfSize
.width
170 pos
.y
+= tcSize
.height
171 if pos
.y
+ selfSize
.height
> dSize
.height
:
172 pos
.y
= dSize
.height
- selfSize
.height
176 self
.MoveXY(pos
.x
,pos
.y
)
178 self
.ctrl
.FormatContent()
183 #---------------------------------------------------------------------------
186 class wxPopupControl(wxPyControl
):
187 def __init__(self
,*_args
,**_kwargs
):
188 if _kwargs
.has_key('value'):
190 apply(wxPyControl
.__init
__,(self
,) + _args
,_kwargs
)
192 self
.textCtrl
= wxTextCtrl(self
,-1,'',pos
= wxPoint(0,0))
193 self
.bCtrl
= PopButton(self
,-1)
198 EVT_SIZE(self
,self
.OnSize
)
199 EVT_BUTTON(self
.bCtrl
,self
.bCtrl
.GetId(),self
.OnButton
)
200 # embedded control should get focus on TAB keypress
201 EVT_SET_FOCUS(self
,self
.OnFocus
)
203 def OnFocus(self
,evt
):
204 self
.textCtrl
.SetFocus()
207 def OnSize(self
,evt
):
208 w
,h
= self
.GetClientSizeTuple()
209 self
.textCtrl
.SetDimensions(0,0,w
-17,h
)
210 self
.bCtrl
.SetDimensions(w
-17,0,17,h
)
212 def OnButton(self
,evt
):
215 self
.pop
= wxPopupDialog(self
,self
.content
)
218 print 'No Content to pop'
222 def Enable(self
,flag
):
223 wxPyControl
.Enable(self
,flag
)
224 self
.textCtrl
.Enable(flag
)
225 self
.bCtrl
.Enable(flag
)
227 def SetPopupContent(self
,content
):
229 self
.content
= content
230 self
.content
.Show(False)
232 self
.pop
.SetContent(content
)
234 def FormatContent(self
):
241 def SetValue(self
,value
):
242 self
.textCtrl
.SetValue(value
)
245 return self
.textCtrl
.GetValue()
249 wxPopupCtrl
= wxPopupControl