Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > by-pkgid > 87f956008f5479527bcce97ec30dbca7 > files > 330

fityk-debug-0.8.6-3mdv2009.1.i586.rpm

// This file is part of fityk program. Copyright (C) Marcin Wojdyr
// Licence: GNU General Public License version 2
// $Id: plot.h 417 2008-04-10 12:54:28Z wojdyr $

#ifndef FITYK__WX_PLOT__H__
#define FITYK__WX_PLOT__H__

#include <limits.h>
#include <vector>
#include <wx/config.h>
#include "../data.h" //Point
#include "uplot.h" //BufferedPanel

// convention: lowercase coordinates of point are real values,
// and uppercase ones are coordinates of point on screen (integers).

// 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);


/// 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
    inline int px(double val) const;
    /// pixel -> value
    inline double val(int px) const;

    // 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; }
};


int Scale::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);
}

double Scale::val(int px) const
{ 
    fp a = px / scale + origin; 
    return logarithm ? exp(a) : a; 
}


/// This class has no instances, MainPlot and AuxPlot are derived from it
/// It knows how to draw on wxDC. Note that wxDC:SetClippingRegion() should be
/// used together with wxDC::SetDeviceOrigin(). Clipping box is used only in
/// get_pixel_width() and get_pixel_height() functions.
/// When plotting a curve, values in each x from 0 to get_pixel_width() is 
/// calculated.

class FPlot : public BufferedPanel 
{
public:
    FPlot (wxWindow *parent)
       : BufferedPanel(parent),
         pen_width(1),
         draw_sigma(false), 
         mouse_press_X(INT_MIN), mouse_press_Y(INT_MIN),
         vlfc_prev_x(INT_MIN), vlfc_prev_x0(INT_MIN)   {}
         
    ~FPlot() {}
    void set_font(wxDC &dc, wxFont const& font);
    wxColour const& get_bg_color() const { return backgroundCol; }
    void draw_crosshair(int X, int Y);
    void set_scale(int pixel_width, int pixel_height);
    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);
    void set_magnification(int m) { pen_width = m > 0 ? m : 1; }

protected:
    Scale xs, ys;
    int pen_width;
    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();

    int get_pixel_width(wxDC const& dc) const 
      //{ return dc.GetSize().GetWidth(); }
    { 
          int w;
          dc.GetClippingBox(NULL, NULL, &w, NULL);
          return w != 0 ? w : dc.GetSize().GetWidth(); 
    }
    int get_pixel_height(wxDC const& dc) const 
    //  { return dc.GetSize().GetHeight(); }
    { 
          int h;
          dc.GetClippingBox(NULL, NULL, NULL, &h);
          return h != 0 ? h : dc.GetSize().GetHeight(); 
    }

    DECLARE_EVENT_TABLE()
};

// utilities

inline wxColour invert_colour(const wxColour& col)
{ return wxColour(255 - col.Red(), 255 - col.Green(), 255 - col.Blue()); }

#endif