448 |
// Create the Tree model: |
// Create the Tree model: |
449 |
m_refTreeModel = Gtk::ListStore::create(m_Columns); |
m_refTreeModel = Gtk::ListStore::create(m_Columns); |
450 |
m_TreeView.set_model(m_refTreeModel); |
m_TreeView.set_model(m_refTreeModel); |
451 |
m_TreeView.set_tooltip_text(_("Right click here for actions on instruments & MIDI Rules.")); |
m_TreeView.set_tooltip_text(_("Right click here for actions on instruments & MIDI Rules. Drag & drop to change the order of instruments.")); |
452 |
instrument_name_connection = m_refTreeModel->signal_row_changed().connect( |
instrument_name_connection = m_refTreeModel->signal_row_changed().connect( |
453 |
sigc::mem_fun(*this, &MainWindow::instrument_name_changed) |
sigc::mem_fun(*this, &MainWindow::instrument_name_changed) |
454 |
); |
); |
456 |
// Add the TreeView's view columns: |
// Add the TreeView's view columns: |
457 |
m_TreeView.append_column_editable("Instrument", m_Columns.m_col_name); |
m_TreeView.append_column_editable("Instrument", m_Columns.m_col_name); |
458 |
m_TreeView.set_headers_visible(false); |
m_TreeView.set_headers_visible(false); |
459 |
|
|
460 |
|
// establish drag&drop within the instrument tree view, allowing to reorder |
461 |
|
// the sequence of instruments within the gig file |
462 |
|
{ |
463 |
|
std::vector<Gtk::TargetEntry> drag_target_instrument; |
464 |
|
drag_target_instrument.push_back(Gtk::TargetEntry("gig::Instrument")); |
465 |
|
m_TreeView.drag_source_set(drag_target_instrument); |
466 |
|
m_TreeView.drag_dest_set(drag_target_instrument); |
467 |
|
m_TreeView.signal_drag_begin().connect( |
468 |
|
sigc::mem_fun(*this, &MainWindow::on_instruments_treeview_drag_begin) |
469 |
|
); |
470 |
|
m_TreeView.signal_drag_data_get().connect( |
471 |
|
sigc::mem_fun(*this, &MainWindow::on_instruments_treeview_drag_data_get) |
472 |
|
); |
473 |
|
m_TreeView.signal_drag_data_received().connect( |
474 |
|
sigc::mem_fun(*this, &MainWindow::on_instruments_treeview_drop_drag_data_received) |
475 |
|
); |
476 |
|
} |
477 |
|
|
478 |
// create samples treeview (including its data model) |
// create samples treeview (including its data model) |
479 |
m_refSamplesTreeModel = SamplesTreeStore::create(m_SamplesModel); |
m_refSamplesTreeModel = SamplesTreeStore::create(m_SamplesModel); |
1911 |
} |
} |
1912 |
} |
} |
1913 |
|
|
1914 |
|
void MainWindow::select_instrument(gig::Instrument* instrument) { |
1915 |
|
if (!instrument) return; |
1916 |
|
|
1917 |
|
Glib::RefPtr<Gtk::TreeModel> model = m_TreeView.get_model(); |
1918 |
|
for (int i = 0; i < model->children().size(); ++i) { |
1919 |
|
Gtk::TreeModel::Row row = model->children()[i]; |
1920 |
|
if (row[m_Columns.m_col_instr] == instrument) { |
1921 |
|
// select and show the respective instrument in the list view |
1922 |
|
show_intruments_tab(); |
1923 |
|
m_TreeView.get_selection()->select(model->children()[i]); |
1924 |
|
Gtk::TreePath path( |
1925 |
|
m_TreeView.get_selection()->get_selected() |
1926 |
|
); |
1927 |
|
m_TreeView.scroll_to_row(path); |
1928 |
|
on_sel_change(); // the regular instrument selection change callback |
1929 |
|
} |
1930 |
|
} |
1931 |
|
} |
1932 |
|
|
1933 |
/// Returns true if requested dimension region was successfully selected and scrolled to in the list view, false on error. |
/// Returns true if requested dimension region was successfully selected and scrolled to in the list view, false on error. |
1934 |
bool MainWindow::select_dimension_region(gig::DimensionRegion* dimRgn) { |
bool MainWindow::select_dimension_region(gig::DimensionRegion* dimRgn) { |
1935 |
gig::Region* pRegion = (gig::Region*) dimRgn->GetParent(); |
gig::Region* pRegion = (gig::Region*) dimRgn->GetParent(); |
2713 |
sizeof(script)/*length of data in bytes*/); |
sizeof(script)/*length of data in bytes*/); |
2714 |
} |
} |
2715 |
|
|
2716 |
|
// see comment on on_sample_treeview_drag_begin() |
2717 |
|
void MainWindow::on_instruments_treeview_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context) |
2718 |
|
{ |
2719 |
|
first_call_to_drag_data_get = true; |
2720 |
|
} |
2721 |
|
|
2722 |
|
void MainWindow::on_instruments_treeview_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&, |
2723 |
|
Gtk::SelectionData& selection_data, guint, guint) |
2724 |
|
{ |
2725 |
|
if (!first_call_to_drag_data_get) return; |
2726 |
|
first_call_to_drag_data_get = false; |
2727 |
|
|
2728 |
|
// get selected source instrument |
2729 |
|
gig::Instrument* src = NULL; |
2730 |
|
{ |
2731 |
|
Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeView.get_selection(); |
2732 |
|
Gtk::TreeModel::iterator it = sel->get_selected(); |
2733 |
|
if (it) { |
2734 |
|
Gtk::TreeModel::Row row = *it; |
2735 |
|
src = row[m_Columns.m_col_instr]; |
2736 |
|
} |
2737 |
|
} |
2738 |
|
if (!src) return; |
2739 |
|
|
2740 |
|
// pass the source gig::Instrument as pointer |
2741 |
|
selection_data.set(selection_data.get_target(), 0/*unused*/, (const guchar*)&src, |
2742 |
|
sizeof(src)/*length of data in bytes*/); |
2743 |
|
} |
2744 |
|
|
2745 |
|
void MainWindow::on_instruments_treeview_drop_drag_data_received( |
2746 |
|
const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, |
2747 |
|
const Gtk::SelectionData& selection_data, guint, guint time) |
2748 |
|
{ |
2749 |
|
gig::Instrument* src = *((gig::Instrument**) selection_data.get_data()); |
2750 |
|
if (!src || selection_data.get_length() != sizeof(gig::Instrument*)) |
2751 |
|
return; |
2752 |
|
|
2753 |
|
gig::Instrument* dst = NULL; |
2754 |
|
{ |
2755 |
|
Gtk::TreeModel::Path path; |
2756 |
|
const bool found = m_TreeView.get_path_at_pos(x, y, path); |
2757 |
|
if (!found) return; |
2758 |
|
|
2759 |
|
Gtk::TreeModel::iterator iter = m_refTreeModel->get_iter(path); |
2760 |
|
if (!iter) return; |
2761 |
|
Gtk::TreeModel::Row row = *iter; |
2762 |
|
dst = row[m_Columns.m_col_instr]; |
2763 |
|
} |
2764 |
|
if (!dst) return; |
2765 |
|
|
2766 |
|
//printf("dragdrop received src=%s dst=%s\n", src->pInfo->Name.c_str(), dst->pInfo->Name.c_str()); |
2767 |
|
src->MoveTo(dst); |
2768 |
|
__refreshEntireGUI(); |
2769 |
|
select_instrument(src); |
2770 |
|
} |
2771 |
|
|
2772 |
// For some reason drag_data_get gets called two times for each |
// For some reason drag_data_get gets called two times for each |
2773 |
// drag'n'drop (at least when target is an Entry). This work-around |
// drag'n'drop (at least when target is an Entry). This work-around |
2774 |
// makes sure the code in drag_data_get and drop_drag_data_received is |
// makes sure the code in drag_data_get and drop_drag_data_received is |