1 
2 /*
3 * This file is part of a wxSmith plugin for Code::Blocks Studio
4 * Copyright (C) 2007  Bartlomiej Swiecki
5 *
6 * wxSmith is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * wxSmith and this file is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with wxSmith; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 * Ron Collins
21 * rcoll@theriver.com
22 * 4-Feb-2010
23 *
24 */
25 
26 #include "wxSpeedButton.h"
27 
28 
29 // ==========================================================================
30 // wxSpeedButton
31 // ==========================================================================
32 IMPLEMENT_DYNAMIC_CLASS( wxSpeedButton, wxControl )
33 
34 BEGIN_EVENT_TABLE(wxSpeedButton,wxControl)
35     EVT_MOUSE_EVENTS ( wxSpeedButton::OnMouseEvents )
36     EVT_PAINT        ( wxSpeedButton::OnPaint )
37     EVT_SIZE         ( wxSpeedButton::OnSize )
38     EVT_SET_FOCUS    ( wxSpeedButton::OnSetFocus )
39     EVT_KILL_FOCUS   ( wxSpeedButton::OnKillFocus )
40     EVT_CHAR         ( wxSpeedButton::OnKey )
41 END_EVENT_TABLE()
42 
43 
44 //------------------------------------------------------------------------------
45 // book-keeping data for a series of speed-buttons
46 
47 static  int             sbgCount    = 0;        // number of speed-buttons created
48 static  wxArrayPtrVoid  sbgArray;               // list of defined buttones
49 
50 //------------------------------------------------------------------------------
51 
~wxSpeedButton()52 wxSpeedButton::~wxSpeedButton() {
53 int         n;
54 
55 // release the mouse
56 
57 //    if (HasCapture()) ReleaseMouse();
58 
59 // erase entry in master array
60 
61     n = sbgArray.Index((void *) this);
62     if (n != wxNOT_FOUND) sbgArray.RemoveAt(n);
63 
64 }
65 
66 //------------------------------------------------------------------------------
67 // the basic contructor
68 
wxSpeedButton(wxWindow * inParent,wxWindowID inID,const wxString & inLabel,const wxBitmap & inGlyph,int inGlyphCount,int inMargin,int inGroupIndex,bool inAllowAllUp,const wxPoint & inPos,const wxSize & inSize,long inStyle,const wxValidator & inVal,const wxString & inName)69 wxSpeedButton::wxSpeedButton( wxWindow     *inParent,           // parent window
70                             wxWindowID      inID,               // id of this button
71                             const wxString &inLabel,            // button text
72                             const wxBitmap &inGlyph,            // bitmaps displayed on button
73                             int             inGlyphCount,       // number of images in inGlyph
74                             int             inMargin,           // area around image and tex
75                             int             inGroupIndex,       // ident of a group of buttons
76                             bool            inAllowAllUp,       // allow all buttons up
77                             const wxPoint  &inPos,              // button position
78                             const wxSize   &inSize,             // button size
79                             long            inStyle,            // border styles
80                             const wxValidator &inVal,           // validator
81                             const wxString &inName) {           // name of button
82 
83     Create( inParent, inID,
84             inLabel,
85             inGlyph, inGlyphCount, inMargin,
86             inGroupIndex, inAllowAllUp,
87             inPos, inSize, inStyle, inVal, inName);
88 }
89 
90 //------------------------------------------------------------------------------
91 // a constructor that creates a bitmap from a filename
92 
wxSpeedButton(wxWindow * inParent,wxWindowID inID,const wxString & inLabel,const wxString & inGlyphFile,int inGlyphCount,int inMargin,int inGroupIndex,bool inAllowAllUp,const wxPoint & inPos,const wxSize & inSize,long inStyle,const wxValidator & inVal,const wxString & inName)93 wxSpeedButton::wxSpeedButton( wxWindow     *inParent,           // parent window
94                             wxWindowID      inID,               // id of this button
95                             const wxString &inLabel,            // button text
96                             const wxString &inGlyphFile,        // bitmaps displayed on button
97                             int             inGlyphCount,       // number of images in inGlyph
98                             int             inMargin,           // area around image and tex
99                             int             inGroupIndex,       // ident of a group of buttons
100                             bool            inAllowAllUp,       // allow all buttons up
101                             const wxPoint  &inPos,              // button position
102                             const wxSize   &inSize,             // button size
103                             long            inStyle,            // border styles
104                             const wxValidator &inVal,           // validator
105                             const wxString &inName) {           // name of button
106 wxBitmap    bmp(inGlyphFile, wxBITMAP_TYPE_ANY );
107 
108     Create( inParent, inID,
109             inLabel,
110             bmp, inGlyphCount, inMargin,
111             inGroupIndex, inAllowAllUp,
112             inPos, inSize, inStyle, inVal, inName);
113 }
114 
115 
116 
117 //------------------------------------------------------------------------------
118 
Create(wxWindow * inParent,wxWindowID inID,const wxString & inLabel,const wxBitmap & inGlyph,int inGlyphCount,int inMargin,int inGroupIndex,bool inAllowAllUp,const wxPoint & inPos,const wxSize & inSize,long inStyle,const wxValidator & inVal,const wxString & inName)119 bool wxSpeedButton::Create( wxWindow       *inParent,           // parent window
120                             wxWindowID      inID,               // id of this button
121                             const wxString &inLabel,            // button text
122                             const wxBitmap &inGlyph,            // bitmaps displayed on button
123                             int             inGlyphCount,       // number of images in inGlyph
124                             int             inMargin,           // area around image and tex
125                             int             inGroupIndex,       // ident of a group of buttons
126                             bool            inAllowAllUp,       // allow all buttons up
127                             const wxPoint  &inPos,              // button position
128                             const wxSize   &inSize,             // button size
129                             long            inStyle,            // border styles
130                             const wxValidator &inVal,           // validator
131                             const wxString &inName) {           // name of button
132 
133 int         n;
134 wxString    name;
135 wxPoint     pos;
136 wxSize      size;
137 wxString    s;
138 
139 // make sure we can load images
140 
141     wxInitAllImageHandlers();
142 
143 // one more button
144 
145     sbgCount += 1;
146 
147 // make a default name
148 
149     name = inName;
150     name.Trim(true);
151     name.Trim(false);
152     if (name.Len() == 0) name.Printf(_T("SpeedButton-%d"), sbgCount);
153 
154 // the position
155 
156     pos = inPos;
157     if (pos.x < 0) pos.x = 0;
158     if (pos.y < 0) pos.y = 0;
159 
160 // the size - default size is 72 x 24
161 
162     size = inSize;
163     size.SetDefaults(wxSize(72, 24));
164 
165 // fix the alignment -- default to BU_LEFT
166 // clear border styles and make sure we clip children
167 
168     n = inStyle;
169     n = n & (~ wxBORDER_MASK);
170     n = n | wxBORDER_NONE;
171     n = n | wxCLIP_CHILDREN;
172 
173     if (((n & wxBU_LEFT)   == 0) &&
174         ((n & wxBU_TOP)    == 0) &&
175         ((n & wxBU_RIGHT)  == 0) &&
176         ((n & wxBU_BOTTOM) == 0))
177             n = n | wxBU_LEFT;
178 
179 // make the control, make sure we clip children
180 
181     if (! wxControl::Create(inParent, inID, pos, size, n, inVal, name)) return false;
182 
183 // basic stuff for any control
184 
185     wxControl::SetLabel(inLabel);
186     wxControl::SetBackgroundColour(inParent->GetBackgroundColour());
187     wxControl::SetForegroundColour(inParent->GetForegroundColour());
188     wxControl::SetFont(inParent->GetFont());
189 
190 // extract bitmaps
191 
192     SplitGlyphs(inGlyph, inGlyphCount);
193 
194 // the blank space around images and text
195 
196     mMargin = inMargin;
197     if (mMargin < 0) mMargin = 0;
198 
199 // ID for a group of buttons
200 
201     mGroupIndex = inGroupIndex;
202     mAllowAllUp = inAllowAllUp;
203 
204 // no button down yet
205 
206     mMouseDown     = false;
207     mMouseOver     = false;
208     mButtonDown    = false;
209     mButtonFocused = false;
210 
211 // the is a small chance that CalcLayout could be called recursively
212 
213     mCalcBusy = false;
214 
215 // keep track of our parent, and the top-most parent
216 
217     mParent = GetParent();
218     mTopParent = mParent;
219     while ((mTopParent != NULL) && (! mTopParent->IsKindOf(CLASSINFO(wxTopLevelWindow))))
220         mTopParent = mTopParent->GetParent();
221 
222 // no user data yet
223 
224     mUserData = 0;
225 
226 // add this button to the master list
227 
228     sbgArray.Add((void *) this);
229 
230 // draw it
231 
232     Refresh(false);
233 
234 // done
235 
236     return true;
237 }
238 
239 //------------------------------------------------------------------------------
240 // given an input bitmap, make 3 glyphs from it:
241 // the input bitmap may be empty (no glyphs),
242 // with 1 image, make UP glyph, DOWN glyph, DISABLED glyph
243 // with 2 images, the first image is UP and DOWN glyphs, the 2nd image is DISABLED glyph
244 // with 3 images, each image is a glyph
245 
SplitGlyphs(const wxBitmap & inBitmap,int inCount)246 void wxSpeedButton::SplitGlyphs(const wxBitmap &inBitmap, int inCount) {
247 int         n;
248 int         bw,bh;
249 int         sw,sh;
250 wxRect      rr;
251 wxImage     img;
252 wxBitmap    *bmp;
253 
254 // no images yet
255 
256     mGlyphUp       = wxNullBitmap;
257     mGlyphDown     = wxNullBitmap;
258     mGlyphDisabled = wxNullBitmap;
259 
260 // if no bitmap, then we are done
261 
262     if (! inBitmap.Ok()) return;
263 
264 // size of the bitmap
265 
266     bw = inBitmap.GetWidth();
267     bh = inBitmap.GetHeight();
268     if ((bw <= 0) || (bh <= 0)) return;
269 
270 // determine the number of images in the source bitmap
271 // if inCount > 0, then that is the count specified by the user
272 // else, count number of square sub-images
273 
274     if      (inCount > 0) n = inCount;
275     else if (bw >= bh)    n = (int) bw / bh;
276     else                  n = (int) bh / bw;
277 
278 // extract sub-images, either vertically or horizontally
279 
280     if (n == 1) {
281         mGlyphUp   = inBitmap;
282         mGlyphDown = inBitmap;
283 
284         img = inBitmap.ConvertToImage();
285         img = img.ConvertToGreyscale();
286         bmp = new wxBitmap(img);
287         mGlyphDisabled = *bmp;
288     }
289     else if ((n == 2) && (bw >= bh)) {
290         sw = (int) bw / n;
291         sh = bh;
292 
293         rr.SetX(0);
294         rr.SetY(0);
295         rr.SetWidth(sw);
296         rr.SetHeight(sh);
297         mGlyphUp = inBitmap.GetSubBitmap(rr);
298         mGlyphDown = inBitmap.GetSubBitmap(rr);
299         rr.SetX(sw);
300         mGlyphDisabled = inBitmap.GetSubBitmap(rr);
301     }
302     else if ((n == 2) && (bh > bw)) {
303         sw = bw;
304         sh = (int) bh / n;
305 
306         rr.SetX(0);
307         rr.SetY(0);
308         rr.SetWidth(sw);
309         rr.SetHeight(sh);
310         mGlyphUp = inBitmap.GetSubBitmap(rr);
311         mGlyphDown = inBitmap.GetSubBitmap(rr);
312         rr.SetY(sh);
313         mGlyphDisabled = inBitmap.GetSubBitmap(rr);
314     }
315     else if ((n >= 3) && (bw >= bh)) {
316         sw = (int) bw / n;
317         sh = bh;
318 
319         rr.SetX(0);
320         rr.SetY(0);
321         rr.SetWidth(sw);
322         rr.SetHeight(sh);
323         mGlyphUp = inBitmap.GetSubBitmap(rr);
324         rr.SetX(sw);
325         mGlyphDown = inBitmap.GetSubBitmap(rr);
326         rr.SetX(sw+sw);
327         mGlyphDisabled = inBitmap.GetSubBitmap(rr);
328     }
329     else { // (n >= 3) && (bh > bw)
330         sw = bw;
331         sh = (int) bh / n;
332 
333         rr.SetX(0);
334         rr.SetY(0);
335         rr.SetWidth(sw);
336         rr.SetHeight(sh);
337         mGlyphUp = inBitmap.GetSubBitmap(rr);
338         rr.SetY(sh);
339         mGlyphDown = inBitmap.GetSubBitmap(rr);
340         rr.SetY(sh+sh);;
341         mGlyphDisabled = inBitmap.GetSubBitmap(rr);
342     };
343 
344 // make them all transparent
345 
346     MakeTransparent(mGlyphUp);
347     MakeTransparent(mGlyphDown);
348     MakeTransparent(mGlyphDisabled);
349 }
350 
351 //------------------------------------------------------------------------------
352 // make sure a bitmap has a transparency mask
353 
MakeTransparent(wxBitmap & inBitmap)354 void wxSpeedButton::MakeTransparent(wxBitmap &inBitmap) {
355 int         h;
356 int         r,g,b;
357 wxImage     img;
358 wxBitmap    *bmp;
359 
360 // not a good image?
361 
362     if (! inBitmap.IsOk()) return;
363 
364 // already have a mask?
365 
366     img = inBitmap.ConvertToImage();
367     if (img.HasMask()) return;
368 
369 // get the colors of the lower-left corner of the image
370 
371     h = img.GetHeight();
372     r = img.GetRed(0, h-1);
373     b = img.GetBlue(0, h-1);
374     g = img.GetGreen(0, h-1);
375 
376 // make a mask from those colors
377 
378     img.SetMaskColour(r, g, b);
379 
380 // store it back in the bitmap
381 
382     bmp = new wxBitmap(img);
383     inBitmap = *bmp;
384 }
385 
386 //------------------------------------------------------------------------------
387 
GetGlyphSize(wxBitmap & inGlyph,int & outWidth,int & outHeight)388 void wxSpeedButton::GetGlyphSize(wxBitmap &inGlyph, int &outWidth, int &outHeight) {
389 
390     if (inGlyph.Ok()) {
391         outWidth  = inGlyph.GetWidth();
392         outHeight = inGlyph.GetHeight();
393     }
394     else {
395         outWidth  = 0;
396         outHeight = 0;
397     };
398 
399 }
400 
401 //------------------------------------------------------------------------------
402 // calc best size for button,
403 // fills in mGlyphSize, mLabelSize, mBestSize
404 
DoGetBestSize(void)405 wxSize wxSpeedButton::DoGetBestSize(void) {
406 int         i,n;
407 int         w,h;
408 int         bn;
409 int         bw, bh;
410 int         gw, gh;
411 int         lw, lh;
412 
413 // max size of the bitmaps
414 
415     bw = 0;
416     bh = 0;
417     GetGlyphSize(mGlyphUp, gw, gh);
418         if (gw > bw) bw = gw;
419         if (gh > bh) bh = gh;
420     GetGlyphSize(mGlyphDown, gw, gh);
421         if (gw > bw) bw = gw;
422         if (gh > bh) bh = gh;
423     GetGlyphSize(mGlyphDisabled, gw, gh);
424         if (gw > bw) bw = gw;
425         if (gh > bh) bh = gh;
426 
427     mGlyphSize.Set(bw, bh);
428 
429 // max size of the t  n = inStyle | wxCLIP_CHILDREN;ext label
430 
431     lw = 0;
432     lh = 0;
433     if (! GetLabel().IsEmpty()) GetTextExtent(GetLabel(), &lw, &lh);
434 
435     mLabelSize.Set(lw, lh);
436 
437 // border size is a magiv number, imperically determined using the
438 // wxNativeRenderer to draw the button
439 
440     bn = 2;
441 
442 // best size depends upon the alignment
443 
444     i = GetWindowStyleFlag();
445 
446     if (((i & wxBU_LEFT) != 0) || ((i & wxBU_RIGHT) != 0)) {
447         w = bn + mMargin + bw + mMargin + lw + mMargin + bn;
448         n = (bh > lh) ? bh : lh;
449         h = bn + mMargin + n + mMargin + bn;
450     }
451     else if (((i & wxBU_TOP) != 0) || ((i & wxBU_BOTTOM) != 0)) {
452         n = (bw > lw) ? bw : lw;
453         w = bn + mMargin + n + mMargin + bn;
454         h = bn + mMargin + bh + mMargin + lh + mMargin + bn;
455     }
456     else { // assume BU_LEFT
457         w = bn + mMargin + bw + mMargin + lw + mMargin + bn;
458         n = (bh > lh) ? bh : lh;
459         h = bn + mMargin + n + mMargin + bn;
460     };
461 
462     mBestSize.Set(w, h);
463 
464 // done
465 
466     return mBestSize;
467 }
468 
469 //------------------------------------------------------------------------------
470 // calculate the position of the bitmap and the label
471 // fills in mGlyphPos, mLabelPos, mCurrentSize
472 
CalcLayout(bool inRefresh)473 void wxSpeedButton::CalcLayout(bool inRefresh) {
474 int         i;
475 int         bn;
476 int         w, h;
477 bool        gz, lz;
478 int         gx, gy;
479 int         lx, ly;
480 
481 // no recursive calls
482 
483     if (mCalcBusy) return;
484     mCalcBusy = true;
485 
486 // current size of the button
487 
488     GetSize(&w,&h);
489     mCurrentSize.Set(w, h);
490 
491 // get sizes of bitmaps and labels, alignment and margin
492 
493     DoGetBestSize();
494 
495 // glyph or label not used?
496 
497     gz = (mGlyphSize.GetWidth() == 0) || (mGlyphSize.GetHeight() == 0);
498     lz = (mLabelSize.GetWidth() == 0) || (mLabelSize.GetHeight() == 0);
499 
500 // border size is a magiv number, imperically determined using the
501 // wxNativeRenderer to draw the button
502 
503     bn = 2;
504 
505 // position depends on alignment
506 
507     i = GetWindowStyleFlag();
508 
509     if (gz && lz) {                 // no glyph, no label
510         gx = 0;
511         gy = 0;
512         lx = 0;
513         ly = 0;
514     }
515     else if (gz) {                  // no glyph, only label
516         gx = 0;
517         gy = 0;
518         lx = (mCurrentSize.GetWidth()  - mLabelSize.GetWidth())  / 2;
519         ly = (mCurrentSize.GetHeight() - mLabelSize.GetHeight()) / 2;
520     }
521     else if (lz) {                  // no label, glyph only
522         gx = (mCurrentSize.GetWidth()  - mGlyphSize.GetWidth())  / 2;
523         gy = (mCurrentSize.GetHeight() - mGlyphSize.GetHeight()) / 2;
524         lx = 0;
525         ly = 0;
526     }
527     else if ((i & wxBU_LEFT) != 0) {
528         gx = bn + mMargin;
529         lx = gx + mGlyphSize.GetWidth() + mMargin;
530         gy = (mCurrentSize.GetHeight() - mGlyphSize.GetHeight()) / 2;
531         ly = (mCurrentSize.GetHeight() - mLabelSize.GetHeight()) / 2;
532     }
533     else if ((i & wxBU_RIGHT) != 0) {
534         gx = mCurrentSize.GetWidth() - (mGlyphSize.GetWidth() + mMargin + bn);
535         lx = gx - (mLabelSize.GetWidth() + mMargin);
536         gy = (mCurrentSize.GetHeight() - mGlyphSize.GetHeight()) / 2;
537         ly = (mCurrentSize.GetHeight() - mLabelSize.GetHeight()) / 2;
538     }
539     else if ((i & wxBU_TOP) != 0) {
540         gx = (mCurrentSize.GetWidth()  - mGlyphSize.GetWidth())  / 2;
541         lx = (mCurrentSize.GetWidth()  - mLabelSize.GetWidth())  / 2;
542         gy = bn + mMargin;
543         ly = gy + mMargin + mGlyphSize.GetHeight();
544     }
545     else if ((i & wxBU_BOTTOM) != 0) {
546         gx = (mCurrentSize.GetWidth()  - mGlyphSize.GetWidth())  / 2;
547         lx = (mCurrentSize.GetWidth()  - mLabelSize.GetWidth())  / 2;
548         gy = mCurrentSize.GetHeight() - (bn + mMargin + mGlyphSize.GetHeight());
549         ly = gy - (mLabelSize.GetHeight() + mMargin);
550     }
551     else { // unknown
552         gx = 0;
553         gy = 0;
554         lx = 0;
555         ly = 0;
556     };
557 
558 // save the positions
559 
560     mGlyphPos.x = gx;
561     mGlyphPos.y = gy;
562     mLabelPos.x = lx;
563     mLabelPos.y = ly;
564 
565 // redraw button?
566 
567     if (inRefresh) Refresh(false);
568 
569 // allow another call
570 
571     mCalcBusy = false;
572 }
573 
574 
575 
576 
577 
578 //------------------------------------------------------------------------------
579 
SetLabel(wxString & inLabel)580 void wxSpeedButton::SetLabel(wxString &inLabel) {
581     wxControl::SetLabel(inLabel);
582     Refresh(false);
583 }
584 
585 //------------------------------------------------------------------------------
586 
SetGlyphUp(wxBitmap & inBitmap)587 void    wxSpeedButton::SetGlyphUp(wxBitmap &inBitmap) {
588 
589     mGlyphUp = inBitmap;
590     Refresh(false);
591 }
592 
GetGlyphUp(void)593 wxBitmap    &wxSpeedButton::GetGlyphUp(void) {
594 
595     return mGlyphUp;
596 }
597 
598 //------------------------------------------------------------------------------
599 
SetGlyphDown(wxBitmap & inBitmap)600 void    wxSpeedButton::SetGlyphDown(wxBitmap &inBitmap) {
601 
602     mGlyphDown = inBitmap;
603     Refresh(false);
604 }
605 
GetGlyphDown(void)606 wxBitmap    &wxSpeedButton::GetGlyphDown(void) {
607 
608     return mGlyphDown;
609 }
610 
611 //------------------------------------------------------------------------------
612 
SetGlyphDisabled(wxBitmap & inBitmap)613 void    wxSpeedButton::SetGlyphDisabled(wxBitmap &inBitmap) {
614 
615     mGlyphDisabled = inBitmap;
616     Refresh(false);
617 }
618 
GetGlyphDisabled(void)619 wxBitmap    &wxSpeedButton::GetGlyphDisabled(void) {
620 
621     return mGlyphDisabled;
622 }
623 
624 
625 
626 
627 //------------------------------------------------------------------------------
628 
SetAlign(int inAlign)629 void    wxSpeedButton::SetAlign(int inAlign) {
630 int     i,n;
631 
632 // make sure a valid alignment
633 
634     n = inAlign;
635     if ((n != wxBU_LEFT) && (n != wxBU_TOP) &&(n != wxBU_RIGHT) &&(n != wxBU_BOTTOM)) n = wxBU_LEFT;
636 
637 // get current style
638 
639     i = GetWindowStyleFlag();
640 
641 // remove old alignment, and border info
642 
643     i = i & (~ wxBORDER_MASK);
644     i = i & (~ wxBU_ALIGN_MASK);
645 
646 // put in alignment and no-border
647 
648     i = i | wxBORDER_NONE;
649     i = i | n;
650     i = i | wxCLIP_CHILDREN;
651 
652 // save new style
653 
654     SetWindowStyleFlag(i);
655     Refresh(false);
656 }
657 
GetAlign(void)658 int     wxSpeedButton::GetAlign(void) {
659 int     i;
660 
661     i = GetWindowStyleFlag();
662     i = i & wxBU_ALIGN_MASK;
663 
664     return i;
665 }
666 
667 //------------------------------------------------------------------------------
668 
SetMargin(int inMargin)669 void    wxSpeedButton::SetMargin(int inMargin) {
670 
671     mMargin = inMargin;
672     Refresh(false);
673 }
674 
GetMargin(void)675 int     wxSpeedButton::GetMargin(void) {
676 
677     return mMargin;
678 }
679 
680 //------------------------------------------------------------------------------
681 
SetGroupIndex(bool inIndex)682 void    wxSpeedButton::SetGroupIndex(bool inIndex) {
683 
684     mGroupIndex = inIndex;
685     Refresh(false);
686 }
687 
GetGroupIndex(void)688 int     wxSpeedButton::GetGroupIndex(void) {
689 
690     return mGroupIndex;
691 }
692 
693 
694 
695 //------------------------------------------------------------------------------
696 
SetDown(bool inDown)697 void    wxSpeedButton::SetDown(bool inDown) {
698 
699 // a simple button never goes DOWN, it always reports as UP
700 
701     if (mGroupIndex == 0) {
702         mButtonDown = false;
703     }
704 
705 // a sime toggle button goes UP and DOWN
706 
707     else if (mGroupIndex == -1) {
708         mButtonDown = inDown;
709     }
710 
711 // a group toggle button, grouped by immediate parent
712 
713     else if (mGroupIndex == -2) {
714         SetAllUp(this);
715         if ((! inDown) && (mAllowAllUp)) mButtonDown = false;
716         else                             mButtonDown = true;
717     }
718 
719 // all else is a group toggle button, grouped by index and top-level parent
720 
721     else {
722         SetAllUp(this);
723         if ((! inDown) && (mAllowAllUp)) mButtonDown = false;
724         else                             mButtonDown = true;
725     };
726 
727 // done
728 
729     Refresh(false);
730 }
731 
GetDown(void)732 bool    wxSpeedButton::GetDown(void) {
733 
734     return mButtonDown;
735 }
736 
SetAllUp(wxSpeedButton * inButton)737 void    wxSpeedButton::SetAllUp(wxSpeedButton *inButton) {
738 int             i,n;
739 wxSpeedButton   *b;
740 
741 // no button?
742 
743     if (inButton == NULL) return;
744 
745 // simple button
746 
747     if (inButton->mGroupIndex == 0) {
748         inButton->mButtonDown = false;
749         inButton->Refresh(false);
750     }
751 
752 // toggle button
753 
754     else if (inButton->mGroupIndex == -1) {
755         inButton->mButtonDown = false;
756         inButton->Refresh(false);
757     }
758 
759 // group button, grouped by immediate parent
760 
761     else if (inButton->mGroupIndex == -2) {
762         n = sbgArray.GetCount();
763         for(i=0; i<n; i++) {
764             b = (wxSpeedButton *) sbgArray.Item(i);
765             if (b->mParent == inButton->mParent) {
766                 b->mButtonDown = false;
767                 b->Refresh(false);
768             };
769         };
770     }
771 
772 // all else is a group toggle button, grouped by index and top-level parent
773 
774     else {
775         n = sbgArray.GetCount();
776         for(i=0; i<n; i++) {
777             b = (wxSpeedButton *) sbgArray.Item(i);
778             if ((b->mGroupIndex == inButton->mGroupIndex) && (b->mTopParent == inButton->mTopParent)) {
779                 b->mButtonDown = false;
780                 b->Refresh(false);
781             };
782         };
783     };
784 
785 
786 }
787 
SetValue(bool inDown)788 void    wxSpeedButton::SetValue(bool inDown) {
789 
790     SetDown(inDown);
791 }
792 
GetValue(void)793 bool    wxSpeedButton::GetValue(void) {
794 
795     return GetDown();
796 }
797 
798 //------------------------------------------------------------------------------
799 
SetAllowAllUp(bool inAllUp)800 void    wxSpeedButton::SetAllowAllUp(bool inAllUp) {
801 
802     mAllowAllUp = inAllUp;
803     Refresh(false);
804 }
805 
GetAllowAllUp(void)806 bool    wxSpeedButton::GetAllowAllUp(void) {
807 
808     return mAllowAllUp;
809 }
810 
811 //------------------------------------------------------------------------------
812 
SetUserData(long inData)813 void    wxSpeedButton::SetUserData(long inData) {
814 
815     mUserData = inData;
816 }
817 
GetUserData(void)818 long    wxSpeedButton::GetUserData(void) {
819 
820     return mUserData;
821 }
822 
823 
824 
825 
826 
827 
828 //------------------------------------------------------------------------------
829 
830 // sequence of events in GTK is up, dclick, up.
831 
OnMouseEvents(wxMouseEvent & event)832 void wxSpeedButton::OnMouseEvents(wxMouseEvent& event) {
833 wxWindow    *win;
834 
835 // our underlying window
836 
837     win = (wxWindow *) this;
838 
839 // any mouse button down
840 
841     if (event.LeftDown() || event.RightDown()) {
842        if (!HasCapture()) CaptureMouse();
843         mMouseDown = true;
844         mButtonFocused = true;
845         win->SetFocus();
846         Redraw();
847     }
848 
849 // any mouse button up
850 // this is where we send a click event
851 
852     else if (event.LeftUp() || event.RightUp()) {
853         if (HasCapture()) ReleaseMouse();
854         mMouseDown = false;
855         mButtonFocused = true;
856         win->SetFocus();
857         SetDown(! mButtonDown);
858         SendEvent(event.LeftUp());
859         Redraw();
860     }
861 
862 // mouse over
863 
864     else if (event.Entering()) {
865         mMouseOver = true;
866         Redraw();
867     }
868     else if (event.Leaving()) {
869         mMouseOver = false;
870         Redraw();
871     };
872 }
873 
874 //------------------------------------------------------------------------------
875 // cake a mouse click
876 
DoClick(bool inLeft)877 void wxSpeedButton::DoClick(bool inLeft) {
878 
879     SetDown(! mButtonDown);
880     SendEvent(inLeft);
881     Refresh(false);
882 }
883 
884 
885 //------------------------------------------------------------------------------
886 // send a command click-event for the left or right buttons
887 
SendEvent(bool inLeft)888 void wxSpeedButton::SendEvent(bool inLeft) {
889 int                 n;
890 long                now;
891 wxCommandEvent      event;
892 
893 // set command type and window ID of caller
894 
895     if (inLeft) event.SetEventType(wxEVT_COMMAND_LEFT_CLICK);
896     else        event.SetEventType(wxEVT_COMMAND_RIGHT_CLICK);
897 
898     event.SetId(GetId());
899 
900 // save pointer to this object
901 
902     event.SetEventObject(this);
903 
904 // if LEFT, the int is 1, else 0
905 
906     n = inLeft ? 1 : 0;
907     event.SetInt(n);
908 
909 // and the time
910 
911     now = (long) wxDateTime::GetTimeNow();
912     event.SetTimestamp(now);
913 
914 // send it
915 
916     GetEventHandler()->ProcessEvent(event);
917 }
918 
919 
920 //------------------------------------------------------------------------------
921 
OnPaint(wxPaintEvent & event)922 void wxSpeedButton::OnPaint(wxPaintEvent& event)
923 {
924     wxPaintDC dc(this);
925     Paint(dc);
926     event.Skip();
927 }
928 
929 //------------------------------------------------------------------------------
930 
Redraw()931 void wxSpeedButton::Redraw()
932 {
933     wxClientDC dc(this);
934     Paint(dc);
935 }
936 
937 //------------------------------------------------------------------------------
938 // drawing up, down, flat
939 // optional hot, transparent
940 
Paint(wxDC & dc)941 void    wxSpeedButton::Paint( wxDC &dc ) {
942 int         n;
943 int         w,h;
944 wxColour    cf;                     // foreground color
945 wxColour    cb;                     // background color
946 wxColour    cg;                     // gray text
947 wxColour    cy;                     // yellow
948 wxBrush     bb;                     // background brush
949 wxPen       pp;                     // line-drawing pen
950 wxBitmap    bmp;
951 wxString    s;
952 wxRect      rr;
953 
954 // get size and layout
955 
956     if (! mCalcBusy) CalcLayout(false);
957 
958     w = mCurrentSize.GetWidth();
959     h = mCurrentSize.GetHeight();
960 
961 // get colors
962 
963     cf = GetForegroundColour();
964     cb = GetBackgroundColour();
965     cg = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT );
966     cy = wxTheColourDatabase->Find(_("YELLOW"));
967 
968 // use wxWidgets to draw the basic button
969 
970     rr.SetX(0);
971     rr.SetY(0);
972     rr.SetWidth(w);
973     rr.SetHeight(h);
974 
975     n = 0;
976     if (mMouseDown || mButtonDown) n = n | wxCONTROL_PRESSED;
977     if (mButtonFocused) n = n | wxCONTROL_ISDEFAULT;
978 
979     wxRendererNative::Get().DrawPushButton(this, dc, rr, n);
980 
981 // track mouse movements with mMouseOver using a dotted yellow line
982 
983     pp = *wxBLACK_PEN;
984     pp.SetColour(cy);
985 //  pp.SetStyle(wxDOT);
986     dc.SetPen(pp);
987     if (mMouseOver) {
988         n = 2;
989         dc.DrawLine(  n,   n, w-n,   n);
990         dc.DrawLine(w-n,   n, w-n, h-n);
991         dc.DrawLine(w-n, h-n,   n, h-n);
992         dc.DrawLine(  n, h-n,   n,   n);
993     };
994 
995 // select the bitmap to draw
996 
997     if      (! IsEnabled())             bmp = mGlyphDisabled;
998     else if (mMouseDown || mButtonDown) bmp = mGlyphDown;
999     else                                bmp = mGlyphUp;
1000 
1001     if (bmp.IsOk()) dc.DrawBitmap(bmp, mGlyphPos.x, mGlyphPos.y, true );
1002 
1003 // the text label
1004 
1005     s = GetLabelText();
1006     if (! s.IsEmpty()) {
1007         dc.SetFont(GetFont());
1008         dc.SetBackgroundMode(wxTRANSPARENT);
1009         if (! IsEnabled()) dc.SetTextForeground(cg);
1010         else               dc.SetTextForeground(cf);
1011         dc.DrawText(s, mLabelPos.x, mLabelPos.y);
1012     };
1013 }
1014 
1015 //------------------------------------------------------------------------------
1016 
OnSize(wxSizeEvent & event)1017 void wxSpeedButton::OnSize( wxSizeEvent &event )
1018 {
1019     Refresh(false);
1020     event.Skip();
1021 }
1022 
1023 
1024 
1025 //------------------------------------------------------------------------------
1026 
OnSetFocus(wxFocusEvent & event)1027 void wxSpeedButton::OnSetFocus(wxFocusEvent& event) {
1028 
1029     mButtonFocused = true;
1030     Redraw();
1031     event.Skip();
1032 }
1033 
1034 //------------------------------------------------------------------------------
1035 
OnKillFocus(wxFocusEvent & event)1036 void wxSpeedButton::OnKillFocus(wxFocusEvent& event) {
1037 
1038     mButtonFocused = false;
1039     Redraw();
1040     event.Skip();
1041 }
1042 
1043 //------------------------------------------------------------------------------
1044 
OnKey(wxKeyEvent & event)1045 void wxSpeedButton::OnKey(wxKeyEvent& event) {
1046 int         n;
1047 wxString    s;
1048 
1049     n = event.GetKeyCode();
1050     if ((n == '\n') || ( n == '\r') || (n == ' ')) {
1051         mButtonFocused = true;
1052         SetDown(! mButtonDown);
1053         SendEvent(true);
1054         Redraw();
1055 //Refresh(false);
1056     };
1057 
1058     event.Skip();
1059 }
1060 
1061 
1062 
1063 
1064 
1065 
1066 
1067 
1068