Sophie

Sophie

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

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: mplot.h 414 2008-04-06 17:37:22Z wojdyr $

#ifndef FITYK__WX_MPLOT__H__
#define FITYK__WX_MPLOT__H__

#include "plot.h"
#include "cmn.h"
#include "../numfuncs.h" // PointQ definition
#include "../guess.h" // enum FunctionKind 


/// it cares about visualization of spline / polyline background 
/// which can be set by selecting points on Plot

class Function;

class BgManager
{
public:
    typedef std::vector<PointQ>::iterator bg_iterator;
    typedef std::vector<PointQ>::const_iterator bg_const_iterator;

    BgManager(Scale const& x_scale_) : x_scale(x_scale_), min_dist(8), 
                                     spline_bg(true) {}
    void add_background_point(fp x, fp y);
    void rm_background_point(fp x);
    void clear_background();
    void forget_background() { clear_background(); bg_backup.clear(); }
    void strip_background();
    void undo_strip_background();
    bool can_strip() const { return !bg.empty(); }
    bool can_undo() const { return !bg_backup.empty(); }
    void set_spline_bg(bool s) { spline_bg=s; }
    void set_as_convex_hull();
    std::vector<int> calculate_bgline(int window_width, Scale const& y_scale);
    bg_const_iterator begin() const { return bg.begin(); }
    bg_const_iterator end() const { return bg.end(); }
protected:
    Scale const& x_scale;
    int min_dist; //minimal distance in X between bg points
    bool spline_bg;
    std::vector<PointQ> bg, bg_backup;
    std::string cmd_tail;
};


class ConfigureAxesDlg;

/// utility used in MainPlot for dragging function
class FunctionMouseDrag
{
public:
    enum drag_type { 
        no_drag, 
        relative_value, //eg. for area
        absolute_value,  //eg. for width
        absolute_pixels 
    };

    class Drag 
    {
    public:
        drag_type how;
        int parameter_idx;
        std::string parameter_name;
        std::string variable_name; /// name of variable that are to be changed 
        fp value; /// current value of parameter
        fp ini_value; /// initial value of parameter
        fp multiplier; /// increases or decreases changing rate
        fp ini_x;

        Drag() : how(no_drag) {}
        void set(Function const* p, int idx, drag_type how_, fp multiplier_);
        void change_value(fp x, fp dx, int dX);
        std::string get_cmd() const {
            return how != no_drag && value != ini_value ?
                "$" + variable_name + " = ~" + S(value) + "; " : "";
        }
    };

    FunctionMouseDrag() : sidebar_dirty(false) {}
    void start(Function const* p, int X, int Y, fp x, fp y);
    void move(bool shift, int X, int Y, fp x, fp y);
    void stop();
    std::vector<fp> const& get_values() const { return values; }
    std::string const& get_status() const { return status; }
    std::string get_cmd() const;

private:
    Drag drag_x; ///for horizontal dragging (x axis)
    Drag drag_y; /// y axis
    Drag drag_shift_x; ///x with [shift]
    Drag drag_shift_y; ///y with [shift]
    fp px, py;
    int pX, pY;
    std::vector<fp> values;
    std::string status;
    bool sidebar_dirty;

    void set_defined_drags();
    bool bind_parameter_to_drag(Drag &drag, std::string const& name,
                          Function const* p, drag_type how, fp multiplier=1.);
    void set_drag(Drag &drag, Function const* p, int idx,
                  drag_type how, fp multiplier=1.);
};

/// main plot, single in application, displays data, fitted peaks etc. 
class MainPlot : public FPlot
{
    friend class ConfigureAxesDlg;
    friend class ConfigurePLabelsDlg;
public:
    BgManager bgm;

    MainPlot(wxWindow *parent); 
    ~MainPlot() {}
    void OnPaint(wxPaintEvent &event);
    void draw(wxDC &dc, bool monochrome=false);
    void OnLeaveWindow (wxMouseEvent& event);
    void OnMouseMove(wxMouseEvent &event);
    void OnButtonDown (wxMouseEvent &event);
    void OnLeftDClick (wxMouseEvent&) { PeakInfo(); }
    void OnButtonUp (wxMouseEvent &event);
    void OnKeyDown (wxKeyEvent& event);

