1 #----------------------------------------------------------------------
2 # Name: wxPython.lib.buttons
3 # Purpose: Various kinds of generic buttons, (not native controls but
10 # Copyright: (c) 1999 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------
15 This module implements various forms of generic buttons, meaning that
16 they are not built on native controls but are self-drawn.
18 The wxGenButton is the base. It acts like a normal button but you
19 are able to better control how it looks, bevel width, colours, etc.
21 wxGenBitmapButton is a button with one or more bitmaps that show
22 the various states the button can be in.
24 wxGenToggleButton stays depressed when clicked, until clicked again.
26 wxGenBitmapToggleButton the same but with bitmaps.
30 from wxPython
.wx
import *
32 #----------------------------------------------------------------------
34 class wxGenButtonEvent(wxPyCommandEvent
):
35 def __init__(self
, eventType
, ID
):
36 wxPyCommandEvent
.__init
__(self
, eventType
, ID
)
40 def SetIsDown(self
, isDown
):
46 def SetButtonObj(self
, btn
):
49 def GetButtonObj(self
):
53 #----------------------------------------------------------------------
55 class wxGenButton(wxControl
):
56 def __init__(self
, parent
, ID
, label
,
57 pos
= wxDefaultPosition
, size
= wxDefaultSize
,
58 style
= 0, validator
= wxDefaultValidator
,
62 wxControl
.__init
__(self
, parent
, ID
, pos
, size
, style
, validator
, name
)
67 self
.useFocusInd
= true
71 font
= parent
.GetFont()
73 font
= wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT
)
75 self
.SetBestSize(size
)
78 EVT_LEFT_DOWN(self
, self
.OnLeftDown
)
79 EVT_LEFT_UP(self
, self
.OnLeftUp
)
80 EVT_MOTION(self
, self
.OnMotion
)
81 EVT_SET_FOCUS(self
, self
.OnGainFocus
)
82 EVT_KILL_FOCUS(self
, self
.OnLoseFocus
)
83 EVT_KEY_DOWN(self
, self
.OnKeyDown
)
84 EVT_KEY_UP(self
, self
.OnKeyUp
)
87 def SetBestSize(self
, size
=None):
89 Given the current font and bezel width settings, calculate
94 if type(size
) == type(()):
95 size
= wxSize(size
[0], size
[1])
97 # make a new size so we don't mess with the one passed in
98 size
= wxSize(size
.width
, size
.height
)
100 w
, h
, useMin
= self
._GetLabelSize
()
101 defSize
= wxButton_GetDefaultSize()
104 if useMin
and size
.width
< defSize
.width
:
105 size
.width
= defSize
.width
106 if size
.height
== -1:
108 if useMin
and size
.height
< defSize
.height
:
109 size
.height
= defSize
.height
111 size
.width
= size
.width
+ self
.bezelWidth
- 1
112 size
.height
= size
.height
+ self
.bezelWidth
- 1
117 def SetBezelWidth(self
, width
):
118 """Set the width of the 3D effect"""
119 self
.bezelWidth
= width
121 def GetBezelWidth(self
):
122 """Return the width of the 3D effect"""
123 return self
.bezelWidth
125 def SetUseFocusIndicator(self
, flag
):
126 """Specifiy if a focus indicator (dotted line) should be used"""
127 self
.useFocusInd
= flag
129 def GetUseFocusIndicator(self
):
130 """Return focus indicator flag"""
131 return self
.useFocusInd
134 def InitColours(self
):
135 faceClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
)
136 textClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNTEXT
)
137 self
.faceDnClr
= faceClr
138 self
.SetBackgroundColour(faceClr
)
139 self
.SetForegroundColour(textClr
)
141 shadowClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNSHADOW
)
142 highlightClr
= wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNHIGHLIGHT
)
143 self
.shadowPen
= wxPen(shadowClr
, 1, wxSOLID
)
144 self
.highlightPen
= wxPen(highlightClr
, 1, wxSOLID
)
145 ##self.focusIndPen = wxPen(textClr, 1, wxUSER_DASH)
146 self
.focusIndPen
= wxPen(textClr
, 1, wxDOT
)
149 def SetBackgroundColour(self
, colour
):
150 wxWindow
.SetBackgroundColour(self
, colour
)
152 # Calculate a new set of highlight and shadow colours based on
153 # the new background colour. Works okay if the colour is dark...
154 r
, g
, b
= colour
.Get()
155 fr
, fg
, fb
= min(255,r
+32), min(255,g
+32), min(255,b
+32)
156 self
.faceDnClr
= wxColour(fr
, fg
, fb
)
157 sr
, sg
, sb
= max(0,r
-32), max(0,g
-32), max(0,b
-32)
158 self
.shadowPen
= wxPen(wxColour(sr
,sg
,sb
), 1, wxSOLID
)
159 hr
, hg
, hb
= min(255,r
+64), min(255,g
+64), min(255,b
+64)
160 self
.highlightPen
= wxPen(wxColour(hr
,hg
,hb
), 1, wxSOLID
)
163 def _GetLabelSize(self
):
164 """ used internally """
165 w
, h
= self
.GetTextExtent(self
.GetLabel())
170 evt
= wxGenButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED
, self
.GetId())
171 evt
.SetIsDown(not self
.up
)
172 evt
.SetButtonObj(self
)
173 self
.GetEventHandler().ProcessEvent(evt
)
176 def DrawBezel(self
, dc
, x1
, y1
, x2
, y2
):
177 # draw the upper left sides
179 dc
.SetPen(self
.highlightPen
)
181 dc
.SetPen(self
.shadowPen
)
182 for i
in range(self
.bezelWidth
):
183 dc
.DrawLine(x1
+i
, y1
, x1
+i
, y2
-i
)
184 dc
.DrawLine(x1
, y1
+i
, x2
-i
, y1
+i
)
186 # draw the lower right sides
188 dc
.SetPen(self
.shadowPen
)
190 dc
.SetPen(self
.highlightPen
)
191 for i
in range(self
.bezelWidth
):
192 dc
.DrawLine(x1
+i
, y2
-i
, x2
+1, y2
-i
)
193 dc
.DrawLine(x2
-i
, y1
+i
, x2
-i
, y2
)
196 def DrawLabel(self
, dc
, width
, height
, dw
=0, dy
=0):
197 dc
.SetFont(self
.GetFont())
199 dc
.SetTextForeground(self
.GetForegroundColour())
201 dc
.SetTextForeground(wxSystemSettings_GetSystemColour(wxSYS_COLOUR_GRAYTEXT
))
202 label
= self
.GetLabel()
203 tw
, th
= dc
.GetTextExtent(label
)
206 dc
.DrawText(label
, (width
-tw
)/2+dw
, (height
-th
)/2+dy
)
209 def DrawFocusIndicator(self
, dc
, w
, h
):
211 dc
.SetLogicalFunction(wxINVERT
)
212 self
.focusIndPen
.SetColour(self
.GetForegroundColour())
213 ##self.focusIndPen.SetDashes([1,2,1,2]) # This isn't quite working the way I expected...
214 dc
.SetPen(self
.focusIndPen
)
215 dc
.SetBrush(wxTRANSPARENT_BRUSH
)
216 dc
.DrawRectangle(bw
+2,bw
+2, w
-bw
*2-4, h
-bw
*2-4)
219 def OnPaint(self
, event
):
220 (width
, height
) = self
.GetClientSizeTuple()
226 dc
.SetBackground(wxBrush(self
.GetBackgroundColour(), wxSOLID
))
228 dc
.SetBackground(wxBrush(self
.faceDnClr
, wxSOLID
))
230 self
.DrawBezel(dc
, x1
, y1
, x2
, y2
)
231 self
.DrawLabel(dc
, width
, height
)
232 if self
.hasFocus
and self
.useFocusInd
:
233 self
.DrawFocusIndicator(dc
, width
, height
)
235 def OnEraseBackground(self
, event
):
239 def OnLeftDown(self
, event
):
240 if not self
.IsEnabled():
248 def OnLeftUp(self
, event
):
249 if not self
.IsEnabled():
251 if not self
.up
: # if the button was down when the mouse was released...
258 def OnMotion(self
, event
):
259 if not self
.IsEnabled():
261 if event
.LeftIsDown():
262 x
,y
= event
.GetPositionTuple()
263 w
,h
= self
.GetClientSizeTuple()
264 if self
.up
and x
<w
and x
>=0 and y
<h
and y
>=0:
268 if not self
.up
and (x
<0 or y
<0 or x
>=w
or y
>=h
):
274 def OnGainFocus(self
, event
):
276 dc
= wxClientDC(self
)
277 w
, h
= self
.GetClientSizeTuple()
279 self
.DrawFocusIndicator(dc
, w
, h
)
282 def OnLoseFocus(self
, event
):
283 self
.hasFocus
= false
284 dc
= wxClientDC(self
)
285 w
, h
= self
.GetClientSizeTuple()
287 self
.DrawFocusIndicator(dc
, w
, h
)
290 def OnKeyDown(self
, event
):
291 if self
.hasFocus
and event
.KeyCode() == ord(" "):
296 def OnKeyUp(self
, event
):
297 if self
.hasFocus
and event
.KeyCode() == ord(" "):
304 #----------------------------------------------------------------------
306 class wxGenBitmapButton(wxGenButton
):
307 def __init__(self
, parent
, ID
, bitmap
,
308 pos
= wxDefaultPosition
, size
= wxDefaultSize
,
309 style
= 0, validator
= wxDefaultValidator
,
311 self
.bmpLabel
= bitmap
312 self
.bmpDisabled
= None
314 self
.bmpSelected
= None
315 wxGenButton
.__init
__(self
, parent
, ID
, "", pos
, size
, style
, validator
, name
)
318 def GetBitmapLabel(self
):
320 def GetBitmapDisabled(self
):
321 return self
.bmpDisabled
322 def GetBitmapFocus(self
):
324 def GetBitmapSelected(self
):
325 return self
.bmpSelected
328 def SetBitmapDisabled(self
, bitmap
):
329 """Set bitmap to display when the button is disabled"""
330 self
.bmpDisabled
= bitmap
332 def SetBitmapFocus(self
, bitmap
):
333 """Set bitmap to display when the button has the focus"""
334 self
.bmpFocus
= bitmap
335 self
.SetUseFocusIndicator(false
)
337 def SetBitmapSelected(self
, bitmap
):
338 """Set bitmap to display when the button is selected (pressed down)"""
339 self
.bmpSelected
= bitmap
341 def SetBitmapLabel(self
, bitmap
):
342 """Set the bitmap to display normally. This is the only one that is required."""
343 self
.bmpLabel
= bitmap
346 def _GetLabelSize(self
):
347 """ used internally """
348 if not self
.bmpLabel
:
350 return self
.bmpLabel
.GetWidth()+2, self
.bmpLabel
.GetHeight()+2, false
353 def DrawLabel(self
, dc
, width
, height
, dw
=0, dy
=0):
355 if self
.bmpDisabled
and not self
.IsEnabled():
356 bmp
= self
.bmpDisabled
357 if self
.bmpFocus
and self
.hasFocus
:
359 if self
.bmpSelected
and not self
.up
:
360 bmp
= self
.bmpSelected
361 bw
,bh
= bmp
.GetWidth(), bmp
.GetHeight()
364 dc
.DrawBitmap(bmp
, (width
-bw
)/2+dw
, (height
-bh
)/2+dy
, true
)
368 #----------------------------------------------------------------------
372 def SetToggle(self
, flag
):
378 def OnLeftDown(self
, event
):
379 if not self
.IsEnabled():
381 self
.up
= not self
.up
386 def OnLeftUp(self
, event
):
387 if not self
.IsEnabled():
393 def OnKeyDown(self
, event
):
396 def OnKeyUp(self
, event
):
397 if self
.hasFocus
and event
.KeyCode() == ord(" "):
398 self
.up
= not self
.up
406 class wxGenToggleButton(__ToggleMixin
, wxGenButton
):
409 class wxGenBitmapToggleButton(__ToggleMixin
, wxGenBitmapButton
):
412 #----------------------------------------------------------------------