]> git.saurik.com Git - wxWidgets.git/blame - utils/wxPython/lib/buttons.py
Compilation fixes
[wxWidgets.git] / utils / wxPython / lib / buttons.py
CommitLineData
6999b0d8
RD
1#----------------------------------------------------------------------
2# Name: wxPython.lib.buttons
3# Purpose: Various kinds of generic buttons, (not native controls but
4# self-drawn.)
5#
6# Author: Robin Dunn
7#
8# Created: 9-Dec-1999
9# RCS-ID: $Id$
10# Copyright: (c) 1999 by Total Control Software
11# Licence: wxWindows license
12#----------------------------------------------------------------------
13
14"""
15This module implements various forms of generic buttons, meaning that
16they are not built on native controls but are self-drawn.
17
18The wxGenButton is the base. It acts like a normal button but you
19are able to better control how it looks, bevel width, colours, etc.
20
21wxGenBitmapButton is a button with one or more bitmaps that show
22the various states the button can be in.
23
24wxGenToggleButton stays depressed when clicked, until clicked again.
25
26wxGenBitmapToggleButton the same but with bitmaps.
27
28"""
29
30from wxPython.wx import *
31
32#----------------------------------------------------------------------
33
34class wxGenButtonEvent(wxPyCommandEvent):
35 def __init__(self, eventType, ID):
36 wxPyCommandEvent.__init__(self, eventType, ID)
37 self.isDown = false
78385733 38 self.theButton = None
6999b0d8
RD
39
40 def SetIsDown(self, isDown):
41 self.isDown = isDown
42
43 def GetIsDown(self):
44 return self.isDown
45
78385733
RD
46 def SetButtonObj(self, btn):
47 self.theButton = btn
48
49 def GetButtonObj(self):
50 return self.theButton
51
6999b0d8
RD
52
53#----------------------------------------------------------------------
54
9b3d3bc4 55class wxGenButton(wxControl):
6999b0d8
RD
56 def __init__(self, parent, ID, label,
57 pos = wxDefaultPosition, size = wxDefaultSize,
58 style = 0, validator = wxDefaultValidator,
59 name = "genbutton"):
9b3d3bc4
RD
60 if style == 0:
61 style = wxNO_BORDER
62 wxControl.__init__(self, parent, ID, pos, size, style, validator, name)
6999b0d8
RD
63
64 self.up = true
65 self.bezelWidth = 2
66 self.hasFocus = false
67 self.useFocusInd = true
68
69 self.SetLabel(label)
70 self.SetPosition(pos)
6999b0d8
RD
71 font = parent.GetFont()
72 if not font.Ok():
73 font = wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT)
74 self.SetFont(font)
78385733 75 self.SetBestSize(size)
6999b0d8
RD
76 self.InitColours()
77
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)
85
86
78385733
RD
87 def SetBestSize(self, size=None):
88 """
89 Given the current font and bezel width settings, calculate
90 and set a good size.
91 """
92 if size is None:
93 size = wxSize(-1,-1)
94 if type(size) == type(()):
95 size = wxSize(size[0], size[1])
96
97 # make a new size so we don't mess with the one passed in
98 size = wxSize(size.width, size.height)
99
100 w, h, useMin = self._GetLabelSize()
101 defSize = wxButton_GetDefaultSize()
102 if size.width == -1:
103 size.width = 12 + w
104 if useMin and size.width < defSize.width:
105 size.width = defSize.width
106 if size.height == -1:
107 size.height = 11 + h
108 if useMin and size.height < defSize.height:
109 size.height = defSize.height
110
111 size.width = size.width + self.bezelWidth - 1
112 size.height = size.height + self.bezelWidth - 1
113
114 self.SetSize(size)
6999b0d8
RD
115
116
117 def SetBezelWidth(self, width):
118 """Set the width of the 3D effect"""
119 self.bezelWidth = width
120
121 def GetBezelWidth(self):
122 """Return the width of the 3D effect"""
123 return self.bezelWidth
124
125 def SetUseFocusIndicator(self, flag):
126 """Specifiy if a focus indicator (dotted line) should be used"""
127 self.useFocusInd = flag
128
129 def GetUseFocusIndicator(self):
130 """Return focus indicator flag"""
131 return self.useFocusInd
132
133
134 def InitColours(self):
135 faceClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE)
136 textClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNTEXT)
78385733 137 self.faceDnClr = faceClr
6999b0d8
RD
138 self.SetBackgroundColour(faceClr)
139 self.SetForegroundColour(textClr)
140
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)
8e425133
RD
145 ##self.focusIndPen = wxPen(textClr, 1, wxUSER_DASH)
146 self.focusIndPen = wxPen(textClr, 1, wxDOT)
6999b0d8
RD
147
148
78385733
RD
149 def SetBackgroundColour(self, colour):
150 wxWindow.SetBackgroundColour(self, colour)
151
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)
161
162
163 def _GetLabelSize(self):
164 """ used internally """
165 w, h = self.GetTextExtent(self.GetLabel())
166 return w, h, true
167
168
6999b0d8
RD
169 def Notify(self):
170 evt = wxGenButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
171 evt.SetIsDown(not self.up)
78385733 172 evt.SetButtonObj(self)
6999b0d8
RD
173 self.GetEventHandler().ProcessEvent(evt)
174
175
176 def DrawBezel(self, dc, x1, y1, x2, y2):
177 # draw the upper left sides
178 if self.up:
179 dc.SetPen(self.highlightPen)
180 else:
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)
185
186 # draw the lower right sides
187 if self.up:
188 dc.SetPen(self.shadowPen)
189 else:
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)
194
195
196 def DrawLabel(self, dc, width, height, dw=0, dy=0):
197 dc.SetFont(self.GetFont())
198 if self.IsEnabled():
199 dc.SetTextForeground(self.GetForegroundColour())
200 else:
201 dc.SetTextForeground(wxSystemSettings_GetSystemColour(wxSYS_COLOUR_GRAYTEXT))
202 label = self.GetLabel()
203 tw, th = dc.GetTextExtent(label)
204 if not self.up:
205 dw = dy = 1
206 dc.DrawText(label, (width-tw)/2+dw, (height-th)/2+dy)
207
208
209 def DrawFocusIndicator(self, dc, w, h):
210 bw = self.bezelWidth
211 dc.SetLogicalFunction(wxINVERT)
212 self.focusIndPen.SetColour(self.GetForegroundColour())
8e425133 213 ##self.focusIndPen.SetDashes([1,2,1,2]) # This isn't quite working the way I expected...
6999b0d8
RD
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)
217
218
219 def OnPaint(self, event):
220 (width, height) = self.GetClientSizeTuple()
221 x1 = y1 = 0
222 x2 = width-1
223 y2 = height-1
224 dc = wxPaintDC(self)
78385733
RD
225 if self.up:
226 dc.SetBackground(wxBrush(self.GetBackgroundColour(), wxSOLID))
227 else:
228 dc.SetBackground(wxBrush(self.faceDnClr, wxSOLID))
6999b0d8
RD
229 dc.Clear()
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)
234
eec92d76 235
6999b0d8
RD
236 def OnEraseBackground(self, event):
237 pass
238
239
240 def OnLeftDown(self, event):
241 if not self.IsEnabled():
242 return
243 self.up = false
244 self.CaptureMouse()
245 self.SetFocus()
246 self.Refresh()
247
248
249 def OnLeftUp(self, event):
250 if not self.IsEnabled():
251 return
252 if not self.up: # if the button was down when the mouse was released...
253 self.Notify()
254 self.up = true
255 self.ReleaseMouse()
256 self.Refresh()
257
258
259 def OnMotion(self, event):
260 if not self.IsEnabled():
261 return
262 if event.LeftIsDown():
263 x,y = event.GetPositionTuple()
264 w,h = self.GetClientSizeTuple()
265 if self.up and x<w and x>=0 and y<h and y>=0:
266 self.up = false
267 self.Refresh()
268 return
269 if not self.up and (x<0 or y<0 or x>=w or y>=h):
270 self.up = true
271 self.Refresh()
272 return
273
274
275 def OnGainFocus(self, event):
276 self.hasFocus = true
277 dc = wxClientDC(self)
278 w, h = self.GetClientSizeTuple()
279 if self.useFocusInd:
280 self.DrawFocusIndicator(dc, w, h)
281
282
283 def OnLoseFocus(self, event):
284 self.hasFocus = false
285 dc = wxClientDC(self)
286 w, h = self.GetClientSizeTuple()
287 if self.useFocusInd:
288 self.DrawFocusIndicator(dc, w, h)
289
290
291 def OnKeyDown(self, event):
292 if self.hasFocus and event.KeyCode() == ord(" "):
293 self.up = false
294 self.Refresh()
295 event.Skip()
296
eec92d76 297
6999b0d8
RD
298 def OnKeyUp(self, event):
299 if self.hasFocus and event.KeyCode() == ord(" "):
300 self.up = true
301 self.Notify()
302 self.Refresh()
303 event.Skip()
304
305
306#----------------------------------------------------------------------
307
308class wxGenBitmapButton(wxGenButton):
309 def __init__(self, parent, ID, bitmap,
310 pos = wxDefaultPosition, size = wxDefaultSize,
311 style = 0, validator = wxDefaultValidator,
312 name = "genbutton"):
6999b0d8
RD
313 self.bmpLabel = bitmap
314 self.bmpDisabled = None
315 self.bmpFocus = None
316 self.bmpSelected = None
78385733
RD
317 wxGenButton.__init__(self, parent, ID, "", pos, size, style, validator, name)
318
6999b0d8
RD
319
320 def GetBitmapLabel(self):
321 return self.bmpLabel
322 def GetBitmapDisabled(self):
323 return self.bmpDisabled
324 def GetBitmapFocus(self):
325 return self.bmpFocus
326 def GetBitmapSelected(self):
327 return self.bmpSelected
328
78385733 329
6999b0d8 330 def SetBitmapDisabled(self, bitmap):
78385733 331 """Set bitmap to display when the button is disabled"""
6999b0d8 332 self.bmpDisabled = bitmap
78385733 333
6999b0d8 334 def SetBitmapFocus(self, bitmap):
78385733 335 """Set bitmap to display when the button has the focus"""
6999b0d8
RD
336 self.bmpFocus = bitmap
337 self.SetUseFocusIndicator(false)
78385733 338
6999b0d8 339 def SetBitmapSelected(self, bitmap):
78385733 340 """Set bitmap to display when the button is selected (pressed down)"""
6999b0d8 341 self.bmpSelected = bitmap
78385733 342
6999b0d8 343 def SetBitmapLabel(self, bitmap):
78385733 344 """Set the bitmap to display normally. This is the only one that is required."""
6999b0d8
RD
345 self.bmpLabel = bitmap
346
347
78385733
RD
348 def _GetLabelSize(self):
349 """ used internally """
350 if not self.bmpLabel:
351 return -1, -1, false
352 return self.bmpLabel.GetWidth()+2, self.bmpLabel.GetHeight()+2, false
353
354
6999b0d8
RD
355 def DrawLabel(self, dc, width, height, dw=0, dy=0):
356 bmp = self.bmpLabel
357 if self.bmpDisabled and not self.IsEnabled():
358 bmp = self.bmpDisabled
359 if self.bmpFocus and self.hasFocus:
360 bmp = self.bmpFocus
361 if self.bmpSelected and not self.up:
362 bmp = self.bmpSelected
363 bw,bh = bmp.GetWidth(), bmp.GetHeight()
364 if not self.up:
365 dw = dy = 1
eec92d76
RD
366 hasMask = bmp.GetMask() != None
367 dc.DrawBitmap(bmp, (width-bw)/2+dw, (height-bh)/2+dy, hasMask)
6999b0d8
RD
368
369
370
371#----------------------------------------------------------------------
372
373
374class __ToggleMixin:
fbff5d1b
RD
375 def SetToggle(self, flag):
376 self.up = not flag
377
378 def GetToggle(self):
379 return not self.up
380
6999b0d8
RD
381 def OnLeftDown(self, event):
382 if not self.IsEnabled():
383 return
c4c829ae 384 self.saveUp = self.up
6999b0d8
RD
385 self.up = not self.up
386 self.CaptureMouse()
387 self.SetFocus()
388 self.Refresh()
389
390 def OnLeftUp(self, event):
391 if not self.IsEnabled():
392 return
c4c829ae
RD
393 if self.up != self.saveUp:
394 self.Notify()
6999b0d8
RD
395 self.ReleaseMouse()
396 self.Refresh()
397
398 def OnKeyDown(self, event):
399 event.Skip()
400
401 def OnKeyUp(self, event):
402 if self.hasFocus and event.KeyCode() == ord(" "):
403 self.up = not self.up
404 self.Notify()
405 self.Refresh()
406 event.Skip()
407
408
fbff5d1b
RD
409
410
6999b0d8
RD
411class wxGenToggleButton(__ToggleMixin, wxGenButton):
412 pass
413
414class wxGenBitmapToggleButton(__ToggleMixin, wxGenBitmapButton):
415 pass
416
417#----------------------------------------------------------------------
418
419