]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/newbmpbtn.cpp
correct access for virtuals
[wxWidgets.git] / contrib / src / fl / newbmpbtn.cpp
CommitLineData
8e08b761 1/////////////////////////////////////////////////////////////////////////////
4cbc57f0
JS
2// Name: newbmpbtn.cpp
3// Purpose: wxNewBitmapButton enhanced bitmap button class.
8e08b761
JS
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: ??/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
4cbc57f0 9// Licence: wxWindows licence
8e08b761
JS
10/////////////////////////////////////////////////////////////////////////////
11
8e08b761
JS
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
65e50848
JS
26#ifdef __WXMSW__
27#include "wx/msw/private.h"
28#endif
29
8e08b761
JS
30///////////// button-label rendering helpers //////////////////
31
32static int* create_array( int width, int height, int fill = 0 )
33{
5515f252 34 int* array = new int[width*height];
8e08b761 35
5515f252
GT
36 int len = width*height;
37 int i;
38 for ( i = 0; i != len; ++i )
39 array[i] = fill;
8e08b761 40
5515f252 41 return array;
8e08b761
JS
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
18c45cd6
WS
50#define GET_RED(col) col & 0xFF
51#define GET_GREEN(col) (col >> 8) & 0xFF
52#define GET_BLUE(col) (col >> 16) & 0xFF
8e08b761
JS
53
54#define MAKE_INT_COLOR(red,green,blue) ( (red) | \
55 ( ( (green) << 8 ) & 0xFF00 ) | \
5515f252 56 ( ( (blue) << 16) & 0xFF0000) \
18c45cd6 57 )
8e08b761
JS
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 ) && \
5515f252
GT
61 ( (GET_BLUE(col1) ) > (GET_BLUE(col2) ) + MIN_COLOR_DIFF ) \
62 )
8e08b761 63
5515f252 64#define MASK_BG 0
8e08b761
JS
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{
5515f252
GT
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 )
18c45cd6 100
5515f252
GT
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
18c45cd6 113 if ( IS_IN_ARRAY(x+1,y-1) )
5515f252
GT
114 {
115 ++x;
116 --y;
117 }
118 else
119 {
18c45cd6 120 while ( IS_IN_ARRAY(x-1,y+1) )
5515f252
GT
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);
8e08b761
JS
143}
144
4cbc57f0 145// algorithm for making the image look "grayed" (e.g. disabled button)
8e08b761
JS
146// NOTE:: used GetPixel(), which is Windows-Only!
147
148void gray_out_image_on_dc( wxDC& dc, int width, int height )
149{
5515f252
GT
150 // assuming the pixels along the edges are of the background color
151 wxColour bgCol;
152 dc.GetPixel( 0, 0, &bgCol );
153
e1c6c6ae
VS
154 wxPen darkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW),1, wxSOLID );
155 wxPen lightPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT),1, wxSOLID );
5515f252
GT
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 {
18c45cd6 182 case MASK_BG : { dc.SetPen( bgPen );
5515f252
GT
183 dc.DrawPoint( x,y ); break;
184 }
18c45cd6 185 case MASK_DARK : { dc.SetPen( darkPen );
5515f252
GT
186 dc.DrawPoint( x,y ); break;
187 }
18c45cd6 188 case MASK_LIGHT : { dc.SetPen( lightPen );
5515f252
GT
189 dc.DrawPoint( x,y ); break;
190 }
191 default : break;
192 }
193 }
194 }
195 delete [] src;
196 delete [] dest;
8e08b761
JS
197}
198
199///////////////////////////////
200
4cbc57f0 201/***** Implementation for class wxNewBitmapButton *****/
8e08b761
JS
202
203IMPLEMENT_DYNAMIC_CLASS(wxNewBitmapButton, wxPanel)
204
205BEGIN_EVENT_TABLE( wxNewBitmapButton, wxPanel )
206
45da7759
JS
207 EVT_LEFT_DOWN ( wxNewBitmapButton::OnLButtonDown )
208 EVT_LEFT_UP ( wxNewBitmapButton::OnLButtonUp )
45d6fd80
JS
209// EVT_LEFT_DCLICK ( wxNewBitmapButton::OnLButtonDClick )
210 EVT_LEFT_DCLICK ( wxNewBitmapButton::OnLButtonDown )
45da7759
JS
211 EVT_ENTER_WINDOW( wxNewBitmapButton::OnMouseEnter )
212 EVT_LEAVE_WINDOW( wxNewBitmapButton::OnMouseLeave )
8e08b761 213
5515f252
GT
214 EVT_SIZE ( wxNewBitmapButton::OnSize )
215 EVT_PAINT( wxNewBitmapButton::OnPaint )
8e08b761 216
5515f252 217 //EVT_KILL_FOCUS( wxNewBitmapButton::OnKillFocus )
8e08b761 218
5515f252 219 EVT_ERASE_BACKGROUND( wxNewBitmapButton::OnEraseBackground )
8e08b761 220
ab839dff
JS
221 EVT_IDLE(wxNewBitmapButton::OnIdle)
222
8e08b761
JS
223END_EVENT_TABLE()
224
ab839dff 225wxNewBitmapButton::wxNewBitmapButton( const wxBitmap& labelBitmap,
5515f252
GT
226 const wxString& labelText,
227 int alignText,
228 bool isFlat,
ab839dff 229 int firedEventType,
5515f252
GT
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
c82c42d4
WS
250 mDragStarted ( false ),
251 mIsPressed ( false ),
252 mIsInFocus ( false ),
253 mIsToggled ( false ),
254 mHasFocusedBmp( false ),
5515f252
GT
255 mFiredEventType( firedEventType ),
256
257 mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ),
e1c6c6ae
VS
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 ),
5515f252 261
c82c42d4
WS
262 mIsCreated( false ),
263 mSizeIsSet( false )
8e08b761
JS
264
265{
266}
267
268wxNewBitmapButton::wxNewBitmapButton( const wxString& bitmapFileName,
52b5ab7e
GD
269 const wxBitmapType bitmapFileType,
270 const wxString& labelText,
271 int alignText,
272 bool isFlat,
18c45cd6 273 int WXUNUSED(firedEventType),
196be0f1
JS
274 int WXUNUSED(marginX),
275 int WXUNUSED(marginY),
276 int WXUNUSED(textToLabelGap),
277 bool WXUNUSED(isSticky))
8e08b761 278
5515f252
GT
279 : mTextToLabelGap ( 2 ),
280 mMarginX( 2 ),
281 mMarginY( 2 ),
282 mTextAlignment( alignText ),
c82c42d4 283 mIsSticky( false ),
5515f252
GT
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
c82c42d4
WS
294 mDragStarted ( false ),
295 mIsPressed ( false ),
296 mIsInFocus ( false ),
297 mIsToggled ( false ),
298 mHasFocusedBmp( false ),
5515f252
GT
299 mFiredEventType( wxEVT_COMMAND_MENU_SELECTED ),
300
301 mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ),
e1c6c6ae
VS
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 ),
5515f252 305
c82c42d4
WS
306 mIsCreated( false ),
307 mSizeIsSet( false )
8e08b761
JS
308
309{
310}
311
18c45cd6 312wxNewBitmapButton::~wxNewBitmapButton(void)
8e08b761 313{
5515f252 314 DestroyLabels();
8e08b761
JS
315}
316
317void wxNewBitmapButton::DrawShade( int outerLevel,
5515f252
GT
318 wxDC& dc,
319 wxPen& upperLeftSidePen,
320 wxPen& lowerRightSidePen )
8e08b761 321{
5515f252 322 wxBitmap* pBmp = GetStateLabel();
ab839dff
JS
323 int x = mMarginX - (outerLevel + 2);
324 int y = mMarginY - (outerLevel + 2);
ab839dff
JS
325 int height = pBmp->GetHeight() + (outerLevel + 2)*2 - 1;
326 int width = pBmp->GetWidth() + (outerLevel + 2)*2 - 1;
5515f252
GT
327 dc.SetPen( upperLeftSidePen );
328 dc.DrawLine( x,y, x + width, y );
329 dc.DrawLine( x,y, x, y + height );
59204530
JS
330 dc.DrawLine( x,y+1, x + width , y +1 ); // top
331 dc.DrawLine( x+1,y, x+1, y + height ); // left
8e08b761 332
5515f252
GT
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 );
59204530
JS
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
8e08b761
JS
338}
339
340void wxNewBitmapButton::DestroyLabels()
341{
5515f252
GT
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;
8e08b761
JS
351}
352
353wxBitmap* wxNewBitmapButton::GetStateLabel()
354{
5515f252
GT
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;
8e08b761
JS
377}
378
18c45cd6
WS
379#ifndef __WXMSW__
380
8e08b761 381static const unsigned char _gDisableImage[] = { 0x55,0xAA,0x55,0xAA,
5515f252
GT
382 0x55,0xAA,0x55,0xAA,
383 0x55,0xAA,0x55,0xAA,
384 0x55,0xAA,0x55,0xAA
385 };
18c45cd6
WS
386
387#endif
388
8e08b761 389void wxNewBitmapButton::RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp,
5515f252 390 bool isEnabled, bool isPressed )
8e08b761 391{
5515f252
GT
392 if ( destBmp != 0 ) return;
393
4cbc57f0 394 // render labels on-demand
5515f252
GT
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
e1c6c6ae 412 srcDc.SetFont( wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) );
5515f252
GT
413 srcDc.GetTextExtent( mLabelText, &txtWidth, &txtHeight );
414
415 if ( mTextAlignment == NB_ALIGN_TEXT_RIGHT )
416 {
417 destDim.x = srcBmp->GetWidth() + 2*mTextToLabelGap + txtWidth;
418
ab839dff 419 destDim.y =
5515f252
GT
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 {
ab839dff 430 destDim.x =
5515f252
GT
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 }
ab839dff 440 else
5515f252 441 {
873a543b 442 wxFAIL_MSG(wxT("Unsupported FL alignment type detected in wxNewBitmapButton::RenderLabelImage()"));
5515f252
GT
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
e1c6c6ae 458 wxBrush grayBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE), wxSOLID );
5515f252 459
5515f252 460 destDc.SetBrush( grayBrush );
18c45cd6 461 destDc.SetPen( *wxTRANSPARENT_PEN );
5515f252 462 destDc.DrawRectangle( 0,0, destDim.x+1, destDim.y+1 );
8e08b761 463
5515f252
GT
464 if ( isPressed )
465 {
466 ++imgPos.x; ++imgPos.y;
467 ++txtPos.x; ++txtPos.y;
468 }
8e08b761 469
5515f252
GT
470 if ( hasImage )
471 {
8e08b761 472
ab839dff 473 destDc.Blit( imgPos.x, imgPos.y,
1480c61a
VZ
474 srcBmp->GetWidth(),
475 srcBmp->GetHeight(),
c82c42d4 476 &srcDc, 0,0, wxCOPY,true );
5515f252 477 }
8e08b761 478
5515f252
GT
479 if ( hasText )
480 {
481 wxWindow* pTopWnd = this;
8e08b761 482
5515f252
GT
483 do
484 {
485 wxWindow* pParent = pTopWnd->GetParent();
8e08b761 486
5515f252 487 if ( pParent == 0 )
8e08b761
JS
488 break;
489
5515f252
GT
490 pTopWnd = pParent;
491 } while (1);
8e08b761 492
e1c6c6ae 493 destDc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT) );
8e08b761 494
5515f252 495 if ( isEnabled )
8e08b761 496 {
e1c6c6ae 497 destDc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT) );
5515f252 498 }
8e08b761
JS
499 else
500 {
e1c6c6ae 501 destDc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW) );
5515f252 502 }
e1c6c6ae 503 destDc.SetTextBackground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE) );
8e08b761 504
5515f252
GT
505 destDc.DrawText( mLabelText, txtPos.x, txtPos.y );
506 }
8e08b761 507
5515f252 508 if ( !isEnabled ){
ab839dff 509
8e08b761 510#ifdef __WXMSW__ // This is currently MSW specific
5515f252 511 gray_out_image_on_dc( destDc, destDim.x, destDim.y );
8e08b761 512#else
c54e5eb0
WS
513 wxBitmap bmp( (const char*)_gDisableImage,8,8);
514 wxBrush checkerBrush(bmp);
e1c6c6ae 515 checkerBrush.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
5515f252
GT
516 destDc.SetBrush( checkerBrush );
517 destDc.DrawRectangle( imgPos.x, imgPos.y, srcBmp->GetWidth()+1, srcBmp->GetHeight()+1);
8e08b761 518#endif
5515f252
GT
519 }
520 // adjust button size to fit the new dimensions of the label
521 if ( !mSizeIsSet && 0 )
522 {
c82c42d4 523 mSizeIsSet = true;
422d0ff0 524 SetSize( wxDefaultCoord, wxDefaultCoord,
5515f252 525 destBmp->GetWidth() + mMarginX*2,
ab839dff 526 destBmp->GetHeight() + mMarginY*2, 0
5515f252
GT
527 );
528 }
65e50848 529 destDc.SelectObject( wxNullBitmap );
ab839dff 530
45747ae3 531#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
65e50848 532 // Map to system colours
2b5f62a0 533 (void) wxToolBar::MapBitmap(destBmp->GetHBITMAP(), destBmp->GetWidth(), destBmp->GetHeight());
ab839dff 534#endif
8e08b761 535}
65e50848 536
8e08b761
JS
537void wxNewBitmapButton::RenderAllLabelImages()
538{
5515f252 539 if ( !mIsCreated )
8e08b761 540 return;
c82c42d4
WS
541 RenderLabelImage( mpDisabledImg, &mDepressedBmp, false );
542 RenderLabelImage( mpPressedImg, &mDepressedBmp, true, true );
543 RenderLabelImage( mpDepressedImg, &mDepressedBmp, true, false );
5515f252 544 if ( mHasFocusedBmp )
8e08b761 545 {
c82c42d4 546 RenderLabelImage( mpFocusedImg, &mFocusedBmp, true, false );
5515f252 547 }
8e08b761 548}
ab839dff 549
8e08b761
JS
550
551void wxNewBitmapButton::RenderLabelImages()
552{
5515f252 553 if ( !mIsCreated )
8e08b761
JS
554 return;
555
5515f252
GT
556 if ( !IsEnabled() )
557 {
c82c42d4 558 RenderLabelImage( mpDisabledImg, &mDepressedBmp, false );
5515f252
GT
559 }
560 else
561
ab839dff 562 if ( mIsPressed )
5515f252 563
c82c42d4 564 RenderLabelImage( mpPressedImg, &mDepressedBmp, true, true );
5515f252
GT
565 else
566 {
567 if ( mIsInFocus )
568 {
569 if ( mHasFocusedBmp )
c82c42d4 570 RenderLabelImage( mpFocusedImg, &mFocusedBmp, true, false );
5515f252 571 else
c82c42d4 572 RenderLabelImage( mpDepressedImg, &mDepressedBmp, true, false );
5515f252
GT
573 }
574 else
c82c42d4 575 RenderLabelImage( mpDepressedImg, &mDepressedBmp, true, false );
5515f252 576 }
8e08b761
JS
577}
578
ab839dff
JS
579bool wxNewBitmapButton::Toggle(bool enable)
580{
581 if ( mIsToggled == enable )
582 {
c82c42d4 583 return false;
ab839dff
JS
584 }
585
586 mIsToggled = enable;
587 Refresh();
588
c82c42d4 589 return true;
ab839dff
JS
590}
591
45da7759
JS
592bool wxNewBitmapButton::Enable(bool enable)
593{
594 if ( enable != m_isEnabled )
595 {
596 if ( mIsInFocus )
597 {
c82c42d4 598 mIsInFocus = false;
45da7759
JS
599 }
600
601 if ( mIsPressed )
602 {
c82c42d4 603 mIsPressed = false;
45da7759
JS
604 }
605
606 Refresh();
607 }
608
609 return wxPanel::Enable( enable );
610}
611
8e08b761
JS
612void wxNewBitmapButton::DrawDecorations( wxDC& dc )
613{
5515f252
GT
614 if ( mIsFlat )
615 {
616 DrawShade( 1, dc, mGrayPen, mGrayPen );
ab839dff
JS
617 if ( mIsToggled )
618 {
619 DrawShade( 0, dc, mDarkPen, mLightPen );
620 }
621 else if ( mIsInFocus )
5515f252
GT
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 {
ab839dff 633 if ( mIsPressed || mIsToggled )
5515f252
GT
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 }
8e08b761
JS
644}
645
ab839dff 646void wxNewBitmapButton::SetLabel(const wxBitmap& labelBitmap,
5515f252 647 const wxString& labelText )
8e08b761 648{
5515f252 649 DestroyLabels();
8e08b761 650
5515f252
GT
651 mLabelText = labelText;
652 mDepressedBmp = labelBitmap;
8e08b761 653
5515f252
GT
654 //RenderLabelImages();
655 RenderAllLabelImages();
8e08b761
JS
656}
657
658void wxNewBitmapButton::SetAlignments( int alignText,
5515f252
GT
659 int marginX,
660 int marginY,
661 int textToLabelGap)
8e08b761 662{
5515f252 663 DestroyLabels();
8e08b761 664
5515f252
GT
665 mMarginX = marginX;
666 mMarginY = marginY;
667 mTextAlignment = alignText;
668 mTextToLabelGap = textToLabelGap;
8e08b761 669
5515f252
GT
670 //RenderLabelImages();
671 RenderAllLabelImages();
8e08b761
JS
672}
673
674// event handlers
675
196be0f1 676void wxNewBitmapButton::OnLButtonDown( wxMouseEvent& WXUNUSED(event) )
8e08b761 677{
c82c42d4
WS
678 mDragStarted = true;
679 mIsPressed = true;
5515f252 680 Refresh();
8e08b761
JS
681}
682
683void wxNewBitmapButton::OnLButtonUp( wxMouseEvent& event )
684{
5515f252 685 if ( !mDragStarted )
8e08b761
JS
686 return;
687
c82c42d4
WS
688 mDragStarted = false;
689 mIsPressed = false;
5515f252 690 Refresh();
8e08b761 691
18c45cd6 692 if ( IsInWindow( event.m_x, event.m_y ) )
45da7759
JS
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}
8e08b761 700
8e08b761
JS
701bool wxNewBitmapButton::IsInWindow( int x, int y )
702{
5515f252
GT
703 int width, height;
704 GetSize( &width, &height );
8e08b761 705
5515f252
GT
706 return ( x >= 0 && y >= 0 &&
707 x < width &&
708 y < height );
8e08b761
JS
709}
710
196be0f1 711void wxNewBitmapButton::OnMouseEnter( wxMouseEvent& WXUNUSED(event) )
8e08b761 712{
45da7759 713 bool prevIsInFocus = mIsInFocus;
5515f252 714
45da7759
JS
715 if ( !mIsInFocus )
716 {
c82c42d4 717 mIsInFocus = true;
5515f252 718 }
45da7759 719 if ( prevIsInFocus != mIsInFocus )
5515f252 720 {
45da7759 721 Refresh();
5515f252 722 }
45da7759 723}
5515f252 724
196be0f1 725void wxNewBitmapButton::OnMouseLeave( wxMouseEvent& WXUNUSED(event) )
45da7759
JS
726{
727 bool prevIsInFocus = mIsInFocus;
728 bool prevIsPressed = mIsPressed;
729 if ( mIsInFocus )
5515f252 730 {
c82c42d4
WS
731 mIsInFocus = false;
732 mIsPressed = false;
5515f252 733 }
45da7759 734 if ( prevIsInFocus != mIsInFocus || prevIsPressed != mIsPressed )
8e08b761 735 {
5515f252
GT
736 Refresh();
737 }
8e08b761
JS
738}
739
196be0f1 740void wxNewBitmapButton::OnSize( wxSizeEvent& WXUNUSED(event) )
8e08b761 741{
5515f252 742 //Reshape();
8e08b761
JS
743}
744
745void wxNewBitmapButton::Reshape( )
18c45cd6 746{
5515f252 747 bool wasCreated = mIsCreated;
c82c42d4 748 mIsCreated = true;
8e08b761 749
5515f252
GT
750 if ( !wasCreated )
751 {
752 // in the case of loading button from stream, check if we
18c45cd6 753 // have non-empty image-file name, load if possible
8e08b761 754
18c45cd6 755 if (!mImageFileName.empty())
5515f252
GT
756 {
757 mDepressedBmp.LoadFile( mImageFileName, mImageFileType );
8e08b761 758
5515f252
GT
759 //wxMessageBox("Image Loaded!!!");
760 }
8e08b761 761
5515f252
GT
762 //RenderLabelImages();
763 RenderAllLabelImages();
8e08b761 764
5515f252 765 wxBitmap* pCurImg = GetStateLabel();
8e08b761 766
5515f252
GT
767 int w = pCurImg->GetWidth(),
768 h = pCurImg->GetHeight();
8e08b761 769
5515f252
GT
770 SetSize( 0,0, w + mMarginX*2, h + mMarginY*2 , 0 );
771 }
8e08b761
JS
772}
773
774void wxNewBitmapButton::DrawLabel( wxDC& dc )
775{
5515f252 776 wxBitmap* pCurBmp = GetStateLabel();
8e08b761 777
5515f252
GT
778 if ( pCurBmp == NULL )
779 {
780 wxSizeEvent evt;
781 OnSize( evt ); // fake it up!
8e08b761 782
5515f252
GT
783 //RenderLabelImages();
784 pCurBmp = GetStateLabel();
785 }
8e08b761 786
5515f252
GT
787 wxMemoryDC mdc;
788 mdc.SelectObject( *pCurBmp );
8e08b761 789
18c45cd6 790 dc.Blit( mMarginX, mMarginY,
5515f252
GT
791 pCurBmp->GetWidth(),
792 pCurBmp->GetHeight(),
18c45cd6 793 &mdc, 0,0, wxCOPY
5515f252 794 );
8e08b761 795
5515f252 796 mdc.SelectObject( wxNullBitmap );
8e08b761
JS
797}
798
196be0f1 799void wxNewBitmapButton::OnPaint( wxPaintEvent& WXUNUSED(event) )
8e08b761 800{
5515f252 801 wxPaintDC dc(this);
8e08b761 802
5515f252
GT
803 // first, make sure images for current state are prepared
804 //RenderLabelImages();
8e08b761 805
5515f252 806 DrawLabel( dc );
8e08b761 807
5515f252 808 DrawDecorations( dc );
8e08b761
JS
809}
810
196be0f1 811void wxNewBitmapButton::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
8e08b761 812{
5515f252 813 // do nothing
8e08b761
JS
814}
815
196be0f1 816void wxNewBitmapButton::OnKillFocus( wxFocusEvent& WXUNUSED(event) )
8e08b761 817{
5515f252 818 // useless
8e08b761 819
873a543b 820 wxMessageBox(wxT("kill-focus for button!"));
8e08b761
JS
821}
822
ab839dff
JS
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}