3d_canvas.cpp 17 KB
Newer Older
plyatov's avatar
plyatov committed
1
/////////////////////////////////////////////////////////////////////////////
2

plyatov's avatar
plyatov committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// Name:        3d_canvas.cpp
/////////////////////////////////////////////////////////////////////////////


#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

#include "fctsys.h"
#include "trigo.h"

#include "wx/image.h"

#if !wxUSE_GLCANVAS
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
#endif

#include "wx/dataobj.h"
#include "wx/clipbrd.h"

24
#include "gestfich.h"
plyatov's avatar
plyatov committed
25 26 27 28 29 30 31 32 33 34 35 36

#include "3d_viewer.h"
#include "trackball.h"

/* Tool and button Bitmaps */
#include "bitmaps.h"


/*
 * Pcb3D_GLCanvas implementation
 */

37 38 39 40 41 42 43
BEGIN_EVENT_TABLE( Pcb3D_GLCanvas, wxGLCanvas )
EVT_PAINT( Pcb3D_GLCanvas::OnPaint )
EVT_CHAR( Pcb3D_GLCanvas::OnChar )
EVT_MOUSE_EVENTS( Pcb3D_GLCanvas::OnMouseEvent )
EVT_ERASE_BACKGROUND( Pcb3D_GLCanvas::OnEraseBackground )
EVT_MENU_RANGE( ID_POPUP_3D_VIEW_START, ID_POPUP_3D_VIEW_END,
                Pcb3D_GLCanvas::OnPopUpMenu )
plyatov's avatar
plyatov committed
44 45 46
END_EVENT_TABLE()

/*************************************************************************/
47
Pcb3D_GLCanvas::Pcb3D_GLCanvas( WinEDA3D_DrawFrame* parent ) :
48
#if wxCHECK_VERSION( 2, 9, 0 )
49
    wxGLCanvas( parent, -1, NULL, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE )
50 51 52
#else
    wxGLCanvas( parent, -1, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE )
#endif
plyatov's avatar
plyatov committed
53 54
/*************************************************************************/
{
55 56 57
    m_init   = FALSE;
    m_gllist = 0;
    m_Parent = parent;
58

59
#if wxCHECK_VERSION( 2, 9, 0 )
60 61
    // Explicitly create a new rendering context instance for this canvas.
    m_glRC = new wxGLContext(this);
62
#endif
63

64
    DisplayStatus();
plyatov's avatar
plyatov committed
65 66 67 68
}


/*************************************/
69
Pcb3D_GLCanvas::~Pcb3D_GLCanvas()
plyatov's avatar
plyatov committed
70 71
/*************************************/
{
72
    ClearLists();
73
    m_init = FALSE;
74
#if wxCHECK_VERSION( 2, 9, 0 )
75
    delete m_glRC;
76
#endif
plyatov's avatar
plyatov committed
77 78
}

79

plyatov's avatar
plyatov committed
80
/*************************************/
81
void Pcb3D_GLCanvas::ClearLists()
plyatov's avatar
plyatov committed
82 83
/*************************************/
{
84 85 86
    if( m_gllist > 0 )
        glDeleteLists( m_gllist, 1 );
    m_gllist = 0;
plyatov's avatar
plyatov committed
87 88
}

89

plyatov's avatar
plyatov committed
90
/*********************************************/
91
void Pcb3D_GLCanvas::OnChar( wxKeyEvent& event )
plyatov's avatar
plyatov committed
92 93
/*********************************************/
{
94 95
    SetView3D( event.GetKeyCode() );
    event.Skip();
plyatov's avatar
plyatov committed
96 97
}

98

