~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to contrib/src/plot/plot.cpp

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        plot.cpp
 
3
// Purpose:     wxPlotWindow
 
4
// Author:      Robert Roebling
 
5
// Modified by:
 
6
// Created:     12/01/2000
 
7
// RCS-ID:      $Id: plot.cpp,v 1.12 2005/08/10 22:53:35 MW Exp $
 
8
// Copyright:   (c) Robert Roebling
 
9
// Licence:     wxWindows license
 
10
/////////////////////////////////////////////////////////////////////////////
 
11
 
 
12
#ifdef __GNUG__
 
13
#pragma implementation "plot.h"
 
14
#endif
 
15
 
 
16
// For compilers that support precompilation, includes "wx.h".
 
17
#include "wx/wxprec.h"
 
18
 
 
19
#ifdef __BORLANDC__
 
20
#pragma hdrstop
 
21
#endif
 
22
 
 
23
#ifndef WX_PRECOMP
 
24
#include "wx/object.h"
 
25
#include "wx/font.h"
 
26
#include "wx/colour.h"
 
27
#include "wx/settings.h"
 
28
#include "wx/sizer.h"
 
29
#include "wx/log.h"
 
30
#include "wx/intl.h"
 
31
#include "wx/dcclient.h"
 
32
#include "wx/stattext.h"
 
33
#endif
 
34
 
 
35
#include "wx/plot/plot.h"
 
36
#include "wx/bmpbuttn.h"
 
37
#include "wx/module.h"
 
38
 
 
39
#include <math.h>
 
40
 
 
41
// ----------------------------------------------------------------------------
 
42
// XPMs
 
43
// ----------------------------------------------------------------------------
 
44
 
 
45
#if !defined(__WXMSW__) && !defined(__WXPM__)
 
46
    #include "wx/plot/plot_enl.xpm"
 
47
    #include "wx/plot/plot_shr.xpm"
 
48
    #include "wx/plot/plot_zin.xpm"
 
49
    #include "wx/plot/plot_zot.xpm"
 
50
    #include "wx/plot/plot_up.xpm"
 
51
    #include "wx/plot/plot_dwn.xpm"
 
52
#endif
 
53
 
 
54
//----------------------------------------------------------------------------
 
55
// event types
 
56
//----------------------------------------------------------------------------
 
57
 
 
58
DEFINE_EVENT_TYPE(wxEVT_PLOT_SEL_CHANGING);
 
59
DEFINE_EVENT_TYPE(wxEVT_PLOT_SEL_CHANGED);
 
60
DEFINE_EVENT_TYPE(wxEVT_PLOT_CLICKED);
 
61
DEFINE_EVENT_TYPE(wxEVT_PLOT_DOUBLECLICKED);
 
62
DEFINE_EVENT_TYPE(wxEVT_PLOT_ZOOM_IN);
 
63
DEFINE_EVENT_TYPE(wxEVT_PLOT_ZOOM_OUT);
 
64
DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CREATING);
 
65
DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CREATED);
 
66
DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CHANGING);
 
67
DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CHANGED);
 
68
DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CREATING);
 
69
DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CREATED);
 
70
DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CHANGING);
 
71
DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CHANGED);
 
72
DEFINE_EVENT_TYPE(wxEVT_PLOT_BEGIN_X_LABEL_EDIT);
 
73
DEFINE_EVENT_TYPE(wxEVT_PLOT_END_X_LABEL_EDIT);
 
74
DEFINE_EVENT_TYPE(wxEVT_PLOT_BEGIN_Y_LABEL_EDIT);
 
75
DEFINE_EVENT_TYPE(wxEVT_PLOT_END_Y_LABEL_EDIT);
 
76
DEFINE_EVENT_TYPE(wxEVT_PLOT_BEGIN_TITLE_EDIT);
 
77
DEFINE_EVENT_TYPE(wxEVT_PLOT_END_TITLE_EDIT);
 
78
DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_CREATE);
 
79
 
 
80
//----------------------------------------------------------------------------
 
81
// accessor functions for the bitmaps (may return NULL, check for it!)
 
82
//----------------------------------------------------------------------------
 
83
 
 
84
static wxBitmap *GetEnlargeBitmap();
 
85
static wxBitmap *GetShrinkBitmap();
 
86
static wxBitmap *GetZoomInBitmap();
 
87
static wxBitmap *GetZoomOutBitmap();
 
88
static wxBitmap *GetUpBitmap();
 
89
static wxBitmap *GetDownBitmap();
 
90
 
 
91
//-----------------------------------------------------------------------------
 
92
// consts
 
93
//-----------------------------------------------------------------------------
 
94
 
 
95
#define wxPLOT_SCROLL_STEP  30
 
96
 
 
97
//-----------------------------------------------------------------------------
 
98
// wxPlotEvent
 
99
//-----------------------------------------------------------------------------
 
100
 
 
101
wxPlotEvent::wxPlotEvent( wxEventType commandType, int id )
 
102
    : wxNotifyEvent( commandType, id )
 
103
{
 
104
    m_curve = (wxPlotCurve*) NULL;
 
105
    m_zoom = 1.0;
 
106
    m_position = 0;
 
107
}
 
108
 
 
109
//-----------------------------------------------------------------------------
 
110
// wxPlotCurve
 
111
//-----------------------------------------------------------------------------
 
112
 
 
113
IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve, wxObject)
 
114
 
 
115
wxPlotCurve::wxPlotCurve( int offsetY, double startY, double endY )
 
116
: m_penNormal(*wxGREY_PEN), m_penSelected(*wxBLACK_PEN)
 
117
{
 
118
    m_offsetY = offsetY;
 
119
    m_startY = startY;
 
120
    m_endY = endY;
 
121
}
 
122
 
 
123
//-----------------------------------------------------------------------------
 
124
// wxPlotOnOffCurve
 
125
//-----------------------------------------------------------------------------
 
126
 
 
127
IMPLEMENT_CLASS(wxPlotOnOffCurve, wxObject)
 
128
 
 
129
#include "wx/arrimpl.cpp"
 
130
WX_DEFINE_OBJARRAY(wxArrayPlotOnOff);
 
131
 
 
132
wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY )
 
133
{
 
134
    m_offsetY = offsetY;
 
135
    m_minX = -1;
 
136
    m_maxX = -1;
 
137
}
 
138
 
 
139
void wxPlotOnOffCurve::Add( wxInt32 on, wxInt32 off, void *clientData )
 
