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