plyatov's avatar
plyatov committed
99
/*********************************************/
100
void Pcb3D_GLCanvas::SetView3D( int keycode )
plyatov's avatar
plyatov committed
101 102
/*********************************************/
{
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
    int    ii;
    double delta_move = 0.7 * g_Parm_3D_Visu.m_Zoom;

    switch( keycode )
    {
    case WXK_LEFT:
        g_Draw3d_dx -= delta_move;
        break;

    case WXK_RIGHT:
        g_Draw3d_dx += delta_move;
        break;

    case WXK_UP:
        g_Draw3d_dy += delta_move;
        break;

    case WXK_DOWN:
        g_Draw3d_dy -= delta_move;
        break;

    case WXK_HOME:
        g_Parm_3D_Visu.m_Zoom = 1.0;
        g_Draw3d_dx = g_Draw3d_dy = 0;
        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        break;

    case WXK_END:
        break;

    case WXK_F1:
        g_Parm_3D_Visu.m_Zoom /= 1.4;
        if( g_Parm_3D_Visu.m_Zoom <= 0.01 )
            g_Parm_3D_Visu.m_Zoom = 0.01;
        break;

    case WXK_F2:
        g_Parm_3D_Visu.m_Zoom *= 1.4;
        break;

    case '+':
        break;

    case '-':
        break;

    case 'r':
    case 'R':
        g_Draw3d_dx = g_Draw3d_dy = 0;
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        break;

    case 'x':
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        g_Parm_3D_Visu.m_ROTZ = -90;
        g_Parm_3D_Visu.m_ROTX = -90;
        break;

    case 'X':
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        g_Parm_3D_Visu.m_ROTZ = 90;
        g_Parm_3D_Visu.m_ROTX = -90;
        break;

    case 'y':
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        g_Parm_3D_Visu.m_ROTX = -90;
        break;

    case 'Y':
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        g_Parm_3D_Visu.m_ROTX = -90;
        g_Parm_3D_Visu.m_ROTZ = -180;
        break;

    case 'z':
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        break;

    case 'Z':
        for( ii = 0; ii < 4; ii++ )
            g_Parm_3D_Visu.m_Rot[ii] = 0.0;

        trackball( g_Parm_3D_Visu.m_Quat, 0.0, 0.0, 0.0, 0.0 );
        g_Parm_3D_Visu.m_ROTX = -180;
        break;

    default:
        return;
    }

    DisplayStatus();
    Refresh( FALSE );
plyatov's avatar
plyatov committed
214 215
}

216

plyatov's avatar
plyatov committed
217
/********************************************************/
218
void Pcb3D_GLCanvas::OnMouseEvent( wxMouseEvent& event )
plyatov's avatar
plyatov committed
219 220
/********************************************************/
{
221
    wxSize size( GetClientSize() );
222
    double spin_quat[4];
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248


    if( event.RightDown() )
    {
        OnRightClick( event ); return;
    }

    if( event.m_wheelRotation )
    {
        if( event.ShiftDown() )
        {
            if( event.GetWheelRotation() < 0 )
            {
                /* up */
                SetView3D( WXK_UP );
            }
            else
            {
                /* down */
                SetView3D( WXK_DOWN );
            }
        }
        else if( event.ControlDown() )
        {
            if( event.GetWheelRotation() > 0 )
            {
249
                /* right */
250 251 252 253
                SetView3D( WXK_RIGHT );
            }
            else
            {
254
                /* left */
255
                SetView3D( WXK_LEFT );
256 257
            }
        }
258 259 260
        else
        {
            if( event.GetWheelRotation() > 0 )
261 262
            {
                g_Parm_3D_Visu.m_Zoom /= 1.4;
263
                if( g_Parm_3D_Visu.m_Zoom <= 0.01 )
264 265
                    g_Parm_3D_Visu.m_Zoom = 0.01;
            }
266 267
            else
                g_Parm_3D_Visu.m_Zoom *= 1.4;
268
            DisplayStatus();
269
            Refresh( FALSE );
270
        }
271
    }
plyatov's avatar
plyatov committed
272

273
    if( event.Dragging() )
plyatov's avatar
plyatov committed
274
    {
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
        if( event.LeftIsDown() )
        {
            /* drag in progress, simulate trackball */
            trackball( spin_quat,
                       (2.0 * g_Parm_3D_Visu.m_Beginx - size.x) / size.x,
                       (size.y - 2.0 * g_Parm_3D_Visu.m_Beginy) / size.y,
                       (     2.0 * event.GetX() - size.x) / size.x,
                       ( size.y - 2.0 * event.GetY() ) / size.y );

            add_quats( spin_quat, g_Parm_3D_Visu.m_Quat, g_Parm_3D_Visu.m_Quat );
        }
        else if( event.MiddleIsDown() )
        {
            /* middle button drag -> pan */
            /* Current zoom and an additional factor are taken into account for the amount of panning. */
290
            const double PAN_FACTOR = 8.0 * g_Parm_3D_Visu.m_Zoom;
291 292 293
            g_Draw3d_dx -= PAN_FACTOR * ( g_Parm_3D_Visu.m_Beginx - event.GetX() ) / size.x;
            g_Draw3d_dy -= PAN_FACTOR * (event.GetY() - g_Parm_3D_Visu.m_Beginy) / size.y;
        }
plyatov's avatar
plyatov committed
294 295

        /* orientation has changed, redraw mesh */
296 297
        DisplayStatus();
        Refresh( FALSE );
plyatov's avatar
plyatov committed
298 299 300 301 302 303
    }

    g_Parm_3D_Visu.m_Beginx = event.GetX();
    g_Parm_3D_Visu.m_Beginy = event.GetY();
}

