PLplot  5.11.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
wxPLplotwindow.h
Go to the documentation of this file.
1 // Copyright (C) 2015 Phil Rosenberg
2 // Copyright (C) 2005 Werner Smekal
3 //
4 // This file is part of PLplot.
5 //
6 // PLplot is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU Library General Public License as published
8 // by the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // PLplot is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public License
17 // along with PLplot; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 
21 #if !defined ( WXPLPLOTWINDOW_H__INCLUDED_ )
22 #define WXPLPLOTWINDOW_H__INCLUDED_
23 
24 #include "plplot.h"
25 #include "wxPLplotstream.h"
26 #include <wx/window.h>
27 #include <wx/dcmemory.h>
28 #include <wx/dcclient.h>
29 #include <wx/dcgraph.h>
30 #include <wx/dcbuffer.h>
31 
32 // A plplot wxWindow template. To create an actual plplot wxWindow use
33 // the type of wxWindow you wish to inherit from at the template parameter
34 // For example to create a plplot wxFrame create a wxPLplotwindow<wxFrame>
35 // then call the base wxWindow's Create method to initialise.
36 template <class WXWINDOW>
37 class wxPLplotwindow : public WXWINDOW
38 {
39 public:
40  wxPLplotwindow( bool useGraphicsContext = true );
41  ~wxPLplotwindow( void );
42 
43  void RenewPlot( void );
44  bool SavePlot( const wxString& driver, const wxString& filename );
45  wxPLplotstream* GetStream() { return m_created ? &m_stream : NULL; }
46  void setUseGraphicsContext( bool useGraphicsContext );
47  void setCanvasColour( const wxColour &colour );
48 
49 protected:
50  virtual void OnPaint( wxPaintEvent& event );
51  virtual void OnSize( wxSizeEvent & event );
52  virtual void OnErase( wxEraseEvent &event );
53  virtual void OnCreate( wxWindowCreateEvent &event );
55  bool m_created;
56 
57 private:
59  wxBitmap m_bitmap;
60  // The memory dc and wrapping gc dc for drawing. Note we
61  //use pointers and reallocate them whenever the bitmap is
62  //resized because reusing either of these causes problems
63  //for rendering on a wxGCDC - at least on Windows.
64  wxMemoryDC *m_memoryDc;
65 #ifdef wxUSE_GRAPHICS_CONTEXT
66  wxGCDC *m_gcDc;
67 #endif
68  wxColour m_canvasColour;
69 };
70 
71 
73 // methods with events. The WXWINDOW default constructor is used.
74 //
75 template<class WXWINDOW>
76 wxPLplotwindow<WXWINDOW>::wxPLplotwindow( bool useGraphicsContext )
77  : m_created( false )
78 
79 {
80  m_memoryDc = NULL;
81 #ifdef wxUSE_GRAPHICS_CONTEXT
82  m_gcDc = NULL;
83 #endif
84  setUseGraphicsContext( useGraphicsContext );
85  m_canvasColour = *wxBLACK;
86 
87  //We use connect instead of Bind for compatiblity with wxWidgets 2.8
88  //but should move to bind in the future.
89  WXWINDOW::Connect( wxEVT_SIZE, wxSizeEventHandler( wxPLplotwindow<WXWINDOW>::OnSize ) );
90  WXWINDOW::Connect( wxEVT_PAINT, wxPaintEventHandler( wxPLplotwindow<WXWINDOW>::OnPaint ) );
91  WXWINDOW::Connect( wxEVT_ERASE_BACKGROUND, wxEraseEventHandler( wxPLplotwindow<WXWINDOW>::OnErase ) );
92  WXWINDOW::Connect( wxEVT_CREATE, wxWindowCreateEventHandler( wxPLplotwindow<WXWINDOW>::OnCreate ) );
93  //Bind( wxEVT_SIZE, &wxPLplotwindow<WXWINDOW>::OnSize, this );
94  //Bind( wxEVT_PAINT, &wxPLplotwindow<WXWINDOW>::OnPaint, this );
95 }
96 
97 
99 //
100 template<class WXWINDOW>
102 {
103 }
104 
105 
107 // later), we also implement our own double buffering here (since the PLplot wxWidgets driver draws
108 // into a wxMemoryDC)
109 //
110 template<class WXWINDOW>
111 void wxPLplotwindow<WXWINDOW>::OnPaint( wxPaintEvent &WXUNUSED( event ) )
112 {
113  //Really this should be in the constructor, but it caused a segfault
114  //on at least one system (CentOS with intel compiler and wxWidgets 2.8.12).
115  //Moving it here after WXWINDOW::Create has been called stops this and
116  //the call does nothing if the style is the same as previous calls so
117  //should be safe to call here.
118  //WXWINDOW::SetBackgroundStyle( wxBG_STYLE_CUSTOM );
119 
120 
121  //wxAutoBufferedPaintDC dc( (WXWINDOW*)this );
122  int width = WXWINDOW::GetClientSize().GetWidth();
123  int height = WXWINDOW::GetClientSize().GetHeight();
124 
125  wxPaintDC paintDc( this );
126 
127  //resize the plot if needed
128  bool needResize = width != m_bitmap.GetWidth() || height != m_bitmap.GetHeight();
129  if ( needResize )
130  {
131  m_bitmap.Create( width, height, 32 );
132  if ( m_memoryDc )
133  delete m_memoryDc;
134  m_memoryDc = new wxMemoryDC;
135  m_memoryDc->SelectObject( m_bitmap );
136  wxDC *drawDc = m_memoryDc;
137 #ifdef wxUSE_GRAPHICS_CONTEXT
138  if ( m_useGraphicsContext )
139  {
140  if ( m_gcDc )
141  delete m_gcDc;
142  m_gcDc = new wxGCDC( *m_memoryDc );
143  drawDc = m_gcDc;
144  }
145 #endif
146  m_stream.SetDC( drawDc );
147  drawDc->SetBackground( wxBrush( m_canvasColour ) );
148  drawDc->Clear();
149  m_stream.SetSize( width, height );
150  }
151 
152  paintDc.Blit( 0, 0, width, height, m_memoryDc, 0, 0 );
153 }
154 
156 //
157 template<class WXWINDOW>
158 void wxPLplotwindow<WXWINDOW>::OnSize( wxSizeEvent& WXUNUSED( event ) )
159 {
160  //Invalidate the whole window so it is all redrawn, otherwise only
161  //newly exposed parts of the window get redrawn
162  RenewPlot();
163 }
164 
166 //
167 template<class WXWINDOW>
168 void wxPLplotwindow<WXWINDOW>::OnErase( wxEraseEvent& WXUNUSED( event ) )
169 {
170  //Do nothing. This stops screen flicker.
171 }
172 
174 // has been called. We note that this has been called to avoid attempting
175 // to redraw a plot on a window that hasn't been created yet.
176 template<class WXWINDOW>
177 void wxPLplotwindow<WXWINDOW>::OnCreate( wxWindowCreateEvent &event )
178 {
179  if ( !m_created )
180  {
181  //create the stream
182  int width = WXWINDOW::GetClientSize().GetWidth();
183  int height = WXWINDOW::GetClientSize().GetHeight();
184  m_bitmap.Create( width, height );
185  if ( m_memoryDc )
186  delete m_memoryDc;
187  m_memoryDc = new wxMemoryDC;
188  m_memoryDc->SelectObject( m_bitmap );
189  wxDC * drawDc = m_memoryDc;
190 #ifdef wxUSE_GRAPHICS_CONTEXT
191  if ( m_useGraphicsContext )
192  {
193  if ( m_gcDc )
194  delete m_gcDc;
195  m_gcDc = new wxGCDC( *m_memoryDc );
196  drawDc = m_gcDc;
197  }
198 #endif
199  if ( !m_stream.IsValid() )
200  m_stream.Create( drawDc, width, height, wxPLPLOT_DRAW_TEXT );
201  else
202  m_stream.SetDC( drawDc );
203  drawDc->SetBackground( wxBrush( m_canvasColour ) );
204  drawDc->Clear();
205 
206  m_created = true;
207  RenewPlot();
208  }
209 }
210 
211 
213 //
214 template<class WXWINDOW>
216 {
217  if ( m_created )
218  {
219  WXWINDOW::Refresh();
220  }
221 }
222 
223 
225 //
226 template<class WXWINDOW>
227 bool wxPLplotwindow<WXWINDOW>::SavePlot( const wxString& devname, const wxString& filename )
228 {
229  int pls, pls_save;
230  FILE *sfile;
231 
232  if ( ( sfile = fopen( filename.mb_str(), "wb+" ) ) == NULL )
233  {
234  return false;
235  }
236 
237  plgstrm( &pls );
238  plmkstrm( &pls_save );
239  if ( pls_save < 0 )
240  {
241  fclose( sfile );
242  return false;
243  }
244  plsdev( devname.mb_str() );
245  plsfile( sfile );
246 
247  plspage( 0., 0., 800, 600, 0, 0 );
248  plcpstrm( pls, 0 );
249  pladv( 0 );
250  plreplot();
251  plend1();
252  plsstrm( pls );
253 
254  return true;
255 }
256 
258 template<class WXWINDOW>
259 void wxPLplotwindow<WXWINDOW>::setUseGraphicsContext( bool useGraphicsContext )
260 {
261  wxDC *drawDc;
262 #ifdef wxUSE_GRAPHICS_CONTEXT
263  if ( useGraphicsContext != m_useGraphicsContext )
264  {
265  m_useGraphicsContext = useGraphicsContext;
266  drawDc = m_useGraphicsContext ? (wxDC *) m_gcDc : (wxDC *) m_memoryDc;
267  }
268 #else
269  drawDc = &m_memoryDc;
270  m_useGraphicsContext = false;
271 #endif
272  if ( m_created )
273  {
274  m_stream.SetDC( drawDc );
275  RenewPlot();
276  }
277 }
278 
279 template<class WXWINDOW>
280 void wxPLplotwindow<WXWINDOW>::setCanvasColour( const wxColour &colour )
281 {
282  m_canvasColour = colour;
283  RenewPlot();
284 }
285 
286 #endif // !defined( WXPLPLOTWINDOW_H__INCLUDED_ )