// 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 <limits.h>
#include <vector>
#include <wx/config.h>
#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<int>(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<wxPoint> 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<wxPoint> 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<Point>::const_iterator,
Sum const*),
std::vector<Point>::const_iterator first,
std::vector<Point>::const_iterator last,
Sum const* sum);
void draw_data (wxDC& dc,
double (*compute_y)(std::vector<Point>::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<double> scale_tics_step (double beg, double end, int max_tics,
std::vector<double> &minors, bool log=false);
#endif
syntax highlighted by Code2HTML, v. 0.9.1