]> git.saurik.com Git - wxWidgets.git/blame - utils/wxPython/lib/buttons.py
added support for vertical toolbars for MSW - seems to work more or less
[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
38
39 def SetIsDown(self, isDown):
40 self.isDown = isDown
41
42 def GetIsDown(self):
43 return self.isDown
44
45
46#----------------------------------------------------------------------
47
48class wxGenButton(wxWindow):
49 def __init__(self, parent, ID, label,
50 pos = wxDefaultPosition, size = wxDefaultSize,
51 style = 0, validator = wxDefaultValidator,
52 name = "genbutton"):
53 wxWindow.__init__(self, parent, ID, pos, size, style, name)
54 self.SetValidator(validator)
55
56 self.up = true
57 self.bezelWidth = 2
58 self.hasFocus = false
59 self.useFocusInd = true
60
61 self.SetLabel(label)
62 self.SetPosition(pos)
63 if type(size) == type(()):
64 size = wxSize(size[0], size[1])
65 w = size.width
66 h = size.height
67 dsize = wxSize(75,23) ### wxButton_GetDefaultSize()
68 if self.bezelWidth > 2:
69 dsize.width = dsize.width + self.bezelWidth - 2
70 dsize.height = dsize.height + self.bezelWidth - 2
71 if w == -1: w = dsize.width
72 if h == -1: h = dsize.height
73 self.SetSize(wxSize(w,h))
74 font = parent.GetFont()
75 if not font.Ok():
76 font = wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT)
77 self.SetFont(font)
78 self.InitColours()
79
80 EVT_LEFT_DOWN(self, self.OnLeftDown)
81 EVT_LEFT_UP(self, self.OnLeftUp)
82 EVT_MOTION(self, self.OnMotion)
83 EVT_SET_FOCUS(self, self.OnGainFocus)
84 EVT_KILL_FOCUS(self, self.OnLoseFocus)
85 EVT_KEY_DOWN(self, self.OnKeyDown)
86 EVT_KEY_UP(self, self.OnKeyUp)
87
88
89
90
91 def SetBezelWidth(self, width):
92 """Set the width of the 3D effect"""
93 self.bezelWidth = width
94
95 def GetBezelWidth(self):
96 """Return the width of the 3D effect"""
97 return self.bezelWidth
98
99 def SetUseFocusIndicator(self, flag):
100 """Specifiy if a focus indicator (dotted line) should be used"""
101 self.useFocusInd = flag
102
103 def GetUseFocusIndicator(self):
104 """Return focus indicator flag"""
105 return self.useFocusInd
106
107
108 def InitColours(self):
109 faceClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE)
110 textClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNTEXT)
111 self.SetBackgroundColour(faceClr)
112 self.SetForegroundColour(textClr)
113
114 shadowClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNSHADOW)
115 highlightClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNHIGHLIGHT)
116 self.shadowPen = wxPen(shadowClr, 1, wxSOLID)
117 self.highlightPen = wxPen(highlightClr, 1, wxSOLID)
118
119 self.focusIndPen = wxPen(textClr, 1, wxUSER_DASH)
120
121
122 def Notify(self):
123 evt = wxGenButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
124 evt.SetIsDown(not self.up)
125 self.GetEventHandler().ProcessEvent(evt)
126
127
128 def DrawBezel(self, dc, x1, y1, x2, y2):
129 # draw the upper left sides
130 if self.up:
131 dc.SetPen(self.highlightPen)
132 else:
133 dc.SetPen(self.shadowPen)
134 for i in range(self.bezelWidth):
135 dc.DrawLine(x1+i, y1, x1+i, y2-i)
136 dc.DrawLine(x1, y1+i, x2-i, y1+i)
137
138 # draw the lower right sides
139 if self.up:
140 dc.SetPen(self.shadowPen)
141 else:
142 dc.SetPen(self.highlightPen)
143 for i in range(self.bezelWidth):
144 dc.DrawLine(x1+i, y2-i, x2+1, y2-i)
145 dc.DrawLine(x2-i, y1+i, x2-i, y2)
146
147
148 def DrawLabel(self, dc, width, height, dw=0, dy=0):
149 dc.SetFont(self.GetFont())
150 if self.IsEnabled():
151 dc.SetTextForeground(self.GetForegroundColour())
152 else:
153 dc.SetTextForeground(wxSystemSettings_GetSystemColour(wxSYS_COLOUR_GRAYTEXT))
154 label = self.GetLabel()
155 tw, th = dc.GetTextExtent(label)
156 if not self.up:
157 dw = dy = 1
158 dc.DrawText(label, (width-tw)/2+dw, (height-th)/2+dy)
159
160
161 def DrawFocusIndicator(self, dc, w, h):
162 bw = self.bezelWidth
163 dc.SetLogicalFunction(wxINVERT)
164 self.focusIndPen.SetColour(self.GetForegroundColour())
165 self.focusIndPen.SetDashes([1,2,1,2]) # This isn't quite working the way I expected...
166 dc.SetPen(self.focusIndPen)
167 dc.SetBrush(wxTRANSPARENT_BRUSH)
168 dc.DrawRectangle(bw+2,bw+2, w-bw*2-4, h-bw*2-4)
169
170
171 def OnPaint(self, event):
172 (width, height) = self.GetClientSizeTuple()
173 x1 = y1 = 0
174 x2 = width-1
175 y2 = height-1
176 dc = wxPaintDC(self)
177 dc.SetBackground(wxBrush(self.GetBackgroundColour(), wxSOLID))
178 dc.Clear()
179 self.DrawBezel(dc, x1, y1, x2, y2)
180 self.DrawLabel(dc, width, height)
181 if self.hasFocus and self.useFocusInd:
182 self.DrawFocusIndicator(dc, width, height)
183
184 def OnEraseBackground(self, event):
185 pass
186
187
188 def OnLeftDown(self, event):
189 if not self.IsEnabled():
190 return
191 self.up = false
192 self.CaptureMouse()
193 self.SetFocus()
194 self.Refresh()
195
196
197 def OnLeftUp(self, event):
198 if not self.IsEnabled():
199 return
200 if not self.up: # if the button was down when the mouse was released...
201 self.Notify()
202 self.up = true
203 self.ReleaseMouse()
204 self.Refresh()
205
206
207 def OnMotion(self, event):
208 if not self.IsEnabled():
209 return
210 if event.LeftIsDown():
211 x,y = event.GetPositionTuple()
212 w,h = self.GetClientSizeTuple()
213 if self.up and x<w and x>=0 and y<h and y>=0:
214 self.up = false
215 self.Refresh()
216 return
217 if not self.up and (x<0 or y<0 or x>=w or y>=h):
218 self.up = true
219 self.Refresh()
220 return
221
222
223 def OnGainFocus(self, event):
224 self.hasFocus = true
225 dc = wxClientDC(self)
226 w, h = self.GetClientSizeTuple()
227 if self.useFocusInd:
228 self.DrawFocusIndicator(dc, w, h)
229
230
231 def OnLoseFocus(self, event):
232 self.hasFocus = false
233 dc = wxClientDC(self)
234 w, h = self.GetClientSizeTuple()
235 if self.useFocusInd:
236 self.DrawFocusIndicator(dc, w, h)
237
238
239 def OnKeyDown(self, event):
240 if self.hasFocus and event.KeyCode() == ord(" "):
241 self.up = false
242 self.Refresh()
243 event.Skip()
244
245 def OnKeyUp(self, event):
246 if self.hasFocus and event.KeyCode() == ord(" "):
247 self.up = true
248 self.Notify()
249 self.Refresh()
250 event.Skip()
251
252
253#----------------------------------------------------------------------
254
255class wxGenBitmapButton(wxGenButton):
256 def __init__(self, parent, ID, bitmap,
257 pos = wxDefaultPosition, size = wxDefaultSize,
258 style = 0, validator = wxDefaultValidator,
259 name = "genbutton"):
260 wxGenButton.__init__(self, parent, ID, "", pos, size, style, validator, name)
261
262 self.bmpLabel = bitmap
263 self.bmpDisabled = None
264 self.bmpFocus = None
265 self.bmpSelected = None
266
267 def GetBitmapLabel(self):
268 return self.bmpLabel
269 def GetBitmapDisabled(self):
270 return self.bmpDisabled
271 def GetBitmapFocus(self):
272 return self.bmpFocus
273 def GetBitmapSelected(self):
274 return self.bmpSelected
275
276 def SetBitmapDisabled(self, bitmap):
277 self.bmpDisabled = bitmap
278 def SetBitmapFocus(self, bitmap):
279 self.bmpFocus = bitmap
280 self.SetUseFocusIndicator(false)
281 def SetBitmapSelected(self, bitmap):
282 self.bmpSelected = bitmap
283 def SetBitmapLabel(self, bitmap):
284 self.bmpLabel = bitmap
285
286
287 def DrawLabel(self, dc, width, height, dw=0, dy=0):
288 bmp = self.bmpLabel
289 if self.bmpDisabled and not self.IsEnabled():
290 bmp = self.bmpDisabled
291 if self.bmpFocus and self.hasFocus:
292 bmp = self.bmpFocus
293 if self.bmpSelected and not self.up:
294 bmp = self.bmpSelected
295 bw,bh = bmp.GetWidth(), bmp.GetHeight()
296 if not self.up:
297 dw = dy = 1
298 dc.DrawBitmap(bmp, (width-bw)/2+dw, (height-bh)/2+dy, true)
299
300
301
302#----------------------------------------------------------------------
303
304
305class __ToggleMixin:
fbff5d1b
RD
306 def SetToggle(self, flag):
307 self.up = not flag
308
309 def GetToggle(self):
310 return not self.up
311
6999b0d8
RD
312 def OnLeftDown(self, event):
313 if not self.IsEnabled():
314 return
315 self.up = not self.up
316 self.CaptureMouse()
317 self.SetFocus()
318 self.Refresh()
319
320 def OnLeftUp(self, event):
321 if not self.IsEnabled():
322 return
323 self.Notify()
324 self.ReleaseMouse()
325 self.Refresh()
326
327 def OnKeyDown(self, event):
328 event.Skip()
329
330 def OnKeyUp(self, event):
331 if self.hasFocus and event.KeyCode() == ord(" "):
332 self.up = not self.up
333 self.Notify()
334 self.Refresh()
335 event.Skip()
336
337
fbff5d1b
RD
338
339
6999b0d8
RD
340class wxGenToggleButton(__ToggleMixin, wxGenButton):
341 pass
342
343class wxGenBitmapToggleButton(__ToggleMixin, wxGenBitmapButton):
344 pass
345
346#----------------------------------------------------------------------
347
348