45 const Glib::ustring& tooltip_)
48 plugin(main_.get_machine().pluginlist_lookup_plugin(name)),
57 hidden_by_move(false) {
77 uimanager->remove_ui(merge_id);
102 action->signal_toggled().connect(sigc::mem_fun(*
this, &PluginUI::on_action_toggled));
105 void PluginUI::on_action_toggled() {
109 if (action->get_active()) {
171 for (RackContainer::rackbox_list::iterator i = l.begin(); i != l.end(); ++i, ++n)
192 res = g_utf8_collate(an, bn);
205 insert(pair<std::string, PluginUI*>(p->
get_id(), p));
209 std::map<std::string, PluginUI*>::iterator i = find(p->
get_id());
215 for (std::map<std::string, PluginUI*>::iterator i = begin(); i !=
end(); ++i) {
226 for (std::map<std::string, PluginUI*>::iterator i = begin(); i !=
end(); ++i) {
227 i->second->compress(state);
237 return alpha ? ((guint (src) << 8) - src) / alpha : 0;
241 guint8
const* src_pixel = src;
242 guint8* dst_pixel = dst;
244 for (
int i = 0; i < height*width; ++i) {
248 dst_pixel[3] = src_pixel[3];
256 : window(), drag_icon_pixbuf() {
257 Glib::RefPtr<Gdk::Screen> screen = context->get_source_window()->get_screen();
258 Glib::RefPtr<Gdk::Colormap> rgba = screen->get_rgba_colormap();
259 if (screen->is_composited()) {
260 window =
new Gtk::Window(Gtk::WINDOW_POPUP);
262 window->set_colormap(rgba);
265 create_drag_icon_pixbuf(plugin, rgba, options);
266 int w = drag_icon_pixbuf->get_width();
267 int h = drag_icon_pixbuf->get_height();
271 window->set_size_request(w, h);
272 window->signal_expose_event().connect(sigc::mem_fun(*
this, &DragIcon::icon_expose_event));
274 gtk_drag_set_icon_widget(context->gobj(), GTK_WIDGET(window->gobj()), w2, h2);
276 context->set_icon(drag_icon_pixbuf, w2, h2);
284 bool DragIcon::icon_expose_event(GdkEventExpose *ev) {
285 Cairo::RefPtr<Cairo::Context> cr =
Glib::wrap(ev->window,
true)->create_cairo_context();
286 gdk_cairo_region(cr->cobj(), ev->region);
287 cr->set_operator(Cairo::OPERATOR_SOURCE);
289 Gdk::Cairo::set_source_pixbuf(cr, drag_icon_pixbuf, 0, 0);
295 Gtk::OffscreenWindow w;
296 w.signal_expose_event().connect(sigc::bind(sigc::mem_fun(*
this, &DragIcon::window_expose_event), sigc::ref(w)));
298 w.set_colormap(rgba);
303 w.get_window()->process_updates(
true);
306 static void destroy_data(
const guint8 *data) {
310 bool DragIcon::window_expose_event(GdkEventExpose *event, Gtk::OffscreenWindow& widget) {
311 Cairo::RefPtr<Cairo::Context> cr = widget.get_window()->create_cairo_context();
312 cr->set_operator(Cairo::OPERATOR_SOURCE);
313 cr->set_source_rgba(0,0,0,0);
315 Gtk::Widget *child = widget.get_child();
317 widget.propagate_expose(*child, event);
319 Cairo::RefPtr<Cairo::Surface> x_surf = cr->get_target();
320 int w = gdk_window_get_width(event->window);
321 int h = gdk_window_get_height(event->window);
322 Cairo::RefPtr<Cairo::LinearGradient> grad = Cairo::LinearGradient::create(w, 0, w-gradient_length, 0);
323 grad->add_color_stop_rgba(0, 1, 1, 1, 1);
324 grad->add_color_stop_rgba(1, 1, 1, 1, 0);
325 cr->rectangle(w-gradient_length, 0, gradient_length, h);
327 Cairo::RefPtr<Cairo::ImageSurface> i_surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, w, h);
328 Cairo::RefPtr<Cairo::Context> crt = Cairo::Context::create(i_surf);
329 crt->set_operator(Cairo::OPERATOR_SOURCE);
330 crt->set_source(x_surf, 0, 0);
332 guint8 *data =
new guint8[w*h*4];
334 drag_icon_pixbuf = Gdk::Pixbuf::create_from_data(data, Gdk::COLORSPACE_RGB,
true, 8, w, h, i_surf->get_stride(), sigc::ptr_fun(destroy_data));
343 Glib::RefPtr<Gtk::SizeGroup> MiniRackBox::szg_label;
345 Gtk::Widget *MiniRackBox::make_delete_button(
RackBox& rb) {
347 if (rb.has_delete()) {
348 Gtk::Label *l =
new Gtk::Label(
"\u2a2f");
350 Gtk::Button *b =
new Gtk::Button();
351 b->set_focus_on_click(
false);
353 b->signal_clicked().connect(sigc::bind(sigc::mem_fun(rb.plugin, &
PluginUI::display),
false,
true));
356 w =
new Gtk::Alignment();
358 w->set_size_request(20, 15);
362 bool MiniRackBox::on_my_leave_out(GdkEventCrossing *focus) {
363 if (!mconbox.get_visible()) {
364 Glib::RefPtr<Gdk::Window> window = this->get_window();
365 window->set_cursor();
370 bool MiniRackBox::on_my_enter_in(GdkEventCrossing *focus) {
371 if (!mconbox.get_visible()) {
372 Glib::RefPtr<Gdk::Window> window = this->get_window();
373 Gdk::Cursor cursor(Gdk::HAND1);
374 window->set_cursor(cursor);
386 on_off_switch(
"switchit"),
387 toggle_on_off(rb.
main.get_machine(), &on_off_switch, rb.plugin.plugin->id_on_off()) {
388 if (strcmp(rb.plugin.
get_id(),
"ampstack") != 0) {
392 szg_label = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
394 evbox.set_visible_window(
false);
395 evbox.signal_leave_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_leave_out));
396 evbox.signal_enter_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_enter_in));
399 Gtk::Alignment *al =
new Gtk::Alignment();
400 al->set_padding(0, 4, 0, 0);
401 al->set_border_width(0);
403 evbox.add(*manage(al));
405 Gtk::HBox *box =
new Gtk::HBox();
406 Gtk::HBox *top =
new Gtk::HBox();
407 al->add(*manage(box));
409 this->set_spacing(0);
410 this->set_border_width(0);
413 box->set_border_width(0);
416 top->set_border_width(0);
417 top->set_name(
"rack_unit_title_bar");
419 box->pack_start(*manage(rb.wrap_bar()), Gtk::PACK_SHRINK);
420 box->pack_start(*manage(top));
421 box->pack_start(*manage(rb.wrap_bar()), Gtk::PACK_SHRINK);
423 top->pack_start(on_off_switch, Gtk::PACK_SHRINK);
424 on_off_switch.set_name(
"effect_on_off");
425 Gtk::Widget *effect_label = RackBox::make_label(rb.plugin, options);
426 szg_label->add_widget(*manage(effect_label));
427 top->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
429 top->pack_start(mconbox, Gtk::PACK_EXPAND_WIDGET);
431 mb_expand_button = rb.make_expand_button(
true);
432 top->pack_end(*manage(mb_expand_button), Gtk::PACK_SHRINK);
434 preset_button = rb.make_preset_button();
435 top->pack_end(*manage(preset_button), Gtk::PACK_SHRINK);
437 mb_delete_button = make_delete_button(rb);
438 mb_delete_button->set_no_show_all(
true);
439 top->pack_end(*manage(mb_delete_button), Gtk::PACK_SHRINK);
441 RackBox::szg->add_widget(*al);
443 al->set_size_request(32, -1);
447 szg_label = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
449 evbox.set_visible_window(
false);
450 evbox.signal_leave_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_leave_out));
451 evbox.signal_enter_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_enter_in));
454 Gtk::Alignment *al =
new Gtk::Alignment();
455 al->set_padding(0, 4, 0, 0);
456 al->set_border_width(0);
458 Gtk::HBox *box =
new Gtk::HBox();
459 Gtk::HBox *top =
new Gtk::HBox();
460 evbox.add(*manage(box));
462 top->set_name(
"rack_unit_title_bar");
463 Gtk::Widget *effect_label = RackBox::make_label(rb.plugin, options);
464 szg_label->add_widget(*manage(effect_label));
465 top->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
466 top->pack_start(mconbox, Gtk::PACK_EXPAND_WIDGET);
467 box->pack_start(*manage(al), Gtk::PACK_SHRINK);
468 box->pack_start(*manage(top));
470 RackBox::szg->add_widget(*al);
472 al->set_size_request(64, 32);
480 mconbox.pack_start(*manage(w), Gtk::PACK_SHRINK, 4);
485 evbox.set_above_child(mode);
489 preset_button->hide();
491 if (mb_expand_button) {
492 mb_expand_button->hide();
494 if (mb_delete_button) {
495 mb_delete_button->show();
500 preset_button->show();
502 if (mb_expand_button) {
503 mb_expand_button->show();
505 if (mb_delete_button) {
506 mb_delete_button->hide();
524 void on_ok(Gtk::Entry *e);
525 virtual bool on_key_press_event(GdkEventKey *event);
527 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
const Glib::ustring& save_name_default);
528 InputWindow(BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
const Glib::ustring& save_name_default);
533 Glib::ustring&
get_name() {
return name; }
536 InputWindow *InputWindow::create_from_builder(BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
537 const Glib::ustring& save_name_default) {
538 return new InputWindow(cobject, bld, save_name_default);
545 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(options.
get_builder_filepath(
"pluginpreset_inputwindow.glade"));
547 bld->get_toplevel_derived(
548 "PluginPresetInputWindow", w,
549 sigc::bind(sigc::ptr_fun(InputWindow::create_from_builder), bld, save_name_default));
553 bool InputWindow::on_key_press_event(GdkEventKey *event) {
554 if (event->keyval ==
GDK_KEY_Escape && (event->state & Gtk::AccelGroup::get_default_mod_mask()) == 0) {
558 return Gtk::Window::on_key_press_event(event);
561 void InputWindow::on_ok(Gtk::Entry *e) {
562 name = e->get_text();
566 InputWindow::InputWindow(BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
567 const Glib::ustring& save_name_default)
568 : Gtk::Window(cobject), name() {
570 bld->find_widget(
"cancelbutton", b);
571 b->signal_clicked().connect(
572 sigc::mem_fun(*
this, &InputWindow::hide));
573 bld->find_widget(
"okbutton", b);
575 bld->find_widget(
"entry", e);
576 e->set_text(save_name_default);
577 e->select_region(0, -1);
578 b->signal_clicked().connect(
579 sigc::bind(sigc::mem_fun(*
this, &InputWindow::on_ok), e));
583 Gtk::Main::run(*
this);
594 Gtk::TreeModelColumn<Glib::ustring>
name;
599 set_column_types(
col);
607 Glib::RefPtr<TextListStore> textliststore;
610 Gtk::TreeView *treeview;
611 Gtk::Button *removebutton;
612 using Gtk::Window::on_remove;
614 void on_selection_changed();
615 virtual bool on_key_press_event(GdkEventKey *event);
617 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
PluginPresetPopup& p);
626 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
PluginPresetPopup& p) {
635 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(
638 bld->get_toplevel_derived(
639 "PluginPresetListWindow", w,
640 sigc::bind(sigc::ptr_fun(PluginPresetListWindow::create_from_builder), bld, sigc::ref(p)));
644 bool PluginPresetListWindow::on_key_press_event(GdkEventKey *event) {
645 if (event->keyval ==
GDK_KEY_Escape && (event->state & Gtk::AccelGroup::get_default_mod_mask()) == 0) {
649 return Gtk::Window::on_key_press_event(event);
652 void PluginPresetListWindow::on_remove() {
653 Gtk::TreeIter it = treeview->get_selection()->get_selected();
656 presetlist.
get_pdef(), it->get_value(textliststore->col.name));
657 textliststore->erase(it);
661 PluginPresetListWindow::PluginPresetListWindow(
662 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
PluginPresetPopup& p)
663 : Gtk::Window(cobject),
667 bld->find_widget(
"closebutton", b);
668 b->signal_clicked().connect(
669 sigc::mem_fun(*
this, &PluginPresetListWindow::hide));
670 bld->find_widget(
"removebutton", removebutton);
671 removebutton->signal_clicked().connect(
672 sigc::mem_fun0(*
this, &PluginPresetListWindow::on_remove));
673 bld->find_widget(
"treeview", treeview);
674 for (gx_preset::UnitPresetList::const_iterator i = presetlist.
begin(); i != presetlist.
end(); ++i) {
675 if (i->name.empty()) {
678 textliststore->append()->set_value(textliststore->col.name, i->name);
680 treeview->set_model(textliststore);
681 removebutton->set_sensitive(
false);
682 Glib::RefPtr<Gtk::TreeSelection> sel = treeview->get_selection();
683 sel->signal_changed().connect(
684 sigc::mem_fun(*
this, &PluginPresetListWindow::on_selection_changed));
687 void PluginPresetListWindow::on_selection_changed() {
688 removebutton->set_sensitive(treeview->get_selection()->get_selected());
692 Gtk::Main::run(*
this);
699 void PluginPresetPopup::set_plugin_preset(
bool factory,
const Glib::ustring& name) {
700 if(strcmp(pdef->
id,
"seq")==0) {
707 void PluginPresetPopup::set_plugin_std_preset() {
711 void PluginPresetPopup::save_plugin_preset() {
716 if(strcmp(pdef->
id,
"dubber")==0) {
717 Glib::ustring name =
"";
723 if(strcmp(pdef->
id,
"seq")==0) {
724 Glib::ustring
id =
"seq." + w->
get_name();
733 void PluginPresetPopup::remove_plugin_preset() {
739 bool PluginPresetPopup::add_plugin_preset_list(
bool *found) {
741 bool found_presets =
false;
742 bool factory =
false;
743 for (gx_preset::UnitPresetList::iterator i = presetnames.begin(); i != presetnames.end(); ++i) {
744 if (i->name.empty()) {
747 append(*manage(
new Gtk::SeparatorMenuItem()));
749 found_presets =
false;
753 found_presets =
true;
755 Gtk::CheckMenuItem *c =
new Gtk::CheckMenuItem(i->name);
759 c->signal_activate().connect(
760 sigc::bind(sigc::mem_fun(
this, &PluginPresetPopup::set_plugin_preset), factory, i->name));
763 return found_presets;
772 Glib::signal_idle().connect(
774 sigc::ptr_fun(delete_plugin_preset_popup),
779 const Glib::ustring& save_name_default_)
783 save_name_default(save_name_default_),
787 if (!add_plugin_preset_list(&found_presets)) {
788 Gtk::CheckMenuItem *c =
new Gtk::CheckMenuItem(_(
"standard"));
792 c->signal_activate().connect(
793 sigc::mem_fun(
this, &PluginPresetPopup::set_plugin_std_preset));
796 append(*manage(
new Gtk::SeparatorMenuItem()));
797 Gtk::MenuItem *mi =
new Gtk::MenuItem(_(
"save..."));
799 mi->signal_activate().connect(
800 sigc::mem_fun(
this, &PluginPresetPopup::save_plugin_preset));
802 mi =
new Gtk::MenuItem(_(
"remove..."));
804 mi->signal_activate().connect(
805 sigc::mem_fun(
this, &PluginPresetPopup::remove_plugin_preset));
808 popup(1, gtk_get_current_event_time());
817 Glib::RefPtr<Gtk::SizeGroup> RackBox::szg;
821 pb.set_name(
"rackbox");
822 pb.property_paint_func().set_value(
"gx_rack_unit_shrink_expose");
823 pb.set_border_width(4);
827 pb.set_name(
"rackbox");
828 pb.property_paint_func().set_value(
"gx_rack_unit_expose");
829 pb.set_border_width(4);
839 pb.set_name(
"rackbox");
841 pb.set_border_width(4);
846 Gtk::Label *effect_label =
new Gtk::Label(effect_name);
847 effect_label->set_alignment(0.0, 0.5);
848 effect_label->set_name(
"effect_title");
850 effect_label->set_markup(
"◗◖ " + effect_label->get_label());
855 Gtk::Widget *RackBox::make_bar(
int left,
int right,
bool sens) {
856 Gtk::Alignment *al =
new Gtk::Alignment(0, 0, 1.0, 1.0);
858 Gtk::Button *button =
new Gtk::Button();
859 button->set_size_request(32,-1);
861 button->set_tooltip_text(_(
"Drag'n' Drop Handle"));
862 button->set_relief(Gtk::RELIEF_NONE);
863 button->set_sensitive(sens);
864 al->add(*manage(button));
868 bool RackBox::on_my_leave_out(GdkEventCrossing *focus) {
869 Glib::RefPtr<Gdk::Window> window = this->get_window();
870 window->set_cursor();
874 bool RackBox::on_my_enter_in(GdkEventCrossing *focus) {
875 Glib::RefPtr<Gdk::Window> window = this->get_window();
876 Gdk::Cursor cursor(Gdk::HAND1);
877 window->set_cursor(cursor);
881 bool RackBox::on_my_button_press(GdkEventButton* ev) {
882 if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) {
889 Gtk::Widget *RackBox::wrap_bar(
int left,
int right,
bool sens) {
890 Gtk::EventBox *ev =
new Gtk::EventBox;
891 ev->set_visible_window(
false);
892 ev->set_above_child(
true);
893 ev->add(*manage(make_bar(left, right, sens)));
894 ev->signal_leave_notify_event().connect(sigc::mem_fun(*
this, &RackBox::on_my_leave_out));
895 ev->signal_enter_notify_event().connect(sigc::mem_fun(*
this, &RackBox::on_my_enter_in));
896 ev->signal_button_press_event().connect(sigc::mem_fun(*
this, &RackBox::on_my_button_press));
897 ev->signal_drag_begin().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_begin));
898 ev->signal_drag_end().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_end));
899 ev->signal_drag_data_get().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_data_get));
900 std::vector<Gtk::TargetEntry> listTargets;
901 listTargets.push_back(Gtk::TargetEntry(target, Gtk::TARGET_SAME_APP, 0));
902 ev->drag_source_set(listTargets, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE);
908 RackBox::set_paintbox(*pb, plugin.
get_type());
909 Gtk::Widget *effect_label = RackBox::make_label(plugin, options);
910 Gtk::Alignment *al =
new Gtk::Alignment(0.0, 0.0, 1.0, 1.0);
911 al->set_padding(0,2,2,0);
912 al->add(*manage(effect_label));
913 pb->pack_start(*manage(al), Gtk::PACK_SHRINK);
920 RackBox::set_paintbox_unit_shrink(*pb, plugin.
get_type());
921 pb->set_name(
"drag_widget");
922 if (strcmp(plugin.
get_id(),
"ampstack") == 0) {
923 pb->property_paint_func().set_value(
"gx_rack_amp_expose");
932 Gtk::Widget *effect_label = RackBox::make_label(plugin, options);
933 Gtk::Alignment *al =
new Gtk::Alignment(0.0, 0.0, 0.0, 0.0);
934 al->set_padding(0,0,4,20);
935 al->add(*manage(RackBox::make_bar(4, 4,
true)));
936 pb->pack_start(*manage(al), Gtk::PACK_SHRINK);
938 pb->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
939 al =
new Gtk::Alignment(0.0, 0.0, 0.0, 0.0);
940 al->set_size_request(70,30);
941 pb->pack_start(*manage(al), Gtk::PACK_SHRINK);
947 assert(box_visible != v);
971 : Gtk::VBox(), plugin(plugin_),
main(tl), config_mode(false), anim_tag(),
972 compress(true), delete_button(true), mbox(Gtk::ORIENTATION_HORIZONTAL), minibox(0),
973 fbox(0), target(), anim_height(0), anim_step(), drag_icon(), target_height(0),
974 box(Gtk::ORIENTATION_HORIZONTAL, 2), box_visible(true), on_off_switch(
"switchit"),
975 toggle_on_off(tl.get_machine(), &on_off_switch, plugin.plugin->id_on_off()) {
976 if (strcmp(plugin.
get_id(),
"ampstack") != 0) {
981 szg = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
986 delete_button =
false;
988 set_paintbox_unit_shrink(mbox, plugin.
get_type());
991 mbox.pack_start(*manage(minibox));
992 pack_start(mbox, Gtk::PACK_SHRINK);
996 mbox.property_paint_func().set_value(
"gx_rack_amp_expose");
1000 set_paintbox_unit(*pb, plugin);
1001 pb->pack_start(*manage(make_full_box(tl.
get_options())));
1002 pack_start(*manage(pb), Gtk::PACK_SHRINK);
1008 void RackBox::init_dnd() {
1009 target =
"application/x-guitarix-";
1015 if (!delete_button) {
1018 mbox.signal_drag_begin().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_begin));
1019 mbox.signal_drag_end().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_end));
1020 mbox.signal_drag_data_get().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_data_get));
1023 void RackBox::enable_drag(
bool v) {
1025 std::vector<Gtk::TargetEntry> listTargets;
1026 listTargets.push_back(Gtk::TargetEntry(target, Gtk::TARGET_SAME_APP, 0));
1027 mbox.drag_source_set(listTargets, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE);
1029 mbox.drag_source_unset();
1033 bool RackBox::animate_vanish() {
1034 anim_height -= anim_step;
1035 if (anim_height <= 0) {
1037 set_visibility(
true);
1038 set_size_request(-1,-1);
1042 set_size_request(-1, anim_height);
1047 void RackBox::animate_remove() {
1048 if (!
get_parent()->check_if_animate(*
this)) {
1051 if (anim_tag.connected()) {
1053 anim_tag.disconnect();
1054 set_size_request(-1,-1);
1057 anim_height = size_request().height;
1058 set_size_request(-1, anim_height);
1059 set_visibility(
false);
1060 anim_step = anim_height / 5;
1061 anim_tag = Glib::signal_timeout().connect(sigc::mem_fun(*
this, &RackBox::animate_vanish), 20);
1066 return dynamic_cast<RackContainer*
>(Gtk::VBox::get_parent());
1069 void RackBox::on_my_drag_begin(
const Glib::RefPtr<Gdk::DragContext>& context) {
1076 bool RackBox::animate_create() {
1078 anim_height += anim_step;
1079 if (anim_height >= target_height) {
1080 set_visibility(
true);
1081 set_size_request(-1,-1);
1084 set_size_request(-1, anim_height);
1091 if (!
get_parent()->check_if_animate(*
this)) {
1095 if (anim_tag.connected()) {
1097 anim_tag.disconnect();
1098 set_size_request(-1,-1);
1100 target_height = size_request().height;
1101 set_size_request(-1,0);
1102 set_visibility(
false);
1105 anim_step = target_height / 5;
1106 anim_tag = Glib::signal_timeout().connect(mem_fun(*
this, &RackBox::animate_create), 20);
1110 void RackBox::on_my_drag_end(
const Glib::RefPtr<Gdk::DragContext>& context) {
1120 void RackBox::on_my_drag_data_get(
const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection,
int info,
int timestamp) {
1121 selection.set(target, plugin.
get_id());
1124 void RackBox::vis_switch(Gtk::Widget& a, Gtk::Widget& b) {
1129 void RackBox::set_visibility(
bool v) {
1132 mbox.set_visible(v);
1135 fbox->set_visible(v);
1143 vis_switch(*fbox, mbox);
1145 vis_switch(mbox, *fbox);
1154 vis_switch(*fbox, mbox);
1155 if (strcmp(plugin.
get_id(),
"ampstack") == 0) {
1159 vis_switch(mbox, *fbox);
1173 void RackBox::do_expand() {
1175 Glib::signal_idle().connect_once(
1181 Gtk::Button *RackBox::make_expand_button(
bool expand) {
1183 Gtk::Button *b =
new Gtk::Button();
1187 b->set_tooltip_text(_(
"expand effect unit"));
1190 b->set_tooltip_text(_(
"shrink effect unit"));
1192 GtkWidget *l = gtk_image_new_from_stock(t, (GtkIconSize)-1);
1193 b->set_focus_on_click(
false);
1195 b->set_name(
"effect_on_off");
1197 b->signal_clicked().connect(
1198 sigc::mem_fun(*
this, &RackBox::do_expand));
1200 b->signal_clicked().connect(
1206 Gtk::Button *RackBox::make_preset_button() {
1207 Gtk::Button *p =
new Gtk::Button();
1209 GtkWidget *l = gtk_image_new_from_stock(
"rack_preset", (GtkIconSize)-1);
1211 p->set_can_default(
false);
1212 p->set_can_focus(
false);
1213 p->set_tooltip_text(_(
"manage effect unit presets"));
1214 p->set_name(
"effect_on_off");
1215 p->signal_clicked().connect(
1224 box.pack_start(*manage(
main));
1225 minibox->
pack(mini);
1226 szg->add_widget(*fbox);
1227 szg->add_widget(mbox);
1231 Gtk::HBox *bx =
new Gtk::HBox();
1232 Gtk::Widget *effect_label = make_label(plugin, options,
false);
1235 Gtk::HBox *main =
new Gtk::HBox();
1237 Gtk::VBox *center =
new Gtk::VBox();
1239 Gtk::HBox *top =
new Gtk::HBox();
1242 Gtk::Alignment *al =
new Gtk::Alignment();
1243 al->set_padding(0, 4, 0, 0);
1244 al->add(*manage(main));
1246 main->set_spacing(0);
1248 center->set_name(
"rack_unit_center");
1249 center->set_border_width(0);
1250 center->set_spacing(4);
1251 center->pack_start(*manage(top), Gtk::PACK_SHRINK);
1252 center->pack_start(box, Gtk::PACK_EXPAND_WIDGET);
1254 top->set_spacing(4);
1255 top->set_name(
"rack_unit_title_bar");
1257 top->pack_start(on_off_switch, Gtk::PACK_SHRINK);
1258 on_off_switch.set_name(
"effect_on_off");
1259 top->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
1260 top->pack_end(*manage(make_expand_button(
false)), Gtk::PACK_SHRINK);
1262 top->pack_end(*manage(make_preset_button()), Gtk::PACK_SHRINK);
1264 main->pack_start(*manage(wrap_bar()), Gtk::PACK_SHRINK);
1265 main->pack_start(*manage(center), Gtk::PACK_EXPAND_WIDGET);
1266 main->pack_end(*manage(wrap_bar()), Gtk::PACK_SHRINK);
1269 bx->pack_start(*manage(al), Gtk::PACK_EXPAND_WIDGET);
1276 Gtk::VBox *vbox =
new Gtk::VBox();
1278 Gtk::HBox *hbox =
new Gtk::HBox();
1279 vbox->pack_start(*manage(hbox));
1280 Gtk::HBox *hbox2 =
new Gtk::HBox();
1281 hbox->pack_start(*manage(hbox2), Gtk::PACK_SHRINK);
1282 Gtk::VBox *vbox2 =
new Gtk::VBox();
1283 hbox2->pack_start(*manage(vbox2));
1284 hbox2->pack_start(*manage(wrap_bar(4,4)), Gtk::PACK_SHRINK);
1286 szg->add_widget(&on_off_switch);
1288 Gtk::Alignment *al =
new Gtk::Alignment(0.5, 0.5, 0.0, 0.0);
1289 al->add(on_off_switch);
1290 vbox2->pack_start(*manage(al));
1299 static const int min_containersize = 40;
1310 highlight_connection(),
1311 autoscroll_connection() {
1312 std::vector<std::string> *pm, *ps;
1320 pm->push_back(
"application/x-guitarix-mono");
1321 pm->push_back(
"application/x-guitarix-mono-s");
1322 pm->push_back(
"application/x-gtk-tool-palette-item-mono");
1323 ps->push_back(
"application/x-guitarix-stereo");
1324 ps->push_back(
"application/x-guitarix-stereo-s");
1325 ps->push_back(
"application/x-gtk-tool-palette-item-stereo");
1326 std::vector<Gtk::TargetEntry> listTargets;
1327 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-mono", Gtk::TARGET_SAME_APP, 0));
1328 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-mono-s", Gtk::TARGET_SAME_APP, 1));
1329 listTargets.push_back(Gtk::TargetEntry(
"application/x-gtk-tool-palette-item-mono", Gtk::TARGET_SAME_APP, 2));
1330 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-stereo", Gtk::TARGET_SAME_APP, 3));
1331 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-stereo-s", Gtk::TARGET_SAME_APP, 4));
1332 listTargets.push_back(Gtk::TargetEntry(
"application/x-gtk-tool-palette-item-stereo", Gtk::TARGET_SAME_APP, 5));
1333 drag_dest_set(listTargets, Gtk::DEST_DEFAULT_DROP, Gdk::ACTION_MOVE);
1334 main.get_machine().signal_rack_unit_order_changed().connect(
1335 sigc::mem_fun(
this, &RackContainer::unit_order_changed));
1336 signal_remove().connect(sigc::mem_fun(*
this, &RackContainer::on_my_remove));
1337 set_size_request(-1, min_containersize);
1341 void RackContainer::unit_order_changed(
bool stereo) {
1347 bool RackContainer::drag_highlight_expose(GdkEventExpose *event,
int y0) {
1348 if (!is_drawable()) {
1351 Cairo::RefPtr<Cairo::Context> cr =
Glib::wrap(event->window,
true)->create_cairo_context();
1352 int x, y, width, height;
1353 if (!get_has_window()) {
1354 Gtk::Allocation a = get_allocation();
1357 width = a.get_width();
1358 height = a.get_height();
1361 get_window()->get_geometry(x, y, width, height, depth);
1365 GdkPixbuf * pb_ = gtk_widget_render_icon(GTK_WIDGET(this->gobj()),
"insert", (GtkIconSize)-1, NULL);
1367 cairo_t *cr_ = gdk_cairo_create(unwrap(get_window()));
1368 gdk_cairo_set_source_pixbuf(cr_, pb_, x, y);
1369 cairo_pattern_set_extend(cairo_get_source(cr_), CAIRO_EXTEND_REPEAT);
1371 cairo_set_line_width(cr_, 4.0);
1372 cairo_rectangle(cr_, x,
max(0, y), width, height);
1375 cairo_rectangle(cr_, x,
max(y, y0 - 3), width, 2);
1379 g_object_unref(pb_);
1390 void RackContainer::find_index(
int x,
int y,
int* len,
int *ypos) {
1391 std::list<childpos> l;
1394 for (std::vector<RackBox*>::iterator ch = children.begin(); ch != children.end(); ++ch) {
1396 if (!(*ch)->get_visible()) {
1399 Gtk::Allocation a = (*ch)->get_allocation();
1400 l.push_back(
childpos(a.get_y(), a.get_y()+a.get_height(), mpos));
1407 Gtk::Allocation a0 = get_allocation();
1409 int sy = l.begin()->y0;
1410 for (std::list<childpos>::iterator cp = l.begin(); cp != l.end(); ++cp) {
1411 if (y < (cp->y0 + cp->y1) / 2) {
1413 *ypos = (cp->y0+sy)/2;
1422 void RackContainer::on_my_remove(Gtk::Widget *ch) {
1427 bool RackContainer::check_targets(
const std::vector<std::string>& tgts1,
const std::vector<std::string>& tgts2) {
1428 for (std::vector<std::string>::const_iterator t1 = tgts1.begin(); t1 != tgts1.end(); ++t1) {
1429 for (std::vector<std::string>::const_iterator t2 = tgts2.begin(); t2 != tgts2.end(); ++t2) {
1438 bool RackContainer::on_drag_motion(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y, guint timestamp) {
1439 const std::vector<std::string>& tg = context->get_targets();
1440 if (!check_targets(tg, targets)) {
1441 if (check_targets(tg, othertargets)) {
1442 if (!autoscroll_connection.connected()) {
1443 autoscroll_connection = Glib::signal_timeout().connect(
1444 sigc::mem_fun(*
this, &RackContainer::scrollother_timeout), 50);
1446 context->drag_status(Gdk::DragAction(0), timestamp);
1451 context->drag_status(Gdk::ACTION_MOVE, timestamp);
1453 find_index(x, y, &i, &ind);
1454 if (in_drag == ind) {
1458 highlight_connection.disconnect();
1460 highlight_connection = signal_expose_event().connect(sigc::bind(sigc::mem_fun(*
this, &RackContainer::drag_highlight_expose), ind),
true);
1463 if (!autoscroll_connection.connected()) {
1464 autoscroll_connection = Glib::signal_timeout().connect(sigc::mem_fun(*
this, &RackContainer::scroll_timeout), 50);
1470 Gtk::Allocation alloc = child.get_allocation();
1471 Gtk::Viewport *p =
dynamic_cast<Gtk::Viewport*
>(get_ancestor(GTK_TYPE_VIEWPORT));
1472 p->get_vadjustment()->clamp_page(alloc.get_y(), alloc.get_y()+alloc.get_height());
1475 static const double scroll_edge_size = 60.0;
1476 static const int step_size = 20;
1478 bool RackContainer::scrollother_timeout() {
1479 Gtk::Viewport *p =
dynamic_cast<Gtk::Viewport*
>(get_ancestor(GTK_TYPE_VIEWPORT));
1480 Gtk::Adjustment *a = p->get_vadjustment();
1481 double off = a->get_value();
1482 Gtk::Allocation alloc = get_allocation();
1485 y -= alloc.get_height();
1487 if (y < -scroll_edge_size) {
1490 step = step_size * exp(-(y+scroll_edge_size)/(1.0*scroll_edge_size));
1496 off =
main.stop_at_stereo_bottom(off, step_size, a->get_page_size());
1498 off =
main.stop_at_mono_top(off, step_size);
1500 if (off < a->get_lower()) {
1501 off = a->get_lower();
1503 if (off > a->get_upper() - a->get_page_size()) {
1504 off = a->get_upper() - a->get_page_size();
1510 bool RackContainer::scroll_timeout() {
1511 Gtk::Viewport *p =
dynamic_cast<Gtk::Viewport*
>(get_ancestor(GTK_TYPE_VIEWPORT));
1512 Gtk::Adjustment *a = p->get_vadjustment();
1513 double off = a->get_value();
1514 Gtk::Allocation alloc = get_allocation();
1517 double sez = scroll_edge_size;
1518 if (sez > a->get_page_size() / 3) {
1519 sez = a->get_page_size() / 3;
1521 double yw = y + alloc.get_y() - off;
1524 step = step_size * (sez-yw) / sez;
1525 off =
max(
double(alloc.get_y()), off-step);
1527 yw = a->get_page_size() - yw;
1529 step = step_size * (sez-yw) / sez;
1530 off =
min(alloc.get_y()+alloc.get_height()-a->get_page_size(), off+step);
1535 if (off < a->get_lower()) {
1536 off = a->get_lower();
1538 if (off > a->get_upper() - a->get_page_size()) {
1539 off = a->get_upper() - a->get_page_size();
1545 void RackContainer::on_drag_leave(
const Glib::RefPtr<Gdk::DragContext>& context, guint timestamp) {
1547 highlight_connection.disconnect();
1551 autoscroll_connection.disconnect();
1554 void RackContainer::on_drag_data_received(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y,
const Gtk::SelectionData& data, guint info, guint timestamp) {
1556 find_index(x, y, &i, &ind);
1557 std::string dtype = data.get_data_type();
1558 if (dtype ==
"application/x-gtk-tool-palette-item-mono" || dtype ==
"application/x-gtk-tool-palette-item-stereo") {
1559 main.get_plugin(data.get_data_as_string())->display_new(
true);
1561 reorder(data.get_data_as_string(), i);
1566 i->second->hidden =
false;
1567 if (!i->second->hidden_by_move) {
1568 RackBox *r = i->second->rackbox;
1578 i->second->hidden =
true;
1579 RackBox *r = i->second->rackbox;
1590 main.get_machine().insert_rack_unit(name, ((pos >= l.size()) ?
"" : l[pos]->get_id()), tp);
1594 void RackContainer::on_add(Widget *ch) {
1599 pack_start(r, Gtk::PACK_SHRINK);
1604 reorder_child(r, pos);
1610 if (child_count == 1) {
1611 set_size_request(-1, -1);
1617 assert(child_count >= 0);
1618 if (child_count == 0) {
1619 set_size_request(-1, min_containersize);
1626 for (std::vector<RackBox*>::iterator c = l.begin(); c != l.end(); ++c) {
1627 (*c)->set_config_mode(mode);
1632 const std::vector<std::string>& ol =
main.get_machine().get_rack_unit_order(tp);
1633 bool in_order =
true;
1634 std::set<std::string> unit_set(ol.begin(), ol.end());
1636 std::vector<std::string>::const_iterator oi = ol.begin();
1637 for (rackbox_list::iterator c = l.begin(); c != l.end(); ++c) {
1638 if (!(*c)->get_box_visible()) {
1641 if (unit_set.find((*c)->get_id()) == unit_set.end()) {
1642 main.get_plugin((*c)->get_id())->hide(
false);
1648 if (oi == ol.end()) {
1652 if (*oi != (*c)->get_id()) {
1657 if (oi != ol.end()) {
1664 for (std::vector<std::string>::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) {
1676 reorder_child(*p->
rackbox, n++);
1681 void RackContainer::renumber() {
1684 unsigned int post_pre = 1;
1685 for (rackbox_list::iterator c = l.begin(); c != l.end(); ++c, ++pos) {
1686 if (strcmp((*c)->get_id(),
"ampstack") == 0) {
1691 (*c)->setOrder(pos, post_pre);