You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
7.5 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2016 CERN
  5. * Copyright (C) 2016-2017 KiCad Developers, see AUTHORS.txt for contributors.
  6. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  7. * @author Maciej Suminski <maciej.suminski@cern.ch>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 3
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * https://www.gnu.org/licenses/gpl-3.0.html
  22. * or you may search the http://www.gnu.org website for the version 3 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #ifndef __SIM_PLOT_PANEL_H
  27. #define __SIM_PLOT_PANEL_H
  28. #include "sim_types.h"
  29. #include <map>
  30. #include <widgets/mathplot.h>
  31. #include <wx/sizer.h>
  32. #include "sim_panel_base.h"
  33. class SIM_PLOT_FRAME;
  34. class SIM_PLOT_PANEL;
  35. class TRACE;
  36. ///> Cursor attached to a trace to follow its values:
  37. class CURSOR : public mpInfoLayer
  38. {
  39. public:
  40. CURSOR( const TRACE* aTrace, SIM_PLOT_PANEL* aPlotPanel )
  41. : mpInfoLayer( wxRect( 0, 0, DRAG_MARGIN, DRAG_MARGIN ), wxTRANSPARENT_BRUSH ),
  42. m_trace( aTrace ), m_updateRequired( true ), m_updateRef( false ),
  43. m_coords( 0.0, 0.0 ), m_window( nullptr ), m_plotPanel( aPlotPanel )
  44. {
  45. SetDrawOutsideMargins( false );
  46. }
  47. void Plot( wxDC& aDC, mpWindow& aWindow ) override;
  48. void SetX( int aX )
  49. {
  50. m_reference.x = 0;
  51. m_updateRef = true;
  52. Move( wxPoint( aX, 0 ) );
  53. }
  54. void Update()
  55. {
  56. m_updateRequired = true;
  57. }
  58. bool Inside( wxPoint& aPoint ) override;
  59. void Move( wxPoint aDelta ) override
  60. {
  61. Update();
  62. mpInfoLayer::Move( aDelta );
  63. }
  64. void UpdateReference() override;
  65. const wxRealPoint& GetCoords() const
  66. {
  67. return m_coords;
  68. }
  69. private:
  70. const TRACE* m_trace;
  71. bool m_updateRequired, m_updateRef;
  72. wxRealPoint m_coords;
  73. mpWindow* m_window;
  74. SIM_PLOT_PANEL* m_plotPanel;
  75. static constexpr int DRAG_MARGIN = 10;
  76. };
  77. class TRACE : public mpFXYVector
  78. {
  79. public:
  80. TRACE( const wxString& aName ) :
  81. mpFXYVector( aName ), m_cursor( nullptr ), m_flags( 0 )
  82. {
  83. SetContinuity( true );
  84. SetDrawOutsideMargins( false );
  85. ShowName( false );
  86. }
  87. /**
  88. * @brief Assigns new data set for the trace. aX and aY need to have the same length.
  89. * @param aX are the X axis values.
  90. * @param aY are the Y axis values.
  91. */
  92. void SetData( const std::vector<double>& aX, const std::vector<double>& aY ) override
  93. {
  94. if( m_cursor )
  95. m_cursor->Update();
  96. mpFXYVector::SetData( aX, aY );
  97. }
  98. const std::vector<double>& GetDataX() const
  99. {
  100. return m_xs;
  101. }
  102. const std::vector<double>& GetDataY() const
  103. {
  104. return m_ys;
  105. }
  106. bool HasCursor() const
  107. {
  108. return m_cursor != nullptr;
  109. }
  110. void SetCursor( CURSOR* aCursor )
  111. {
  112. m_cursor = aCursor;
  113. }
  114. CURSOR* GetCursor() const
  115. {
  116. return m_cursor;
  117. }
  118. void SetFlags( int aFlags )
  119. {
  120. m_flags = aFlags;
  121. }
  122. int GetFlags() const
  123. {
  124. return m_flags;
  125. }
  126. void SetTraceColour( wxColour aColour )
  127. {
  128. m_traceColour = aColour;
  129. }
  130. wxColour GetTraceColour()
  131. {
  132. return m_traceColour;
  133. }
  134. protected:
  135. CURSOR* m_cursor;
  136. int m_flags;
  137. wxColour m_traceColour;
  138. };
  139. class SIM_PLOT_PANEL : public SIM_PANEL_BASE
  140. {
  141. public:
  142. SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
  143. wxWindowID id, const wxPoint& pos = wxDefaultPosition,
  144. const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr );
  145. virtual ~SIM_PLOT_PANEL();
  146. ///> set the pointer to the sim plot frame
  147. void SetMasterFrame( SIM_PLOT_FRAME* aFrame )
  148. {
  149. m_masterFrame = aFrame;
  150. }
  151. wxString GetLabelX() const
  152. {
  153. return m_axis_x ? m_axis_x->GetName() : "";
  154. }
  155. wxString GetLabelY1() const
  156. {
  157. return m_axis_y1 ? m_axis_y1->GetName() : "";
  158. }
  159. wxString GetLabelY2() const
  160. {
  161. return m_axis_y2 ? m_axis_y2->GetName() : "";
  162. }
  163. bool AddTrace( const wxString& aName, int aPoints,
  164. const double* aX, const double* aY, SIM_PLOT_TYPE aFlags );
  165. bool DeleteTrace( const wxString& aName );
  166. void DeleteAllTraces();
  167. bool TraceShown( const wxString& aName ) const
  168. {
  169. return m_traces.count( aName ) > 0;
  170. }
  171. const std::map<wxString, TRACE*>& GetTraces() const
  172. {
  173. return m_traces;
  174. }
  175. TRACE* GetTrace( const wxString& aName ) const
  176. {
  177. auto trace = m_traces.find( aName );
  178. return trace == m_traces.end() ? NULL : trace->second;
  179. }
  180. void ShowGrid( bool aEnable )
  181. {
  182. m_axis_x->SetTicks( !aEnable );
  183. m_axis_y1->SetTicks( !aEnable );
  184. m_axis_y2->SetTicks( !aEnable );
  185. m_plotWin->UpdateAll();
  186. }
  187. bool IsGridShown() const
  188. {
  189. if( !m_axis_x || !m_axis_y1 )
  190. return false;
  191. assert( m_axis_x->GetTicks() == m_axis_y1->GetTicks() );
  192. return !m_axis_x->GetTicks();
  193. }
  194. void ShowLegend( bool aEnable )
  195. {
  196. m_legend->SetVisible( aEnable );
  197. m_plotWin->UpdateAll();
  198. }
  199. bool IsLegendShown() const
  200. {
  201. return m_legend->IsVisible();
  202. }
  203. void SetDottedCurrentPhase( bool aEnable )
  204. {
  205. m_dotted_cp = aEnable;
  206. for( const auto& tr : m_traces )
  207. {
  208. UpdateTraceStyle( tr.second );
  209. }
  210. m_plotWin->UpdateAll();
  211. }
  212. bool GetDottedCurrentPhase() const
  213. {
  214. return m_dotted_cp;
  215. }
  216. ///> Returns true if the trace has cursor shown.
  217. bool HasCursorEnabled( const wxString& aName ) const;
  218. ///> Toggles cursor for a particular trace.
  219. void EnableCursor( const wxString& aName, bool aEnable );
  220. ///> Resets scale ranges to fit the current traces
  221. void ResetScales();
  222. ///> Update trace line style
  223. void UpdateTraceStyle( TRACE* trace );
  224. /**
  225. * A proxy to SIM_PLOT_FRAME::GetPlotColor()
  226. * @return the color stored in m_colorList.
  227. * @param aIndex is the index in list
  228. */
  229. wxColour GetPlotColor( int aIndex );
  230. ///> Update plot colors
  231. void UpdatePlotColors();
  232. ///> Getter for math plot window
  233. mpWindow* GetPlotWin() const
  234. {
  235. return m_plotWin;
  236. }
  237. private:
  238. ///> @return a new color from the palette
  239. wxColour generateColor();
  240. // Color index to get a new color from the palette
  241. unsigned int m_colorIdx;
  242. // Top-level plot window
  243. mpWindow* m_plotWin;
  244. wxBoxSizer* m_sizer;
  245. // Traces to be plotted
  246. std::map<wxString, TRACE*> m_traces;
  247. mpScaleXBase* m_axis_x;
  248. mpScaleY* m_axis_y1;
  249. mpScaleY* m_axis_y2;
  250. mpInfoLegend* m_legend;
  251. bool m_dotted_cp;
  252. std::vector<mpLayer*> m_topLevel;
  253. SIM_PLOT_FRAME* m_masterFrame;
  254. };
  255. wxDECLARE_EVENT( EVT_SIM_CURSOR_UPDATE, wxCommandEvent );
  256. #endif