140
{
 
141
    wxASSERT_MSG( on > 0, _T("plot index < 0") );
 
142
    wxASSERT( on <= off );
 
143
 
 
144
    if (m_minX == -1)
 
145
        m_minX = on;
 
146
    if (off > m_maxX)
 
147
        m_maxX = off;
 
148
 
 
149
    wxPlotOnOff *v = new wxPlotOnOff;
 
150
    v->m_on = on;
 
151
    v->m_off = off;
 
152
    v->m_clientData = clientData;
 
153
    m_marks.Add( v );
 
154
}
 
155
 
 
156
size_t wxPlotOnOffCurve::GetCount()
 
157
{
 
158
    return m_marks.GetCount();
 
159
}
 
160
 
 
161
wxInt32 wxPlotOnOffCurve::GetOn( size_t index )
 
162
{
 
163
    wxPlotOnOff *v = &m_marks.Item( index );
 
164
    return v->m_on;
 
165
}
 
166
 
 
167
wxInt32 wxPlotOnOffCurve::GetOff( size_t index )
 
168
{
 
169
    wxPlotOnOff *v = &m_marks.Item( index );
 
170
    return v->m_off;
 
171
}
 
172
 
 
173
void* wxPlotOnOffCurve::GetClientData( size_t index )
 
174
{
 
175
    wxPlotOnOff *v = &m_marks.Item( index );
 
176
    return v->m_clientData;
 
177
}
 
178
 
 
179
wxPlotOnOff *wxPlotOnOffCurve::GetAt( size_t index )
 
180
{
 
181
    return &m_marks.Item( index );
 
182
}
 
183
 
 
184
void wxPlotOnOffCurve::DrawOnLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end, void *WXUNUSED(clientData) )
 
185
{
 
186
    dc.DrawLine( start, y, start, y-30 );
 
187
    dc.DrawLine( start, y-30, end, y-30 );
 
188
    dc.DrawLine( end, y-30, end, y );
 
189
}
 
190
 
 
191
void wxPlotOnOffCurve::DrawOffLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end )
 
192
{
 
193
    dc.DrawLine( start, y, end, y );
 
194
}
 
195
 
 
196
//-----------------------------------------------------------------------------
 
197
// wxPlotArea
 
198
//-----------------------------------------------------------------------------
 
199
 
 
200
IMPLEMENT_DYNAMIC_CLASS(wxPlotArea, wxWindow)
 
201
 
 
202
BEGIN_EVENT_TABLE(wxPlotArea, wxWindow)
 
203
    EVT_PAINT(        wxPlotArea::OnPaint)
 
204
    EVT_LEFT_DOWN(    wxPlotArea::OnMouse)
 
205
    EVT_LEFT_DCLICK(  wxPlotArea::OnMouse)
 
206
END_EVENT_TABLE()
 
207
 
 
208
wxPlotArea::wxPlotArea( wxPlotWindow *parent )
 
209
        : wxWindow( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER, _T("plotarea") )
 
210
{
 
211
    m_owner = parent;
 
212
 
 
213
    m_zooming = false;
 
214
 
 
215
    SetBackgroundColour( *wxWHITE );
 
216
}
 
217
 
 
218
void wxPlotArea::OnMouse( wxMouseEvent &event )
 
219
{
 
220
    int client_width;
 
221
    int client_height;
 
222
    GetClientSize( &client_width, &client_height);
 
223
    int view_x;
 
224
    int view_y;
 
225
    m_owner->GetViewStart( &view_x, &view_y );
 
226
    view_x *= wxPLOT_SCROLL_STEP;
 
227
    view_y *= wxPLOT_SCROLL_STEP;
 
228
 
 
229
    wxCoord x = event.GetX();
 
230
    wxCoord y = event.GetY();
 
231
    x += view_x;
 
232
    y += view_y;
 
233
 
 
234
    wxList::compatibility_iterator node = m_owner->m_curves.GetFirst();
 
235
    while (node)
 
236
    {
 
237
        wxPlotCurve *curve = (wxPlotCurve*)node->GetData();
 
238
 
 
239
        double double_client_height = (double)client_height;
 
240
        double range = curve->GetEndY() - curve->GetStartY();
 
241
        double end = curve->GetEndY();
 
242
        wxCoord offset_y = curve->GetOffsetY();
 
243
 
 
244
        double dy = (end - curve->GetY( (wxInt32)(x/m_owner->GetZoom()) )) / range;
 
245
        wxCoord curve_y = (wxCoord)(dy * double_client_height) - offset_y - 1;
 
246
 
 
247
        if ((y-curve_y < 4) && (y-curve_y > -4))
 
248
        {
 
249
            wxPlotEvent event1( event.ButtonDClick() ? wxEVT_PLOT_DOUBLECLICKED : wxEVT_PLOT_CLICKED, m_owner->GetId() );
 
250
            event1.SetEventObject( m_owner );
 
251
            event1.SetZoom( m_owner->GetZoom() );
 
252
            event1.SetCurve( curve );
 
253
            event1.SetPosition( (int)floor(x/m_owner->GetZoom()) );
 
254
            m_owner->GetEventHandler()->ProcessEvent( event1 );
 
255
 
 
256
            if (curve != m_owner->GetCurrentCurve())
 
257
            {
 
258
                wxPlotEvent event2( wxEVT_PLOT_SEL_CHANGING, m_owner->GetId() );
 
259
                event2.SetEventObject( m_owner );
 
260
                event2.SetZoom( m_owner->GetZoom() );
 
261
                event2.SetCurve( curve );
 
262
                if (!m_owner->GetEventHandler()->ProcessEvent( event2 ) || event2.IsAllowed())
 
263
                {
 
264
                    m_owner->SetCurrentCurve( curve );
 
265
                }
 
266
            }
 
267
            return;
 
268
        }
 
269
 
 
270
        node = node->GetNext();
 
271
    }
 
272
}
 
273
 
 
274
void wxPlotArea::DeleteCurve( wxPlotCurve *curve, int from, int to )
 
275
{
 
276
    wxClientDC dc(this);
 
277
    m_owner->PrepareDC( dc );
 
278
    dc.SetPen( *wxWHITE_PEN );
 
279
    DrawCurve( &dc, curve, from, to );
 
280
}
 
281
 
 
282
void wxPlotArea::DrawCurve( wxDC *dc, wxPlotCurve *curve, int from, int to )
 