304

plyatov's avatar
plyatov committed
305
/*******************************************************/
306
void Pcb3D_GLCanvas::OnRightClick( wxMouseEvent& event )
plyatov's avatar
plyatov committed
307
/*******************************************************/
308

plyatov's avatar
plyatov committed
309
/* Construit et affiche un menu Popup lorsque on actionne le bouton droit
310 311
 *  de la souris
 */
plyatov's avatar
plyatov committed
312
{
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    wxPoint     pos;
    wxMenu      PopUpMenu;

    pos.x = event.GetX(); pos.y = event.GetY();
    wxMenuItem* item = new wxMenuItem( &PopUpMenu, ID_POPUP_ZOOMIN,
                                      _( "Zoom +" ) );
    item->SetBitmap( zoom_in_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_ZOOMOUT,
                          _( "Zoom -" ) );
    item->SetBitmap( zoom_out_xpm );
    PopUpMenu.Append( item );

    PopUpMenu.AppendSeparator();
    item = new wxMenuItem( &PopUpMenu, ID_POPUP_VIEW_ZPOS,
                          _( "Top View" ) );
    item->SetBitmap( axis3d_top_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_VIEW_ZNEG,
                          _( "Bottom View" ) );
    item->SetBitmap( axis3d_bottom_xpm );
    PopUpMenu.Append( item );

    PopUpMenu.AppendSeparator();
    item = new wxMenuItem( &PopUpMenu, ID_POPUP_VIEW_XPOS,
                          _( "Right View" ) );
    item->SetBitmap( axis3d_right_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_VIEW_XNEG,
                          _( "Left View" ) );
    item->SetBitmap( axis3d_left_xpm );
    PopUpMenu.Append( item );


    PopUpMenu.AppendSeparator();
    item = new wxMenuItem( &PopUpMenu, ID_POPUP_VIEW_YPOS,
                          _( "Front View" ) );
    item->SetBitmap( axis3d_front_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_VIEW_YNEG,
                          _( "Back View" ) );
    item->SetBitmap( axis3d_back_xpm );
    PopUpMenu.Append( item );

    PopUpMenu.AppendSeparator();
    item = new wxMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_LEFT,
                          _( "Move left <-" ) );
    item->SetBitmap( left_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_RIGHT,
                          _( "Move right ->" ) );
    item->SetBitmap( right_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_UP,
                          _( "Move Up ^" ) );
    item->SetBitmap( up_xpm );
    PopUpMenu.Append( item );

    item = new wxMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_DOWN,
                          _( "Move Down" ) );
    item->SetBitmap( down_xpm );
    PopUpMenu.Append( item );

    PopupMenu( &PopUpMenu, pos );
plyatov's avatar
plyatov committed
383 384
}

385

plyatov's avatar
plyatov committed
386
/*******************************************************/
387
void Pcb3D_GLCanvas::OnPopUpMenu( wxCommandEvent& event )
plyatov's avatar
plyatov committed
388 389
/*******************************************************/
{
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
    int key = 0;

    switch( event.GetId() )
    {
    case ID_POPUP_ZOOMIN:
        key = WXK_F1;
        break;

    case ID_POPUP_ZOOMOUT:
        key = WXK_F2;
        break;

    case ID_POPUP_VIEW_XPOS:
        key = 'x';
        break;

    case ID_POPUP_VIEW_XNEG:
        key = 'X';
        break;

    case ID_POPUP_VIEW_YPOS:
        key = 'y';
        break;

    case ID_POPUP_VIEW_YNEG:
        key = 'Y';
        break;

    case ID_POPUP_VIEW_ZPOS:
        key = 'z';
        break;

    case ID_POPUP_VIEW_ZNEG:
        key = 'Z';
        break;

    case ID_POPUP_MOVE3D_LEFT:
        key = WXK_LEFT;
        break;

    case ID_POPUP_MOVE3D_RIGHT:
        key = WXK_RIGHT;
        break;

    case ID_POPUP_MOVE3D_UP:
        key = WXK_UP;
        break;

    case ID_POPUP_MOVE3D_DOWN:
        key = WXK_DOWN;
        break;

    default:
        return;
    }

    SetView3D( key );
plyatov's avatar
plyatov committed
447 448 449 450
}


