// This file is part of fityk program. Copyright (C) Marcin Wojdyr
// Licence: GNU General Public License version 2
// $Id: sidebar.cpp 345 2007-08-21 01:09:15Z wojdyr $
/// In this file:
/// SideBar class, the right hand sidebar in GUI
#include <wx/wxprec.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/imaglist.h>
#include "sidebar.h"
#include "fancyrc.h"
#include "listptxt.h"
#include "gradient.h"
#include "cmn.h" //SpinCtrl, ProportionalSplitter, change_color_dlg, ...
#include "gui.h" //frame
#include "mplot.h"
#include "../common.h" //vector4, join_vector, S(), ...
#include "../ui.h"
#include "../logic.h"
#include "../data.h"
#include "../sum.h"
#include "../func.h"
#include "img/add.xpm"
#include "img/sum.xpm"
#include "img/rename.xpm"
#include "img/close.xpm"
#include "img/colorsel.xpm"
#include "img/editf.xpm"
#include "img/filter.xpm"
#include "img/shiftup.xpm"
#include "img/dpsize.xpm"
#include "img/convert.xpm"
#include "img/copyfunc.xpm"
#include "img/unused.xpm"
#include "img/zshift.xpm"
using namespace std;
enum {
ID_DP_LIST = 27500 ,
ID_DP_LOOK ,
ID_DP_PSIZE ,
ID_DP_PLINE ,
ID_DP_PS ,
ID_DP_SHIFTUP ,
ID_DP_NEW ,
ID_DP_DUP ,
ID_DP_REN ,
ID_DP_DEL ,
ID_DP_CPF ,
ID_DP_COL ,
ID_FP_FILTER ,
ID_FP_LIST ,
ID_FP_NEW ,
ID_FP_DEL ,
ID_FP_EDIT ,
ID_FP_CHTYPE ,
ID_FP_COL ,
ID_VP_LIST ,
ID_VP_NEW ,
ID_VP_DEL ,
ID_VP_EDIT
};
//===============================================================
// SideBar
//===============================================================
void add_bitmap_button(wxWindow* parent, wxWindowID id, char** xpm,
wxString const& tip, wxSizer* sizer)
{
wxBitmapButton *btn = new wxBitmapButton(parent, id, wxBitmap(xpm));
btn->SetToolTip(tip);
sizer->Add(btn);
}
BEGIN_EVENT_TABLE(SideBar, ProportionalSplitter)
EVT_BUTTON (ID_DP_NEW, SideBar::OnDataButtonNew)
EVT_BUTTON (ID_DP_DUP, SideBar::OnDataButtonDup)
EVT_BUTTON (ID_DP_REN, SideBar::OnDataButtonRen)
EVT_BUTTON (ID_DP_DEL, SideBar::OnDataButtonDel)
EVT_BUTTON (ID_DP_CPF, SideBar::OnDataButtonCopyF)
EVT_BUTTON (ID_DP_COL, SideBar::OnDataButtonCol)
EVT_CHOICE (ID_DP_LOOK, SideBar::OnDataLookChanged)
EVT_SPINCTRL (ID_DP_PSIZE, SideBar::OnDataPSizeChanged)
EVT_CHECKBOX (ID_DP_PLINE, SideBar::OnDataPLineChanged)
EVT_CHECKBOX (ID_DP_PS, SideBar::OnDataPSChanged)
EVT_SPINCTRL (ID_DP_SHIFTUP, SideBar::OnDataShiftUpChanged)
EVT_LIST_ITEM_SELECTED(ID_DP_LIST, SideBar::OnDataFocusChanged)
EVT_LIST_ITEM_DESELECTED(ID_DP_LIST, SideBar::OnDataFocusChanged)
EVT_LIST_ITEM_FOCUSED(ID_DP_LIST, SideBar::OnDataFocusChanged)
EVT_CHOICE (ID_FP_FILTER, SideBar::OnFuncFilterChanged)
EVT_BUTTON (ID_FP_NEW, SideBar::OnFuncButtonNew)
EVT_BUTTON (ID_FP_DEL, SideBar::OnFuncButtonDel)
EVT_BUTTON (ID_FP_EDIT, SideBar::OnFuncButtonEdit)
EVT_BUTTON (ID_FP_CHTYPE, SideBar::OnFuncButtonChType)
EVT_BUTTON (ID_FP_COL, SideBar::OnFuncButtonCol)
EVT_LIST_ITEM_FOCUSED(ID_FP_LIST, SideBar::OnFuncFocusChanged)
EVT_BUTTON (ID_VP_NEW, SideBar::OnVarButtonNew)
EVT_BUTTON (ID_VP_DEL, SideBar::OnVarButtonDel)
EVT_BUTTON (ID_VP_EDIT, SideBar::OnVarButtonEdit)
EVT_LIST_ITEM_FOCUSED(ID_VP_LIST, SideBar::OnVarFocusChanged)
END_EVENT_TABLE()
SideBar::SideBar(wxWindow *parent, wxWindowID id)
: ProportionalSplitter(parent, id, 0.75), bp_func(0), active_function(-1)
{
//wxPanel *upper = new wxPanel(this, -1);
//wxBoxSizer *upper_sizer = new wxBoxSizer(wxVERTICAL);
nb = new wxNotebook(this, -1);
//upper_sizer->Add(nb, 1, wxEXPAND);
//upper->SetSizerAndFit(upper_sizer);
bottom_panel = new wxPanel(this, -1);
SplitHorizontally(nb, bottom_panel);
//----- data page -----
data_page = new wxPanel(nb, -1);
wxBoxSizer *data_sizer = new wxBoxSizer(wxVERTICAL);
d = new DataListPlusText(data_page, -1, ID_DP_LIST,
vector4(pair<string,int>("No", 43),
pair<string,int>("#F+#Z", 43),
pair<string,int>("Name", 108),
pair<string,int>("File", 0)));
d->list->set_side_bar(this);
data_sizer->Add(d, 1, wxEXPAND|wxALL, 1);
wxBoxSizer *data_look_sizer = new wxBoxSizer(wxHORIZONTAL);
wxArrayString choices;
choices.Add(wxT("show all datasets"));
choices.Add(wxT("show only selected"));
choices.Add(wxT("shadow unselected"));
choices.Add(wxT("hide all"));
data_look = new wxChoice(data_page, ID_DP_LOOK,
wxDefaultPosition, wxDefaultSize, choices);
data_look_sizer->Add(data_look, 1, wxEXPAND);
data_sizer->Add(data_look_sizer, 0, wxEXPAND);
wxBoxSizer *data_spin_sizer = new wxBoxSizer(wxHORIZONTAL);
// point-size spin button
data_spin_sizer->Add(new wxStaticBitmap(data_page, -1,
wxBitmap(dpsize_xpm)),
0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5);
dpsize_sc = new SpinCtrl(data_page, ID_DP_PSIZE, 1, 1, 8, 40);
dpsize_sc->SetToolTip(wxT("data point size"));
data_spin_sizer->Add(dpsize_sc, 0);
// line between points
dpline_cb = new wxCheckBox(data_page, ID_DP_PLINE, wxT("line"));
dpline_cb->SetToolTip(wxT("line between data points"));
data_spin_sizer->Add(dpline_cb, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5);
// line between points
dpsigma_cb = new wxCheckBox(data_page, ID_DP_PS, wxT("s"));
dpsigma_cb->SetToolTip(wxT("show std. dev. of y (sigma)"));
data_spin_sizer->Add(dpsigma_cb, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5);
// shift-up spin button
data_spin_sizer->AddStretchSpacer();
data_spin_sizer->Add(new wxStaticBitmap(data_page, -1,
wxBitmap(shiftup_xpm)),
0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5);
shiftup_sc = new SpinCtrl(data_page, ID_DP_SHIFTUP, 0, 0, 80, 40);
shiftup_sc->SetToolTip(wxT("shift up (in \% of plot height)"));
data_spin_sizer->Add(shiftup_sc, 0);
data_sizer->Add(data_spin_sizer, 0, wxEXPAND);
wxBoxSizer *data_buttons_sizer = new wxBoxSizer(wxHORIZONTAL);
add_bitmap_button(data_page, ID_DP_COL, colorsel_xpm,
wxT("change color"), data_buttons_sizer);
add_bitmap_button(data_page, ID_DP_NEW, add_xpm,
wxT("new data"), data_buttons_sizer);
add_bitmap_button(data_page, ID_DP_DUP, sum_xpm,
wxT("duplicate/sum"), data_buttons_sizer);
add_bitmap_button(data_page, ID_DP_CPF, copyfunc_xpm,
wxT("copy F to next dataset"), data_buttons_sizer);
add_bitmap_button(data_page, ID_DP_REN, rename_xpm,
wxT("rename"), data_buttons_sizer);
add_bitmap_button(data_page, ID_DP_DEL, close_xpm,
wxT("delete"), data_buttons_sizer);
data_sizer->Add(data_buttons_sizer, 0, wxEXPAND);
data_page->SetSizerAndFit(data_sizer);
nb->AddPage(data_page, wxT("data"));
//----- functions page -----
func_page = new wxPanel(nb, -1);
wxBoxSizer *func_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *func_filter_sizer = new wxBoxSizer(wxHORIZONTAL);
func_filter_sizer->Add(new wxStaticBitmap(func_page, -1,
wxBitmap(filter_xpm)),
0, wxALIGN_CENTER_VERTICAL);
filter_ch = new wxChoice(func_page, ID_FP_FILTER,
wxDefaultPosition, wxDefaultSize, 0, 0);
filter_ch->Append(wxT("list all functions"));
filter_ch->Select(0);
func_filter_sizer->Add(filter_ch, 1, wxEXPAND);
func_sizer->Add(func_filter_sizer, 0, wxEXPAND);
vector<pair<string,int> > fdata;
fdata.push_back( pair<string,int>("Name", 54) );
fdata.push_back( pair<string,int>("Type", 80) );
fdata.push_back( pair<string,int>("Center", 60) );
fdata.push_back( pair<string,int>("Area", 0) );
fdata.push_back( pair<string,int>("Height", 0) );
fdata.push_back( pair<string,int>("FWHM", 0) );
f = new ListPlusText(func_page, -1, ID_FP_LIST, fdata);
f->list->set_side_bar(this);
func_sizer->Add(f, 1, wxEXPAND|wxALL, 1);
wxBoxSizer *func_buttons_sizer = new wxBoxSizer(wxHORIZONTAL);
add_bitmap_button(func_page, ID_FP_NEW, add_xpm,
wxT("new function"), func_buttons_sizer);
add_bitmap_button(func_page, ID_FP_DEL, close_xpm,
wxT("delete"), func_buttons_sizer);
add_bitmap_button(func_page, ID_FP_EDIT, editf_xpm,
wxT("edit function"), func_buttons_sizer);
add_bitmap_button(func_page, ID_FP_CHTYPE, convert_xpm,
wxT("change type of function"), func_buttons_sizer);
add_bitmap_button(func_page, ID_FP_COL, colorsel_xpm,
wxT("change color"), func_buttons_sizer);
func_sizer->Add(func_buttons_sizer, 0, wxEXPAND);
func_page->SetSizerAndFit(func_sizer);
nb->AddPage(func_page, wxT("functions"));
//----- variables page -----
var_page = new wxPanel(nb, -1);
wxBoxSizer *var_sizer = new wxBoxSizer(wxVERTICAL);
vector<pair<string,int> > vdata = vector4(
pair<string,int>("Name", 52),
pair<string,int>("#/#", 72),
pair<string,int>("value", 70),
pair<string,int>("formula", 0) );
v = new ListPlusText(var_page, -1, ID_VP_LIST, vdata);
v->list->set_side_bar(this);
var_sizer->Add(v, 1, wxEXPAND|wxALL, 1);
wxBoxSizer *var_buttons_sizer = new wxBoxSizer(wxHORIZONTAL);
add_bitmap_button(var_page, ID_VP_NEW, add_xpm,
wxT("new variable"), var_buttons_sizer);
add_bitmap_button(var_page, ID_VP_DEL, close_xpm,
wxT("delete"), var_buttons_sizer);
add_bitmap_button(var_page, ID_VP_EDIT, editf_xpm,
wxT("edit variable"), var_buttons_sizer);
var_sizer->Add(var_buttons_sizer, 0, wxEXPAND);
var_page->SetSizerAndFit(var_sizer);
nb->AddPage(var_page, wxT("variables"));
//-----
wxBoxSizer* bp_topsizer = new wxBoxSizer(wxVERTICAL);
bp_label = new wxStaticText(bottom_panel, -1, wxT(""),
wxDefaultPosition, wxDefaultSize,
wxST_NO_AUTORESIZE|wxALIGN_CENTRE);
bp_topsizer->Add(bp_label, 0, wxEXPAND|wxALL, 5);
bp_sizer = new wxFlexGridSizer(2, 0, 0);
bp_sizer->AddGrowableCol(1);
bp_topsizer->Add(bp_sizer, 1, wxEXPAND);
bottom_panel->SetSizer(bp_topsizer);
bottom_panel->SetAutoLayout(true);
}
void SideBar::OnDataButtonNew (wxCommandEvent&)
{
ftk->exec("@+");
frame->refresh_plots(false, true);
}
void SideBar::OnDataButtonDup (wxCommandEvent&)
{
ftk->exec("@+ = sum_same_x " + join_vector(d->get_selected_data(), " + "));
frame->refresh_plots(false, true);
}
void SideBar::OnDataButtonRen (wxCommandEvent&)
{
int n = get_focused_data();
Data *data = ftk->get_data(n);
wxString old_title = s2wx(data->get_title());
wxString s = wxGetTextFromUser(
wxString::Format(wxT("New name for dataset @%i"), n),
wxT("Rename dataset"),
old_title);
if (!s.IsEmpty() && s != old_title)
ftk->exec("@" + S(n) + ".title = '" + wx2s(s) + "'");
}
void SideBar::delete_selected_items()
{
int n = nb->GetSelection();
if (n < 0)
return;
string txt = wx2s(nb->GetPageText(n));
if (txt == "data") {
ftk->exec("delete " + join_vector(d->get_selected_data(), ", "));
frame->refresh_plots(false, true);
}
else if (txt == "functions")
ftk->exec("delete " + join_vector(get_selected_func(), ", "));
else if (txt == "variables")
ftk->exec("delete " + join_vector(get_selected_vars(), ", "));
else
assert(0);
}
void SideBar::OnDataButtonCopyF (wxCommandEvent&)
{
int n = get_focused_data();
if (n+1 >= ftk->get_ds_count())
return;
d->list->Select(n, false);
d->list->Select(n+1, true);
d->list->Focus(n+1);
DataFocusChanged();
string cmd = "@" + S(n+1) + ".F=copy(@" + S(n) + ".F)";
if (!ftk->get_sum(n)->get_zz_names().empty()
|| !ftk->get_sum(n+1)->get_zz_names().empty())
cmd += "; @" + S(n+1) + ".Z=copy(@" + S(n) + ".Z)";
ftk->exec(cmd);
}
void SideBar::OnDataButtonCol (wxCommandEvent&)
{
int sel_size = d->list->GetSelectedItemCount();
if (sel_size == 0)
return;
else if (sel_size == 1) {
int n = d->list->GetFirstSelected();
wxColour col = frame->get_main_plot()->get_data_color(n);
if (change_color_dlg(col)) {
frame->get_main_plot()->set_data_color(n, col);
update_lists();
frame->refresh_plots(false, true);
}
}
else {//sel_size > 1
vector<string> sel = d->get_selected_data();
int first_sel = d->list->GetFirstSelected();
int last_sel = 0;
for (int i = first_sel; i != -1; i = d->list->GetNextSelected(i))
last_sel = i;
wxColour first_col = frame->get_main_plot()->get_data_color(first_sel);
wxColour last_col = frame->get_main_plot()->get_data_color(last_sel);
GradientDlgWithApply<SideBar> gd(this, -1, first_col, last_col,
this, &SideBar::OnDataColorsChanged);
gd.ShowModal();
}
}
void SideBar::OnDataColorsChanged(GradientDlg *gd)
{
vector<int> selected;
for (int i = d->list->GetFirstSelected(), c = 0; i != -1;
i = d->list->GetNextSelected(i), ++c) {
selected.push_back(i);
wxColour col = gd->get_value(c / (d->list->GetSelectedItemCount()-1.));
frame->get_main_plot()->set_data_color(i, col);
}
update_lists();
frame->refresh_plots(false, true);
for (vector<int>::const_iterator i = selected.begin();
i != selected.end(); ++i)
for (int i = 0; i != d->list->GetItemCount(); ++i)
d->list->Select(i, contains_element(selected, i));
}
void SideBar::OnDataLookChanged (wxCommandEvent&)
{
frame->refresh_plots(false, true);
}
void SideBar::OnDataShiftUpChanged (wxSpinEvent&)
{
frame->refresh_plots(false, true);
}
void SideBar::OnDataPSizeChanged (wxSpinEvent& event)
{
//for (int i = d->list->GetFirstSelected(); i != -1;
// i = d->list->GetNextSelected(i))
// frame->get_main_plot()->set_data_point_size(i, event.GetPosition());
// now it is set globally
frame->get_main_plot()->set_data_point_size(0, event.GetPosition());
frame->refresh_plots(false, true);
}
void SideBar::OnDataPLineChanged (wxCommandEvent& event)
{
frame->get_main_plot()->set_data_with_line(0, event.IsChecked());
frame->refresh_plots(false, true);
}
void SideBar::OnDataPSChanged (wxCommandEvent& event)
{
frame->get_main_plot()->set_data_with_sigma(0, event.IsChecked());
frame->refresh_plots(false, true);
}
void SideBar::OnFuncFilterChanged (wxCommandEvent&)
{
update_lists(false);
}
void SideBar::OnFuncButtonNew (wxCommandEvent&)
{
string peak_type = frame->get_peak_type();
string formula = Function::get_formula(peak_type);
vector<string> varnames = Function::get_varnames_from_formula(formula);
string t = "%put_name_here = " + peak_type + "("
+ join_vector(varnames, "= , ") + "= )";
frame->edit_in_input(t);
}
void SideBar::OnFuncButtonEdit (wxCommandEvent&)
{
if (!bp_func)
return;
string t = bp_func->get_current_assignment(ftk->get_variables(),
ftk->get_parameters());
frame->edit_in_input(t);
}
void SideBar::OnFuncButtonChType (wxCommandEvent&)
{
ftk->warn("Sorry. Changing type of function is not implemented yet.");
}
void SideBar::OnFuncButtonCol (wxCommandEvent&)
{
vector<int> const& ffi
= ftk->get_sum(ftk->get_active_ds_position())->get_ff_idx();
vector<int>::const_iterator in_ff = find(ffi.begin(), ffi.end(),
active_function);
if (in_ff == ffi.end())
return;
int color_id = in_ff - ffi.begin();
wxColour col = frame->get_main_plot()->get_func_color(color_id);
if (change_color_dlg(col)) {
frame->get_main_plot()->set_func_color(color_id, col);
update_lists();
frame->refresh_plots(false, true);
}
}
void SideBar::OnVarButtonNew (wxCommandEvent&)
{
frame->edit_in_input("$put_name_here = ");
}
void SideBar::OnVarButtonEdit (wxCommandEvent&)
{
int n = get_focused_var();
if (n < 0 || n >= size(ftk->get_variables()))
return;
Variable const* var = ftk->get_variable(n);
string t = var->xname + " = "+ var->get_formula(ftk->get_parameters());
frame->edit_in_input(t);
}
void SideBar::read_settings(wxConfigBase *cf)
{
cf->SetPath(wxT("/SideBar"));
d->split(cfg_read_double(cf, wxT("dataProportion"), 0.75));
f->split(cfg_read_double(cf, wxT("funcProportion"), 0.75));
v->split(cfg_read_double(cf, wxT("varProportion"), 0.75));
data_look->Select(cf->Read(wxT("dataLook"), 0L));
}
void SideBar::save_settings(wxConfigBase *cf) const
{
cf->SetPath(wxT("/SideBar"));
cf->Write(wxT("dataProportion"), d->GetProportion());
cf->Write(wxT("funcProportion"), f->GetProportion());
cf->Write(wxT("varProportion"), v->GetProportion());
cf->Write(wxT("dataLook"), data_look->GetSelection());
}
void SideBar::update_lists(bool nondata_changed)
{
Freeze();
d->update_data_list(nondata_changed, true);
update_func_list(nondata_changed);
update_var_list();
//-- enable/disable buttons
bool not_the_last = get_focused_data()+1 < ftk->get_ds_count();
data_page->FindWindow(ID_DP_CPF)->Enable(not_the_last);
bool has_any_funcs = (f->list->GetItemCount() > 0);
func_page->FindWindow(ID_FP_DEL)->Enable(has_any_funcs);
func_page->FindWindow(ID_FP_EDIT)->Enable(has_any_funcs);
func_page->FindWindow(ID_FP_CHTYPE)->Enable(has_any_funcs);
func_page->FindWindow(ID_FP_COL)->Enable(has_any_funcs);
bool has_any_vars = (v->list->GetItemCount() > 0);
var_page->FindWindow(ID_VP_DEL)->Enable(has_any_vars);
var_page->FindWindow(ID_VP_EDIT)->Enable(has_any_vars);
int n = get_focused_data();
dpline_cb->SetValue(frame->get_main_plot()->get_data_with_line(n));
dpsize_sc->SetValue(frame->get_main_plot()->get_data_point_size(n));
update_data_inf();
update_func_inf();
update_var_inf();
update_bottom_panel();
Thaw();
}
void SideBar::update_func_list(bool nondata_changed)
{
MainPlot const* mplot = frame->get_main_plot();
wxColour const& bg_col = mplot->get_bg_color();
//functions filter
while ((int) filter_ch->GetCount() > ftk->get_ds_count() + 1)
filter_ch->Delete(filter_ch->GetCount()-1);
for (int i = filter_ch->GetCount() - 1; i < ftk->get_ds_count(); ++i)
filter_ch->Append(wxString::Format(wxT("only functions from @%i"), i));
//functions
static vector<int> func_col_id;
static int old_func_size;
vector<string> func_data;
vector<int> new_func_col_id;
int active_ds_pos = ftk->get_active_ds_position();
Sum const* sum = ftk->get_sum(active_ds_pos);
Sum const* filter_sum = 0;
if (filter_ch->GetSelection() > 0)
filter_sum = ftk->get_sum(filter_ch->GetSelection()-1);
int func_size = ftk->get_functions().size();
if (active_function == -1)
active_function = func_size - 1;
else {
if (active_function >= func_size ||
ftk->get_function(active_function) != bp_func)
active_function = ftk->find_function_nr(active_function_name);
if (active_function == -1 || func_size == old_func_size+1)
active_function = func_size - 1;
}
if (active_function != -1)
active_function_name = ftk->get_function(active_function)->name;
else
active_function_name = "";
int pos = -1;
for (int i = 0; i < func_size; ++i) {
if (filter_sum && !contains_element(filter_sum->get_ff_idx(), i)
&& !contains_element(filter_sum->get_zz_idx(), i))
continue;
if (i == active_function)
pos = new_func_col_id.size();
Function const* f = ftk->get_function(i);
func_data.push_back(f->name);
func_data.push_back(f->type_name);
func_data.push_back(f->has_center() ? S(f->center()).c_str() : "-");
func_data.push_back(f->has_area() ? S(f->area()).c_str() : "-");
func_data.push_back(f->has_height() ? S(f->height()).c_str() : "-");
func_data.push_back(f->has_fwhm() ? S(f->fwhm()).c_str() : "-");
vector<int> const& ffi = sum->get_ff_idx();
vector<int> const& zzi = sum->get_zz_idx();
vector<int>::const_iterator in_ff = find(ffi.begin(), ffi.end(), i);
int color_id = -2;
if (in_ff != ffi.end())
color_id = in_ff - ffi.begin();
else if (find(zzi.begin(), zzi.end(), i) != zzi.end())
color_id = -1;
new_func_col_id.push_back(color_id);
}
wxImageList* func_images = 0;
if (nondata_changed || func_col_id != new_func_col_id) {
func_col_id = new_func_col_id;
func_images = new wxImageList(16, 16);
for (vector<int>::const_iterator i = func_col_id.begin();
i != func_col_id.end(); ++i) {
if (*i == -2)
func_images->Add(wxBitmap(unused_xpm));
else if (*i == -1)
func_images->Add(wxBitmap(zshift_xpm));
else
func_images->Add(make_color_bitmap16(mplot->get_func_color(*i),
bg_col));
}
}
old_func_size = func_size;
f->list->populate(func_data, func_images, pos);
}
void SideBar::update_var_list()
{
vector<string> var_data;
// count references first
vector<Variable*> const& variables = ftk->get_variables();
vector<int> var_vrefs(variables.size(), 0), var_frefs(variables.size(), 0);
for (vector<Variable*>::const_iterator i = variables.begin();
i != variables.end(); ++i) {
for (int j = 0; j != (*i)->get_vars_count(); ++j)
var_vrefs[(*i)->get_var_idx(j)]++;
}
for (vector<Function*>::const_iterator i = ftk->get_functions().begin();
i != ftk->get_functions().end(); ++i) {
for (int j = 0; j != (*i)->get_vars_count(); ++j)
var_frefs[(*i)->get_var_idx(j)]++;
}
for (int i = 0; i < size(variables); ++i) {
Variable const* v = variables[i];
var_data.push_back(v->name); //name
string refs = S(var_frefs[i]) + "+" + S(var_vrefs[i]) + " / "
+ S(v->get_vars_count());
var_data.push_back(refs); //refs
var_data.push_back(S(v->get_value())); //value
var_data.push_back(v->get_formula(ftk->get_parameters())); //formula
}
v->list->populate(var_data);
}
int SideBar::get_focused_data() const
{
int n = d->list->GetFocusedItem();
return n == -1 ? 0 : n;
}
int SideBar::get_focused_var() const
{
if (ftk->get_variables().empty())
return -1;
else {
int n = v->list->GetFocusedItem();
return n > 0 ? n : 0;
}
}
//bool SideBar::is_func_selected(int n) const
//{
// return f->list->IsSelected(n) || f->list->GetFocusedItem() == n;
//}
//
void SideBar::activate_function(int n)
{
active_function = n;
do_activate_function();
int pos = n;
if (filter_ch->GetSelection() > 0)
pos = f->list->FindItem(-1, s2wx(active_function_name));
f->list->Focus(pos);
for (int i = 0; i != f->list->GetItemCount(); ++i)
f->list->Select(i, i==pos);
}
void SideBar::do_activate_function()
{
if (active_function != -1)
active_function_name = ftk->get_function(active_function)->name;
else
active_function_name = "";
frame->refresh_plots(false, true);
update_func_inf();
update_bottom_panel();
}
void SideBar::DataFocusChanged()
{
int n = d->list->GetFocusedItem();
if (n < 0)
return;
int length = ftk->get_ds_count();
if (length > 1 && ftk->get_active_ds_position() != n)
ftk->exec("plot .. in @" + S(n));
data_page->FindWindow(ID_DP_CPF)->Enable(n+1<length);
}
string SideBar::get_datasets_str()
{
if (data_look->GetSelection() == 0) // all datasets
return "@*";
else { // only selected datasets
int first = d->list->GetFirstSelected();
if (first == -1)
return frame->get_active_data_str();
string s = "@" + S(first);
for (int i = d->list->GetNextSelected(first); i != -1;
i = d->list->GetNextSelected(i))
s += ", @" + S(i);
return s;
}
}
void SideBar::update_data_inf()
{
int n = get_focused_data();
if (n < 0)
return;
wxTextCtrl* inf = d->inf;
inf->Clear();
wxTextAttr defattr = inf->GetDefaultStyle();
wxFont font = defattr.GetFont();
wxTextAttr boldattr = defattr;
font.SetWeight(wxFONTWEIGHT_BOLD);
boldattr.SetFont(font);
inf->SetDefaultStyle(boldattr);
inf->AppendText(s2wx("@" + S(n) + "\n"));
inf->SetDefaultStyle(defattr);
inf->AppendText(s2wx(ftk->get_data(n)->get_info()));
wxFileName fn(s2wx(ftk->get_data(n)->get_filename()));
if (fn.IsOk() && !fn.IsAbsolute())
inf->AppendText(wxT("\nPath: ") + fn.MakeAbsolute());
inf->ShowPosition(0);
}
void SideBar::update_func_inf()
{
wxTextCtrl* inf = f->inf;
inf->Clear();
if (active_function < 0)
return;
wxTextAttr defattr = inf->GetDefaultStyle();
wxFont font = defattr.GetFont();
wxTextAttr boldattr = defattr;
font.SetWeight(wxFONTWEIGHT_BOLD);
boldattr.SetFont(font);
Function const* func = ftk->get_function(active_function);
inf->SetDefaultStyle(boldattr);
inf->AppendText(s2wx(func->xname));
inf->SetDefaultStyle(defattr);
if (func->has_center())
inf->AppendText(wxT("\nCenter: ") + s2wx(S(func->center())));
if (func->has_area())
inf->AppendText(wxT("\nArea: ") + s2wx(S(func->area())));
if (func->has_height())
inf->AppendText(wxT("\nHeight: ") + s2wx(S(func->height())));
if (func->has_fwhm())
inf->AppendText(wxT("\nFWHM: ") + s2wx(S(func->fwhm())));
if (func->has_iwidth())
inf->AppendText(wxT("\nInt. Width: ") + s2wx(S(func->iwidth())));
if (func->has_other_props())
inf->AppendText(wxT("\n") + s2wx(func->other_props_str()));
vector<string> in;
for (int i = 0; i < ftk->get_ds_count(); ++i) {
if (contains_element(ftk->get_sum(i)->get_ff_idx(), active_function))
in.push_back("@" + S(i) + ".F");
if (contains_element(ftk->get_sum(i)->get_zz_idx(), active_function))
in.push_back("@" + S(i) + ".Z");
}
if (!in.empty())
inf->AppendText(s2wx("\nIn: " + join_vector(in, ", ")));
inf->ShowPosition(0);
}
void SideBar::update_var_inf()
{
wxTextCtrl* inf = v->inf;
inf->Clear();
int n = get_focused_var();
if (n < 0)
return;
wxTextAttr defattr = inf->GetDefaultStyle();
wxFont font = defattr.GetFont();
wxTextAttr boldattr = defattr;
font.SetWeight(wxFONTWEIGHT_BOLD);
boldattr.SetFont(font);
Variable const* var = ftk->get_variable(n);
inf->SetDefaultStyle(boldattr);
string t = var->xname + " = " + var->get_formula(ftk->get_parameters());
inf->AppendText(s2wx(t));
inf->SetDefaultStyle(defattr);
vector<string> in = ftk->get_variable_references(var->name);
if (!in.empty())
inf->AppendText(s2wx("\nIn:\n " + join_vector(in, "\n ")));
inf->ShowPosition(0);
}
void SideBar::add_variable_to_bottom_panel(Variable const* var,
string const& tv_name)
{
wxStaticText* name_st = new wxStaticText(bottom_panel, -1, s2wx(tv_name));
bp_sizer->Add(name_st, 0, wxALL|wxALIGN_CENTER_VERTICAL, 1);
bp_statict.push_back(name_st);
if (var->is_simple() || var->is_constant()) {
FancyRealCtrl *frc = new FancyRealCtrl(bottom_panel, -1,
var->get_value(),
s2wx(var->xname),
!var->is_simple(),
make_callback<FancyRealCtrl const*>().V1(this,
&SideBar::on_changing_frc_value),
make_callback<FancyRealCtrl const*>().V1(this,
&SideBar::on_changed_frc_value),
make_callback<FancyRealCtrl const*>().V1(this,
&SideBar::on_toggled_frc_lock));
frc->ConnectToOnKeyDown(wxKeyEventHandler(FFrame::focus_input), frame);
bp_sizer->Add(frc, 1, wxALL|wxEXPAND, 1);
bp_frc.push_back(frc);
}
else {
string t = var->xname + " = " + var->get_formula(ftk->get_parameters());
wxStaticText *var_st = new wxStaticText(bottom_panel, -1, s2wx(t));
bp_sizer->Add(var_st, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 1);
bp_statict.push_back(var_st);
bp_frc.push_back(0);
}
}
/// draw function draft with XOR
void SideBar::on_changing_frc_value(FancyRealCtrl const* frc)
{
vector<fp> p_values(bp_func->nv);
for (int i = 0; i < bp_func->nv; ++i) {
string xname = "$" + bp_func->get_var_name(i);
p_values[i] = wx2s(frc->GetTip()) != xname ? bp_func->get_var_value(i)
: frc->GetValue();
}
frame->get_main_plot()->draw_xor_peak(bp_func, p_values);
}
void SideBar::on_changed_frc_value(FancyRealCtrl const* frc)
{
ftk->exec(wx2s(frc->GetTip()) + " = ~" + wx2s(frc->GetValueStr()));
}
void SideBar::on_toggled_frc_lock(FancyRealCtrl const* frc)
{
string vname = wx2s(frc->GetTip());
ftk->exec(vname + " = " + (frc->IsLocked() ? "{" : "~{") + vname + "}");
}
void SideBar::clear_bottom_panel()
{
for (vector<wxStaticText*>::iterator i = bp_statict.begin();
i != bp_statict.end(); ++i)
(*i)->Destroy();
bp_statict.clear();
for (vector<FancyRealCtrl*>::iterator i = bp_frc.begin();
i != bp_frc.end(); ++i)
if (*i)
(*i)->Destroy();
bp_frc.clear();
bp_label->SetLabel(wxT(""));
bp_sig.clear();
}
vector<bool> SideBar::make_bottom_panel_sig(Function const* func)
{
vector<bool> sig;
for (int i = 0; i < size(func->type_var_names); ++i) {
Variable const* var = ftk->get_variable(func->get_var_idx(i));
sig.push_back(var->is_simple() || var->is_constant());
}
return sig;
}
void SideBar::change_bp_parameter_value(int idx, double value)
{
if (idx < (int)bp_frc.size())
bp_frc[idx]->SetTemporaryValue(value);
}
void SideBar::update_bottom_panel()
{
if (active_function < 0) {
clear_bottom_panel();
bp_func = 0;
return;
}
bottom_panel->Freeze();
bp_func = ftk->get_function(active_function);
wxString new_label = s2wx(bp_func->xname + " : " + bp_func->type_name);
if (bp_label->GetLabel() != new_label)
bp_label->SetLabel(new_label);
vector<bool> sig = make_bottom_panel_sig(bp_func);
if (sig != bp_sig) {
clear_bottom_panel();
bp_sig = sig;
for (int i = 0; i < bp_func->nv; ++i) {
Variable const* var = ftk->get_variable(bp_func->get_var_idx(i));
add_variable_to_bottom_panel(var, bp_func->type_var_names[i]);
}
int sash_pos = GetClientSize().GetHeight() - 3
- bottom_panel->GetSizer()->GetMinSize().GetHeight();
if (sash_pos < GetSashPosition())
SetSashPosition(max(50, sash_pos));
}
else {
vector<wxStaticText*>::iterator st = bp_statict.begin();
for (int i = 0; i < bp_func->nv; ++i) {
string const& t = bp_func->type_var_names[i];
(*st)->SetLabel(s2wx(t));
++st;
Variable const* var = ftk->get_variable(bp_func->get_var_idx(i));
if (var->is_simple() || var->is_constant()) {
bp_frc[i]->SetValue(var->get_value());
bp_frc[i]->SetTip(s2wx(var->xname));
if (bp_frc[i]->IsLocked() != !var->is_simple())
bp_frc[i]->ToggleLock();
}
else {
assert (bp_frc[i] == 0);
string f = var->xname + " = "
+ var->get_formula(ftk->get_parameters());
(*st)->SetLabel(s2wx(f));
++st;
}
}
}
bottom_panel->Layout();
bottom_panel->Thaw();
}
bool SideBar::howto_plot_dataset(int n, bool& shadowed, int& offset) const
{
if (ftk->get_ds_count() != d->list->GetItemCount())
d->update_data_list(true, true);
// choice_idx: 0: "show all datasets"
// 1: "show only selected"
// 2: "shadow unselected"
// 3: "hide all"
int choice_idx = data_look->GetSelection();
bool sel = d->list->IsSelected(n) || d->list->GetFocusedItem() == n;
if ((choice_idx == 1 && !sel) || choice_idx == 3)
return false;
shadowed = (choice_idx == 2 && !sel);
offset = n * shiftup_sc->GetValue();
return true;
}
vector<string> SideBar::get_selected_func() const
{
vector<string> dd;
for (int i = f->list->GetFirstSelected(); i != -1;
i = f->list->GetNextSelected(i))
dd.push_back(ftk->get_function(i)->xname);
if (dd.empty() && f->list->GetItemCount() > 0) {
int n = f->list->GetFocusedItem();
dd.push_back(ftk->get_function(n == -1 ? 0 : n)->xname);
}
return dd;
}
vector<string> SideBar::get_selected_vars() const
{
vector<string> dd;
for (int i = v->list->GetFirstSelected(); i != -1;
i = v->list->GetNextSelected(i))
dd.push_back(ftk->get_variable(i)->xname);
if (dd.empty() && v->list->GetItemCount() > 0) {
int n = v->list->GetFocusedItem();
dd.push_back(ftk->get_function(n == -1 ? 0 : n)->xname);
}
return dd;
}
void SideBar::OnFuncFocusChanged(wxListEvent&)
{
int n = f->list->GetFocusedItem();
if (n == -1)
active_function = -1;
else {
string name = wx2s(f->list->GetItemText(n));
active_function = ftk->find_function_nr(name);
}
do_activate_function();
}
void SideBar::OnVarFocusChanged(wxListEvent&)
{
update_var_inf();
}
syntax highlighted by Code2HTML, v. 0.9.1