283
{
 
284
    int view_x;
 
285
    int view_y;
 
286
    m_owner->GetViewStart( &view_x, &view_y );
 
287
    view_x *= wxPLOT_SCROLL_STEP;
 
288
 
 
289
    if (from == -1)
 
290
        from = view_x;
 
291
 
 
292
    int client_width;
 
293
    int client_height;
 
294
    GetClientSize( &client_width, &client_height);
 
295
 
 
296
    if (to == -1)
 
297
        to = view_x + client_width;
 
298
 
 
299
    double zoom = m_owner->GetZoom();
 
300
 
 
301
    int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) );
 
302
    int end_x = wxMin( to, (int)floor(curve->GetEndX()*zoom) );
 
303
 
 
304
    start_x = wxMax( view_x, start_x );
 
305
    end_x = wxMin( view_x + client_width, end_x );
 
306
 
 
307
    end_x++;
 
308
 
 
309
    double double_client_height = (double)client_height;
 
310
    double range = curve->GetEndY() - curve->GetStartY();
 
311
    double end = curve->GetEndY();
 
312
    wxCoord offset_y = curve->GetOffsetY();
 
313
 
 
314
    wxCoord last_y=0;
 
315
    for (int x = start_x; x < end_x; x++)
 
316
    {
 
317
        double dy = (end - curve->GetY( (wxInt32)(x/zoom) )) / range;
 
318
        wxCoord y = (wxCoord)(dy * double_client_height) - offset_y - 1;
 
319
 
 
320
        if (x != start_x)
 
321
           dc->DrawLine( x-1, last_y, x, y );
 
322
 
 
323
        last_y = y;
 
324
    }
 
325
}
 
326
 
 
327
void wxPlotArea::DrawOnOffCurve( wxDC *dc, wxPlotOnOffCurve *curve, int from, int to )
 
328
{
 
329
    int view_x;
 
330
    int view_y;
 
331
    m_owner->GetViewStart( &view_x, &view_y );
 
332
    view_x *= wxPLOT_SCROLL_STEP;
 
333
 
 
334
    if (from == -1)
 
335
        from = view_x;
 
336
 
 
337
    int client_width;
 
338
    int client_height;
 
339
    GetClientSize( &client_width, &client_height);
 
340
 
 
341
    if (to == -1)
 
342
        to = view_x + client_width;
 
343
 
 
344
    double zoom = m_owner->GetZoom();
 
345
 
 
346
    int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) );
 
347
    int end_x = wxMin( to, (int)floor(curve->GetEndX()*zoom) );
 
348
 
 
349
    start_x = wxMax( view_x, start_x );
 
350
    end_x = wxMin( view_x + client_width, end_x );
 
351
 
 
352
    end_x++;
 
353
 
 
354
    wxCoord offset_y = curve->GetOffsetY();
 
355
    wxCoord last_off = -5;
 
356
 
 
357
    if (curve->GetCount() == 0)
 
358
        return;
 
359
 
 
360
    for (size_t index = 0; index < curve->GetCount(); index++)
 
361
    {
 
362
        wxPlotOnOff *p = curve->GetAt( index );
 
363
 
 
364
        wxCoord on = (wxCoord)(p->m_on*zoom);
 
365
        wxCoord off = (wxCoord)(p->m_off*zoom);
 
366
 
 
367
        if (end_x < on)
 
368
        {
 
369
            curve->DrawOffLine( *dc, client_height-offset_y, last_off, on );
 
370
            break;
 
371
        }
 
372
 
 
373
        if (off >= start_x)
 
374
        {
 
375
            curve->DrawOffLine( *dc, client_height-offset_y, last_off, on );
 
376
            curve->DrawOnLine( *dc, client_height-offset_y, on, off, p->m_clientData );
 
377
        }
 
378
        last_off = off;
 
379
    }
 
380
 
 
381
    wxPlotOnOff *p = curve->GetAt( curve->GetCount()-1 );
 
382
    wxCoord off = (wxCoord)(p->m_off*zoom);
 
383
    if (off < end_x)
 
384
        curve->DrawOffLine( *dc, client_height-offset_y, off, to );
 
385
}
 
386
 
 
387
void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
388
{
 
389
    int view_x;
 
390
    int view_y;
 
391
    m_owner->GetViewStart( &view_x, &view_y );
 
392
    view_x *= wxPLOT_SCROLL_STEP;
 
393
    view_y *= wxPLOT_SCROLL_STEP;
 
394
 
 
395
    wxPaintDC dc( this );
 
396
    m_owner->PrepareDC( dc );
 
397
 
 
398
    wxRegionIterator upd( GetUpdateRegion() );
 
399
 
 
400
    while (upd)
 
401
    {
 
402
        int update_x = upd.GetX() + view_x;
 
403
        int update_width = upd.GetWidth();
 
404
 
 
405
/*
 
406
        if (m_owner->m_current)
 
407
        {
 
408
            dc.SetPen( *wxLIGHT_GREY_PEN );
 
409
            int base_line = client_height - m_owner->m_current->GetOffsetY();
 
410
            dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 );
 
411
        }
 
412
*/
 
413
 
 
414
        wxList::compatibility_iterator node = m_owner->m_curves.GetFirst();
 
415
        while (node)
 
416
        {
 
417
            wxPlotCurve *curve = (wxPlotCurve*) node->GetData();
 
418
 
 
419
            if (curve == m_owner->GetCurrentCurve())
 
420
                dc.SetPen( curve->GetPenSelected() );
 
421
            else
 
422
                dc.SetPen( curve->GetPenNormal() );
 
423
 
 
424
            DrawCurve( &dc, curve, update_x-1, update_x+update_width+2 );
 
425
 
 
426
            node = node->GetNext();
 
427
        }
 
428
 
 
429
        dc.SetPen( *wxRED_PEN );
 
430
 
 
431
        node = m_owner->m_onOffCurves.GetFirst();
 
432
        while (node)
 
433
        {
 
434
            wxPlotOnOffCurve *curve = (wxPlotOnOffCurve*) node->GetData();
 
435
 
 
436
            DrawOnOffCurve( &dc, curve, update_x-1, update_x+update_width+2 );
 
437
 
 
438
            node = node->GetNext();
 
439
        }
 
440
 
 
441
        upd ++;
 
442
    }
 
443
}
 
444
 
 
445
void wxPlotArea::ScrollWindow( int dx, int dy, const wxRect *rect )
 
446
{
 
447
    wxWindow::ScrollWindow( dx, dy, rect );
 
448
//    m_owner->m_xaxis->ScrollWindow( dx, 0 );
 
449
}
 
450
 
 
451
//-----------------------------------------------------------------------------
 
