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
32static 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
70static 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
148void 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
203IMPLEMENT_DYNAMIC_CLASS(wxNewBitmapButton, wxPanel)
204
205BEGIN_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
223END_EVENT_TABLE()
224
225wxNewBitmapButton::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
268wxNewBitmapButton::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
312wxNewBitmapButton::~wxNewBitmapButton(void)
313{
314    DestroyLabels();
315}
316
317void 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
340void 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
353wxBitmap* 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
381static 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
389void 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
537void 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
551void 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
579bool 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
592bool 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
612void 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
646void 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
658void 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
676void wxNewBitmapButton::OnLButtonDown( wxMouseEvent& WXUNUSED(event) )
677{
678    mDragStarted      = true;
679    mIsPressed        = true;
680    Refresh();
681}
682
683void 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
701bool 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
711void 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
725void 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
740void wxNewBitmapButton::OnSize( wxSizeEvent& WXUNUSED(event) )
741{
742        //Reshape();
743}
744
745void 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
774void 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
799void 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
811void wxNewBitmapButton::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
812{
813    // do nothing
814}
815
816void wxNewBitmapButton::OnKillFocus( wxFocusEvent& WXUNUSED(event) )
817{
818    // useless
819
820    wxMessageBox(wxT("kill-focus for button!"));
821}
822
823// ----------------------------------------------------------------------------
824// UI updates
825// ----------------------------------------------------------------------------
826
827void 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)
835void 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