/***************************************/
451
void Pcb3D_GLCanvas::DisplayStatus()
plyatov's avatar
plyatov committed
452 453
/***************************************/
{
454 455 456 457
    wxString msg;

    msg.Printf( wxT( "dx %3.2f" ), g_Draw3d_dx );
    m_Parent->SetStatusText( msg, 1 );
plyatov's avatar
plyatov committed
458

459 460
    msg.Printf( wxT( "dy %3.2f" ), g_Draw3d_dy );
    m_Parent->SetStatusText( msg, 2 );
plyatov's avatar
plyatov committed
461

462 463
    msg.Printf( wxT( "View: %3.1f" ), 45 * g_Parm_3D_Visu.m_Zoom );
    m_Parent->SetStatusText( msg, 3 );
plyatov's avatar
plyatov committed
464 465 466 467 468 469 470
}


/*************************************************/
void Pcb3D_GLCanvas::OnPaint( wxPaintEvent& event )
/*************************************************/
{
471 472 473
    wxPaintDC dc( this );
    Redraw();
    event.Skip();
plyatov's avatar
plyatov committed
474 475 476 477
}


/***********************************************************/
478
void Pcb3D_GLCanvas::OnEraseBackground( wxEraseEvent& event )
plyatov's avatar
plyatov committed
479 480
/***********************************************************/
{
481
    // Do nothing, to avoid flashing.
plyatov's avatar
plyatov committed
482 483 484 485 486 487
}


/****************************/
void Pcb3D_GLCanvas::InitGL()
/****************************/
488

plyatov's avatar
plyatov committed
489
/* Int parametres generaux pour OPENGL
490
 */
plyatov's avatar
plyatov committed
491
{
492
    wxSize size = GetClientSize();
plyatov's avatar
plyatov committed
493

494 495 496 497 498
    if( !m_init )
    {
        m_init = TRUE;
        g_Parm_3D_Visu.m_Zoom = 1.0;
        ZBottom = 1.0; ZTop = 10.0;
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516

        glDisable( GL_CULL_FACE );      // show back faces

        glEnable( GL_DEPTH_TEST );      // Enable z-buferring

        glEnable( GL_LINE_SMOOTH );
        glEnable( GL_COLOR_MATERIAL );
        glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );

        /* speedups */
        glEnable( GL_DITHER );
        glShadeModel( GL_SMOOTH );
        glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
        glHint( GL_POLYGON_SMOOTH_HINT, GL_FASTEST );

        /* blend */
        glEnable( GL_BLEND );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
517
    }
plyatov's avatar
plyatov committed
518 519

    /* set viewing projection */
520 521
    double ratio_HV = (double) size.x / size.y; // Ratio largeur /hauteur de la fenetre d'affichage
    glMatrixMode( GL_PROJECTION );
plyatov's avatar
plyatov committed
522 523
    glLoadIdentity();

524
#define MAX_VIEW_ANGLE 160.0 / 45.0
525 526 527
    if( g_Parm_3D_Visu.m_Zoom > MAX_VIEW_ANGLE )
        g_Parm_3D_Visu.m_Zoom = MAX_VIEW_ANGLE;
    gluPerspective( 45.0 * g_Parm_3D_Visu.m_Zoom, ratio_HV, 1, 10 );
plyatov's avatar
plyatov committed
528 529 530 531

//	glFrustum(-1., 1.1F, -1.1F, 1.1F, ZBottom, ZTop);

    /* position viewer */
532 533 534
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0.0F, 0.0F, -( ZBottom + ZTop) / 2 );
plyatov's avatar
plyatov committed
535 536 537

    /* clear color and depth buffers */
    glClearColor( g_Parm_3D_Visu.m_BgColor.m_Red,
538 539
                  g_Parm_3D_Visu.m_BgColor.m_Green,
                  g_Parm_3D_Visu.m_BgColor.m_Blue, 1 );
plyatov's avatar
plyatov committed
540 541
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

542 543
    /* Setup light souces: */
    SetLights();
plyatov's avatar
plyatov committed
544 545 546 547 548 549


}