452
// wxPlotXAxisArea
 
453
//-----------------------------------------------------------------------------
 
454
 
 
455
IMPLEMENT_DYNAMIC_CLASS(wxPlotXAxisArea, wxWindow)
 
456
 
 
457
BEGIN_EVENT_TABLE(wxPlotXAxisArea, wxWindow)
 
458
  EVT_PAINT(        wxPlotXAxisArea::OnPaint)
 
459
  EVT_LEFT_DOWN(    wxPlotXAxisArea::OnMouse)
 
460
END_EVENT_TABLE()
 
461
 
 
462
wxPlotXAxisArea::wxPlotXAxisArea( wxPlotWindow *parent )
 
463
        : wxWindow( parent, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,40), 0, _T("plotxaxisarea") )
 
464
{
 
465
    m_owner = parent;
 
466
 
 
467
    SetBackgroundColour( *wxWHITE );
 
468
    SetFont( *wxSMALL_FONT );
 
469
}
 
470
 
 
471
void wxPlotXAxisArea::OnMouse( wxMouseEvent &event )
 
472
{
 
473
    int client_width;
 
474
    int client_height;
 
475
    GetClientSize( &client_width, &client_height);
 
476
    int view_x;
 
477
    int view_y;
 
478
    m_owner->GetViewStart( &view_x, &view_y );
 
479
    view_x *= wxPLOT_SCROLL_STEP;
 
480
    view_y *= wxPLOT_SCROLL_STEP;
 
481
 
 
482
    wxCoord x = event.GetX() + view_x;
 
483
    wxCoord y = event.GetY() + view_y;
 
484
 
 
485
    /* TO DO: do something here */
 
486
    wxUnusedVar(x);
 
487
    wxUnusedVar(y);
 
488
}
 
489
 
 
490
void wxPlotXAxisArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
491
{
 
492
    int view_x;
 
493
    int view_y;
 
494
    m_owner->GetViewStart( &view_x, &view_y );
 
495
    view_x *= wxPLOT_SCROLL_STEP;
 
496
    view_y *= wxPLOT_SCROLL_STEP;
 
497
 
 
498
    wxPaintDC dc( this );
 
499
 
 
500
    int client_width;
 
501
    int client_height;
 
502
    GetClientSize( &client_width, &client_height);
 
503
 
 
504
    double zoom = m_owner->GetZoom();
 
505
 
 
506
    double ups = m_owner->GetUnitsPerValue() / zoom;
 
507
 
 
508
    double start = view_x * ups;
 
509
    double end = (view_x + client_width) * ups;
 
510
    double range = end - start;
 
511
 
 
512
    int int_log_range = (int)floor( log10( range ) );
 
513
    double step = 1.0;
 
514
    if (int_log_range > 0)
 
515
    {
 
516
        for (int i = 0; i < int_log_range; i++)
 
517
           step *= 10;
 
518
    }
 
519
    if (int_log_range < 0)
 
520
    {
 
521
        for (int i = 0; i < -int_log_range; i++)
 
522
           step /= 10;
 
523
    }
 
524
    double lower = ceil(start / step) * step;
 
525
    double upper = floor(end / step) * step;
 
526
 
 
527
    // if too few values, shrink size
 
528
    if ((range/step) < 4)
 
529
    {
 
530
        step /= 2;
 
531
        if (lower-step > start) lower -= step;
 
532
        if (upper+step < end) upper += step;
 
533
    }
 
534
 
 
535
    // if still too few, again
 
536
    if ((range/step) < 4)
 
537
    {
 
538
        step /= 2;
 
539
        if (lower-step > start) lower -= step;
 
540
        if (upper+step < end) upper += step;
 
541
    }
 
542
 
 
543
    dc.SetBrush( *wxWHITE_BRUSH );
 
544
    dc.SetPen( *wxTRANSPARENT_PEN );
 
545
    dc.DrawRectangle( 4, 5, client_width-14, 10 );
 
546
    dc.DrawRectangle( 0, 20, client_width, 20 );
 
547
    dc.SetPen( *wxBLACK_PEN );
 
548
 
 
549
    double current = lower;
 
550
    while (current < upper+(step/2))
 
551
    {
 
552
        int x = (int)ceil((current-start) / range * (double)client_width) - 1;
 
553
        if ((x > 4) && (x < client_width-25))
 
554
        {
 
555
            dc.DrawLine( x, 5, x, 15 );
 
556
            wxString label;
 
557
            if (range < 50)
 
558
            {
 
559
                label.Printf( _T("%f"), current );
 
560
                while (label.Last() == _T('0'))
 
561
                    label.RemoveLast();
 
562
                if ((label.Last() == _T('.')) || (label.Last() == _T(',')))
 
563
                    label.Append( _T('0') );
 
564
            }
 
565
            else
 
566
                label.Printf( _T("%d"), (int)floor(current) );
 
567
            dc.DrawText( label, x-4, 20 );
 
568
        }
 
569
 
 
570
        current += step;
 
571
    }
 
572
 
 
573
    dc.DrawLine( 0, 15, client_width-8, 15 );
 
574
    dc.DrawLine( client_width-4, 15, client_width-10, 10 );
 
575
    dc.DrawLine( client_width-4, 15, client_width-10, 20 );
 
576
}
 
577
 
 
578
//-----------------------------------------------------------------------------
 
579
// wxPlotYAxisArea
 
580
//-----------------------------------------------------------------------------
 
581
 
 
582
IMPLEMENT_DYNAMIC_CLASS(wxPlotYAxisArea, wxWindow)
 
583
 
 
584
BEGIN_EVENT_TABLE(wxPlotYAxisArea, wxWindow)
 
585
  EVT_PAINT(        wxPlotYAxisArea::OnPaint)
 
586
  EVT_LEFT_DOWN(    wxPlotYAxisArea::OnMouse)
 
587
END_EVENT_TABLE()
 
588
 
 
589
wxPlotYAxisArea::wxPlotYAxisArea( wxPlotWindow *parent )
 
590
        : wxWindow( parent, wxID_ANY, wxDefaultPosition, wxSize(60,wxDefaultCoord), 0, _T("plotyaxisarea") )
 
591
{
 
592
    m_owner = parent;
 
593
 
 
594
    SetBackgroundColour( *wxWHITE );
 
595
    SetFont( *wxSMALL_FONT );
 
596
}
 
597
 
 
598
void wxPlotYAxisArea::OnMouse( wxMouseEvent &WXUNUSED(event) )
 
599
{
 
600
    /* do something here */
 
601
}
 
