// This file is part of fityk program. Copyright (C) Marcin Wojdyr
// Licence: GNU General Public License version 2
// $Id: mplot.h 326 2007-08-01 05:54:03Z 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
struct t_xy { fp x, y; };
class Function;
class BgManager
{
public:
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; recompute_bgline(); }
void set_as_convex_hull();
protected:
Scale const& x_scale;
int min_dist; //minimal distance in X between bg points
bool spline_bg;
typedef std::vector<PointQ>::iterator bg_iterator;
typedef std::vector<PointQ>::const_iterator bg_const_iterator;
std::vector<PointQ> bg, bg_backup;
std::vector<t_xy> bgline;
std::string cmd_tail;
void recompute_bgline();
};
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, public BgManager
{
friend class ConfigureAxesDlg;
friend class ConfigurePLabelsDlg;
public:
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);
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);
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
syntax highlighted by Code2HTML, v. 0.9.1