/***********************************/
550
void Pcb3D_GLCanvas::SetLights()
plyatov's avatar
plyatov committed
551
/***********************************/
552

plyatov's avatar
plyatov committed
553
/* Init sources lumineuses pour OPENGL
554
 */
plyatov's avatar
plyatov committed
555
{
556 557
    double  light;
    GLfloat light_color[4];
plyatov's avatar
plyatov committed
558 559

    /* set viewing projection */
560 561 562
    light_color[3] = 1.0;
    GLfloat Z_axis_pos[4]    = { 0.0, 0.0, 3.0, 0.0 };
    GLfloat lowZ_axis_pos[4] = { 0.0, 0.0, -3.0, 0.5 };
plyatov's avatar
plyatov committed
563 564

    /* activate light */
565 566 567 568 569 570 571 572 573 574 575
    light = 1.0;
    light_color[0] = light_color[1] = light_color[2] = light;
    glLightfv( GL_LIGHT0, GL_POSITION, Z_axis_pos );
    glLightfv( GL_LIGHT0, GL_DIFFUSE, light_color );
    light = 0.3;
    light_color[0] = light_color[1] = light_color[2] = light;
    glLightfv( GL_LIGHT1, GL_POSITION, lowZ_axis_pos );
    glLightfv( GL_LIGHT1, GL_DIFFUSE, light_color );
    glEnable( GL_LIGHT0 );      // White spot on Z axis
    glEnable( GL_LIGHT1 );      // White spot on Z axis ( bottom)
    glEnable( GL_LIGHTING );
plyatov's avatar
plyatov committed
576 577 578 579
}


/**********************************************************/
580
void Pcb3D_GLCanvas::TakeScreenshot( wxCommandEvent& event )
plyatov's avatar
plyatov committed
581
/**********************************************************/
582

plyatov's avatar
plyatov committed
583
/* Create a Screenshot of the current 3D view.
584 585
 *  Output file format is png or jpeg, or image is copied on clipboard
 */
plyatov's avatar
plyatov committed
586
{
587
    wxFileName fn( m_Parent->m_Parent->GetScreen()->m_FileName );
588 589 590
    wxString   FullFileName;
    wxString   file_ext, mask;
    bool       fmt_is_jpeg = FALSE;
591 592 593 594 595

    if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
        fmt_is_jpeg = TRUE;
    if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
    {
596 597
        file_ext = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png"; )
                   mask = wxT( "*." ) + file_ext;
598
        FullFileName    = m_Parent->m_Parent->GetScreen()->m_FileName;
599
        fn.SetExt( file_ext );
600 601 602 603

        FullFileName =
            EDA_FileSelector( _( "3D Image filename:" ),
                              wxEmptyString,    /* Chemin par defaut */
604
                              fn.GetFullName(), /* nom fichier par defaut */
605 606 607 608 609 610 611 612 613 614 615
                              file_ext,         /* extension par defaut */
                              mask,             /* Masque d'affichage */
                              this,
                              wxFD_SAVE,
                              TRUE
                              );
        if( FullFileName.IsEmpty() )
            return;
    }

    Redraw( true );
616

617 618 619 620 621 622 623
    wxSize     image_size = GetClientSize();
    wxClientDC dc( this );
    wxBitmap   bitmap( image_size.x, image_size.y );
    wxMemoryDC memdc;
    memdc.SelectObject( bitmap );
    memdc.Blit( 0, 0, image_size.x, image_size.y, &dc, 0, 0 );
    memdc.SelectObject( wxNullBitmap );
plyatov's avatar
plyatov committed
624

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
    if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
    {
        wxBitmapDataObject* dobjBmp = new wxBitmapDataObject;
        dobjBmp->SetBitmap( bitmap );
        if( wxTheClipboard->Open() )
        {
            if( !wxTheClipboard->SetData( dobjBmp ) )
                wxLogError( _T( "Failed to copy image to clipboard" ) );
            wxTheClipboard->Flush();    /* the data on clipboard
                                         *  will stay available after the application exits */
            wxTheClipboard->Close();
        }
    }
    else
    {
640 641
        wxImage image = bitmap.ConvertToImage();

642 643 644
        if( !image.SaveFile( FullFileName,
                             fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
            wxLogError( wxT( "Can't save file" ) );
plyatov's avatar
plyatov committed
645

646 647 648
        image.Destroy();
    }
}