602
 
 
603
void wxPlotYAxisArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
604
{
 
605
    wxPaintDC dc( this );
 
606
 
 
607
    wxPlotCurve *curve = m_owner->GetCurrentCurve();
 
608
 
 
609
    if (!curve) return;
 
610
 
 
611
    int client_width;
 
612
    int client_height;
 
613
    GetClientSize( &client_width, &client_height);
 
614
 
 
615
 
 
616
    double range = curve->GetEndY() - curve->GetStartY();
 
617
    double offset = ((double) curve->GetOffsetY() / (double)client_height ) * range;
 
618
    double start = curve->GetStartY() - offset;
 
619
    double end = curve->GetEndY() - offset;
 
620
 
 
621
    int int_log_range = (int)floor( log10( range ) );
 
622
    double step = 1.0;
 
623
    if (int_log_range > 0)
 
624
    {
 
625
        for (int i = 0; i < int_log_range; i++)
 
626
           step *= 10;
 
627
    }
 
628
    if (int_log_range < 0)
 
629
    {
 
630
        for (int i = 0; i < -int_log_range; i++)
 
631
           step /= 10;
 
632
    }
 
633
    double lower = ceil(start / step) * step;
 
634
    double upper = floor(end / step) * step;
 
635
 
 
636
    // if too few values, shrink size
 
637
    if ((range/step) < 4)
 
638
    {
 
639
        step /= 2;
 
640
        if (lower-step > start) lower -= step;
 
641
        if (upper+step < end) upper += step;
 
642
    }
 
643
 
 
644
    // if still too few, again
 
645
    if ((range/step) < 4)
 
646
    {
 
647
        step /= 2;
 
648
        if (lower-step > start) lower -= step;
 
649
        if (upper+step < end) upper += step;
 
650
    }
 
651
 
 
652
    dc.SetPen( *wxBLACK_PEN );
 
653
 
 
654
    double current = lower;
 
655
    while (current < upper+(step/2))
 
656
    {
 
657
        int y = (int)((curve->GetEndY()-current) / range * (double)client_height) - 1;
 
658
        y -= curve->GetOffsetY();
 
659
        if ((y > 10) && (y < client_height-7))
 
660
        {
 
661
            dc.DrawLine( client_width-15, y, client_width-7, y );
 
662
            wxString label;
 
663
            if (range < 50)
 
664
            {
 
665
                label.Printf( _T("%f"), current );
 
666
                while (label.Last() == _T('0'))
 
667
                    label.RemoveLast();
 
668
                if ((label.Last() == _T('.')) || (label.Last() == _T(',')))
 
669
                    label.Append( _T('0') );
 
670
            }
 
671
            else
 
672
                label.Printf( _T("%d"), (int)floor(current) );
 
673
            dc.DrawText( label, 5, y-7 );
 
674
        }
 
675
 
 
676
        current += step;
 
677
    }
 
678
 
 
679
    dc.DrawLine( client_width-15, 6, client_width-15, client_height );
 
680
    dc.DrawLine( client_width-15, 2, client_width-20, 8 );
 
681
    dc.DrawLine( client_width-15, 2, client_width-10, 8 );
 
682
}
 
683
 
 
684
//-----------------------------------------------------------------------------
 
685
// wxPlotWindow
 
686
//-----------------------------------------------------------------------------
 
687
 
 
688
#define  ID_ENLARGE       1000
 
689
#define  ID_SHRINK        1002
 
690
 
 
691
#define  ID_MOVE_UP       1006
 
692
#define  ID_MOVE_DOWN     1007
 
693
 
 
694
#define  ID_ZOOM_IN       1010
 
695
#define  ID_ZOOM_OUT      1011
 
696
 
 
697
 
 
698
IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow, wxScrolledWindow)
 
699
 
 
700
BEGIN_EVENT_TABLE(wxPlotWindow, wxScrolledWindow)
 
701
    EVT_BUTTON(  ID_MOVE_UP,     wxPlotWindow::OnMoveUp)
 
702
    EVT_BUTTON(  ID_MOVE_DOWN,   wxPlotWindow::OnMoveDown)
 
703
 
 
704
    EVT_BUTTON(  ID_ENLARGE,  wxPlotWindow::OnEnlarge)
 
705
    EVT_BUTTON(  ID_SHRINK,   wxPlotWindow::OnShrink)
 
706
 
 
707
    EVT_BUTTON(  ID_ZOOM_IN,     wxPlotWindow::OnZoomIn)
 
708
    EVT_BUTTON(  ID_ZOOM_OUT,    wxPlotWindow::OnZoomOut)
 
709
 
 
710
    EVT_SCROLLWIN( wxPlotWindow::OnScroll2)
 
711
END_EVENT_TABLE()
 
712
 
 
713
wxPlotWindow::wxPlotWindow( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, int flag )
 
714
        : wxScrolledWindow( parent, id, pos, size, flag, _T("plotcanvas") ),
 
715
          m_titleStaticText( NULL )
 
716
{
 
717
    m_xUnitsPerValue = 1.0;
 
718
    m_xZoom = 1.0;
 
719
 
 
720
    m_enlargeAroundWindowCentre = false;
 
721
    m_scrollOnThumbRelease = false;
 
722
 
 
723
    m_area = new wxPlotArea( this );
 
724
    wxBoxSizer *mainsizer = new wxBoxSizer( wxHORIZONTAL );
 
725
 
 
726
    if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ALL) != 0)
 
727
    {
 
728
        wxBoxSizer *buttonlist = new wxBoxSizer( wxVERTICAL );
 
729
        if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ENLARGE) != 0)
 
730
        {
 
731
            buttonlist->Add( new wxBitmapButton( this, ID_ENLARGE, *GetEnlargeBitmap() ), 0, wxEXPAND|wxALL, 2 );
 
732
            buttonlist->Add( new wxBitmapButton( this, ID_SHRINK, *GetShrinkBitmap() ), 0, wxEXPAND|wxALL, 2 );
 
733
            buttonlist->Add( 20,10, 0 );
 
734
        }
 
735
        if ((GetWindowStyleFlag() & wxPLOT_BUTTON_MOVE) != 0)
 
736
        {
 
737
            buttonlist->Add( new wxBitmapButton( this, ID_MOVE_UP, *GetUpBitmap() ), 0, wxEXPAND|wxALL, 2 );
 
738
            buttonlist->Add( new wxBitmapButton( this, ID_MOVE_DOWN, *GetDownBitmap() ), 0, wxEXPAND|wxALL, 2 );
 
739
            buttonlist->Add( 20,10, 0 );
 
740
        }
 
