1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        newbmpbtn.cpp
3 // Purpose:     wxNewBitmapButton enhanced bitmap button class.
4 // Author:      Aleksandras Gluchovas
5 // Modified by:
6 // Created:     ??/09/98
7 // RCS-ID:      $Id: newbmpbtn.cpp 36920 2006-01-17 15:05:08Z JS $
8 // Copyright:   (c) Aleksandras Gluchovas
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14 
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18 
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22 
23 #include "wx/fl/newbmpbtn.h"
24 #include "wx/utils.h"     // import wxMin,wxMax macros
25 
26 #ifdef __WXMSW__
27 #include "wx/msw/private.h"
28 #endif
29 
30 ///////////// button-label rendering helpers //////////////////
31 
create_array(int width,int height,int fill=0)32 static int* create_array( int width, int height, int fill = 0 )
33 {
34     int* array = new int[width*height];
35 
36     int len = width*height;
37     int i;
38     for ( i = 0; i != len; ++i )
39         array[i] = fill;
40 
41     return array;
42 }
43 
44 #define GET_ELEM(array,x,y) (array[width*(y)+(x)])
45 
46 #define MIN_COLOR_DIFF 10
47 
48 #define IS_IN_ARRAY(x,y) ( (x) < width && (y) < height && (x) >= 0 && (y) >= 0 )
49 
50 #define GET_RED(col)    col        & 0xFF
51 #define GET_GREEN(col) (col >> 8)  & 0xFF
52 #define GET_BLUE(col)  (col >> 16) & 0xFF
53 
54 #define MAKE_INT_COLOR(red,green,blue) (     (red)                      | \
55                                          ( ( (green) << 8 ) & 0xFF00  ) | \
56                                          ( ( (blue)  << 16) & 0xFF0000) \
57                                        )
58 
59 #define IS_GREATER(col1,col2) ( ( (GET_RED(col1)  ) > (GET_RED(col2)  ) + MIN_COLOR_DIFF ) && \
60                                 ( (GET_GREEN(col1)) > (GET_GREEN(col2)) + MIN_COLOR_DIFF ) &&  \
61                                 ( (GET_BLUE(col1) ) > (GET_BLUE(col2) ) + MIN_COLOR_DIFF )     \
62                               )
63 
64 #define MASK_BG    0
65 #define MASK_DARK  1
66 #define MASK_LIGHT 2
67 
68 // helper function, used internally
69 
gray_out_pixmap(int * src,int * dest,int width,int height)70 static void gray_out_pixmap( int* src, int* dest, int width, int height )
71 {
72     // assuming the pixels along the edges are of the background color
73 
74     int x = 0;
75     int y = 1;
76 
77     do
78     {
79         int cur       = GET_ELEM(src,x,y);
80 
81 
82         if ( IS_IN_ARRAY(x-1,y-1) )
83         {
84             int upperElem = GET_ELEM(src,x-1,y-1);
85 
86             // if the upper element is lighter than current
87             if ( IS_GREATER(upperElem,cur) )
88             {
89                 GET_ELEM(dest,x,y) = MASK_DARK;
90             }
91             else
92             // if the current element is ligher than the upper
93             if ( IS_GREATER(cur,upperElem) )
94             {
95                 GET_ELEM(dest,x,y) = MASK_LIGHT;
96             }
97             else
98             {
99                 if ( GET_ELEM(dest,x-1,y-1) == MASK_LIGHT )
100 
101                     GET_ELEM(dest,x,y) = MASK_BG;
102 
103                 if ( GET_ELEM(dest,x-1,y-1 ) == MASK_DARK )
104 
105                     GET_ELEM(dest,x,y) = MASK_DARK;
106                 else
107                     GET_ELEM(dest,x,y) = MASK_BG;
108             }
109         }
110 
111         // go zig-zag
112 
113         if ( IS_IN_ARRAY(x+1,y-1) )
114         {
115             ++x;
116             --y;
117         }
118         else
119         {
120             while ( IS_IN_ARRAY(x-1,y+1) )
121             {
122                 --x;
123                 ++y;
124             }
125 
126             if ( IS_IN_ARRAY(x,y+1) )
127             {
128                 ++y;
129                 continue;
130             }
131             else
132             {
133                 if ( IS_IN_ARRAY(x+1,y) )
134                 {
135                     ++x;
136                     continue;
137                 }
138                 else break;
139             }
140         }
141 
142     } while (1);
143 }
144 
145 // algorithm for making the image look "grayed" (e.g. disabled button)
146 // NOTE:: used GetPixel(), which is Windows-Only!
147 
gray_out_image_on_dc(wxDC & dc,int width,int height)148 void gray_out_image_on_dc( wxDC& dc, int width, int height )
149 {
150     // assuming the pixels along the edges are of the background color
151     wxColour bgCol;
152     dc.GetPixel( 0, 0, &bgCol );
153 
154     wxPen darkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW),1, wxSOLID );
155     wxPen lightPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT),1, wxSOLID );
156     wxPen bgPen   ( bgCol,                1, wxSOLID );
157 
158     int* src  = create_array( width, height, MASK_BG );
159     int* dest = create_array( width, height, MASK_BG );
160 
161     int x, y;
162     for ( y = 0; y != height; ++y )
163     {
164         for ( x = 0; x != width; ++x )
165         {
166             wxColour col;
167             dc.GetPixel( x,y, &col );
168 
169             GET_ELEM(src,x,y) = MAKE_INT_COLOR( col.Red(), col.Green(), col.Blue() );
170         }
171     }
172     gray_out_pixmap( src, dest, width, height );
173 
174     for ( y = 0; y != height; ++y )
175     {
176         for ( x = 0; x != width; ++x )
177         {
178             int mask = GET_ELEM(dest,x,y);
179 
180             switch (mask)
181             {
182                 case MASK_BG    : { dc.SetPen( bgPen );
183                                     dc.DrawPoint( x,y ); break;
184                                   }
185                 case MASK_DARK  : { dc.SetPen( darkPen );
186                                     dc.DrawPoint( x,y ); break;
187                                   }
188                 case MASK_LIGHT : { dc.SetPen( lightPen );
189                                     dc.DrawPoint( x,y ); break;
190                                   }
191                 default : break;
192             }
193         }
194     }
195     delete [] src;
196     delete [] dest;
197 }
198 
199 ///////////////////////////////
200 
201 /***** Implementation for class wxNewBitmapButton *****/
202 
IMPLEMENT_DYNAMIC_CLASS(wxNewBitmapButton,wxPanel)203 IMPLEMENT_DYNAMIC_CLASS(wxNewBitmapButton, wxPanel)
204 
205 BEGIN_EVENT_TABLE( wxNewBitmapButton, wxPanel )
206 
207     EVT_LEFT_DOWN   ( wxNewBitmapButton::OnLButtonDown   )
208     EVT_LEFT_UP     ( wxNewBitmapButton::OnLButtonUp     )
209 //    EVT_LEFT_DCLICK ( wxNewBitmapButton::OnLButtonDClick )
210     EVT_LEFT_DCLICK ( wxNewBitmapButton::OnLButtonDown )
211     EVT_ENTER_WINDOW( wxNewBitmapButton::OnMouseEnter    )
212     EVT_LEAVE_WINDOW( wxNewBitmapButton::OnMouseLeave    )
213 
214     EVT_SIZE ( wxNewBitmapButton::OnSize  )
215     EVT_PAINT( wxNewBitmapButton::OnPaint )
216 
217     //EVT_KILL_FOCUS( wxNewBitmapButton::OnKillFocus )
218 
219     EVT_ERASE_BACKGROUND( wxNewBitmapButton::OnEraseBackground )
220 
221     EVT_IDLE(wxNewBitmapButton::OnIdle)
222 
223 END_EVENT_TABLE()
224 
225 wxNewBitmapButton::wxNewBitmapButton( const wxBitmap& labelBitmap,
226                                       const wxString& labelText,
227                                       int  alignText,
228                                       bool isFlat,
229                                       int  firedEventType,
230                                       int  marginX,
231                                       int  marginY,
232                                       int  textToLabelGap,
233                                       bool isSticky)
234     :   mTextToLabelGap  ( textToLabelGap ),
235         mMarginX( marginX ),
236         mMarginY( marginY ),
237         mTextAlignment( alignText ),
238         mIsSticky( isSticky ),
239         mIsFlat( isFlat ),
240         mLabelText( labelText ),
241         mImageFileType( wxBITMAP_TYPE_INVALID ),
242         mDepressedBmp( labelBitmap ),
243 
244         mpDepressedImg( NULL ),
245         mpPressedImg  ( NULL ),
246         mpDisabledImg ( NULL ),
247         mpFocusedImg  ( NULL ),
248 
249 
250         mDragStarted  ( false ),
251         mIsPressed    ( false ),
252         mIsInFocus    ( false ),
253         mIsToggled    ( false ),
254         mHasFocusedBmp( false ),
255         mFiredEventType( firedEventType ),
256 
257         mBlackPen( wxColour(  0,  0,  0), 1, wxSOLID ),
258         mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
259         mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
260         mLightPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT), 1, wxSOLID ),
261 
262         mIsCreated( false ),
263         mSizeIsSet( false )
264 
265 {
266 }
267 
wxNewBitmapButton(const wxString & bitmapFileName,const wxBitmapType bitmapFileType,const wxString & labelText,int alignText,bool isFlat,int WXUNUSED (firedEventType),int WXUNUSED (marginX),int WXUNUSED (marginY),int WXUNUSED (textToLabelGap),bool WXUNUSED (isSticky))268 wxNewBitmapButton::wxNewBitmapButton( const wxString& bitmapFileName,
269                                       const wxBitmapType  bitmapFileType,
270                                       const wxString& labelText,
271                                       int  alignText,
272                                       bool isFlat,
273                                       int  WXUNUSED(firedEventType),
274                                       int  WXUNUSED(marginX),
275                                       int  WXUNUSED(marginY),
276                                       int  WXUNUSED(textToLabelGap),
277                                       bool WXUNUSED(isSticky))
278 
279     :   mTextToLabelGap  ( 2 ),
280         mMarginX( 2 ),
281         mMarginY( 2 ),
282         mTextAlignment( alignText ),
283         mIsSticky( false ),
284         mIsFlat( isFlat ),
285         mLabelText( labelText ),
286         mImageFileName( bitmapFileName ),
287         mImageFileType( bitmapFileType ),
288 
289         mpDepressedImg( NULL ),
290         mpPressedImg  ( NULL ),
291         mpDisabledImg ( NULL ),
292         mpFocusedImg  ( NULL ),
293 
294         mDragStarted  ( false ),
295         mIsPressed    ( false ),
296         mIsInFocus    ( false ),
297         mIsToggled    ( false ),
298         mHasFocusedBmp( false ),
299         mFiredEventType( wxEVT_COMMAND_MENU_SELECTED ),
300 
301         mBlackPen( wxColour(  0,  0,  0), 1, wxSOLID ),
302         mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
303         mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
304         mLightPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT), 1, wxSOLID ),
305 
306         mIsCreated( false ),
307         mSizeIsSet( false )
308 
309 {
310 }
311 
~wxNewBitmapButton(void)312 wxNewBitmapButton::~wxNewBitmapButton(void)
313 {
314     DestroyLabels();
315 }
316 
DrawShade(int outerLevel,wxDC & dc,wxPen & upperLeftSidePen,wxPen & lowerRightSidePen)317 void wxNewBitmapButton::DrawShade( int outerLevel,
318                                    wxDC&  dc,
319                                    wxPen& upperLeftSidePen,
320                                    wxPen& lowerRightSidePen )
321 {
322     wxBitmap* pBmp = GetStateLabel();
323     int x = mMarginX - (outerLevel + 2);
324     int y = mMarginY - (outerLevel + 2);
325     int height = pBmp->GetHeight() + (outerLevel + 2)*2 - 1;
326     int width  = pBmp->GetWidth()  + (outerLevel + 2)*2 - 1;
327     dc.SetPen( upperLeftSidePen );
328     dc.DrawLine( x,y, x + width, y  );
329     dc.DrawLine( x,y, x, y + height );
330     dc.DrawLine( x,y+1, x + width , y +1 );  // top
331     dc.DrawLine( x+1,y, x+1, y + height );  // left
332 
333     dc.SetPen( lowerRightSidePen );
334     dc.DrawLine( x + width, y, x + width, y + height + 1  );
335     dc.DrawLine( x, y + height, x + width, y + height );
336     dc.DrawLine( x + width-1, y+1, x + width-1, y + height +1  );  // right
337     dc.DrawLine( x +1, y + height-1, x + width, y + height-1 );  // bottom
338 }
339 
DestroyLabels()340 void wxNewBitmapButton::DestroyLabels()
341 {
342     if ( mpDepressedImg ) delete mpDepressedImg;
343     if ( mpPressedImg   ) delete mpPressedImg;
344     if ( mpDisabledImg  ) delete mpDisabledImg;
345     if ( mpFocusedImg   ) delete mpFocusedImg;
346 
347     mpDepressedImg = NULL;
348     mpPressedImg   = NULL;
349     mpDisabledImg  = NULL;
350     mpFocusedImg   = NULL;
351 }
352 
GetStateLabel()353 wxBitmap* wxNewBitmapButton::GetStateLabel()
354 {
355     if ( IsEnabled() )
356     {
357         if ( mIsPressed )
358         {
359             return mpPressedImg;
360         }
361         else
362         {
363             if ( mIsInFocus )
364             {
365                 if ( mHasFocusedBmp )
366 
367                     return mpFocusedImg;
368                 else
369                     return mpDepressedImg;
370             }
371             else
372                 return mpDepressedImg;
373         }
374     }
375     else
376         return mpDisabledImg;
377 }
378 
379 #ifndef __WXMSW__
380 
381 static const unsigned char _gDisableImage[] = { 0x55,0xAA,0x55,0xAA,
382                                               0x55,0xAA,0x55,0xAA,
383                                               0x55,0xAA,0x55,0xAA,
384                                               0x55,0xAA,0x55,0xAA
385                                             };
386 
387 #endif
388 
RenderLabelImage(wxBitmap * & destBmp,wxBitmap * srcBmp,bool isEnabled,bool isPressed)389 void wxNewBitmapButton::RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp,
390                                           bool isEnabled, bool isPressed )
391 {
392     if ( destBmp != 0 ) return;
393 
394     // render labels on-demand
395 
396     wxMemoryDC srcDc;
397     srcDc.SelectObject( *srcBmp );
398 
399     bool hasText = ( mTextAlignment != NB_NO_TEXT ) &&
400                    ( mLabelText.length() != 0 );
401 
402     bool hasImage = (mTextAlignment != NB_NO_IMAGE);
403 
404     wxSize destDim;
405     wxPoint txtPos;
406     wxPoint imgPos;
407 
408     if ( hasText )
409     {
410         long txtWidth, txtHeight;
411 
412         srcDc.SetFont( wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) );
413         srcDc.GetTextExtent( mLabelText, &txtWidth, &txtHeight );
414 
415         if ( mTextAlignment == NB_ALIGN_TEXT_RIGHT )
416         {
417             destDim.x = srcBmp->GetWidth() + 2*mTextToLabelGap + txtWidth;
418 
419             destDim.y =
420                 wxMax( srcBmp->GetHeight(), txtHeight );
421 
422             txtPos.x = srcBmp->GetWidth() + mTextToLabelGap;
423             txtPos.y = (destDim.y - txtHeight)/2;
424             imgPos.x = 0;
425             imgPos.y = (destDim.y - srcBmp->GetHeight())/2;
426         }
427         else
428         if ( mTextAlignment == NB_ALIGN_TEXT_BOTTOM )
429         {
430             destDim.x =
431                 wxMax( srcBmp->GetWidth(), txtWidth );
432 
433             destDim.y = srcBmp->GetHeight() + mTextToLabelGap + txtHeight;
434 
435             txtPos.x = (destDim.x - txtWidth)/2;
436             txtPos.y = srcBmp->GetHeight() + mTextToLabelGap;
437             imgPos.x = (destDim.x - srcBmp->GetWidth())/2;
438             imgPos.y = 0;
439         }
440         else
441         {
442             wxFAIL_MSG(wxT("Unsupported FL alignment type detected in wxNewBitmapButton::RenderLabelImage()"));
443         }
444     }
445     else
446     {
447         imgPos.x = 0;
448         imgPos.y = 0;
449         destDim.x = srcBmp->GetWidth();
450         destDim.y = srcBmp->GetHeight();
451     }
452 
453     destBmp = new wxBitmap( int(destDim.x), int(destDim.y) );
454 
455     wxMemoryDC destDc;
456     destDc.SelectObject( *destBmp );
457 
458     wxBrush grayBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE), wxSOLID );
459 
460     destDc.SetBrush( grayBrush );
461     destDc.SetPen( *wxTRANSPARENT_PEN );
462     destDc.DrawRectangle( 0,0, destDim.x+1, destDim.y+1 );
463 
464     if ( isPressed )
465     {
466         ++imgPos.x; ++imgPos.y;
467         ++txtPos.x; ++txtPos.y;
468     }
469 
470     if ( hasImage )
471     {
472 
473         destDc.Blit( imgPos.x, imgPos.y,
474                  srcBmp->GetWidth(),
475                  srcBmp->GetHeight(),
476                  &srcDc, 0,0, wxCOPY,true );
477     }
478 
479     if ( hasText )
480     {
481         wxWindow* pTopWnd = this;
482 
483         do
484         {
485             wxWindow* pParent = pTopWnd->GetParent();
486 
487             if ( pParent == 0 )
488                 break;
489 
490             pTopWnd = pParent;
491         } while (1);
492 
493         destDc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT) );
494 
495         if ( isEnabled )
496         {
497             destDc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT) );
498         }
499         else
500         {
501             destDc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW) );
502         }
503         destDc.SetTextBackground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE) );
504 
505         destDc.DrawText( mLabelText, txtPos.x, txtPos.y );
506     }
507 
508     if ( !isEnabled ){
509 
510 #ifdef __WXMSW__ // This is currently MSW specific
511         gray_out_image_on_dc( destDc, destDim.x, destDim.y );
512 #else
513         wxBitmap bmp( (const char*)_gDisableImage,8,8);
514         wxBrush checkerBrush(bmp);
515         checkerBrush.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
516         destDc.SetBrush( checkerBrush );
517         destDc.DrawRectangle( imgPos.x, imgPos.y, srcBmp->GetWidth()+1, srcBmp->GetHeight()+1);
518 #endif
519     }
520     // adjust button size to fit the new dimensions of the label
521     if ( !mSizeIsSet && 0 )
522     {
523         mSizeIsSet = true;
524         SetSize( wxDefaultCoord, wxDefaultCoord,
525                  destBmp->GetWidth()  + mMarginX*2,
526                  destBmp->GetHeight() + mMarginY*2, 0
527             );
528     }
529     destDc.SelectObject( wxNullBitmap );
530 
531 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
532     // Map to system colours
533     (void) wxToolBar::MapBitmap(destBmp->GetHBITMAP(), destBmp->GetWidth(), destBmp->GetHeight());
534 #endif
535 }
536 
RenderAllLabelImages()537 void wxNewBitmapButton::RenderAllLabelImages()
538 {
539     if ( !mIsCreated )
540         return;
541     RenderLabelImage( mpDisabledImg, &mDepressedBmp, false );
542     RenderLabelImage( mpPressedImg,   &mDepressedBmp, true, true );
543     RenderLabelImage( mpDepressedImg, &mDepressedBmp, true, false );
544     if ( mHasFocusedBmp )
545     {
546         RenderLabelImage( mpFocusedImg, &mFocusedBmp, true, false );
547     }
548 }
549 
550 
RenderLabelImages()551 void wxNewBitmapButton::RenderLabelImages()
552 {
553     if ( !mIsCreated )
554         return;
555 
556     if ( !IsEnabled() )
557     {
558         RenderLabelImage( mpDisabledImg, &mDepressedBmp, false );
559     }
560     else
561 
562     if ( mIsPressed )
563 
564         RenderLabelImage( mpPressedImg,   &mDepressedBmp, true, true );
565     else
566     {
567         if ( mIsInFocus )
568         {
569             if ( mHasFocusedBmp )
570                 RenderLabelImage( mpFocusedImg, &mFocusedBmp, true, false );
571             else
572                 RenderLabelImage( mpDepressedImg, &mDepressedBmp, true, false );
573         }
574         else
575             RenderLabelImage( mpDepressedImg, &mDepressedBmp, true, false );
576     }
577 }
578 
Toggle(bool enable)579 bool wxNewBitmapButton::Toggle(bool enable)
580 {
581     if ( mIsToggled == enable )
582     {
583         return false;
584     }
585 
586     mIsToggled = enable;
587     Refresh();
588 
589     return true;
590 }
591 
Enable(bool enable)592 bool wxNewBitmapButton::Enable(bool enable)
593 {
594     if ( enable != m_isEnabled )
595     {
596         if ( mIsInFocus )
597         {
598             mIsInFocus = false;
599         }
600 
601         if ( mIsPressed )
602         {
603             mIsPressed = false;
604         }
605 
606         Refresh();
607     }
608 
609     return wxPanel::Enable( enable );
610 }
611 
DrawDecorations(wxDC & dc)612 void wxNewBitmapButton::DrawDecorations( wxDC& dc )
613 {
614     if ( mIsFlat )
615     {
616         DrawShade( 1, dc, mGrayPen,  mGrayPen  );
617         if ( mIsToggled )
618         {
619             DrawShade( 0, dc, mDarkPen,  mLightPen  );
620         }
621         else if ( mIsInFocus )
622         {
623             if ( mIsPressed )
624                 DrawShade( 0, dc, mDarkPen,  mLightPen  );
625             else
626                 DrawShade( 0, dc, mLightPen,  mDarkPen  );
627         }
628         else
629             DrawShade( 0, dc, mGrayPen,  mGrayPen  );
630     }
631     else
632     {
633         if ( mIsPressed || mIsToggled )
634         {
635             DrawShade( 0, dc, mDarkPen,  mGrayPen  );
636             DrawShade( 1, dc, mBlackPen, mLightPen );
637         }
638         else
639         {
640             DrawShade( 0, dc, mGrayPen,  mDarkPen  );
641             DrawShade( 1, dc, mLightPen, mBlackPen );
642         }
643     }
644 }
645 
SetLabel(const wxBitmap & labelBitmap,const wxString & labelText)646 void wxNewBitmapButton::SetLabel(const wxBitmap& labelBitmap,
647                                  const wxString& labelText )
648 {
649     DestroyLabels();
650 
651     mLabelText    = labelText;
652     mDepressedBmp = labelBitmap;
653 
654     //RenderLabelImages();
655     RenderAllLabelImages();
656 }
657 
SetAlignments(int alignText,int marginX,int marginY,int textToLabelGap)658 void wxNewBitmapButton::SetAlignments( int alignText,
659                                        int marginX,
660                                        int marginY,
661                                        int textToLabelGap)
662 {
663     DestroyLabels();
664 
665     mMarginX        = marginX;
666     mMarginY        = marginY;
667     mTextAlignment  = alignText;
668     mTextToLabelGap = textToLabelGap;
669 
670     //RenderLabelImages();
671     RenderAllLabelImages();
672 }
673 
674 // event handlers
675 
OnLButtonDown(wxMouseEvent & WXUNUSED (event))676 void wxNewBitmapButton::OnLButtonDown( wxMouseEvent& WXUNUSED(event) )
677 {
678     mDragStarted      = true;
679     mIsPressed        = true;
680     Refresh();
681 }
682 
OnLButtonUp(wxMouseEvent & event)683 void wxNewBitmapButton::OnLButtonUp( wxMouseEvent& event )
684 {
685     if ( !mDragStarted )
686         return;
687 
688     mDragStarted = false;
689     mIsPressed   = false;
690     Refresh();
691 
692     if ( IsInWindow( event.m_x, event.m_y ) )
693     {
694         // fire event, if mouse was released
695         // within the bounds of button
696         wxCommandEvent cmd( mFiredEventType, GetId() );
697         GetParent()->ProcessEvent( cmd );
698     }
699 }
700 
IsInWindow(int x,int y)701 bool wxNewBitmapButton::IsInWindow( int x, int y )
702 {
703     int width, height;
704     GetSize( &width, &height );
705 
706     return ( x >= 0 && y >= 0 &&
707              x < width &&
708              y < height );
709 }
710 
OnMouseEnter(wxMouseEvent & WXUNUSED (event))711 void wxNewBitmapButton::OnMouseEnter( wxMouseEvent& WXUNUSED(event) )
712 {
713     bool prevIsInFocus = mIsInFocus;
714 
715     if ( !mIsInFocus )
716     {
717         mIsInFocus = true;
718     }
719     if ( prevIsInFocus != mIsInFocus )
720     {
721         Refresh();
722     }
723 }
724 
OnMouseLeave(wxMouseEvent & WXUNUSED (event))725 void wxNewBitmapButton::OnMouseLeave( wxMouseEvent& WXUNUSED(event) )
726 {
727     bool prevIsInFocus = mIsInFocus;
728     bool prevIsPressed = mIsPressed;
729     if ( mIsInFocus )
730     {
731         mIsInFocus = false;
732         mIsPressed = false;
733     }
734     if ( prevIsInFocus != mIsInFocus || prevIsPressed != mIsPressed )
735     {
736         Refresh();
737     }
738 }
739 
OnSize(wxSizeEvent & WXUNUSED (event))740 void wxNewBitmapButton::OnSize( wxSizeEvent& WXUNUSED(event) )
741 {
742         //Reshape();
743 }
744 
Reshape()745 void wxNewBitmapButton::Reshape( )
746 {
747     bool wasCreated = mIsCreated;
748     mIsCreated = true;
749 
750     if ( !wasCreated )
751     {
752         // in the case of loading button from stream, check if we
753         // have non-empty image-file name, load if possible
754 
755         if (!mImageFileName.empty())
756         {
757             mDepressedBmp.LoadFile( mImageFileName, mImageFileType );
758 
759             //wxMessageBox("Image Loaded!!!");
760         }
761 
762         //RenderLabelImages();
763         RenderAllLabelImages();
764 
765         wxBitmap* pCurImg = GetStateLabel();
766 
767         int w = pCurImg->GetWidth(),
768             h = pCurImg->GetHeight();
769 
770         SetSize( 0,0, w + mMarginX*2, h + mMarginY*2 , 0 );
771     }
772 }
773 
DrawLabel(wxDC & dc)774 void wxNewBitmapButton::DrawLabel( wxDC& dc )
775 {
776     wxBitmap* pCurBmp = GetStateLabel();
777 
778     if ( pCurBmp == NULL )
779     {
780         wxSizeEvent evt;
781         OnSize( evt ); // fake it up!
782 
783         //RenderLabelImages();
784         pCurBmp = GetStateLabel();
785     }
786 
787     wxMemoryDC mdc;
788     mdc.SelectObject( *pCurBmp );
789 
790     dc.Blit( mMarginX, mMarginY,
791              pCurBmp->GetWidth(),
792              pCurBmp->GetHeight(),
793              &mdc, 0,0, wxCOPY
794            );
795 
796     mdc.SelectObject( wxNullBitmap );
797 }
798 
OnPaint(wxPaintEvent & WXUNUSED (event))799 void wxNewBitmapButton::OnPaint( wxPaintEvent& WXUNUSED(event) )
800 {
801     wxPaintDC dc(this);
802 
803     // first, make sure images for current state are prepared
804     //RenderLabelImages();
805 
806     DrawLabel( dc );
807 
808     DrawDecorations( dc );
809 }
810 
OnEraseBackground(wxEraseEvent & WXUNUSED (event))811 void wxNewBitmapButton::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
812 {
813     // do nothing
814 }
815 
OnKillFocus(wxFocusEvent & WXUNUSED (event))816 void wxNewBitmapButton::OnKillFocus( wxFocusEvent& WXUNUSED(event) )
817 {
818     // useless
819 
820     wxMessageBox(wxT("kill-focus for button!"));
821 }
822 
823 // ----------------------------------------------------------------------------
824 // UI updates
825 // ----------------------------------------------------------------------------
826 
OnIdle(wxIdleEvent & event)827 void wxNewBitmapButton::OnIdle(wxIdleEvent& event)
828 {
829     DoButtonUpdate();
830 
831     event.Skip();
832 }
833 
834 // Do the toolbar button updates (check for EVT_UPDATE_UI handlers)
DoButtonUpdate()835 void wxNewBitmapButton::DoButtonUpdate()
836 {
837     wxUpdateUIEvent event(GetId());
838     event.SetEventObject(this);
839 
840     if ( GetParent()->ProcessEvent(event) )
841     {
842         if ( event.GetSetEnabled() )
843         {
844             bool enabled = event.GetEnabled();
845             if ( enabled != IsEnabled() )
846                 Enable( enabled );
847         }
848         if ( event.GetSetChecked() )
849             Toggle( event.GetChecked() );
850     }
851 }
852