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)
191 res = g_utf8_collate(an, bn);
204 insert(pair<std::string, PluginUI*>(p->
get_id(), p));
208 std::map<std::string, PluginUI*>::iterator i = find(p->
get_id());
214 for (std::map<std::string, PluginUI*>::iterator i = begin(); i !=
end(); ++i) {
225 for (std::map<std::string, PluginUI*>::iterator i = begin(); i !=
end(); ++i) {
226 i->second->compress(state);
236 return alpha ? ((guint (src) << 8) - src) / alpha : 0;
240 guint8
const* src_pixel = src;
241 guint8* dst_pixel = dst;
243 for (
int i = 0; i < height*width; ++i) {
247 dst_pixel[3] = src_pixel[3];
255 : window(), drag_icon_pixbuf() {
256 Glib::RefPtr<Gdk::Screen> screen = context->get_source_window()->get_screen();
257 Glib::RefPtr<Gdk::Colormap> rgba = screen->get_rgba_colormap();
258 if (screen->is_composited()) {
259 window =
new Gtk::Window(Gtk::WINDOW_POPUP);
261 window->set_colormap(rgba);
264 create_drag_icon_pixbuf(plugin, rgba, options);
265 int w = drag_icon_pixbuf->get_width();
266 int h = drag_icon_pixbuf->get_height();
270 window->set_size_request(w, h);
271 window->signal_expose_event().connect(sigc::mem_fun(*
this, &DragIcon::icon_expose_event));
273 gtk_drag_set_icon_widget(context->gobj(), GTK_WIDGET(window->gobj()), w2, h2);
275 context->set_icon(drag_icon_pixbuf, w2, h2);
283 bool DragIcon::icon_expose_event(GdkEventExpose *ev) {
284 Cairo::RefPtr<Cairo::Context> cr =
Glib::wrap(ev->window,
true)->create_cairo_context();
285 gdk_cairo_region(cr->cobj(), ev->region);
286 cr->set_operator(Cairo::OPERATOR_SOURCE);
288 Gdk::Cairo::set_source_pixbuf(cr, drag_icon_pixbuf, 0, 0);
294 Gtk::OffscreenWindow w;
295 w.signal_expose_event().connect(sigc::bind(sigc::mem_fun(*
this, &DragIcon::window_expose_event), sigc::ref(w)));
297 w.set_colormap(rgba);
302 w.get_window()->process_updates(
true);
305 static void destroy_data(
const guint8 *data) {
309 bool DragIcon::window_expose_event(GdkEventExpose *event, Gtk::OffscreenWindow& widget) {
310 Cairo::RefPtr<Cairo::Context> cr = widget.get_window()->create_cairo_context();
311 cr->set_operator(Cairo::OPERATOR_SOURCE);
312 cr->set_source_rgba(0,0,0,0);
314 Gtk::Widget *child = widget.get_child();
316 widget.propagate_expose(*child, event);
318 Cairo::RefPtr<Cairo::Surface> x_surf = cr->get_target();
322 gdk_drawable_get_size(event->window, &w, &h);
323 Cairo::RefPtr<Cairo::LinearGradient> grad = Cairo::LinearGradient::create(w, 0, w-gradient_length, 0);
324 grad->add_color_stop_rgba(0, 1, 1, 1, 1);
325 grad->add_color_stop_rgba(1, 1, 1, 1, 0);
326 cr->rectangle(w-gradient_length, 0, gradient_length, h);
328 Cairo::RefPtr<Cairo::ImageSurface> i_surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, w, h);
329 Cairo::RefPtr<Cairo::Context> crt = Cairo::Context::create(i_surf);
330 crt->set_operator(Cairo::OPERATOR_SOURCE);
331 crt->set_source(x_surf, 0, 0);
333 guint8 *data =
new guint8[w*h*4];
335 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));
344 Glib::RefPtr<Gtk::SizeGroup> MiniRackBox::szg_label;
346 Gtk::Widget *MiniRackBox::make_delete_button(
RackBox& rb) {
348 if (rb.has_delete()) {
349 Gtk::Label *l =
new Gtk::Label(
"\u2a2f");
351 Gtk::Button *b =
new Gtk::Button();
352 b->set_focus_on_click(
false);
354 b->signal_clicked().connect(sigc::bind(sigc::mem_fun(rb.plugin, &
PluginUI::display),
false,
true));
357 w =
new Gtk::Alignment();
359 w->set_size_request(20, 15);
363 bool MiniRackBox::on_my_leave_out(GdkEventCrossing *focus) {
364 if (!mconbox.get_visible()) {
365 Glib::RefPtr<Gdk::Window> window = this->get_window();
366 window->set_cursor();
371 bool MiniRackBox::on_my_enter_in(GdkEventCrossing *focus) {
372 if (!mconbox.get_visible()) {
373 Glib::RefPtr<Gdk::Window> window = this->get_window();
374 Gdk::Cursor cursor(Gdk::HAND1);
375 window->set_cursor(cursor);
387 on_off_switch(
"switchit"),
388 toggle_on_off(rb.
main.get_machine(), &on_off_switch, rb.plugin.plugin->id_on_off()) {
389 if (strcmp(rb.plugin.
get_id(),
"ampstack") != 0) {
393 szg_label = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
395 evbox.set_visible_window(
false);
396 evbox.signal_leave_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_leave_out));
397 evbox.signal_enter_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_enter_in));
400 Gtk::Alignment *al =
new Gtk::Alignment();
401 al->set_padding(0, 4, 0, 0);
402 al->set_border_width(0);
404 evbox.add(*manage(al));
406 Gtk::HBox *box =
new Gtk::HBox();
407 Gtk::HBox *top =
new Gtk::HBox();
408 al->add(*manage(box));
410 this->set_spacing(0);
411 this->set_border_width(0);
414 box->set_border_width(0);
417 top->set_border_width(0);
418 top->set_name(
"rack_unit_title_bar");
420 box->pack_start(*manage(rb.wrap_bar()), Gtk::PACK_SHRINK);
421 box->pack_start(*manage(top));
422 box->pack_start(*manage(rb.wrap_bar()), Gtk::PACK_SHRINK);
424 top->pack_start(on_off_switch, Gtk::PACK_SHRINK);
425 on_off_switch.set_name(
"effect_on_off");
426 Gtk::Widget *effect_label = RackBox::make_label(rb.plugin, options);
427 szg_label->add_widget(*manage(effect_label));
428 top->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
430 top->pack_start(mconbox, Gtk::PACK_EXPAND_WIDGET);
432 mb_expand_button = rb.make_expand_button(
true);
433 top->pack_end(*manage(mb_expand_button), Gtk::PACK_SHRINK);
435 preset_button = rb.make_preset_button();
436 top->pack_end(*manage(preset_button), Gtk::PACK_SHRINK);
438 mb_delete_button = make_delete_button(rb);
439 mb_delete_button->set_no_show_all(
true);
440 top->pack_end(*manage(mb_delete_button), Gtk::PACK_SHRINK);
442 RackBox::szg->add_widget(*al);
444 al->set_size_request(32, -1);
448 szg_label = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
450 evbox.set_visible_window(
false);
451 evbox.signal_leave_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_leave_out));
452 evbox.signal_enter_notify_event().connect(sigc::mem_fun(*
this, &MiniRackBox::on_my_enter_in));
455 Gtk::Alignment *al =
new Gtk::Alignment();
456 al->set_padding(0, 4, 0, 0);
457 al->set_border_width(0);
459 Gtk::HBox *box =
new Gtk::HBox();
460 Gtk::HBox *top =
new Gtk::HBox();
461 evbox.add(*manage(box));
463 top->set_name(
"rack_unit_title_bar");
464 Gtk::Widget *effect_label = RackBox::make_label(rb.plugin, options);
465 szg_label->add_widget(*manage(effect_label));
466 top->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
467 top->pack_start(mconbox, Gtk::PACK_EXPAND_WIDGET);
468 box->pack_start(*manage(al), Gtk::PACK_SHRINK);
469 box->pack_start(*manage(top));
471 RackBox::szg->add_widget(*al);
473 al->set_size_request(64, 32);
481 mconbox.pack_start(*manage(w), Gtk::PACK_SHRINK, 4);
486 evbox.set_above_child(mode);
490 preset_button->hide();
492 if (mb_expand_button) {
493 mb_expand_button->hide();
495 if (mb_delete_button) {
496 mb_delete_button->show();
501 preset_button->show();
503 if (mb_expand_button) {
504 mb_expand_button->show();
506 if (mb_delete_button) {
507 mb_delete_button->hide();
525 void on_ok(Gtk::Entry *e);
526 virtual bool on_key_press_event(GdkEventKey *event);
528 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
const Glib::ustring& save_name_default);
529 InputWindow(BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
const Glib::ustring& save_name_default);
537 InputWindow *InputWindow::create_from_builder(BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
538 const Glib::ustring& save_name_default) {
539 return new InputWindow(cobject, bld, save_name_default);
546 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(options.
get_builder_filepath(
"pluginpreset_inputwindow.glade"));
548 bld->get_toplevel_derived(
549 "PluginPresetInputWindow", w,
550 sigc::bind(sigc::ptr_fun(InputWindow::create_from_builder), bld, save_name_default));
554 bool InputWindow::on_key_press_event(GdkEventKey *event) {
555 if (event->keyval ==
GDK_KEY_Escape && (event->state & Gtk::AccelGroup::get_default_mod_mask()) == 0) {
559 return Gtk::Window::on_key_press_event(event);
562 void InputWindow::on_ok(Gtk::Entry *e) {
563 name = e->get_text();
567 InputWindow::InputWindow(BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
568 const Glib::ustring& save_name_default)
569 : Gtk::Window(cobject), name() {
571 bld->find_widget(
"cancelbutton", b);
572 b->signal_clicked().connect(
573 sigc::mem_fun(*
this, &InputWindow::hide));
574 bld->find_widget(
"okbutton", b);
576 bld->find_widget(
"entry", e);
577 e->set_text(save_name_default);
578 e->select_region(0, -1);
579 b->signal_clicked().connect(
580 sigc::bind(sigc::mem_fun(*
this, &InputWindow::on_ok), e));
584 Gtk::Main::run(*
this);
595 Gtk::TreeModelColumn<Glib::ustring>
name;
600 set_column_types(col);
608 Glib::RefPtr<TextListStore> textliststore;
611 Gtk::TreeView *treeview;
612 Gtk::Button *removebutton;
613 using Gtk::Window::on_remove;
615 void on_selection_changed();
616 virtual bool on_key_press_event(GdkEventKey *event);
618 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
PluginPresetPopup& p);
627 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
PluginPresetPopup& p) {
636 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(
639 bld->get_toplevel_derived(
640 "PluginPresetListWindow", w,
641 sigc::bind(sigc::ptr_fun(PluginPresetListWindow::create_from_builder), bld, sigc::ref(p)));
645 bool PluginPresetListWindow::on_key_press_event(GdkEventKey *event) {
646 if (event->keyval ==
GDK_KEY_Escape && (event->state & Gtk::AccelGroup::get_default_mod_mask()) == 0) {
650 return Gtk::Window::on_key_press_event(event);
653 void PluginPresetListWindow::on_remove() {
654 Gtk::TreeIter it = treeview->get_selection()->get_selected();
656 presetlist.get_machine().plugin_preset_list_remove(
657 presetlist.get_pdef(), it->get_value(textliststore->col.name));
658 textliststore->erase(it);
662 PluginPresetListWindow::PluginPresetListWindow(
663 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld,
PluginPresetPopup& p)
664 : Gtk::Window(cobject),
668 bld->find_widget(
"closebutton", b);
669 b->signal_clicked().connect(
670 sigc::mem_fun(*
this, &PluginPresetListWindow::hide));
671 bld->find_widget(
"removebutton", removebutton);
672 removebutton->signal_clicked().connect(
673 sigc::mem_fun0(*
this, &PluginPresetListWindow::on_remove));
674 bld->find_widget(
"treeview", treeview);
675 for (gx_preset::UnitPresetList::const_iterator i = presetlist.begin(); i != presetlist.end(); ++i) {
676 if (i->name.empty()) {
679 textliststore->append()->set_value(textliststore->col.name, i->name);
681 treeview->set_model(textliststore);
682 removebutton->set_sensitive(
false);
683 Glib::RefPtr<Gtk::TreeSelection> sel = treeview->get_selection();
684 sel->signal_changed().connect(
685 sigc::mem_fun(*
this, &PluginPresetListWindow::on_selection_changed));
688 void PluginPresetListWindow::on_selection_changed() {
689 removebutton->set_sensitive(treeview->get_selection()->get_selected());
693 Gtk::Main::run(*
this);
700 void PluginPresetPopup::set_plugin_preset(
bool factory,
const Glib::ustring& name) {
701 if(strcmp(pdef->id,
"seq")==0) {
702 machine.plugin_preset_list_sync_set(pdef, factory, name);
704 machine.plugin_preset_list_set(pdef, factory, name);
708 void PluginPresetPopup::set_plugin_std_preset() {
709 machine.reset_unit(pdef);
712 void PluginPresetPopup::save_plugin_preset() {
717 if(strcmp(pdef->id,
"dubber")==0) {
718 Glib::ustring name =
"";
719 machine.set_parameter_value(
"dubber.filename", name);
720 machine.set_parameter_value(
"dubber.savefile",
true);
721 machine.set_parameter_value(
"dubber.filename", w->
get_name());
723 machine.plugin_preset_list_save(pdef, w->
get_name());
724 if(strcmp(pdef->id,
"seq")==0) {
725 Glib::ustring
id =
"seq." + w->
get_name();
726 if (!machine.parameter_hasId(
id)) {
727 machine.insert_param(
"seq", w->
get_name());
734 void PluginPresetPopup::remove_plugin_preset() {
740 bool PluginPresetPopup::add_plugin_preset_list(
bool *found) {
742 bool found_presets =
false;
743 bool factory =
false;
744 for (gx_preset::UnitPresetList::iterator i = presetnames.begin(); i != presetnames.end(); ++i) {
745 if (i->name.empty()) {
748 append(*manage(
new Gtk::SeparatorMenuItem()));
750 found_presets =
false;
754 found_presets =
true;
756 Gtk::CheckMenuItem *c =
new Gtk::CheckMenuItem(i->name);
760 c->signal_activate().connect(
761 sigc::bind(sigc::mem_fun(
this, &PluginPresetPopup::set_plugin_preset), factory, i->name));
764 return found_presets;
773 Glib::signal_idle().connect(
775 sigc::ptr_fun(delete_plugin_preset_popup),
780 const Glib::ustring& save_name_default_)
784 save_name_default(save_name_default_),
788 if (!add_plugin_preset_list(&found_presets)) {
789 Gtk::CheckMenuItem *c =
new Gtk::CheckMenuItem(_(
"standard"));
793 c->signal_activate().connect(
794 sigc::mem_fun(
this, &PluginPresetPopup::set_plugin_std_preset));
797 append(*manage(
new Gtk::SeparatorMenuItem()));
798 Gtk::MenuItem *mi =
new Gtk::MenuItem(_(
"save..."));
800 mi->signal_activate().connect(
801 sigc::mem_fun(
this, &PluginPresetPopup::save_plugin_preset));
803 mi =
new Gtk::MenuItem(_(
"remove..."));
805 mi->signal_activate().connect(
806 sigc::mem_fun(
this, &PluginPresetPopup::remove_plugin_preset));
809 popup(1, gtk_get_current_event_time());
818 Glib::RefPtr<Gtk::SizeGroup> RackBox::szg;
822 pb.set_name(
"rackbox");
823 pb.property_paint_func().set_value(
"gx_rack_unit_shrink_expose");
824 pb.set_border_width(4);
828 pb.set_name(
"rackbox");
829 pb.property_paint_func().set_value(
"gx_rack_unit_expose");
830 pb.set_border_width(4);
840 pb.set_name(
"rackbox");
842 pb.set_border_width(4);
847 Gtk::Label *effect_label =
new Gtk::Label(effect_name);
848 effect_label->set_alignment(0.0, 0.5);
849 effect_label->set_name(
"effect_title");
851 effect_label->set_markup(
"◗◖ " + effect_label->get_label());
856 Gtk::Widget *RackBox::make_bar(
int left,
int right,
bool sens) {
857 Gtk::Alignment *al =
new Gtk::Alignment(0, 0, 1.0, 1.0);
859 Gtk::Button *button =
new Gtk::Button();
860 button->set_size_request(32,-1);
862 button->set_tooltip_text(_(
"Drag'n' Drop Handle"));
863 button->set_relief(Gtk::RELIEF_NONE);
864 button->set_sensitive(sens);
865 al->add(*manage(button));
869 bool RackBox::on_my_leave_out(GdkEventCrossing *focus) {
870 Glib::RefPtr<Gdk::Window> window = this->get_window();
871 window->set_cursor();
875 bool RackBox::on_my_enter_in(GdkEventCrossing *focus) {
876 Glib::RefPtr<Gdk::Window> window = this->get_window();
877 Gdk::Cursor cursor(Gdk::HAND1);
878 window->set_cursor(cursor);
882 bool RackBox::on_my_button_press(GdkEventButton* ev) {
883 if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) {
890 Gtk::Widget *RackBox::wrap_bar(
int left,
int right,
bool sens) {
891 Gtk::EventBox *ev =
new Gtk::EventBox;
892 ev->set_visible_window(
false);
893 ev->set_above_child(
true);
894 ev->add(*manage(make_bar(left, right, sens)));
895 ev->signal_leave_notify_event().connect(sigc::mem_fun(*
this, &RackBox::on_my_leave_out));
896 ev->signal_enter_notify_event().connect(sigc::mem_fun(*
this, &RackBox::on_my_enter_in));
897 ev->signal_button_press_event().connect(sigc::mem_fun(*
this, &RackBox::on_my_button_press));
898 ev->signal_drag_begin().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_begin));
899 ev->signal_drag_end().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_end));
900 ev->signal_drag_data_get().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_data_get));
901 std::vector<Gtk::TargetEntry> listTargets;
902 listTargets.push_back(Gtk::TargetEntry(target, Gtk::TARGET_SAME_APP, 0));
903 ev->drag_source_set(listTargets, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE);
909 RackBox::set_paintbox(*pb, plugin.
get_type());
910 Gtk::Widget *effect_label = RackBox::make_label(plugin, options);
911 Gtk::Alignment *al =
new Gtk::Alignment(0.0, 0.0, 1.0, 1.0);
912 al->set_padding(0,2,2,0);
913 al->add(*manage(effect_label));
914 pb->pack_start(*manage(al), Gtk::PACK_SHRINK);
921 RackBox::set_paintbox_unit_shrink(*pb, plugin.
get_type());
922 pb->set_name(
"drag_widget");
923 if (strcmp(plugin.
get_id(),
"ampstack") == 0) {
924 pb->property_paint_func().set_value(
"gx_rack_amp_expose");
933 Gtk::Widget *effect_label = RackBox::make_label(plugin, options);
934 Gtk::Alignment *al =
new Gtk::Alignment(0.0, 0.0, 0.0, 0.0);
935 al->set_padding(0,0,4,20);
936 al->add(*manage(RackBox::make_bar(4, 4,
true)));
937 pb->pack_start(*manage(al), Gtk::PACK_SHRINK);
939 pb->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
940 al =
new Gtk::Alignment(0.0, 0.0, 0.0, 0.0);
941 al->set_size_request(70,30);
942 pb->pack_start(*manage(al), Gtk::PACK_SHRINK);
948 assert(box_visible != v);
957 get_parent()->increment();
966 get_parent()->decrement();
972 : Gtk::VBox(), plugin(plugin_),
main(tl), config_mode(false), anim_tag(),
973 compress(true), delete_button(true), mbox(Gtk::ORIENTATION_HORIZONTAL), minibox(0),
974 fbox(0), target(), anim_height(0), anim_step(), drag_icon(), target_height(0),
975 box(Gtk::ORIENTATION_HORIZONTAL, 2), box_visible(true), on_off_switch(
"switchit"),
976 toggle_on_off(tl.
get_machine(), &on_off_switch, plugin.plugin->id_on_off()) {
977 if (strcmp(plugin.
get_id(),
"ampstack") != 0) {
982 szg = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
987 delete_button =
false;
989 set_paintbox_unit_shrink(mbox, plugin.
get_type());
992 mbox.pack_start(*manage(minibox));
993 pack_start(mbox, Gtk::PACK_SHRINK);
997 mbox.property_paint_func().set_value(
"gx_rack_amp_expose");
1001 set_paintbox_unit(*pb, plugin);
1002 pb->pack_start(*manage(make_full_box(tl.
get_options())));
1003 pack_start(*manage(pb), Gtk::PACK_SHRINK);
1009 void RackBox::init_dnd() {
1010 target =
"application/x-guitarix-";
1016 if (!delete_button) {
1019 mbox.signal_drag_begin().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_begin));
1020 mbox.signal_drag_end().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_end));
1021 mbox.signal_drag_data_get().connect(sigc::mem_fun(*
this, &RackBox::on_my_drag_data_get));
1024 void RackBox::enable_drag(
bool v) {
1026 std::vector<Gtk::TargetEntry> listTargets;
1027 listTargets.push_back(Gtk::TargetEntry(target, Gtk::TARGET_SAME_APP, 0));
1028 mbox.drag_source_set(listTargets, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE);
1030 mbox.drag_source_unset();
1034 bool RackBox::animate_vanish() {
1035 anim_height -= anim_step;
1036 if (anim_height <= 0) {
1038 set_visibility(
true);
1039 set_size_request(-1,-1);
1043 set_size_request(-1, anim_height);
1048 void RackBox::animate_remove() {
1049 if (!
get_parent()->check_if_animate(*
this)) {
1052 if (anim_tag.connected()) {
1054 anim_tag.disconnect();
1055 set_size_request(-1,-1);
1058 anim_height = size_request().height;
1059 set_size_request(-1, anim_height);
1060 set_visibility(
false);
1061 anim_step = anim_height / 5;
1062 anim_tag = Glib::signal_timeout().connect(sigc::mem_fun(*
this, &RackBox::animate_vanish), 20);
1067 return dynamic_cast<RackContainer*
>(Gtk::VBox::get_parent());
1070 void RackBox::on_my_drag_begin(
const Glib::RefPtr<Gdk::DragContext>& context) {
1077 bool RackBox::animate_create() {
1079 anim_height += anim_step;
1080 if (anim_height >= target_height) {
1081 set_visibility(
true);
1082 set_size_request(-1,-1);
1085 set_size_request(-1, anim_height);
1092 if (!
get_parent()->check_if_animate(*
this)) {
1096 if (anim_tag.connected()) {
1098 anim_tag.disconnect();
1099 set_size_request(-1,-1);
1101 target_height = size_request().height;
1102 set_size_request(-1,0);
1103 set_visibility(
false);
1106 anim_step = target_height / 5;
1107 anim_tag = Glib::signal_timeout().connect(mem_fun(*
this, &RackBox::animate_create), 20);
1111 void RackBox::on_my_drag_end(
const Glib::RefPtr<Gdk::DragContext>& context) {
1121 void RackBox::on_my_drag_data_get(
const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection,
int info,
int timestamp) {
1122 selection.set(target, plugin.
get_id());
1125 void RackBox::vis_switch(Gtk::Widget& a, Gtk::Widget& b) {
1130 void RackBox::set_visibility(
bool v) {
1133 mbox.set_visible(v);
1136 fbox->set_visible(v);
1144 vis_switch(*fbox, mbox);
1146 vis_switch(mbox, *fbox);
1155 vis_switch(*fbox, mbox);
1156 if (strcmp(plugin.
get_id(),
"ampstack") == 0) {
1160 vis_switch(mbox, *fbox);
1174 void RackBox::do_expand() {
1176 Glib::signal_idle().connect_once(
1182 Gtk::Button *RackBox::make_expand_button(
bool expand) {
1184 Gtk::Button *b =
new Gtk::Button();
1188 b->set_tooltip_text(_(
"expand effect unit"));
1191 b->set_tooltip_text(_(
"shrink effect unit"));
1193 GtkWidget *l = gtk_image_new_from_stock(t, (GtkIconSize)-1);
1194 b->set_focus_on_click(
false);
1196 b->set_name(
"effect_on_off");
1198 b->signal_clicked().connect(
1199 sigc::mem_fun(*
this, &RackBox::do_expand));
1201 b->signal_clicked().connect(
1207 Gtk::Button *RackBox::make_preset_button() {
1208 Gtk::Button *p =
new Gtk::Button();
1210 GtkWidget *l = gtk_image_new_from_stock(
"rack_preset", (GtkIconSize)-1);
1212 p->set_can_default(
false);
1213 p->set_can_focus(
false);
1214 p->set_tooltip_text(_(
"manage effect unit presets"));
1215 p->set_name(
"effect_on_off");
1216 p->signal_clicked().connect(
1221 void RackBox::pack(Gtk::Widget *main, Gtk::Widget *mini,
const Glib::RefPtr<Gtk::SizeGroup>& szg) {
1225 box.pack_start(*manage(main));
1226 minibox->
pack(mini);
1227 szg->add_widget(*fbox);
1228 szg->add_widget(mbox);
1232 Gtk::HBox *bx =
new Gtk::HBox();
1233 Gtk::Widget *effect_label = make_label(plugin, options,
false);
1236 Gtk::HBox *main =
new Gtk::HBox();
1238 Gtk::VBox *center =
new Gtk::VBox();
1240 Gtk::HBox *top =
new Gtk::HBox();
1243 Gtk::Alignment *al =
new Gtk::Alignment();
1244 al->set_padding(0, 4, 0, 0);
1245 al->add(*manage(main));
1247 main->set_spacing(0);
1249 center->set_name(
"rack_unit_center");
1250 center->set_border_width(0);
1251 center->set_spacing(4);
1252 center->pack_start(*manage(top), Gtk::PACK_SHRINK);
1253 center->pack_start(box, Gtk::PACK_EXPAND_WIDGET);
1255 top->set_spacing(4);
1256 top->set_name(
"rack_unit_title_bar");
1258 top->pack_start(on_off_switch, Gtk::PACK_SHRINK);
1259 on_off_switch.set_name(
"effect_on_off");
1260 top->pack_start(*manage(effect_label), Gtk::PACK_SHRINK);
1261 top->pack_end(*manage(make_expand_button(
false)), Gtk::PACK_SHRINK);
1263 top->pack_end(*manage(make_preset_button()), Gtk::PACK_SHRINK);
1265 main->pack_start(*manage(wrap_bar()), Gtk::PACK_SHRINK);
1266 main->pack_start(*manage(center), Gtk::PACK_EXPAND_WIDGET);
1267 main->pack_end(*manage(wrap_bar()), Gtk::PACK_SHRINK);
1269 main->set_name(plugin.
get_id());
1270 bx->pack_start(*manage(al), Gtk::PACK_EXPAND_WIDGET);
1277 Gtk::VBox *vbox =
new Gtk::VBox();
1279 Gtk::HBox *hbox =
new Gtk::HBox();
1280 vbox->pack_start(*manage(hbox));
1281 Gtk::HBox *hbox2 =
new Gtk::HBox();
1282 hbox->pack_start(*manage(hbox2), Gtk::PACK_SHRINK);
1283 Gtk::VBox *vbox2 =
new Gtk::VBox();
1284 hbox2->pack_start(*manage(vbox2));
1285 hbox2->pack_start(*manage(wrap_bar(4,4)), Gtk::PACK_SHRINK);
1287 szg->add_widget(&on_off_switch);
1289 Gtk::Alignment *al =
new Gtk::Alignment(0.5, 0.5, 0.0, 0.0);
1290 al->add(on_off_switch);
1291 vbox2->pack_start(*manage(al));
1300 static const int min_containersize = 40;
1311 highlight_connection(),
1312 autoscroll_connection() {
1313 std::vector<std::string> *pm, *ps;
1321 pm->push_back(
"application/x-guitarix-mono");
1322 pm->push_back(
"application/x-guitarix-mono-s");
1323 pm->push_back(
"application/x-gtk-tool-palette-item-mono");
1324 ps->push_back(
"application/x-guitarix-stereo");
1325 ps->push_back(
"application/x-guitarix-stereo-s");
1326 ps->push_back(
"application/x-gtk-tool-palette-item-stereo");
1327 std::vector<Gtk::TargetEntry> listTargets;
1328 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-mono", Gtk::TARGET_SAME_APP, 0));
1329 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-mono-s", Gtk::TARGET_SAME_APP, 1));
1330 listTargets.push_back(Gtk::TargetEntry(
"application/x-gtk-tool-palette-item-mono", Gtk::TARGET_SAME_APP, 2));
1331 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-stereo", Gtk::TARGET_SAME_APP, 3));
1332 listTargets.push_back(Gtk::TargetEntry(
"application/x-guitarix-stereo-s", Gtk::TARGET_SAME_APP, 4));
1333 listTargets.push_back(Gtk::TargetEntry(
"application/x-gtk-tool-palette-item-stereo", Gtk::TARGET_SAME_APP, 5));
1334 drag_dest_set(listTargets, Gtk::DEST_DEFAULT_DROP, Gdk::ACTION_MOVE);
1336 sigc::mem_fun(
this, &RackContainer::unit_order_changed));
1337 signal_remove().connect(sigc::mem_fun(*
this, &RackContainer::on_my_remove));
1338 set_size_request(-1, min_containersize);
1342 void RackContainer::unit_order_changed(
bool stereo) {
1348 bool RackContainer::drag_highlight_expose(GdkEventExpose *event,
int y0) {
1349 if (!is_drawable()) {
1352 Cairo::RefPtr<Cairo::Context> cr =
Glib::wrap(event->window,
true)->create_cairo_context();
1353 int x, y, width, height;
1354 if (!get_has_window()) {
1355 Gtk::Allocation a = get_allocation();
1358 width = a.get_width();
1359 height = a.get_height();
1362 get_window()->get_geometry(x, y, width, height, depth);
1366 GdkPixbuf * pb_ = gtk_widget_render_icon(GTK_WIDGET(this->gobj()),
"insert", (GtkIconSize)-1, NULL);
1368 cairo_t *cr_ = gdk_cairo_create(unwrap(get_window()));
1369 gdk_cairo_set_source_pixbuf(cr_, pb_, x, y);
1370 cairo_pattern_set_extend(cairo_get_source(cr_), CAIRO_EXTEND_REPEAT);
1372 cairo_set_line_width(cr_, 4.0);
1373 cairo_rectangle(cr_, x,
max(0, y), width, height);
1376 cairo_rectangle(cr_, x,
max(y, y0 - 3), width, 2);
1380 g_object_unref(pb_);
1387 childpos(
int y0_,
int y1_,
int pos_): y0(y0_), y1(y1_), pos(pos_) {}
1391 void RackContainer::find_index(
int x,
int y,
int* len,
int *ypos) {
1392 std::list<childpos> l;
1395 for (std::vector<RackBox*>::iterator ch = children.begin(); ch != children.end(); ++ch) {
1397 if (!(*ch)->get_visible()) {
1400 Gtk::Allocation a = (*ch)->get_allocation();
1401 l.push_back(
childpos(a.get_y(), a.get_y()+a.get_height(), mpos));
1408 Gtk::Allocation a0 = get_allocation();
1410 int sy = l.begin()->y0;
1411 for (std::list<childpos>::iterator cp = l.begin(); cp != l.end(); ++cp) {
1412 if (y < (cp->y0 + cp->y1) / 2) {
1414 *ypos = (cp->y0+sy)/2;
1423 void RackContainer::on_my_remove(Gtk::Widget *ch) {
1428 bool RackContainer::check_targets(
const std::vector<std::string>& tgts1,
const std::vector<std::string>& tgts2) {
1429 for (std::vector<std::string>::const_iterator t1 = tgts1.begin(); t1 != tgts1.end(); ++t1) {
1430 for (std::vector<std::string>::const_iterator t2 = tgts2.begin(); t2 != tgts2.end(); ++t2) {
1439 bool RackContainer::on_drag_motion(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y, guint timestamp) {
1440 const std::vector<std::string>& tg = context->get_targets();
1441 if (!check_targets(tg, targets)) {
1442 if (check_targets(tg, othertargets)) {
1443 if (!autoscroll_connection.connected()) {
1444 autoscroll_connection = Glib::signal_timeout().connect(
1445 sigc::mem_fun(*
this, &RackContainer::scrollother_timeout), 50);
1447 context->drag_status(Gdk::DragAction(0), timestamp);
1452 context->drag_status(Gdk::ACTION_MOVE, timestamp);
1454 find_index(x, y, &i, &ind);
1455 if (in_drag == ind) {
1459 highlight_connection.disconnect();
1461 highlight_connection = signal_expose_event().connect(sigc::bind(sigc::mem_fun(*
this, &RackContainer::drag_highlight_expose), ind),
true);
1464 if (!autoscroll_connection.connected()) {
1465 autoscroll_connection = Glib::signal_timeout().connect(sigc::mem_fun(*
this, &RackContainer::scroll_timeout), 50);
1471 Gtk::Allocation alloc = child.get_allocation();
1472 Gtk::Viewport *p =
dynamic_cast<Gtk::Viewport*
>(get_ancestor(GTK_TYPE_VIEWPORT));
1473 p->get_vadjustment()->clamp_page(alloc.get_y(), alloc.get_y()+alloc.get_height());
1476 static const double scroll_edge_size = 60.0;
1477 static const int step_size = 20;
1479 bool RackContainer::scrollother_timeout() {
1480 Gtk::Viewport *p =
dynamic_cast<Gtk::Viewport*
>(get_ancestor(GTK_TYPE_VIEWPORT));
1481 Gtk::Adjustment *a = p->get_vadjustment();
1482 double off = a->get_value();
1483 Gtk::Allocation alloc = get_allocation();
1486 y -= alloc.get_height();
1488 if (y < -scroll_edge_size) {
1491 step = step_size * exp(-(y+scroll_edge_size)/(1.0*scroll_edge_size));
1497 off =
main.stop_at_stereo_bottom(off, step_size, a->get_page_size());
1499 off =
main.stop_at_mono_top(off, step_size);
1501 if (off < a->get_lower()) {
1502 off = a->get_lower();
1504 if (off > a->get_upper() - a->get_page_size()) {
1505 off = a->get_upper() - a->get_page_size();
1511 bool RackContainer::scroll_timeout() {
1512 Gtk::Viewport *p =
dynamic_cast<Gtk::Viewport*
>(get_ancestor(GTK_TYPE_VIEWPORT));
1513 Gtk::Adjustment *a = p->get_vadjustment();
1514 double off = a->get_value();
1515 Gtk::Allocation alloc = get_allocation();
1518 double sez = scroll_edge_size;
1519 if (sez > a->get_page_size() / 3) {
1520 sez = a->get_page_size() / 3;
1522 double yw = y + alloc.get_y() - off;
1525 step = step_size * (sez-yw) / sez;
1526 off =
max(
double(alloc.get_y()), off-step);
1528 yw = a->get_page_size() - yw;
1530 step = step_size * (sez-yw) / sez;
1531 off =
min(alloc.get_y()+alloc.get_height()-a->get_page_size(), off+step);
1536 if (off < a->get_lower()) {
1537 off = a->get_lower();
1539 if (off > a->get_upper() - a->get_page_size()) {
1540 off = a->get_upper() - a->get_page_size();
1546 void RackContainer::on_drag_leave(
const Glib::RefPtr<Gdk::DragContext>& context, guint timestamp) {
1548 highlight_connection.disconnect();
1552 autoscroll_connection.disconnect();
1555 void RackContainer::on_drag_data_received(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y,
const Gtk::SelectionData& data, guint info, guint timestamp) {
1557 find_index(x, y, &i, &ind);
1558 std::string dtype = data.get_data_type();
1559 if (dtype ==
"application/x-gtk-tool-palette-item-mono" || dtype ==
"application/x-gtk-tool-palette-item-stereo") {
1560 main.get_plugin(data.get_data_as_string())->display_new(
true);
1562 reorder(data.get_data_as_string(), i);
1567 i->second->hidden =
false;
1568 if (!i->second->hidden_by_move) {
1569 RackBox *r = i->second->rackbox;
1579 i->second->hidden =
true;
1580 RackBox *r = i->second->rackbox;
1591 main.get_machine().insert_rack_unit(name, ((pos >= l.size()) ?
"" : l[pos]->get_id()), tp);
1595 void RackContainer::on_add(Widget *ch) {
1596 add(*dynamic_cast<RackBox*>(ch));
1600 pack_start(r, Gtk::PACK_SHRINK);
1605 reorder_child(r, pos);
1611 if (child_count == 1) {
1612 set_size_request(-1, -1);
1618 assert(child_count >= 0);
1619 if (child_count == 0) {
1620 set_size_request(-1, min_containersize);
1627 for (std::vector<RackBox*>::iterator c = l.begin(); c != l.end(); ++c) {
1628 (*c)->set_config_mode(mode);
1633 const std::vector<std::string>& ol =
main.get_machine().get_rack_unit_order(tp);
1634 bool in_order =
true;
1635 std::set<std::string> unit_set(ol.begin(), ol.end());
1637 std::vector<std::string>::const_iterator oi = ol.begin();
1638 for (rackbox_list::iterator c = l.begin(); c != l.end(); ++c) {
1639 if (!(*c)->get_box_visible()) {
1642 if (unit_set.find((*c)->get_id()) == unit_set.end()) {
1643 main.get_plugin((*c)->get_id())->hide(
false);
1649 if (oi == ol.end()) {
1653 if (*oi != (*c)->get_id()) {
1658 if (oi != ol.end()) {
1665 for (std::vector<std::string>::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) {
1677 reorder_child(*p->
rackbox, n++);
1682 void RackContainer::renumber() {
1685 unsigned int post_pre = 1;
1686 for (rackbox_list::iterator c = l.begin(); c != l.end(); ++c, ++pos) {
1687 if (strcmp((*c)->get_id(),
"ampstack") == 0) {
1692 (*c)->setOrder(pos, post_pre);
MiniRackBox(RackBox &rb, gx_system::CmdlineOptions &options)
CmdConnection::msg_type end
void convert_bgra_to_rgba(guint8 const *src, guint8 *dst, int width, int height)
Gtk::TreeModelColumn< Glib::ustring > name
void add(RackBox &r, int pos=-1)
static Glib::RefPtr< TextListStore > create()
gx_engine::GxMachineBase & get_machine()
void add_icon(const std::string &name)
void ensure_visible(RackBox &child)
const char * get_shortname() const
std::string get_builder_filepath(const std::string &basename) const
const std::string & id_on_off() const
const char * get_name() const
bool get_plug_visible() const
void display(bool v, bool animate)
RackContainer(PluginType tp, MainWindow &main)
void set_config_mode(bool mode)
DragIcon(const PluginUI &plugin, Glib::RefPtr< Gdk::DragContext > context, gx_system::CmdlineOptions &options, int xoff=0)
static bool is_registered(gx_engine::GxMachineBase &m, const char *name)
void plugin_preset_popup(const PluginDef *pdef)
void set_config_mode(bool mode)
RackBox(PluginUI &plugin, MainWindow &main, Gtk::Widget *bare=0)
bool get_box_visible() const
void hide_effect(const std::string &name)
void display(bool v, bool animate)
virtual bool parameter_unit_has_std_values(const PluginDef *pdef) const =0
childpos(int y0_, int y1_, int pos_)
virtual void on_plugin_preset_popup()
void pack(Gtk::Widget *mainbox, Gtk::Widget *minibox, const Glib::RefPtr< Gtk::SizeGroup > &szg)
~PluginPresetListWindow()
static Gtk::Widget * create_icon_widget(const PluginUI &plugin, gx_system::CmdlineOptions &options)
Gtk::ToolItemGroup * group
gx_engine::Plugin * plugin
void pack(Gtk::Widget *w)
bool operator<(const childpos &p)
gx_system::CmdlineOptions & get_options()
virtual sigc::signal< void, bool > & signal_rack_unit_order_changed()=0
RackBox * add_rackbox(PluginUI &pl, bool mini=false, int pos=-1, bool animate=false)
static PluginPresetListWindow * create(const gx_system::CmdlineOptions &options, PluginPresetPopup &p)
PluginType get_type() const
void set_action(Glib::RefPtr< Gtk::ToggleAction > &act)
virtual void plugin_preset_list_load(const PluginDef *pdef, gx_preset::UnitPresetList &presetnames)=0
void connect_midi_controller(Gtk::Widget *w, const std::string &id, gx_engine::GxMachineBase &machine)
void set_config_mode(bool mode)
virtual void remove_rack_unit(const std::string &unit, PluginType type)=0
rackbox_list get_children()
void set_effect_post_pre(int v) const
void set_position(int v) const
guint8 convert_color_channel(guint8 src, guint8 alpha)
void unset_ui_merge_id(Glib::RefPtr< Gtk::UIManager > uimanager)
RackContainer * get_parent()
int main(int argc, char *argv[])
void set_plug_visible(bool v) const
void compress(bool state)
const char * get_id() const
Gxw::BigKnob * wrap(GxBigKnob *object, bool take_copy)
PluginUI(MainWindow &main, const char *id_, const Glib::ustring &tooltip_="")
void display_new(bool unordered=false)
void reorder(const std::string &name, unsigned int pos)
virtual Plugin * pluginlist_lookup_plugin(const std::string &id) const =0
void set_box_visible(bool v) const
void setOrder(int pos, int post_pre)
void set_on_off(bool v) const
virtual void insert_rack_unit(const std::string &unit, const std::string &before, PluginType type)=0
friend bool plugins_by_name_less(PluginUI *a, PluginUI *b)
std::map< std::string, PluginUI * >::iterator iterator
Glib::ListHandle< RackBox * > rackbox_list
void compress(bool state)
static Gtk::Widget * create_drag_widget(const PluginUI &plugin, gx_system::CmdlineOptions &options)