741
        if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ZOOM) != 0)
 
742
        {
 
743
            buttonlist->Add( new wxBitmapButton( this, ID_ZOOM_IN, *GetZoomInBitmap() ), 0, wxEXPAND|wxALL, 2 );
 
744
            buttonlist->Add( new wxBitmapButton( this, ID_ZOOM_OUT, *GetZoomOutBitmap() ), 0, wxEXPAND|wxALL, 2 );
 
745
        }
 
746
        mainsizer->Add( buttonlist, 0, wxEXPAND|wxALL, 4 );
 
747
    }
 
748
 
 
749
    wxBoxSizer *plotsizer = new wxBoxSizer( wxHORIZONTAL );
 
750
 
 
751
    //Add sizer to hold the title and plot.
 
752
    //Title to be added later.
 
753
    m_plotAndTitleSizer = new wxBoxSizer( wxVERTICAL );
 
754
    m_plotAndTitleSizer->Add( plotsizer, 1, wxEXPAND | wxTOP, 10 );
 
755
 
 
756
    if ((GetWindowStyleFlag() & wxPLOT_Y_AXIS) != 0)
 
757
    {
 
758
        m_yaxis = new wxPlotYAxisArea( this );
 
759
 
 
760
        wxBoxSizer *vert1 = new wxBoxSizer( wxVERTICAL );
 
761
        plotsizer->Add( vert1, 1, wxEXPAND|wxTOP,10 );
 
762
        vert1->Add( m_yaxis, 1 );
 
763
        if ((GetWindowStyleFlag() & wxPLOT_X_AXIS) != 0)
 
764
            vert1->Add( 60, 40 );
 
765
    }
 
766
    else
 
767
    {
 
768
        m_yaxis = (wxPlotYAxisArea*) NULL;
 
769
    }
 
770
 
 
771
    if ((GetWindowStyleFlag() & wxPLOT_X_AXIS) != 0)
 
772
    {
 
773
        m_xaxis = new wxPlotXAxisArea( this );
 
774
 
 
775
        wxBoxSizer *vert2 = new wxBoxSizer( wxVERTICAL );
 
776
        plotsizer->Add( vert2, 5, wxEXPAND);
 
777
        vert2->Add( m_area, 1, wxEXPAND|wxTOP,10 );
 
778
        vert2->Add( m_xaxis, 0, wxEXPAND );
 
779
    }
 
780
    else
 
781
    {
 
782
        plotsizer->Add( m_area, 1, wxEXPAND );
 
783
        m_xaxis = (wxPlotXAxisArea*) NULL;
 
784
    }
 
785
 
 
786
    mainsizer->Add( m_plotAndTitleSizer, 1, wxEXPAND );
 
787
 
 
788
    SetAutoLayout( true );
 
789
    SetSizer( mainsizer );
 
790
    mainsizer->Fit(this);
 
791
    mainsizer->SetSizeHints(this);
 
792
 
 
793
    SetTargetWindow( m_area );
 
794
 
 
795
    SetBackgroundColour( *wxWHITE );
 
796
 
 
797
    m_current = (wxPlotCurve*) NULL;
 
798
}
 
799
 
 
800
wxPlotWindow::~wxPlotWindow()
 
801
{
 
802
}
 
803
 
 
804
void wxPlotWindow::Add( wxPlotCurve *curve )
 
805
{
 
806
    m_curves.Append( curve );
 
807
    if (!m_current) m_current = curve;
 
808
 
 
809
    ResetScrollbar();
 
810
}
 
811
 
 
812
size_t wxPlotWindow::GetCount()
 
813
{
 
814
    return m_curves.GetCount();
 
815
}
 
816
 
 
817
wxPlotCurve *wxPlotWindow::GetAt( size_t n )
 
818
{
 
819
    wxList::compatibility_iterator node = m_curves.Item( n );
 
820
    if (!node)
 
821
        return (wxPlotCurve*) NULL;
 
822
 
 
823
    return (wxPlotCurve*) node->GetData();
 
824
}
 
825
 
 
826
void wxPlotWindow::SetCurrentCurve( wxPlotCurve* current )
 
827
{
 
828
    m_current = current;
 
829
    m_area->Refresh( false );
 
830
 
 
831
    RedrawYAxis();
 
832
 
 
833
    wxPlotEvent event( wxEVT_PLOT_SEL_CHANGED, GetId() );
 
834
    event.SetEventObject( this );
 
835
    event.SetZoom( GetZoom() );
 
836
    event.SetCurve( m_current );
 
837
    GetEventHandler()->ProcessEvent( event );
 
838
}
 
839
 
 
840
void wxPlotWindow::Delete( wxPlotCurve* curve )
 
841
{
 
842
    wxList::compatibility_iterator node = m_curves.Find( curve );
 
843
    if (!node) return;
 
844
 
 
845
    m_curves.DeleteObject( curve );
 
846
 
 
847
    m_area->DeleteCurve( curve );
 
848
    m_area->Refresh( false );
 
849
 
 
850
    if (curve == m_current) m_current = (wxPlotCurve *) NULL;
 
851
}
 
852
 
 
853
wxPlotCurve *wxPlotWindow::GetCurrentCurve()
 
854
{
 
855
    return m_current;
 
856
}
 
857
 
 
858
void wxPlotWindow::Add( wxPlotOnOffCurve *curve )
 
859
{
 
860
    m_onOffCurves.Append( curve );
 
861
}
 
862
 
 
863
void wxPlotWindow::Delete( wxPlotOnOffCurve* curve )
 
864
{
 
865
    wxList::compatibility_iterator node = m_onOffCurves.Find( curve );
 
866
    if (!node) return;
 
867
 
 
868
    m_onOffCurves.DeleteObject( curve );
 
869
}
 
870
 
 
871
size_t wxPlotWindow::GetOnOffCurveCount()
 
872
{
 
873
    return m_onOffCurves.GetCount();
 
874
}
 
875
 
 
876
wxPlotOnOffCurve *wxPlotWindow::GetOnOffCurveAt( size_t n )
 
877
{
 
878
    wxList::compatibility_iterator node = m_onOffCurves.Item( n );
 
879
    if (!node)
 
880
        return (wxPlotOnOffCurve*) NULL;
 
881
 
 
882
    return (wxPlotOnOffCurve*) node->GetData();
 
883
}
 
884
 
 
885
void wxPlotWindow::Move( wxPlotCurve* curve, int pixels_up )
 
