1 #----------------------------------------------------------------------
3 # Purpose: Generic popup control
5 # Author: Gerrit van Dyk
9 # RCS-ID: $Id: popupctl.py,v 1.1.2.5 2003/05/20 18:26:47 RD Exp $
10 # License: wxWindows license
11 #----------------------------------------------------------------------
12 # Local changes: built on top of wxPanel and using sizer
14 from wxPython
.wx
import *
15 from wxPython
.lib
.buttons
import wxGenButtonEvent
18 class PopButton(wxPyControl
):
19 def __init__(self
,*_args
,**_kwargs
):
20 apply(wxPyControl
.__init
__,(self
,) + _args
,_kwargs
)
27 EVT_LEFT_DOWN(self
, self
.OnLeftDown
)
28 EVT_LEFT_UP(self
, self
.OnLeftUp
)
29 EVT_MOTION(self
, self
.OnMotion
)
30 EVT_PAINT(self
, self
.OnPaint
)
32 def InitColours(self
):
33 faceClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
)
34 self
.faceDnClr
= faceClr
35 self
.SetBackgroundColour(faceClr
)
37 shadowClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNSHADOW
)
38 highlightClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNHIGHLIGHT
)
39 self
.shadowPen
= wxPen(shadowClr
, 1, wxSOLID
)
40 self
.highlightPen
= wxPen(highlightClr
, 1, wxSOLID
)
41 self
.blackPen
= wxPen(wxBLACK
, 1, wxSOLID
)
44 evt
= wxGenButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED
, self
.GetId())
45 evt
.SetIsDown(not self
.up
)
46 evt
.SetButtonObj(self
)
47 evt
.SetEventObject(self
)
48 self
.GetEventHandler().ProcessEvent(evt
)
50 def OnEraseBackground(self
, event
):
53 def OnLeftDown(self
, event
):
54 if not self
.IsEnabled():
59 self
.GetParent().textCtrl
.SetFocus()
63 def OnLeftUp(self
, event
):
64 if not self
.IsEnabled():
75 def OnMotion(self
, event
):
76 if not self
.IsEnabled():
78 if event
.LeftIsDown():
80 x
,y
= event
.GetPositionTuple()
81 w
,h
= self
.GetClientSizeTuple()
82 if self
.up
and x
<w
and x
>=0 and y
<h
and y
>=0:
86 if not self
.up
and (x
<0 or y
<0 or x
>=w
or y
>=h
):
92 def DrawBezel(self
, dc
, x1
, y1
, x2
, y2
):
93 # draw the upper left sides
95 dc
.SetPen(self
.highlightPen
)
97 dc
.SetPen(self
.shadowPen
)
99 dc
.DrawLine(x1
+i
, y1
, x1
+i
, y2
-i
)
100 dc
.DrawLine(x1
, y1
+i
, x2
-i
, y1
+i
)
102 # draw the lower right sides
104 dc
.SetPen(self
.shadowPen
)
106 dc
.SetPen(self
.highlightPen
)
108 dc
.DrawLine(x1
+i
, y2
-i
, x2
+1, y2
-i
)
109 dc
.DrawLine(x2
-i
, y1
+i
, x2
-i
, y2
)
111 def DrawArrow(self
,dc
):
112 size
= self
.GetSize()
115 dc
.SetPen(self
.highlightPen
)
116 dc
.DrawLine(mx
-5,my
-5,mx
+5,my
-5)
117 dc
.DrawLine(mx
-5,my
-5,mx
,my
+5)
118 dc
.SetPen(self
.shadowPen
)
119 dc
.DrawLine(mx
+4,my
-5,mx
,my
+5)
120 dc
.SetPen(self
.blackPen
)
121 dc
.DrawLine(mx
+5,my
-5,mx
,my
+5)
123 def OnPaint(self
, event
):
124 width
, height
= self
.GetClientSizeTuple()
128 dc
= wxBufferedPaintDC(self
)
130 dc
.SetBackground(wxBrush(self
.GetBackgroundColour(), wxSOLID
))
132 dc
.SetBackground(wxBrush(self
.faceDnClr
, wxSOLID
))
134 self
.DrawBezel(dc
, x1
, y1
, x2
, y2
)
138 #---------------------------------------------------------------------------
141 # Tried to use wxPopupWindow but the control misbehaves on MSW
142 class wxPopupDialog(wxDialog
):
143 def __init__(self
,parent
,content
= None):
144 wxDialog
.__init
__(self
,parent
,-1,'', style
= wxBORDER_SIMPLE|wxSTAY_ON_TOP
)
147 self
.win
= wxWindow(self
,-1,pos
= wxPoint(0,0),style
= 0)
150 self
.SetContent(content
)
152 def SetContent(self
,content
):
153 self
.content
= content
154 self
.content
.Reparent(self
.win
)
155 self
.content
.Show(True)
156 self
.win
.SetClientSize(self
.content
.GetSize())
157 self
.SetSize(self
.win
.GetSize())
160 pos
= self
.ctrl
.ClientToScreen( (0,0) )
161 dSize
= wxGetDisplaySize()
162 selfSize
= self
.GetSize()
163 tcSize
= self
.ctrl
.GetSize()
165 pos
.x
-= (selfSize
.x
- tcSize
.x
) / 2
166 if pos
.x
+ selfSize
.x
> dSize
.x
:
167 pos
.x
= dSize
.x
- selfSize
.x
171 pos
.y
+= tcSize
.height
172 if pos
.y
+ selfSize
.y
> dSize
.y
:
173 pos
.y
= dSize
.y
- selfSize
.y
177 self
.MoveXY(pos
.x
,pos
.y
)
179 self
.ctrl
.FormatContent()
184 #---------------------------------------------------------------------------
187 class wxPopupControl(wxPanel
):
188 def __init__(self
, parent
, value
):
189 wxPanel
.__init
__(self
, parent
, -1)
191 self
.sizer
= wxFlexGridSizer(1, 2)
192 self
.sizer
.AddGrowableCol(0)
193 self
.textCtrl
= wxTextCtrl(self
,-1,value
)
194 self
.bCtrl
= PopButton(self
,-1)
196 (self
.textCtrl
, 1, wxEXPAND
),
197 (self
.bCtrl
, 1, wxEXPAND
),
202 self
.SetAutoLayout(True)
203 self
.SetSizer(self
.sizer
)
206 # EVT_SIZE(self,self.OnSize)
207 EVT_BUTTON(self
.bCtrl
,self
.bCtrl
.GetId(),self
.OnButton
)
208 # embedded control should get focus on TAB keypress
209 EVT_SET_FOCUS(self
,self
.OnFocus
)
211 def OnFocus(self
,evt
):
212 self
.textCtrl
.SetFocus()
215 # def OnSize(self,evt):
216 # w,h = self.GetClientSizeTuple()
217 # self.textCtrl.SetDimensions(0,0,w-17,h)
218 # self.bCtrl.SetDimensions(w-17,0,17,h)
220 def OnButton(self
,evt
):
223 self
.pop
= wxPopupDialog(self
,self
.content
)
226 print 'No Content to pop'
230 def Enable(self
,flag
):
231 wxPyControl
.Enable(self
,flag
)
232 self
.textCtrl
.Enable(flag
)
233 self
.bCtrl
.Enable(flag
)
235 def SetPopupContent(self
,content
):
237 self
.content
= content
238 self
.content
.Show(False)
240 self
.pop
.SetContent(content
)
242 def FormatContent(self
):
249 def SetValue(self
,value
):
250 self
.textCtrl
.SetValue(value
)
253 return self
.textCtrl
.GetValue()
257 wxPopupCtrl
= wxPopupControl