// This file is part of fityk program. Copyright (C) Marcin Wojdyr // Licence: GNU General Public License version 2 // $Id: plot.h 288 2007-04-22 02:14:02Z wojdyr $ #ifndef FITYK__WX_PLOT__H__ #define FITYK__WX_PLOT__H__ #include #include #include #include "../data.h" //Point // INT_MIN, given as coordinate, is invalid value, means "cancel drawing" class Sum; class Data; class View; enum MouseActEnum { mat_start, mat_stop, mat_move, mat_redraw }; void draw_line_with_style(wxDC& dc, int style, wxCoord X1, wxCoord Y1, wxCoord X2, wxCoord Y2); // convention here: lowercase coordinates of point are real values, // and uppercase ones are coordinates of point on screen (integers). class BufferedPanel : public wxPanel { public: BufferedPanel(wxWindow *parent) : wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxFULL_REPAINT_ON_RESIZE) {} void refresh(bool now=false); void buffered_draw(); virtual void draw(wxDC &dc, bool monochrome=false) = 0; protected: wxColour backgroundCol; private: wxMemoryDC memory_dc; wxBitmap buffer; bool resize_buffer(wxDC &dc); void clear_and_draw(); }; /// convertion between pixels and logical values class Scale { public: double scale, origin; bool logarithm, reversed; Scale() : scale(1.), origin(0.), logarithm(false), reversed(false) {} /// value -> pixel int px(double val) const { if (logarithm) { if (val <= 0) return inf_px(scale); val = log(val); } double t = (val - origin) * scale; return fabs(t) < SHRT_MAX ? static_cast(t) : inf_px(t); } /// pixel -> value double val(int px) const { fp a = px / scale + origin; return logarithm ? exp(a) : a; } // set scale using minimum and maximum logical values and width/height // of the screen in pixels. // In case of y scale, where pixel=0 is at the top, m and M are switched void set(fp m, fp M, int pixels); private: static int inf_px(float t) { return t > 0 ? SHRT_MAX : SHRT_MIN; } }; /// This class has no instances, MainPlot and AuxPlot are derived from it class FPlot : public BufferedPanel { public: FPlot (wxWindow *parent) : BufferedPanel(parent), draw_sigma(false), mouse_press_X(INT_MIN), mouse_press_Y(INT_MIN), vlfc_prev_x(INT_MIN), vlfc_prev_x0(INT_MIN) {} ~FPlot() {} wxColour const& get_bg_color() const { return backgroundCol; } void draw_crosshair(int X, int Y); void set_scale(); int get_special_point_at_pointer(wxMouseEvent& event); std::vector const& get_special_points() const { return special_points; } Scale const& get_x_scale() const { return xs; } Scale const& get_y_scale() const { return ys; } virtual void save_settings(wxConfigBase *cf) const; virtual void read_settings(wxConfigBase *cf); protected: Scale xs, ys; wxColour activeDataCol, inactiveDataCol, xAxisCol; wxFont ticsFont; int point_radius; bool line_between_points; bool draw_sigma; bool x_axis_visible, y_axis_visible, xtics_visible, ytics_visible, xminor_tics_visible, yminor_tics_visible; bool x_grid, y_grid; int x_max_tics, y_max_tics, x_tic_size, y_tic_size; int mouse_press_X, mouse_press_Y; int vlfc_prev_x, vlfc_prev_x0; //vertical lines following cursor std::vector special_points; //used to mark positions of peak tops void draw_dashed_vert_line(int X, int style=wxSHORT_DASH); bool vert_line_following_cursor(MouseActEnum ma, int x=0, int x0=INT_MIN); void draw_xtics (wxDC& dc, View const& v, bool set_pen=true); void draw_ytics (wxDC& dc, View const &v, bool set_pen=true); double get_max_abs_y(double (*compute_y)(std::vector::const_iterator, Sum const*), std::vector::const_iterator first, std::vector::const_iterator last, Sum const* sum); void draw_data (wxDC& dc, double (*compute_y)(std::vector::const_iterator, Sum const*), Data const* data, Sum const* sum, wxColour const& color = wxNullColour, wxColour const& inactive_color = wxNullColour, int Y_offset = 0, bool cumulative=false); void change_tics_font(); DECLARE_EVENT_TABLE() }; // utilities inline wxColour invert_colour(const wxColour& col) { return wxColour(255 - col.Red(), 255 - col.Green(), 255 - col.Blue()); } std::vector scale_tics_step (double beg, double end, int max_tics, std::vector &minors, bool log=false); #endif