886
{
 
887
    m_area->DeleteCurve( curve );
 
888
 
 
889
    curve->SetOffsetY( curve->GetOffsetY() + pixels_up );
 
890
 
 
891
    m_area->Refresh( false );
 
892
 
 
893
    RedrawYAxis();
 
894
}
 
895
 
 
896
void wxPlotWindow::OnMoveUp( wxCommandEvent& WXUNUSED(event) )
 
897
{
 
898
    if (!m_current) return;
 
899
 
 
900
    Move( m_current, 25 );
 
901
}
 
902
 
 
903
void wxPlotWindow::OnMoveDown( wxCommandEvent& WXUNUSED(event) )
 
904
{
 
905
    if (!m_current) return;
 
906
 
 
907
    Move( m_current, -25 );
 
908
}
 
909
 
 
910
void wxPlotWindow::Enlarge( wxPlotCurve *curve, double factor )
 
911
{
 
912
    m_area->DeleteCurve( curve );
 
913
 
 
914
    int client_width;
 
915
    int client_height;
 
916
    m_area->GetClientSize( &client_width, &client_height);
 
917
    double offset = (double)curve->GetOffsetY() / (double)client_height;
 
918
 
 
919
    double range = curve->GetEndY() - curve->GetStartY();
 
920
    offset *= range;
 
921
 
 
922
    double new_range = range / factor;
 
923
    double new_offset = offset / factor;
 
924
 
 
925
    if (m_enlargeAroundWindowCentre)
 
926
    {
 
927
        double middle = curve->GetStartY() - offset + range/2;
 
928
 
 
929
        curve->SetStartY( middle - new_range / 2 + new_offset );
 
930
        curve->SetEndY( middle + new_range / 2 + new_offset  );
 
931
    }
 
932
    else
 
933
    {
 
934
        curve->SetStartY( (curve->GetStartY() - offset)/factor + new_offset );
 
935
        curve->SetEndY( (curve->GetEndY() - offset)/factor + new_offset );
 
936
    }
 
937
 
 
938
    m_area->Refresh( false );
 
939
    RedrawYAxis();
 
940
}
 
941
 
 
942
void wxPlotWindow::SetUnitsPerValue( double upv )
 
943
{
 
944
    m_xUnitsPerValue = upv;
 
945
 
 
946
    RedrawXAxis();
 
947
}
 
948
 
 
949
void wxPlotWindow::SetZoom( double zoom )
 
950
{
 
951
    double old_zoom = m_xZoom;
 
952
    m_xZoom = zoom;
 
953
 
 
954
    int view_x = 0;
 
955
    int view_y = 0;
 
956
    GetViewStart( &view_x, &view_y );
 
957
 
 
958
    wxInt32 max = 0;
 
959
    wxList::compatibility_iterator node = m_curves.GetFirst();
 
960
    while (node)
 
961
    {
 
962
        wxPlotCurve *curve = (wxPlotCurve*) node->GetData();
 
963
        if (curve->GetEndX() > max)
 
964
            max = curve->GetEndX();
 
965
        node = node->GetNext();
 
966
    }
 
967
    SetScrollbars( wxPLOT_SCROLL_STEP, wxPLOT_SCROLL_STEP,
 
968
                   (int)((max*m_xZoom)/wxPLOT_SCROLL_STEP)+1, 0,
 
969
                   (int)(view_x*zoom/old_zoom), 0,
 
970
                   true );
 
971
 
 
972
    RedrawXAxis();
 
973
    m_area->Refresh( true );
 
974
}
 
975
 
 
976
void wxPlotWindow::ResetScrollbar()
 
977
{
 
978
    wxInt32 max = 0;
 
979
    wxList::compatibility_iterator node = m_curves.GetFirst();
 
980
    while (node)
 
981
    {
 
982
        wxPlotCurve *curve = (wxPlotCurve*) node->GetData();
 
983
        if (curve->GetEndX() > max)
 
984
            max = curve->GetEndX();
 
985
        node = node->GetNext();
 
986
    }
 
987
 
 
988
    SetScrollbars( wxPLOT_SCROLL_STEP, wxPLOT_SCROLL_STEP,
 
989
                   (int)(((max*m_xZoom)/wxPLOT_SCROLL_STEP)+1), 0 );
 
990
}
 
991
 
 
992
void wxPlotWindow::AddChartTitle(const wxString& title, wxFont font,
 
993
                                 wxColour colour)
 
994
{
 
995
    m_title = title;
 
996
    m_titleFont = font;
 
997
    m_titleColour = colour;
 
998
    DrawChartTitle();
 
999
}
 
1000
 
 
1001
void wxPlotWindow::DrawChartTitle()
 
1002
{
 
1003
    if(m_title.size() != 0)
 
1004
    {
 
1005
        //If it is already added, remove child and delete
 
1006
        if(m_titleStaticText)
 
1007
        {
 
1008
            RemoveChild( m_titleStaticText );
 
1009
            m_titleStaticText->Destroy();
 
1010
        }
 
1011
 
 
1012
        //Create the text control and set the font, colour
 
1013
        m_titleStaticText = new wxStaticText( this, -1, m_title );
 
1014
        m_titleStaticText->SetFont( m_titleFont );
 
1015
        m_titleStaticText->SetForegroundColour( m_titleColour );
 
1016
 
 
1017
        //Create a sizer for the title. Prepend it to the Plot + Title sizer.
 
1018
        wxBoxSizer* titleSizer = new wxBoxSizer( wxHORIZONTAL );
 
1019
        titleSizer->Add( m_titleStaticText, 0, wxALIGN_CENTER | wxALL, 10 );
 
1020
        m_plotAndTitleSizer->Prepend( titleSizer, 0, wxALIGN_CENTER_HORIZONTAL );
 
1021
 
 
1022
        //Finally, force layout
 
1023
        m_plotAndTitleSizer->Layout();
 
1024
    }
 
1025
}
 
1026
 
 
1027
void wxPlotWindow::RedrawXAxis()
 
1028
{
 
1029
    if (m_xaxis)
 
1030
        m_xaxis->Refresh( true );
 
1031
}
 
1032
 
 
1033
void wxPlotWindow::RedrawYAxis()
 
1034
{
 
1035
    if (m_yaxis)
 
1036
       m_yaxis->Refresh( true );
 
1037
}
 
1038
 
 
1039
void wxPlotWindow::RedrawEverything()
 