    void OnPopupShowXX (wxCommandEvent& event);
    void OnPopupColor (wxCommandEvent& event);
    void OnInvertColors (wxCommandEvent& event);
    void OnPopupRadius (wxCommandEvent& event);
    void OnConfigureAxes (wxCommandEvent& event);
    void OnConfigurePLabels (wxCommandEvent& event);
    void OnZoomAll (wxCommandEvent& event);
    void PeakInfo ();
    void OnPeakInfo (wxCommandEvent&) { PeakInfo(); }
    void OnPeakDelete (wxCommandEvent& event);
    void OnPeakGuess(wxCommandEvent &event);
    void cancel_mouse_press();
    void save_settings(wxConfigBase *cf) const;
    void read_settings(wxConfigBase *cf);
    void update_mouse_hints();
    void set_mouse_mode(MouseModeEnum m);
    MouseModeEnum get_mouse_mode() const { return mode; }
    wxColour const& get_data_color(int n) const
        { return dataColour[n % max_data_cols]; }
    wxColour const& get_func_color(int n) const
        { return peakCol[n % max_peak_cols]; }
    void set_data_color(int n, wxColour const& col) 
        { dataColour[n % max_data_cols] = col; }
    void set_data_point_size(int /*n*/, int r) { point_radius = r; }
    void set_data_with_line(int /*n*/, bool b) { line_between_points = b; }
    void set_data_with_sigma(int /*n*/, bool b) { draw_sigma = b; }
    int get_data_point_size(int /*n*/) const { return point_radius; }
    bool get_data_with_line(int /*n*/) const { return line_between_points; }
    void set_func_color(int n, wxColour const& col) 
        { peakCol[n % max_peak_cols] = col; }
    bool get_x_reversed() const { return x_reversed; }
    void draw_xor_peak(Function const* func, std::vector<fp> const& p_values);
    void show_popup_menu(wxMouseEvent &event);

private:
    MouseModeEnum basic_mode, 
                  mode;  ///actual mode -- either basic_mode or mmd_peak
    static const int max_group_cols = 8;
    static const int max_peak_cols = 32;
    static const int max_data_cols = 64;
    static const int max_radius = 4; ///size of data point
    bool peaks_visible, groups_visible, sum_visible,  
         plabels_visible, x_reversed;  
    wxFont plabelFont;
    std::string plabel_format;
    bool vertical_plabels;
    std::vector<std::string> plabels;
    wxColour sumCol, bg_pointsCol;
    wxColour groupCol[max_group_cols], peakCol[max_peak_cols];
    wxColour dataColour[max_data_cols];
    int pressed_mouse_button;
    bool ctrl_on_down;
    bool shift_on_down;
    int over_peak; /// the cursor is over peaktop of this peak
    int limit1, limit2; /// for drawing function limits (vertical lines)
    FunctionMouseDrag fmd; //for function dragging
    FunctionKind func_draft_kind; // for function adding (with drawing draft)

    void draw_x_axis (wxDC& dc, bool set_pen=true);
    void draw_y_axis (wxDC& dc, bool set_pen=true);
    void draw_background(wxDC& dc, bool set_pen=true); 
    void draw_sum (wxDC& dc, Sum const* sum, bool set_pen=true);
    void draw_groups (wxDC& dc, Sum const* sum, bool set_pen=true);
    void draw_peaks (wxDC& dc, Sum const* sum, bool set_pen=true);
    void draw_peaktops (wxDC& dc, Sum const* sum);
    void draw_peaktop_selection(wxDC& dc, Sum const* sum);
    void draw_plabels (wxDC& dc, Sum const* sum, bool set_pen=true);
    void draw_dataset(wxDC& dc, int n, bool set_pen=true);
    void prepare_peaktops(Sum const* sum, int Ymax);
    void prepare_peak_labels(Sum const* sum);
    void look_for_peaktop (wxMouseEvent& event);
    void show_peak_menu (wxMouseEvent &event);
    void peak_draft (MouseActEnum ma, int X_=0, int Y_=0);
    bool draw_moving_func(MouseActEnum ma, int X=0, int Y=0, bool shift=false);
    void draw_peak_draft (int X_mid, int X_hwhm, int Y);
    void draw_temporary_rect(MouseActEnum ma, int X_=0, int Y_=0);
    void draw_rect (int X1, int Y1, int X2, int Y2);
    bool visible_peaktops(MouseModeEnum mode);
    void add_peak_from_draft(int X, int Y);
    bool can_disactivate();

    DECLARE_EVENT_TABLE()
};

class ConfigureAxesDlg: public wxDialog
{
public:
    ConfigureAxesDlg(wxWindow* parent, wxWindowID id, MainPlot* plot_);
    void OnApply (wxCommandEvent& event);
    void OnClose (wxCommandEvent&) { close_it(this); }
    void OnChangeColor (wxCommandEvent&) { change_color_dlg(axis_color); }
    void OnChangeFont (wxCommandEvent& event); 
private:
    MainPlot *plot;
    wxColour axis_color;
    wxCheckBox *x_show_axis, *x_show_tics, *x_show_minor_tics, 
               *x_show_grid, *x_reversed_cb, *x_logarithm_cb; 
    wxCheckBox *y_show_axis, *y_show_tics, *y_show_minor_tics, 
               *y_show_grid, *y_reversed_cb, *y_logarithm_cb; 
    wxSpinCtrl *x_max_tics, *x_tics_size;
    wxSpinCtrl *y_max_tics, *y_tics_size;
    DECLARE_EVENT_TABLE()
};


class ConfigurePLabelsDlg: public wxDialog
{
public:
    ConfigurePLabelsDlg(wxWindow* parent, wxWindowID id, MainPlot* plot_);
    void OnApply (wxCommandEvent& event);
    void OnClose (wxCommandEvent&) { close_it(this); }
    void OnChangeLabelFont (wxCommandEvent& event); 
    void OnChangeLabelText (wxCommandEvent& event); 
    void OnCheckShowLabel (wxCommandEvent& event); 
    void OnRadioLabel (wxCommandEvent& event); 
private:
    MainPlot *plot;
    bool in_onradiolabel;
    wxCheckBox *show_plabels;
    wxRadioBox *label_radio, *vertical_rb;
    wxTextCtrl *label_text;
    DECLARE_EVENT_TABLE()
};


#endif