// 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 #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #include #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("No", 43), pair("#F+#Z", 43), pair("Name", 108), pair("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 > fdata; fdata.push_back( pair("Name", 54) ); fdata.push_back( pair("Type", 80) ); fdata.push_back( pair("Center", 60) ); fdata.push_back( pair("Area", 0) ); fdata.push_back( pair("Height", 0) ); fdata.push_back( pair("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 > vdata = vector4( pair("Name", 52), pair("#/#", 72), pair("value", 70), pair("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 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 gd(this, -1, first_col, last_col, this, &SideBar::OnDataColorsChanged); gd.ShowModal(); } } void SideBar::OnDataColorsChanged(GradientDlg *gd) { vector 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::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 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 const& ffi = ftk->get_sum(ftk->get_active_ds_position())->get_ff_idx(); vector::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 func_col_id; static int old_func_size; vector func_data; vector 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 const& ffi = sum->get_ff_idx(); vector const& zzi = sum->get_zz_idx(); vector::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::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 var_data; // count references first vector const& variables = ftk->get_variables(); vector var_vrefs(variables.size(), 0), var_frefs(variables.size(), 0); for (vector::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::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+1GetSelection() == 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 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 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().V1(this, &SideBar::on_changing_frc_value), make_callback().V1(this, &SideBar::on_changed_frc_value), make_callback().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 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::iterator i = bp_statict.begin(); i != bp_statict.end(); ++i) (*i)->Destroy(); bp_statict.clear(); for (vector::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 SideBar::make_bottom_panel_sig(Function const* func) { vector 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 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::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 SideBar::get_selected_func() const { vector 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 SideBar::get_selected_vars() const { vector 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(); }