1040
{
 
1041
    if (m_xaxis)
 
1042
        m_xaxis->Refresh( true );
 
1043
    if (m_yaxis)
 
1044
        m_yaxis->Refresh( true );
 
1045
    m_area->Refresh( true );
 
1046
 
 
1047
    DrawChartTitle();
 
1048
}
 
1049
 
 
1050
void wxPlotWindow::OnZoomIn( wxCommandEvent& WXUNUSED(event) )
 
1051
{
 
1052
    SetZoom( m_xZoom * 1.5 );
 
1053
}
 
1054
 
 
1055
void wxPlotWindow::OnZoomOut( wxCommandEvent& WXUNUSED(event) )
 
1056
{
 
1057
    SetZoom( m_xZoom * 0.6666 );
 
1058
}
 
1059
 
 
1060
void wxPlotWindow::OnEnlarge( wxCommandEvent& WXUNUSED(event) )
 
1061
{
 
1062
    if (!m_current) return;
 
1063
 
 
1064
    Enlarge( m_current, 1.5 );
 
1065
}
 
1066
 
 
1067
void wxPlotWindow::OnShrink( wxCommandEvent& WXUNUSED(event) )
 
1068
{
 
1069
    if (!m_current) return;
 
1070
 
 
1071
    Enlarge( m_current, 0.6666666 );
 
1072
}
 
1073
 
 
1074
void wxPlotWindow::OnScroll2( wxScrollWinEvent& event )
 
1075
{
 
1076
    if ((!m_scrollOnThumbRelease) || (event.GetEventType() != wxEVT_SCROLLWIN_THUMBTRACK))
 
1077
    {
 
1078
        wxScrolledWindow::OnScroll( event );
 
1079
        RedrawXAxis();
 
1080
    }
 
1081
}
 
1082
 
 
1083
// ----------------------------------------------------------------------------
 
1084
// global functions
 
1085
// ----------------------------------------------------------------------------
 
1086
 
 
1087
// FIXME MT-UNSAFE
 
1088
static wxBitmap *GetEnlargeBitmap()
 
1089
{
 
1090
    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
 
1091
    static bool s_loaded = false;
 
1092
 
 
1093
    if ( !s_loaded )
 
1094
    {
 
1095
        s_loaded = true; // set it to true anyhow, we won't try again
 
1096
 
 
1097
        #if defined(__WXMSW__) || defined(__WXPM__)
 
1098
            s_bitmap = new wxBitmap(_T("plot_enl_bmp"), wxBITMAP_TYPE_RESOURCE);
 
1099
        #else
 
1100
            s_bitmap = new wxBitmap( plot_enl_xpm );
 
1101
        #endif
 
1102
    }
 
1103
 
 
1104
    return s_bitmap;
 
1105
}
 
1106
 
 
1107
static wxBitmap *GetShrinkBitmap()
 
1108
{
 
1109
    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
 
1110
    static bool s_loaded = false;
 
1111
 
 
1112
    if ( !s_loaded )
 
1113
    {
 
1114
        s_loaded = true; // set it to true anyhow, we won't try again
 
1115
 
 
1116
        #if defined(__WXMSW__) || defined(__WXPM__)
 
1117
            s_bitmap = new wxBitmap(_T("plot_shr_bmp"), wxBITMAP_TYPE_RESOURCE);
 
1118
        #else
 
1119
            s_bitmap = new wxBitmap( plot_shr_xpm );
 
1120
        #endif
 
1121
    }
 
1122
 
 
1123
    return s_bitmap;
 
1124
}
 
1125
 
 
1126
static wxBitmap *GetZoomInBitmap()
 
1127
{
 
1128
    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
 
1129
    static bool s_loaded = false;
 
1130
 
 
1131
    if ( !s_loaded )
 
1132
    {
 
1133
        s_loaded = true; // set it to true anyhow, we won't try again
 
1134
 
 
1135
        #if defined(__WXMSW__) || defined(__WXPM__)
 
1136
            s_bitmap = new wxBitmap(_T("plot_zin_bmp"), wxBITMAP_TYPE_RESOURCE);
 
1137
        #else
 
1138
            s_bitmap = new wxBitmap( plot_zin_xpm );
 
1139
        #endif
 
1140
    }
 
1141
 
 
1142
    return s_bitmap;
 
1143
}
 
1144
 
 
1145
static wxBitmap *GetZoomOutBitmap()
 
1146
{
 
1147
    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
 
1148
    static bool s_loaded = false;
 
1149
 
 
1150
    if ( !s_loaded )
 
1151
    {
 
1152
        s_loaded = true; // set it to true anyhow, we won't try again
 
1153
 
 
1154
        #if defined(__WXMSW__) || defined(__WXPM__)
 
1155
            s_bitmap = new wxBitmap(_T("plot_zot_bmp"), wxBITMAP_TYPE_RESOURCE);
 
1156
        #else
 
1157
            s_bitmap = new wxBitmap( plot_zot_xpm );
 
1158
        #endif
 
1159
    }
 
1160
 
 
1161
    return s_bitmap;
 
1162
}
 
1163
 
 
1164
static wxBitmap *GetUpBitmap()
 
1165
{
 
1166
    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
 
1167
    static bool s_loaded = false;
 
1168
 
 
1169
    if ( !s_loaded )
 
1170
    {
 
1171
        s_loaded = true; // set it to true anyhow, we won't try again
 
1172
 
 
1173
        #if defined(__WXMSW__) || defined(__WXPM__)
 
1174
            s_bitmap = new wxBitmap(_T("plot_up_bmp"), wxBITMAP_TYPE_RESOURCE);
 
1175
        #else
 
1176
            s_bitmap = new wxBitmap( plot_up_xpm );
 
1177
        #endif
 
1178
    }
 
1179
 
 
1180
    return s_bitmap;
 
1181
}
 
1182
 
 
1183
static wxBitmap *GetDownBitmap()
 
1184
{
 
1185
    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
 
1186
    static bool s_loaded = false;
 
1187
 
 
1188
    if ( !s_loaded )
 
1189
    {
 
1190
        s_loaded = true; // set it to true anyhow, we won't try again
 
1191
 
 
1192
        #if defined(__WXMSW__) || defined(__WXPM__)
 
1193
            s_bitmap = new wxBitmap(_T("plot_dwn_bmp"), wxBITMAP_TYPE_RESOURCE);
 
1194
        #else
 
1195
            s_bitmap = new wxBitmap( plot_dwn_xpm );
 
1196
        #endif
 
1197
    }
 
1198
 
 
1199
    return s_bitmap;
 
1200
}
 
1201