1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        plotcurv.cpp
3 // Purpose:     wxPlotCurve for wxPlotCtrl
4 // Author:      John Labenski
5 // Modified by:
6 // Created:     12/01/2000
7 // Copyright:   (c) John Labenski
8 // Licence:     wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 #ifdef __BORLANDC__
15     #pragma hdrstop
16 #endif
17 
18 #ifndef WX_PRECOMP
19     #include "wx/bitmap.h"
20     #include "wx/dcmemory.h"
21 #endif // WX_PRECOMP
22 
23 #include "wx/plotctrl/plotcurv.h"
24 
25 const wxRect2DDouble wxNullPlotBounds(0, 0, 0, 0);
26 
27 #ifdef USE_BITMAPS_FOR_DRAWING
28 
29 /* XPM */
30 static const char *normal_symbol_xpm_data[] = {
31 /* columns rows colors chars-per-pixel */
32 "5 5 2 1",
33 "  c None",
34 "b c #000000",
35 /* pixels */
36 " bbb ",
37 "b   b",
38 "b   b",
39 "b   b",
40 " bbb "
41 };
42 
43 static const char *active_symbol_xpm_data[] = {
44 /* columns rows colors chars-per-pixel */
45 "5 5 2 1",
46 "  c None",
47 "b c #0000FF",
48 /* pixels */
49 " bbb ",
50 "b   b",
51 "b   b",
52 "b   b",
53 " bbb "
54 };
55 
56 static const char *selected_symbol_xpm_data[] = {
57 /* columns rows colors chars-per-pixel */
58 "5 5 2 1",
59 "  c None",
60 "b c #FF0000",
61 /* pixels */
62 " bbb ",
63 "b   b",
64 "b   b",
65 "b   b",
66 " bbb "
67 };
68 
69 #endif // USE_BITMAPS_FOR DRAWING
70 
71 // Can't load these now since wxWindows must initialize first
72 wxBitmap wxPlotSymbolNormal;
73 wxBitmap wxPlotSymbolActive;
74 wxBitmap wxPlotSymbolSelected;
75 
76 //----------------------------------------------------------------------------
77 // Interpolate
78 //----------------------------------------------------------------------------
LinearInterpolateX(double x0,double y0,double x1,double y1,double y)79 double LinearInterpolateX(double x0, double y0, double x1, double y1, double y)
80 {
81     //wxCHECK_MSG( (y1 - y0) != 0.0, 0.0, wxT("Divide by zero, LinearInterpolateX()") );
82     return ( (y - y0)*(x1 - x0)/(y1 - y0) + x0 );
83 }
84 
LinearInterpolateY(double x0,double y0,double x1,double y1,double x)85 double LinearInterpolateY(double x0, double y0, double x1, double y1, double x)
86 {
87     //wxCHECK_MSG( (x1 - x0) != 0.0, 0.0, wxT("Divide by zero, LinearInterpolateY()") );
88     double m = (y1 - y0) / (x1 - x0);
89     return (m*x + (y0 - m*x0));
90 }
91 
92 //----------------------------------------------------------------------------
93 // wxPlotCurveRefData
94 //----------------------------------------------------------------------------
95 
96 wxArrayGenericPen wxPlotCurveRefData::sm_defaultPens;
97 
InitPlotCurveDefaultPens()98 void InitPlotCurveDefaultPens()
99 {
100     static bool s_init_default_pens = false;
101     if (!s_init_default_pens)
102     {
103         s_init_default_pens = true;
104         wxPlotCurveRefData::sm_defaultPens.Add(wxGenericPen( wxGenericColour(  0, 0,   0), 1, wxSOLID ));
105         wxPlotCurveRefData::sm_defaultPens.Add(wxGenericPen( wxGenericColour(  0, 0, 255), 1, wxSOLID ));
106         wxPlotCurveRefData::sm_defaultPens.Add(wxGenericPen( wxGenericColour(255, 0,   0), 1, wxSOLID ));
107     }
108 }
109 
wxPlotCurveRefData()110 wxPlotCurveRefData::wxPlotCurveRefData() : wxObjectRefData()
111 {
112     InitPlotCurveDefaultPens();
113     m_pens = sm_defaultPens;
114 }
115 
wxPlotCurveRefData(const wxPlotCurveRefData & data)116 wxPlotCurveRefData::wxPlotCurveRefData(const wxPlotCurveRefData& data)
117                    :wxObjectRefData()
118 {
119     Copy(data);
120 }
121 
Copy(const wxPlotCurveRefData & source)122 void wxPlotCurveRefData::Copy(const wxPlotCurveRefData &source)
123 {
124     m_boundingRect = source.m_boundingRect;
125     m_pens         = source.m_pens;
126     m_optionNames  = source.m_optionNames;
127     m_optionValues = source.m_optionValues;
128 }
129 
130 #define M_PLOTCURVEDATA ((wxPlotCurveRefData*)m_refData)
131 
132 //-----------------------------------------------------------------------------
133 // wxPlotCurve
134 //-----------------------------------------------------------------------------
135 IMPLEMENT_DYNAMIC_CLASS(wxPlotCurve, wxObject);
136 
CreateRefData() const137 wxObjectRefData *wxPlotCurve::CreateRefData() const
138 {
139     return new wxPlotCurveRefData;
140 }
CloneRefData(const wxObjectRefData * data) const141 wxObjectRefData *wxPlotCurve::CloneRefData(const wxObjectRefData *data) const
142 {
143     return new wxPlotCurveRefData(*(const wxPlotCurveRefData *)data);
144 }
145 
wxPlotCurve()146 wxPlotCurve::wxPlotCurve() : wxObject()
147 {
148     // Note: You must do this in your constructor in order to use the the curve
149     // m_refData = new wxPlotCurveRefData (or wxMySubclassedPlotCurveRefData)
150 }
151 
Ok() const152 bool wxPlotCurve::Ok() const
153 {
154     return (M_PLOTCURVEDATA != NULL);
155 }
156 
GetBoundingRect() const157 wxRect2DDouble wxPlotCurve::GetBoundingRect() const
158 {
159     wxCHECK_MSG(Ok(), wxRect2DDouble(0,0,0,0), wxT("invalid plotcurve"));
160     return M_PLOTCURVEDATA->m_boundingRect;
161 }
SetBoundingRect(const wxRect2DDouble & rect)162 void wxPlotCurve::SetBoundingRect( const wxRect2DDouble &rect )
163 {
164     wxCHECK_RET(Ok(), wxT("invalid plotcurve"));
165     M_PLOTCURVEDATA->m_boundingRect = rect;
166 }
167 
168 //----------------------------------------------------------------------------
169 // Get/Set Pen
170 //----------------------------------------------------------------------------
171 
GetPen(wxPlotPen_Type colour_type) const172 wxGenericPen wxPlotCurve::GetPen(wxPlotPen_Type colour_type) const
173 {
174     wxCHECK_MSG(Ok(), wxGenericPen(), wxT("invalid plotcurve"));
175     wxCHECK_MSG((colour_type >= 0) && (colour_type < (int)M_PLOTCURVEDATA->m_pens.GetCount()), wxGenericPen(), wxT("invalid plot colour"));
176 
177     return M_PLOTCURVEDATA->m_pens[colour_type];
178 }
SetPen(wxPlotPen_Type colour_type,const wxGenericPen & pen)179 void wxPlotCurve::SetPen(wxPlotPen_Type colour_type, const wxGenericPen &pen )
180 {
181     wxCHECK_RET(Ok(), wxT("invalid plotcurve"));
182     wxCHECK_RET((colour_type >= 0) && (colour_type < (int)M_PLOTCURVEDATA->m_pens.GetCount()), wxT("invalid plot colour"));
183 
184     M_PLOTCURVEDATA->m_pens[colour_type] = pen;
185 }
186 
GetDefaultPen(wxPlotPen_Type colour_type)187 wxGenericPen wxPlotCurve::GetDefaultPen(wxPlotPen_Type colour_type)
188 {
189     InitPlotCurveDefaultPens();
190     wxCHECK_MSG((colour_type >= 0) && (colour_type < int(wxPlotCurveRefData::sm_defaultPens.GetCount())), wxGenericPen(), wxT("invalid plot colour"));
191     return wxPlotCurveRefData::sm_defaultPens[colour_type];
192 }
SetDefaultPen(wxPlotPen_Type colour_type,const wxGenericPen & pen)193 void wxPlotCurve::SetDefaultPen(wxPlotPen_Type colour_type, const wxGenericPen &pen )
194 {
195     InitPlotCurveDefaultPens();
196     wxCHECK_RET((colour_type >= 0) && (colour_type < int(wxPlotCurveRefData::sm_defaultPens.GetCount())), wxT("invalid plot colour"));
197     wxPlotCurveRefData::sm_defaultPens[colour_type] = pen;
198 }
199 
200 // ----------------------------------------------------------------------------
201 // Get/Set Option names/values
202 // ----------------------------------------------------------------------------
203 
GetOptionCount() const204 size_t wxPlotCurve::GetOptionCount() const
205 {
206     wxCHECK_MSG(M_PLOTCURVEDATA, 0, wxT("invalid plotcurve"));
207     return M_PLOTCURVEDATA->m_optionNames.GetCount();
208 }
209 
HasOption(const wxString & name) const210 int wxPlotCurve::HasOption(const wxString& name) const
211 {
212     wxCHECK_MSG(M_PLOTCURVEDATA, wxNOT_FOUND, wxT("invalid plotcurve"));
213     return M_PLOTCURVEDATA->m_optionNames.Index(name);
214 }
215 
GetOptionName(size_t i) const216 wxString wxPlotCurve::GetOptionName( size_t i ) const
217 {
218     wxCHECK_MSG(M_PLOTCURVEDATA&&(i<GetOptionCount()), wxEmptyString, wxT("invalid plotcurve") );
219     return M_PLOTCURVEDATA->m_optionNames[i];
220 }
GetOptionValue(size_t i) const221 wxString wxPlotCurve::GetOptionValue( size_t i ) const
222 {
223     wxCHECK_MSG(M_PLOTCURVEDATA&&(i<GetOptionCount()), wxEmptyString, wxT("invalid plotcurve") );
224     return M_PLOTCURVEDATA->m_optionValues[i];
225 }
226 
SetOption(const wxString & name,const wxString & value,bool update)227 int wxPlotCurve::SetOption(const wxString& name, const wxString& value, bool update)
228 {
229     wxCHECK_MSG(M_PLOTCURVEDATA, -1, wxT("invalid plotcurve"));
230     int n = M_PLOTCURVEDATA->m_optionNames.Index(name);
231     if (n == wxNOT_FOUND)
232     {
233         n = M_PLOTCURVEDATA->m_optionNames.Add(name);
234         M_PLOTCURVEDATA->m_optionValues.Insert(value, n);
235     }
236     else if (update)
237     {
238         M_PLOTCURVEDATA->m_optionNames[n] = name;
239         M_PLOTCURVEDATA->m_optionValues[n] = value;
240     }
241     return n;
242 }
SetOption(const wxString & name,int option,bool update)243 int wxPlotCurve::SetOption(const wxString &name, int option, bool update)
244 {
245     return SetOption(name, wxString::Format(wxT("%d"), option), update);
246 }
GetOption(const wxString & name) const247 wxString wxPlotCurve::GetOption(const wxString& name) const
248 {
249     wxCHECK_MSG(M_PLOTCURVEDATA, wxEmptyString, wxT("invalid plotcurve"));
250     int n = M_PLOTCURVEDATA->m_optionNames.Index(name);
251 
252     if (n == wxNOT_FOUND)
253         return wxEmptyString;
254 
255     return M_PLOTCURVEDATA->m_optionValues[n];
256 }
GetOption(const wxString & name,wxString & value) const257 int wxPlotCurve::GetOption(const wxString& name, wxString &value ) const
258 {
259     wxCHECK_MSG(M_PLOTCURVEDATA, wxNOT_FOUND, wxT("invalid plotcurve"));
260 
261     int n = M_PLOTCURVEDATA->m_optionNames.Index(name);
262 
263     if (n == wxNOT_FOUND) return wxNOT_FOUND;
264 
265     value = M_PLOTCURVEDATA->m_optionValues[n];
266     return n;
267 }
GetOptionInt(const wxString & name) const268 int wxPlotCurve::GetOptionInt(const wxString& name) const
269 {
270     wxCHECK_MSG(M_PLOTCURVEDATA, 0, wxT("invalid plotcurve"));
271     return wxAtoi(GetOption(name));
272 }
273 
GetOptionNames() const274 wxArrayString wxPlotCurve::GetOptionNames() const
275 {
276     wxCHECK_MSG(M_PLOTCURVEDATA, wxArrayString(), wxT("invalid plotcurve"));
277     return M_PLOTCURVEDATA->m_optionNames;
278 }
GetOptionValues() const279 wxArrayString wxPlotCurve::GetOptionValues() const
280 {
281     wxCHECK_MSG(M_PLOTCURVEDATA, wxArrayString(), wxT("invalid plotcurve"));
282     return M_PLOTCURVEDATA->m_optionValues;
283 }
284 
285 //-------------------------------------------------------------------------
286 
SetClientObject(wxClientData * data)287 void wxPlotCurve::SetClientObject( wxClientData *data )
288 {
289     wxCHECK_RET(M_PLOTCURVEDATA, wxT("invalid plotcurve"));
290     M_PLOTCURVEDATA->SetClientObject(data);
291 }
GetClientObject() const292 wxClientData *wxPlotCurve::GetClientObject() const
293 {
294     wxCHECK_MSG(M_PLOTCURVEDATA, NULL, wxT("invalid plotcurve"));
295     return M_PLOTCURVEDATA->GetClientObject();
296 }
SetClientData(void * data)297 void wxPlotCurve::SetClientData( void *data )
298 {
299     wxCHECK_RET(M_PLOTCURVEDATA, wxT("invalid plotcurve"));
300     M_PLOTCURVEDATA->SetClientData(data);
301 }
GetClientData() const302 void *wxPlotCurve::GetClientData() const
303 {
304     wxCHECK_MSG(M_PLOTCURVEDATA, NULL, wxT("invalid plotcurve"));
305     return M_PLOTCURVEDATA->GetClientData();
306 }
307