From f9e5e4360e54f5ff5327b4384ee451d86f8dec91 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 17 Jul 2017 04:55:52 +0200 Subject: Move more Gtkmm2ext widgets into libwidget --- gtk2_ardour/ardour_ui.cc | 1 - gtk2_ardour/ardour_ui.h | 18 +- gtk2_ardour/ardour_ui_dependents.cc | 2 +- gtk2_ardour/ardour_ui_ed.cc | 9 +- gtk2_ardour/editor.cc | 7 +- gtk2_ardour/editor.h | 6 +- gtk2_ardour/editor_actions.cc | 14 +- gtk2_ardour/editor_audio_import.cc | 6 +- gtk2_ardour/editor_export_audio.cc | 2 - gtk2_ardour/editor_ops.cc | 9 +- gtk2_ardour/editor_pt_import.cc | 2 - gtk2_ardour/editor_regions.cc | 4 +- gtk2_ardour/editor_snapshots.cc | 6 +- gtk2_ardour/engine_dialog.h | 11 +- gtk2_ardour/enums.cc | 4 +- gtk2_ardour/location_ui.h | 4 +- gtk2_ardour/luawindow.cc | 4 +- gtk2_ardour/luawindow.h | 1 + gtk2_ardour/main.cc | 3 +- gtk2_ardour/midi_channel_selector.h | 10 +- gtk2_ardour/midi_scroomer.cc | 3 +- gtk2_ardour/midi_scroomer.h | 5 +- gtk2_ardour/mixer_strip.cc | 1 - gtk2_ardour/mixer_ui.cc | 17 +- gtk2_ardour/mixer_ui.h | 16 +- gtk2_ardour/monitor_section.cc | 2 +- gtk2_ardour/monitor_section.h | 6 +- gtk2_ardour/mono_panner.h | 4 +- gtk2_ardour/plugin_selector.cc | 7 +- gtk2_ardour/plugin_selector.h | 3 + gtk2_ardour/plugin_setup_dialog.cc | 2 + gtk2_ardour/port_insert_ui.h | 4 +- gtk2_ardour/processor_box.cc | 7 +- gtk2_ardour/prompter.cc | 2 +- gtk2_ardour/prompter.h | 4 +- gtk2_ardour/public_editor.h | 5 +- gtk2_ardour/rc_option_editor.cc | 7 +- gtk2_ardour/rc_option_editor.h | 4 +- gtk2_ardour/route_params_ui.h | 16 +- gtk2_ardour/route_ui.cc | 8 +- gtk2_ardour/session_dialog.cc | 1 + gtk2_ardour/shuttle_control.h | 14 +- gtk2_ardour/stereo_panner.h | 6 +- gtk2_ardour/strip_silence_dialog.cc | 1 + gtk2_ardour/toolbar_test.cc | 6 +- libs/gtkmm2ext/ardour_icon.cc | 1120 --------------------------- libs/gtkmm2ext/binding_proxy.cc | 116 --- libs/gtkmm2ext/choice.cc | 71 -- libs/gtkmm2ext/eventboxext.cc | 25 - libs/gtkmm2ext/gtk_ui.cc | 28 - libs/gtkmm2ext/gtkmm2ext/ardour_icon.h | 48 -- libs/gtkmm2ext/gtkmm2ext/binding_proxy.h | 63 -- libs/gtkmm2ext/gtkmm2ext/choice.h | 46 -- libs/gtkmm2ext/gtkmm2ext/eventboxext.h | 59 -- libs/gtkmm2ext/gtkmm2ext/pane.h | 134 ---- libs/gtkmm2ext/gtkmm2ext/paths_dialog.h | 57 -- libs/gtkmm2ext/gtkmm2ext/popup.h | 65 -- libs/gtkmm2ext/gtkmm2ext/prompter.h | 78 -- libs/gtkmm2ext/gtkmm2ext/scroomer.h | 93 --- libs/gtkmm2ext/gtkmm2ext/stateful_button.h | 95 --- libs/gtkmm2ext/gtkmm2ext/tabbable.h | 100 --- libs/gtkmm2ext/gtkmm2ext/tearoff.h | 92 --- libs/gtkmm2ext/pane.cc | 670 ----------------- libs/gtkmm2ext/paths_dialog.cc | 164 ---- libs/gtkmm2ext/popup.cc | 148 ---- libs/gtkmm2ext/prompter.cc | 139 ---- libs/gtkmm2ext/scroomer.cc | 408 ---------- libs/gtkmm2ext/stateful_button.cc | 273 ------- libs/gtkmm2ext/tabbable.cc | 387 ---------- libs/gtkmm2ext/tearoff.cc | 343 --------- libs/gtkmm2ext/wscript | 14 +- libs/widgets/ardour_button.cc | 9 +- libs/widgets/ardour_icon.cc | 1121 ++++++++++++++++++++++++++++ libs/widgets/binding_proxy.cc | 112 +++ libs/widgets/choice.cc | 71 ++ libs/widgets/eventboxext.cc | 25 + libs/widgets/pane.cc | 671 +++++++++++++++++ libs/widgets/paths_dialog.cc | 164 ++++ libs/widgets/popup.cc | 149 ++++ libs/widgets/prompter.cc | 138 ++++ libs/widgets/scroomer.cc | 408 ++++++++++ libs/widgets/stateful_button.cc | 273 +++++++ libs/widgets/tabbable.cc | 389 ++++++++++ libs/widgets/tearoff.cc | 341 +++++++++ libs/widgets/widgets/ardour_button.h | 10 +- libs/widgets/widgets/ardour_icon.h | 50 ++ libs/widgets/widgets/ardour_knob.h | 2 +- libs/widgets/widgets/barcontroller.h | 2 +- libs/widgets/widgets/binding_proxy.h | 68 ++ libs/widgets/widgets/choice.h | 47 ++ libs/widgets/widgets/click_box.h | 3 +- libs/widgets/widgets/eventboxext.h | 59 ++ libs/widgets/widgets/pane.h | 133 ++++ libs/widgets/widgets/paths_dialog.h | 57 ++ libs/widgets/widgets/popup.h | 64 ++ libs/widgets/widgets/prompter.h | 77 ++ libs/widgets/widgets/scroomer.h | 93 +++ libs/widgets/widgets/slider_controller.h | 4 +- libs/widgets/widgets/stateful_button.h | 95 +++ libs/widgets/widgets/tabbable.h | 102 +++ libs/widgets/widgets/tearoff.h | 92 +++ libs/widgets/wscript | 12 + 102 files changed, 4968 insertions(+), 4983 deletions(-) delete mode 100644 libs/gtkmm2ext/ardour_icon.cc delete mode 100644 libs/gtkmm2ext/binding_proxy.cc delete mode 100644 libs/gtkmm2ext/choice.cc delete mode 100644 libs/gtkmm2ext/eventboxext.cc delete mode 100644 libs/gtkmm2ext/gtkmm2ext/ardour_icon.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/binding_proxy.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/choice.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/eventboxext.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/pane.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/paths_dialog.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/popup.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/prompter.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/scroomer.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/stateful_button.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/tabbable.h delete mode 100644 libs/gtkmm2ext/gtkmm2ext/tearoff.h delete mode 100644 libs/gtkmm2ext/pane.cc delete mode 100644 libs/gtkmm2ext/paths_dialog.cc delete mode 100644 libs/gtkmm2ext/popup.cc delete mode 100644 libs/gtkmm2ext/prompter.cc delete mode 100644 libs/gtkmm2ext/scroomer.cc delete mode 100644 libs/gtkmm2ext/stateful_button.cc delete mode 100644 libs/gtkmm2ext/tabbable.cc delete mode 100644 libs/gtkmm2ext/tearoff.cc create mode 100644 libs/widgets/ardour_icon.cc create mode 100644 libs/widgets/binding_proxy.cc create mode 100644 libs/widgets/choice.cc create mode 100644 libs/widgets/eventboxext.cc create mode 100644 libs/widgets/pane.cc create mode 100644 libs/widgets/paths_dialog.cc create mode 100644 libs/widgets/popup.cc create mode 100644 libs/widgets/prompter.cc create mode 100644 libs/widgets/scroomer.cc create mode 100644 libs/widgets/stateful_button.cc create mode 100644 libs/widgets/tabbable.cc create mode 100644 libs/widgets/tearoff.cc create mode 100644 libs/widgets/widgets/ardour_icon.h create mode 100644 libs/widgets/widgets/binding_proxy.h create mode 100644 libs/widgets/widgets/choice.h create mode 100644 libs/widgets/widgets/eventboxext.h create mode 100644 libs/widgets/widgets/pane.h create mode 100644 libs/widgets/widgets/paths_dialog.h create mode 100644 libs/widgets/widgets/popup.h create mode 100644 libs/widgets/widgets/prompter.h create mode 100644 libs/widgets/widgets/scroomer.h create mode 100644 libs/widgets/widgets/stateful_button.h create mode 100644 libs/widgets/widgets/tabbable.h create mode 100644 libs/widgets/widgets/tearoff.h diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index f956161b06..b7f61a3fb7 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -74,7 +74,6 @@ #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/utils.h" -#include "gtkmm2ext/popup.h" #include "gtkmm2ext/window_title.h" #include "widgets/fastmeter.h" diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 80baef517c..f66f9b467b 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include #include @@ -151,7 +153,7 @@ namespace Gtk { class ProgressBar; } -namespace Gtkmm2ext { +namespace ArdourWidgets { class Tabbable; } @@ -414,15 +416,15 @@ private: bool _initial_verbose_plugin_scan; bool first_time_engine_run; - void show_tabbable (Gtkmm2ext::Tabbable*); - void hide_tabbable (Gtkmm2ext::Tabbable*); - void detach_tabbable (Gtkmm2ext::Tabbable*); - void attach_tabbable (Gtkmm2ext::Tabbable*); - void button_change_tabbable_visibility (Gtkmm2ext::Tabbable*); - void key_change_tabbable_visibility (Gtkmm2ext::Tabbable*); + void show_tabbable (ArdourWidgets::Tabbable*); + void hide_tabbable (ArdourWidgets::Tabbable*); + void detach_tabbable (ArdourWidgets::Tabbable*); + void attach_tabbable (ArdourWidgets::Tabbable*); + void button_change_tabbable_visibility (ArdourWidgets::Tabbable*); + void key_change_tabbable_visibility (ArdourWidgets::Tabbable*); void toggle_editor_and_mixer (); - void tabbable_state_change (Gtkmm2ext::Tabbable&); + void tabbable_state_change (ArdourWidgets::Tabbable&); void toggle_meterbridge (); void toggle_luawindow (); diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index 84f1145adb..87beab6b0e 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -153,7 +153,7 @@ ARDOUR_UI::tab_window_root_drop (GtkNotebook* src, using namespace std; Gtk::Notebook* nb = 0; Gtk::Window* win = 0; - Gtkmm2ext::Tabbable* tabbable = 0; + ArdourWidgets::Tabbable* tabbable = 0; if (w == GTK_WIDGET(editor->contents().gobj())) { diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index ffe39844bf..1a2188c85c 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -33,14 +33,15 @@ #include #include +#include "pbd/file_utils.h" +#include "pbd/fpu.h" +#include "pbd/convert.h" + #include "gtkmm2ext/cairo_packer.h" -#include "gtkmm2ext/tearoff.h" #include "gtkmm2ext/utils.h" #include "gtkmm2ext/window_title.h" -#include "pbd/file_utils.h" -#include "pbd/fpu.h" -#include "pbd/convert.h" +#include "widgets/tearoff.h" #include "ardour_ui.h" #include "public_editor.h" diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 58b731f293..6a20d81316 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -57,12 +57,10 @@ #include #include "gtkmm2ext/bindings.h" -#include "gtkmm2ext/eventboxext.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/keyboard.h" #include "gtkmm2ext/utils.h" #include "gtkmm2ext/window_title.h" -#include "gtkmm2ext/choice.h" #include "gtkmm2ext/cell_renderer_pixbuf_toggle.h" #include "ardour/analysis_graph.h" @@ -84,6 +82,7 @@ #include "canvas/text.h" #include "widgets/ardour_spacer.h" +#include "widgets/eventboxext.h" #include "widgets/tooltips.h" #include "control_protocol/control_protocol.h" @@ -761,11 +760,11 @@ Editor::Editor () ebox->set_name("EditorWindow"); ebox->add (toolbar_hbox); - Gtk::EventBox* epane_box = manage (new Gtkmm2ext::EventBoxExt); //a themeable box + Gtk::EventBox* epane_box = manage (new EventBoxExt); //a themeable box epane_box->set_name("EditorWindow"); epane_box->add (edit_pane); - Gtk::EventBox* epane_box2 = manage (new Gtkmm2ext::EventBoxExt); //a themeable box + Gtk::EventBox* epane_box2 = manage (new EventBoxExt); //a themeable box epane_box2->set_name("EditorWindow"); epane_box2->add (global_vpacker); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index ba1f989964..8be6dcf77c 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -36,7 +36,6 @@ #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/dndtreeview.h" -#include "gtkmm2ext/pane.h" #include "pbd/stateful.h" #include "pbd/signals.h" @@ -51,6 +50,7 @@ #include "widgets/ardour_button.h" #include "widgets/ardour_dropdown.h" +#include "widgets/pane.h" #include "ardour_dialog.h" #include "public_editor.h" @@ -635,8 +635,8 @@ private: void add_notebook_page (std::string const &, Gtk::Widget &); bool notebook_tab_clicked (GdkEventButton *, Gtk::Widget *); - Gtkmm2ext::HPane edit_pane; - Gtkmm2ext::VPane editor_summary_pane; + ArdourWidgets::HPane edit_pane; + ArdourWidgets::VPane editor_summary_pane; Gtk::EventBox meter_base; Gtk::HBox meter_box; diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 17ee8e17a1..9fc9361bd2 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -483,38 +483,38 @@ Editor::register_actions () act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-object", _("Object Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseObject)); mouse_move_button.set_related_action (act); - mouse_move_button.set_icon (Gtkmm2ext::ArdourIcon::ToolGrab); + mouse_move_button.set_icon (ArdourWidgets::ArdourIcon::ToolGrab); mouse_move_button.set_name ("mouse mode button"); act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-range", _("Range Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseRange)); mouse_select_button.set_related_action (act); - mouse_select_button.set_icon (Gtkmm2ext::ArdourIcon::ToolRange); + mouse_select_button.set_icon (ArdourWidgets::ArdourIcon::ToolRange); mouse_select_button.set_name ("mouse mode button"); act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-draw", _("Note Drawing Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseDraw)); mouse_draw_button.set_related_action (act); - mouse_draw_button.set_icon (Gtkmm2ext::ArdourIcon::ToolDraw); + mouse_draw_button.set_icon (ArdourWidgets::ArdourIcon::ToolDraw); mouse_draw_button.set_name ("mouse mode button"); act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-audition", _("Audition Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseAudition)); mouse_audition_button.set_related_action (act); - mouse_audition_button.set_icon (Gtkmm2ext::ArdourIcon::ToolAudition); + mouse_audition_button.set_icon (ArdourWidgets::ArdourIcon::ToolAudition); mouse_audition_button.set_name ("mouse mode button"); act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-timefx", _("Time FX Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseTimeFX)); mouse_timefx_button.set_related_action (act); - mouse_timefx_button.set_icon (Gtkmm2ext::ArdourIcon::ToolStretch); + mouse_timefx_button.set_icon (ArdourWidgets::ArdourIcon::ToolStretch); mouse_timefx_button.set_name ("mouse mode button"); act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-content", _("Content Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseContent)); mouse_content_button.set_related_action (act); - mouse_content_button.set_icon (Gtkmm2ext::ArdourIcon::ToolContent); + mouse_content_button.set_icon (ArdourWidgets::ArdourIcon::ToolContent); mouse_content_button.set_name ("mouse mode button"); if(!Profile->get_mixbus()) { act = myactions.register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-cut", _("Cut Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseCut)); mouse_cut_button.set_related_action (act); - mouse_cut_button.set_icon (Gtkmm2ext::ArdourIcon::ToolCut); + mouse_cut_button.set_icon (ArdourWidgets::ArdourIcon::ToolCut); mouse_cut_button.set_name ("mouse mode button"); } diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 1e8d157f14..c217f05823 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -31,7 +31,7 @@ #include "pbd/shortpath.h" #include "pbd/stateful_diff_command.h" -#include +#include "widgets/choice.h" #include "ardour/audio_track.h" #include "ardour/audiofilesource.h" @@ -651,7 +651,7 @@ Editor::embed_sndfiles (vector paths, choices.push_back (_("Don't embed it")); choices.push_back (_("Embed all without questions")); - Gtkmm2ext::Choice rate_choice ( + ArdourWidgets::Choice rate_choice ( _("Sample rate"), string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), short_path (path, 40)), @@ -677,7 +677,7 @@ Editor::embed_sndfiles (vector paths, choices.push_back (_("Cancel")); choices.push_back (_("Embed it anyway")); - Gtkmm2ext::Choice rate_choice ( + ArdourWidgets::Choice rate_choice ( _("Sample rate"), string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path), choices, false diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index f2cc8e3d04..1a4f88e2f2 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -27,8 +27,6 @@ #include "pbd/gstdio_compat.h" -#include "gtkmm2ext/choice.h" - #include "pbd/pthread_utils.h" #include "ardour/audio_track.h" diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 3cb62da846..17521e436c 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -36,9 +36,10 @@ #include "pbd/whitespace.h" #include "pbd/stateful_diff_command.h" -#include -#include -#include +#include "gtkmm2ext/utils.h" + +#include "widgets/choice.h" +#include "widgets/popup.h" #include "ardour/audio_track.h" #include "ardour/audioregion.h" @@ -5047,7 +5048,7 @@ Editor::remove_last_capture () choices.push_back (_("No, do nothing.")); choices.push_back (_("Yes, destroy it.")); - Gtkmm2ext::Choice prompter (_("Destroy last capture"), prompt, choices); + Choice prompter (_("Destroy last capture"), prompt, choices); if (prompter.run () == 1) { _session->remove_last_capture (); diff --git a/gtk2_ardour/editor_pt_import.cc b/gtk2_ardour/editor_pt_import.cc index cb3054a62b..55c3b0b43c 100644 --- a/gtk2_ardour/editor_pt_import.cc +++ b/gtk2_ardour/editor_pt_import.cc @@ -29,8 +29,6 @@ #include "pbd/shortpath.h" #include "pbd/stateful_diff_command.h" -#include - #include "ardour/audio_track.h" #include "ardour/audiofilesource.h" #include "ardour/audioregion.h" diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc index 83b3f00165..0372e1f3d8 100644 --- a/gtk2_ardour/editor_regions.cc +++ b/gtk2_ardour/editor_regions.cc @@ -33,10 +33,10 @@ #include "ardour/session.h" #include "ardour/profile.h" -#include "gtkmm2ext/choice.h" #include "gtkmm2ext/treeutils.h" #include "gtkmm2ext/utils.h" +#include "widgets/choice.h" #include "widgets/tooltips.h" #include "audio_clock.h" @@ -503,7 +503,7 @@ EditorRegions::remove_unused_regions () choices.push_back (_("No, do nothing.")); choices.push_back (_("Yes, remove.")); - Gtkmm2ext::Choice prompter (_("Remove unused regions"), prompt, choices); + ArdourWidgets::Choice prompter (_("Remove unused regions"), prompt, choices); if (prompter.run () == 1) { _no_redisplay = true; diff --git a/gtk2_ardour/editor_snapshots.cc b/gtk2_ardour/editor_snapshots.cc index 0a2ea085cd..8ab16cc48b 100644 --- a/gtk2_ardour/editor_snapshots.cc +++ b/gtk2_ardour/editor_snapshots.cc @@ -26,13 +26,13 @@ #include -#include "gtkmm2ext/choice.h" - #include "ardour/filename_extensions.h" #include "ardour/session.h" #include "ardour/session_state_utils.h" #include "ardour/session_directory.h" +#include "widgets/choice.h" + #include "editor_snapshots.h" #include "ardour_ui.h" #include "pbd/i18n.h" @@ -173,7 +173,7 @@ EditorSnapshots::remove (std::string name) choices.push_back (_("No, do nothing.")); choices.push_back (_("Yes, remove it.")); - Gtkmm2ext::Choice prompter (_("Remove snapshot"), prompt, choices); + ArdourWidgets::Choice prompter (_("Remove snapshot"), prompt, choices); if (prompter.run () == 1) { _session->remove_state (name); diff --git a/gtk2_ardour/engine_dialog.h b/gtk2_ardour/engine_dialog.h index b9bfabb61e..2f5399e564 100644 --- a/gtk2_ardour/engine_dialog.h +++ b/gtk2_ardour/engine_dialog.h @@ -24,14 +24,15 @@ #include #include +#include +#include +#include +#include #include +#include +#include #include -#include #include -#include -#include -#include -#include #include "pbd/signals.h" diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc index 2f141d23a9..608d257645 100644 --- a/gtk2_ardour/enums.cc +++ b/gtk2_ardour/enums.cc @@ -19,7 +19,7 @@ #include "pbd/enumwriter.h" -#include "gtkmm2ext/ardour_icon.h" +#include "widgets/ardour_icon.h" #include "audio_clock.h" #include "editing.h" @@ -30,7 +30,7 @@ using namespace std; using namespace PBD; using namespace ARDOUR; using namespace Editing; -using namespace Gtkmm2ext; +using namespace ArdourWidgets; void setup_gtk_ardour_enums () diff --git a/gtk2_ardour/location_ui.h b/gtk2_ardour/location_ui.h index 0d1115feba..46495aa4fc 100644 --- a/gtk2_ardour/location_ui.h +++ b/gtk2_ardour/location_ui.h @@ -33,8 +33,8 @@ #include "ardour/location.h" #include "ardour/session_handle.h" -#include "gtkmm2ext/pane.h" #include "widgets/ardour_button.h" +#include "widgets/pane.h" #include "ardour_window.h" #include "audio_clock.h" @@ -180,7 +180,7 @@ private: LocationEditRow punch_edit_row; Gtk::VBox loop_punch_box; - Gtkmm2ext::VPane loc_range_panes; + ArdourWidgets::VPane loc_range_panes; Gtk::VBox loc_frame_box; Gtk::Button add_location_button; diff --git a/gtk2_ardour/luawindow.cc b/gtk2_ardour/luawindow.cc index 8a9c2aee3b..beb2cc0356 100644 --- a/gtk2_ardour/luawindow.cc +++ b/gtk2_ardour/luawindow.cc @@ -34,10 +34,10 @@ #include "pbd/md5.h" #include "gtkmm2ext/gtk_ui.h" -#include "gtkmm2ext/pane.h" #include "gtkmm2ext/utils.h" #include "gtkmm2ext/window_title.h" +#include "widgets/pane.h" #include "widgets/tooltips.h" #include "ardour/filesystem_paths.h" @@ -156,7 +156,7 @@ LuaWindow::LuaWindow () vbox->pack_start (*scrollin, true, true, 0); vbox->pack_start (*hbox, false, false, 2); - Gtkmm2ext::VPane *vpane = manage (new Gtkmm2ext::VPane ()); + ArdourWidgets::VPane *vpane = manage (new ArdourWidgets::VPane ()); vpane->add (*vbox); vpane->add (scrollout); vpane->set_divider (0, 0.75); diff --git a/gtk2_ardour/luawindow.h b/gtk2_ardour/luawindow.h index 3994970adb..c786e4d63a 100644 --- a/gtk2_ardour/luawindow.h +++ b/gtk2_ardour/luawindow.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "pbd/signals.h" diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 1113fce769..9c9981bcc3 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -48,8 +48,9 @@ #include "ardour/filesystem_paths.h" #include +#include + #include -#include #include #include "ardour_ui.h" diff --git a/gtk2_ardour/midi_channel_selector.h b/gtk2_ardour/midi_channel_selector.h index 7f1281d7d0..c7c754c2b7 100644 --- a/gtk2_ardour/midi_channel_selector.h +++ b/gtk2_ardour/midi_channel_selector.h @@ -30,7 +30,7 @@ #include "gtkmm/radiobutton.h" #include "gtkmm/label.h" -#include "gtkmm2ext/stateful_button.h" +#include "widgets/stateful_button.h" #include "ardour/types.h" @@ -53,11 +53,11 @@ public: protected: virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr) = 0; - Gtk::Label _button_labels[4][4]; - Gtkmm2ext::StatefulToggleButton _buttons[4][4]; - int _recursion_counter; + Gtk::Label _button_labels[4][4]; + ArdourWidgets::StatefulToggleButton _buttons[4][4]; + int _recursion_counter; - bool was_clicked (GdkEventButton*); + bool was_clicked (GdkEventButton*); }; class SingleMidiChannelSelector : public MidiChannelSelector diff --git a/gtk2_ardour/midi_scroomer.cc b/gtk2_ardour/midi_scroomer.cc index 0cd7eae46a..6fad2cc1f1 100644 --- a/gtk2_ardour/midi_scroomer.cc +++ b/gtk2_ardour/midi_scroomer.cc @@ -22,14 +22,13 @@ #include "midi_scroomer.h" #include "ui_config.h" -using namespace Gtkmm2ext; using namespace Gtk; using namespace std; //std::map > MidiScroomer::piano_pixmaps; MidiScroomer::MidiScroomer(Adjustment& adj) - : Gtkmm2ext::Scroomer(adj) + : ArdourWidgets::Scroomer(adj) { adj.set_lower(0); diff --git a/gtk2_ardour/midi_scroomer.h b/gtk2_ardour/midi_scroomer.h index 2b4ebe6c64..bbf1ec3d64 100644 --- a/gtk2_ardour/midi_scroomer.h +++ b/gtk2_ardour/midi_scroomer.h @@ -20,10 +20,9 @@ #ifndef __ardour_midi_scroomer_h__ #define __ardour_midi_scroomer_h__ -#include -#include +#include "widgets/scroomer.h" -class MidiScroomer : public Gtkmm2ext::Scroomer +class MidiScroomer : public ArdourWidgets::Scroomer { public: MidiScroomer(Gtk::Adjustment&); diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 32a82fc2a6..8f101ee09d 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -30,7 +30,6 @@ #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/menu_elems.h" #include "gtkmm2ext/utils.h" -#include "gtkmm2ext/choice.h" #include "gtkmm2ext/doi.h" #include "widgets/tooltips.h" diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 02391a3a44..88489f8cc3 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -33,15 +33,6 @@ #include "pbd/stacktrace.h" #include "pbd/unwind.h" -#include - -#include -#include -#include -#include -#include -#include - #include "ardour/amp.h" #include "ardour/debug.h" #include "ardour/audio_track.h" @@ -53,6 +44,14 @@ #include "ardour/vca.h" #include "ardour/vca_manager.h" +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/keyboard.h" +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/window_title.h" +#include "gtkmm2ext/doi.h" + +#include "widgets/tearoff.h" + #include "keyboard.h" #include "mixer_ui.h" #include "mixer_strip.h" diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index adf86b09d2..9485ea252f 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "pbd/stateful.h" @@ -43,10 +44,11 @@ #include #include "gtkmm2ext/dndtreeview.h" -#include -#include "gtkmm2ext/tabbable.h" #include "gtkmm2ext/treeutils.h" +#include "widgets/pane.h" +#include "widgets/tabbable.h" + #include "axis_provider.h" #include "enums.h" #include "route_processor_selection.h" @@ -77,7 +79,7 @@ protected: virtual bool row_drop_possible_vfunc (const Gtk::TreeModel::Path&, const Gtk::SelectionData&) const; }; -class Mixer_UI : public Gtkmm2ext::Tabbable, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr, public AxisViewProvider +class Mixer_UI : public ArdourWidgets::Tabbable, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr, public AxisViewProvider { public: static Mixer_UI* instance(); @@ -152,9 +154,9 @@ private: Gtk::Frame track_display_frame; Gtk::Frame group_display_frame; Gtk::Frame favorite_plugins_frame; - Gtkmm2ext::VPane rhs_pane1; - Gtkmm2ext::VPane rhs_pane2; - Gtkmm2ext::HPane inner_pane; + ArdourWidgets::VPane rhs_pane1; + ArdourWidgets::VPane rhs_pane2; + ArdourWidgets::HPane inner_pane; Gtk::HBox strip_packer; Gtk::ScrolledWindow vca_scroller; Gtk::HBox vca_hpacker; @@ -163,7 +165,7 @@ private: Gtk::Label vca_label; Gtk::EventBox vca_scroller_base; Gtk::HBox out_packer; - Gtkmm2ext::HPane list_hpane; + ArdourWidgets::HPane list_hpane; MixerGroupTabs* _group_tabs; diff --git a/gtk2_ardour/monitor_section.cc b/gtk2_ardour/monitor_section.cc index ca0b23399d..4ec75a4ce4 100644 --- a/gtk2_ardour/monitor_section.cc +++ b/gtk2_ardour/monitor_section.cc @@ -23,13 +23,13 @@ #include "pbd/error.h" #include "pbd/replace_all.h" -#include "gtkmm2ext/tearoff.h" #include "gtkmm2ext/actions.h" #include "gtkmm2ext/utils.h" #include #include +#include "widgets/tearoff.h" #include "widgets/tooltips.h" #include "ardour/amp.h" diff --git a/gtk2_ardour/monitor_section.h b/gtk2_ardour/monitor_section.h index ca85aa5457..9e3cec59bc 100644 --- a/gtk2_ardour/monitor_section.h +++ b/gtk2_ardour/monitor_section.h @@ -35,7 +35,7 @@ #include "processor_box.h" #include "processor_selection.h" -namespace Gtkmm2ext { +namespace ArdourWidgets { class TearOff; } @@ -47,7 +47,7 @@ public: void set_session (ARDOUR::Session*); - Gtkmm2ext::TearOff& tearoff() const { return *_tearoff; } + ArdourWidgets::TearOff& tearoff() const { return *_tearoff; } std::string state_id() const; @@ -56,7 +56,7 @@ public: private: Gtk::HBox hpacker; Gtk::VBox vpacker; - Gtkmm2ext::TearOff* _tearoff; + ArdourWidgets::TearOff* _tearoff; Gtk::HBox channel_table_packer; Gtk::HBox table_hpacker; diff --git a/gtk2_ardour/mono_panner.h b/gtk2_ardour/mono_panner.h index aef11d9c7a..5022e9b52d 100644 --- a/gtk2_ardour/mono_panner.h +++ b/gtk2_ardour/mono_panner.h @@ -24,7 +24,7 @@ #include -#include "gtkmm2ext/binding_proxy.h" +#include "widgets/binding_proxy.h" #include "panner_interface.h" @@ -72,7 +72,7 @@ private: double accumulated_delta; bool detented; - BindingProxy position_binder; + ArdourWidgets::BindingProxy position_binder; void set_tooltip (); diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index cd904f6cd9..0a609eb9cd 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -25,10 +25,13 @@ #include -#include -#include #include +#include +#include +#include #include +#include +#include #include "gtkmm2ext/utils.h" #include "pbd/convert.h" diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h index 548ed826ff..14aa47322d 100644 --- a/gtk2_ardour/plugin_selector.h +++ b/gtk2_ardour/plugin_selector.h @@ -23,6 +23,9 @@ #include #include #include +#include +#include + #include "gtkmm2ext/dndtreeview.h" #include "ardour/plugin.h" diff --git a/gtk2_ardour/plugin_setup_dialog.cc b/gtk2_ardour/plugin_setup_dialog.cc index c3bbc0dbc0..db128b5c5f 100644 --- a/gtk2_ardour/plugin_setup_dialog.cc +++ b/gtk2_ardour/plugin_setup_dialog.cc @@ -19,6 +19,8 @@ #include #include +#include +#include #include "plugin_setup_dialog.h" #include "pbd/i18n.h" diff --git a/gtk2_ardour/port_insert_ui.h b/gtk2_ardour/port_insert_ui.h index a04ef1fe40..3249cb0c3f 100644 --- a/gtk2_ardour/port_insert_ui.h +++ b/gtk2_ardour/port_insert_ui.h @@ -20,7 +20,7 @@ #ifndef __gtkardour_port_insert_ui_h__ #define __gtkardour_port_insert_ui_h__ -#include "gtkmm2ext/stateful_button.h" +#include "widgets/stateful_button.h" #include "ardour_dialog.h" #include "io_selector.h" @@ -40,7 +40,7 @@ private: boost::shared_ptr _pi; Gtk::Notebook notebook; - Gtkmm2ext::StatefulToggleButton latency_button; + ArdourWidgets::StatefulToggleButton latency_button; IOSelector input_selector; IOSelector output_selector; Gtk::Label latency_display; diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index a3d1833e34..ec29255d90 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -37,11 +37,10 @@ #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/menu_elems.h" #include "gtkmm2ext/utils.h" -#include "gtkmm2ext/choice.h" -#include "gtkmm2ext/utils.h" #include "gtkmm2ext/doi.h" #include "gtkmm2ext/rgb_macros.h" +#include "widgets/choice.h" #include "widgets/tooltips.h" #include "ardour/amp.h" @@ -3470,7 +3469,7 @@ ProcessorBox::clear_processors () choices.push_back (_("Cancel")); choices.push_back (_("Yes, remove them all")); - Gtkmm2ext::Choice prompter (_("Remove processors"), prompt, choices); + ArdourWidgets::Choice prompter (_("Remove processors"), prompt, choices); if (prompter.run () == 1) { _route->clear_processors (PreFader); @@ -3495,7 +3494,7 @@ ProcessorBox::clear_processors (Placement p) choices.push_back (_("Cancel")); choices.push_back (_("Yes, remove them all")); - Gtkmm2ext::Choice prompter (_("Remove processors"), prompt, choices); + ArdourWidgets::Choice prompter (_("Remove processors"), prompt, choices); if (prompter.run () == 1) { _route->clear_processors (p); diff --git a/gtk2_ardour/prompter.cc b/gtk2_ardour/prompter.cc index 16428eef19..6cf9018dbc 100644 --- a/gtk2_ardour/prompter.cc +++ b/gtk2_ardour/prompter.cc @@ -20,7 +20,7 @@ #include "prompter.h" ArdourPrompter::ArdourPrompter (bool modal) - : Gtkmm2ext::Prompter (modal) + : ArdourWidgets::Prompter (modal) { } diff --git a/gtk2_ardour/prompter.h b/gtk2_ardour/prompter.h index cea78f6b22..b01f845baf 100644 --- a/gtk2_ardour/prompter.h +++ b/gtk2_ardour/prompter.h @@ -20,9 +20,9 @@ #ifndef __ardour_gtk_prompter_h__ #define __ardour_gtk_prompter_h__ -#include +#include "widgets/prompter.h" -class ArdourPrompter : public Gtkmm2ext::Prompter +class ArdourPrompter : public ArdourWidgets::Prompter { public: ArdourPrompter (bool modal = false); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index b83a806b00..183ae1cc8d 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -46,9 +46,10 @@ #include "gtkmm2ext/actions.h" #include "gtkmm2ext/bindings.h" -#include "gtkmm2ext/tabbable.h" #include "gtkmm2ext/visibility_tracker.h" +#include "widgets/tabbable.h" + #include "axis_provider.h" #include "editing.h" #include "selection.h" @@ -108,7 +109,7 @@ using ARDOUR::framecnt_t; * of PublicEditor need not be recompiled if private methods or member variables * change. */ -class PublicEditor : public Gtkmm2ext::Tabbable, public ARDOUR::SessionHandlePtr, public AxisViewProvider +class PublicEditor : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public AxisViewProvider { public: PublicEditor (Gtk::Widget& content); diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index edc85643d2..b69cddf89e 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -35,7 +35,6 @@ #include "gtkmm2ext/utils.h" #include "gtkmm2ext/gtk_ui.h" -#include "gtkmm2ext/paths_dialog.h" #include "gtkmm2ext/window_title.h" #include "pbd/fpu.h" @@ -53,6 +52,8 @@ #include "control_protocol/control_protocol.h" #include "canvas/wave_view.h" + +#include "widgets/paths_dialog.h" #include "widgets/tooltips.h" #include "ardour_dialog.h" @@ -3995,7 +3996,7 @@ void RCOptionEditor::clear_au_blacklist () { void RCOptionEditor::edit_lxvst_path () { Glib::RefPtr win = get_parent_window (); - Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog ( + PathsDialog *pd = new PathsDialog ( *current_toplevel(), _("Set Linux VST Search Path"), _rc_config->get_plugin_path_lxvst(), PluginManager::instance().get_default_lxvst_path() @@ -4017,7 +4018,7 @@ void RCOptionEditor::edit_lxvst_path () { } void RCOptionEditor::edit_vst_path () { - Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog ( + PathsDialog *pd = new PathsDialog ( *current_toplevel(), _("Set Windows VST Search Path"), _rc_config->get_plugin_path_vst(), PluginManager::instance().get_default_windows_vst_path() diff --git a/gtk2_ardour/rc_option_editor.h b/gtk2_ardour/rc_option_editor.h index d6c5bed4a7..3a3283e86c 100644 --- a/gtk2_ardour/rc_option_editor.h +++ b/gtk2_ardour/rc_option_editor.h @@ -20,7 +20,7 @@ #ifndef __gtk_ardour_rc_option_editor_h__ #define __gtk_ardour_rc_option_editor_h__ -#include "gtkmm2ext/tabbable.h" +#include "widgets/tabbable.h" #include "option_editor.h" #include "visibility_group.h" @@ -34,7 +34,7 @@ */ /** Editor for options which are obtained from and written back to one of the .rc files. */ -class RCOptionEditor : public OptionEditorContainer, public ARDOUR::SessionHandlePtr, public Gtkmm2ext::Tabbable +class RCOptionEditor : public OptionEditorContainer, public ARDOUR::SessionHandlePtr, public ArdourWidgets::Tabbable { public: RCOptionEditor (); diff --git a/gtk2_ardour/route_params_ui.h b/gtk2_ardour/route_params_ui.h index fea6d02050..76a56c7957 100644 --- a/gtk2_ardour/route_params_ui.h +++ b/gtk2_ardour/route_params_ui.h @@ -36,7 +36,7 @@ #include "ardour/ardour.h" -#include +#include #include "ardour_window.h" #include "processor_box.h" @@ -71,22 +71,22 @@ private: Gtk::ScrolledWindow route_select_scroller; Gtk::Notebook notebook; - Gtk::Frame input_frame; - Gtk::Frame output_frame; - Gtkmm2ext::HPane redir_hpane; + Gtk::Frame input_frame; + Gtk::Frame output_frame; + ArdourWidgets::HPane redir_hpane; - Gtk::Frame route_select_frame; + Gtk::Frame route_select_frame; Gtk::HBox route_hpacker; Gtk::VBox route_vpacker; ProcessorBox* insert_box; - Gtkmm2ext::HPane list_hpane; + ArdourWidgets::HPane list_hpane; - Gtkmm2ext::HPane right_hpane; + ArdourWidgets::HPane right_hpane; - Gtk::Frame route_param_frame; + Gtk::Frame route_param_frame; Gtk::VBox choice_vpacker; diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index e5c4d196f5..be5807dbf7 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -21,12 +21,12 @@ #include #include "gtkmm2ext/gtk_ui.h" -#include "gtkmm2ext/choice.h" #include "gtkmm2ext/doi.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/utils.h" #include "widgets/ardour_button.h" +#include "widgets/binding_proxy.h" #include "pbd/memento_command.h" #include "pbd/stacktrace.h" @@ -416,7 +416,7 @@ RouteUI::mute_press (GdkEventButton* ev) } //if this is a binding action, let the ArdourButton handle it - if ( BindingProxy::is_bind_action(ev) ) + if (BindingProxy::is_bind_action(ev) ) return false; multiple_mute_change = false; @@ -591,7 +591,7 @@ RouteUI::solo_press(GdkEventButton* ev) } //if this is a binding action, let the ArdourButton handle it - if ( BindingProxy::is_bind_action(ev) ) + if (BindingProxy::is_bind_action(ev) ) return false; multiple_solo_change = false; @@ -767,7 +767,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev) } //if this is a binding action, let the ArdourButton handle it - if ( BindingProxy::is_bind_action(ev) ) + if (BindingProxy::is_bind_action(ev) ) return false; if (!_session->engine().connected()) { diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index 7490b48b8f..bec810d53e 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -30,6 +30,7 @@ #include #include +#include #include "pbd/basename.h" #include "pbd/failed_constructor.h" diff --git a/gtk2_ardour/shuttle_control.h b/gtk2_ardour/shuttle_control.h index 1b6cce5870..bba5f17df1 100644 --- a/gtk2_ardour/shuttle_control.h +++ b/gtk2_ardour/shuttle_control.h @@ -21,15 +21,15 @@ #include -#include "gtkmm2ext/binding_proxy.h" -#include "gtkmm2ext/cairo_widget.h" - #include "pbd/controllable.h" #include "ardour/session_handle.h" #include "ardour/types.h" +#include "gtkmm2ext/cairo_widget.h" + #include "widgets/ardour_button.h" +#include "widgets/binding_proxy.h" namespace Gtk { class Menu; @@ -76,10 +76,10 @@ protected: ARDOUR::microseconds_t last_shuttle_request; PBD::ScopedConnection parameter_connection; ArdourWidgets::ArdourButton _info_button; - Gtk::Menu* shuttle_unit_menu; - Gtk::Menu* shuttle_style_menu; - Gtk::Menu* shuttle_context_menu; - BindingProxy binding_proxy; + Gtk::Menu* shuttle_unit_menu; + Gtk::Menu* shuttle_style_menu; + Gtk::Menu* shuttle_context_menu; + ArdourWidgets::BindingProxy binding_proxy; float bg_r, bg_g, bg_b; void build_shuttle_context_menu (); void shuttle_style_changed(); diff --git a/gtk2_ardour/stereo_panner.h b/gtk2_ardour/stereo_panner.h index d897bd3644..f1e1025d76 100644 --- a/gtk2_ardour/stereo_panner.h +++ b/gtk2_ardour/stereo_panner.h @@ -21,7 +21,7 @@ #define __gtk_ardour_stereo_panner_h__ #include "pbd/signals.h" -#include "gtkmm2ext/binding_proxy.h" +#include "widgets/binding_proxy.h" #include "panner_interface.h" namespace ARDOUR { @@ -79,8 +79,8 @@ private: double accumulated_delta; bool detented; - BindingProxy position_binder; - BindingProxy width_binder; + ArdourWidgets::BindingProxy position_binder; + ArdourWidgets::BindingProxy width_binder; void set_tooltip (); diff --git a/gtk2_ardour/strip_silence_dialog.cc b/gtk2_ardour/strip_silence_dialog.cc index 5fa115d692..52f05a6b94 100644 --- a/gtk2_ardour/strip_silence_dialog.cc +++ b/gtk2_ardour/strip_silence_dialog.cc @@ -21,6 +21,7 @@ #include #include +#include #include #include "ardour/audioregion.h" diff --git a/gtk2_ardour/toolbar_test.cc b/gtk2_ardour/toolbar_test.cc index e1b9623bc3..ab248fde72 100644 --- a/gtk2_ardour/toolbar_test.cc +++ b/gtk2_ardour/toolbar_test.cc @@ -100,7 +100,7 @@ LogReceiver::receive (Transmitter::Channel chn, const char * str) /* ***************************************************************************/ void -setup_action_button (ArdourButton& button, std::string const & action, Gtkmm2ext::ArdourIcon::Icon icon, std::string const & button_theme_name) +setup_action_button (ArdourButton& button, std::string const & action, ArdourWidgets::ArdourIcon::Icon icon, std::string const & button_theme_name) { button.set_name (button_theme_name + string (" button")); Glib::RefPtr act; @@ -110,7 +110,7 @@ setup_action_button (ArdourButton& button, std::string const & action, Gtkmm2ext } ArdourButton* -make_action_button (std::string const & action, Gtkmm2ext::ArdourIcon::Icon icon, std::string const & button_theme_name) +make_action_button (std::string const & action, ArdourWidgets::ArdourIcon::Icon icon, std::string const & button_theme_name) { ArdourButton* button = new ArdourButton; setup_action_button (*button, action, icon, button_theme_name); @@ -227,7 +227,7 @@ CANVAS_UI::build_toolbar (ArdourCanvas::Item* parent, std::string const & spec_p break; } - Gtkmm2ext::ArdourIcon::Icon i = (ArdourIcon::Icon) string_2_enum (string ("ArdourIcon::") + icon, i); + ArdourWidgets::ArdourIcon::Icon i = (ArdourWidgets::ArdourIcon::Icon) string_2_enum (string ("ArdourIcon::") + icon, i); ArdourCanvas::Widget* w = new ArdourCanvas::Widget (canvas, *make_action_button (action, i, theme_name)); grid->place (w, col, row); diff --git a/libs/gtkmm2ext/ardour_icon.cc b/libs/gtkmm2ext/ardour_icon.cc deleted file mode 100644 index e46ee6a2b4..0000000000 --- a/libs/gtkmm2ext/ardour_icon.cc +++ /dev/null @@ -1,1120 +0,0 @@ -/* - Copyright (C) 2009 Paul Davis - Copyright (C) 2015 Robin Gareus - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -*/ - -#include // M_PI -#include -#include // std:min -#include "gtkmm2ext/ardour_icon.h" - -using namespace Gtkmm2ext::ArdourIcon; - -/* general style info: - * - * - geometry: icons should be centered, spanning - * wh = std::min (width * .5, height *.5) * .55; - * - * - all shapes should have a contrasting outline - * (usually white foreground, black outline) - */ - -#define OUTLINEWIDTH 1.5 // px - -#define VECTORICONSTROKEFILL(fillalpha) \ - cairo_set_line_width (cr, OUTLINEWIDTH); \ - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); \ - cairo_stroke_preserve (cr); \ - cairo_set_source_rgba (cr, 1, 1, 1, (fillalpha)); \ - cairo_fill (cr); - -#define VECTORICONSTROKEOUTLINE(LW, color) \ - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); \ - cairo_set_line_width (cr, (LW) + OUTLINEWIDTH); \ - ardour_icon_set_source_inv_rgba (cr, color); \ - cairo_stroke_preserve (cr); \ - ardour_icon_set_source_rgba (cr, color); \ - cairo_set_line_width (cr, (LW)); \ - cairo_stroke (cr); - - -/** convert 32bit 'RRGGBBAA' to cairo doubles - * from libs/canvas/utils.cc and canvas/types.h: typedef uint32_t Color; - */ -static void ardour_icon_set_source_rgba (cairo_t *cr, uint32_t color) -{ - cairo_set_source_rgba (cr, - ((color >> 24) & 0xff) / 255.0, - ((color >> 16) & 0xff) / 255.0, - ((color >> 8) & 0xff) / 255.0, - ((color >> 0) & 0xff) / 255.0 - ); -} - -/** inverse color */ -static void ardour_icon_set_source_inv_rgba (cairo_t *cr, uint32_t color) -{ - cairo_set_source_rgba (cr, - 1.0 - ((color >> 24) & 0xff) / 255.0, - 1.0 - ((color >> 16) & 0xff) / 255.0, - 1.0 - ((color >> 8) & 0xff) / 255.0, - ((color >> 0) & 0xff) / 255.0 - ); -} - -/***************************************************************************** - * Tool Icons. - * Foreground is always white, compatible with small un-blurred rendering. - */ - -/** internal edit icon */ -static void icon_tool_content (cairo_t *cr, const int width, const int height) { -#define EM_POINT(X,Y) round (x + (X) * em) + .5, round (y + (Y) * em) + .5 - - const double x = width * .5; - const double y = height * .5; - const double em = std::min (x, y) * .1; // 1px at 20x20 - - // draw dot outlines (control-points) - cairo_move_to (cr, EM_POINT(-6.0, 0.0)); - cairo_close_path (cr); - cairo_move_to (cr, EM_POINT(-2.5, 4.0)); - cairo_close_path (cr); - cairo_move_to (cr, EM_POINT( 5.0, -5.0)); - cairo_close_path (cr); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - ardour_icon_set_source_inv_rgba (cr, 0xffffffff); - cairo_set_line_width (cr, 3 * em + OUTLINEWIDTH); - cairo_stroke (cr); - - // "midi note" lines - cairo_move_to (cr, EM_POINT(-7.0, -5.0)); - cairo_line_to (cr, EM_POINT( 0.0, -5.0)); - - cairo_move_to (cr, EM_POINT( 2.0, 4.0)); - cairo_line_to (cr, EM_POINT( 6.0, 4.0)); - - // automation line (connect control-points) - cairo_move_to (cr, EM_POINT(-6.0, 0.0)); - cairo_line_to (cr, EM_POINT(-2.5, 4.0)); - cairo_line_to (cr, EM_POINT( 5.0, -5.0)); - - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - VECTORICONSTROKEOUTLINE(1 * em, 0xffffffff); - - // remove automation line outline at control-points - cairo_move_to (cr, EM_POINT(-6.0, 0.0)); - cairo_close_path (cr); - cairo_move_to (cr, EM_POINT(-2.5, 4.0)); - cairo_close_path (cr); - cairo_move_to (cr, EM_POINT( 5.0, -5.0)); - cairo_close_path (cr); - - ardour_icon_set_source_rgba (cr, 0xffffffff); - cairo_set_line_width (cr, 3 * em); - cairo_stroke (cr); -#undef EM_POINT -} - -/** range tool |<->| */ -static void icon_tool_range (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y) * .55; - const double lw = rint (wh / 6.0); // line width - const double ar = wh * .6; // arrow - - const double bw = ceil (wh) - .5; - const double y0 = ceil (y); - const double ym = rint (y0 - wh * .1) + .5; // arrow-horizontal; slightly to the top, on a px - const double x0 = rint (x) - bw; // left arrow tip - const double x1 = rint (x) + bw; // right arrow tip - - // left and right box - cairo_move_to (cr, x0, y0 - bw); - cairo_line_to (cr, x0, y0 + bw); - VECTORICONSTROKEOUTLINE(lw, 0xffffffff); - cairo_move_to (cr, x1, y0 - bw); - cairo_line_to (cr, x1, y0 + bw); - VECTORICONSTROKEOUTLINE(lw, 0xffffffff); - - // arrows - cairo_move_to (cr, x0 + ar, ym - ar); - cairo_line_to (cr, x0 + .5, ym); - cairo_line_to (cr, x0 + ar, ym + ar); - - cairo_move_to (cr, x1 - ar, ym - ar); - cairo_line_to (cr, x1 - .5, ym); - cairo_line_to (cr, x1 - ar, ym + ar); - - // line connecting the arrows - cairo_move_to (cr, x0, ym); - cairo_line_to (cr, x1, ym); - VECTORICONSTROKEOUTLINE(lw, 0xffffffff); - - cairo_set_source_rgba (cr, 1, 1, 1, 1.0); - cairo_set_line_width (cr, lw); - - cairo_move_to (cr, x0, y0 - bw); - cairo_line_to (cr, x0, y0 + bw); - cairo_stroke (cr); - - cairo_move_to (cr, x1, y0 - bw); - cairo_line_to (cr, x1, y0 + bw); - cairo_stroke (cr); - - -} - -/** Grab/Object tool - 6x8em "hand", with 'em' wide index finger. */ -static void icon_tool_grab (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double em = std::min (x, y) * .15; // 1.5px at 20x20 - -#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em - - // wrist - cairo_move_to (cr, EM_POINT( 2.0, 4.0)); - cairo_line_to (cr, EM_POINT(-1.5, 4.0)); - cairo_line_to (cr, EM_POINT(-2.5, 2.0)); - // thumb - cairo_line_to (cr, EM_POINT(-3.0, 1.0)); - - // index finger - cairo_line_to (cr, EM_POINT(-2.0, 0.0)); - cairo_line_to (cr, EM_POINT(-2.1, -4.0)); - cairo_line_to (cr, EM_POINT(-1.5, -4.5)); - cairo_line_to (cr, EM_POINT(-1.1, -4.0)); - cairo_line_to (cr, EM_POINT(-1.0, 0.1)); - - // middle finger knuckle - cairo_line_to (cr, EM_POINT(-0.6, 0.3)); - cairo_line_to (cr, EM_POINT(-0.3, 0.0)); - cairo_line_to (cr, EM_POINT(-0.2, -0.2)); - cairo_line_to (cr, EM_POINT( 0.1, -0.3)); - cairo_line_to (cr, EM_POINT( 0.4, -0.2)); - cairo_line_to (cr, EM_POINT( 0.5, 0.1)); - - // ring finger knuckle - cairo_line_to (cr, EM_POINT( 0.8, 0.4)); - cairo_line_to (cr, EM_POINT( 1.1, 0.2)); - cairo_line_to (cr, EM_POINT( 1.2, 0.0)); - cairo_line_to (cr, EM_POINT( 1.5, -0.1)); - cairo_line_to (cr, EM_POINT( 1.8, 0.0)); - cairo_line_to (cr, EM_POINT( 1.9, 0.4)); - - // pinky - cairo_line_to (cr, EM_POINT( 2.0, 0.6)); - cairo_line_to (cr, EM_POINT( 2.4, 0.4)); - cairo_line_to (cr, EM_POINT( 2.8, 0.5)); - cairo_line_to (cr, EM_POINT( 3.0, 1.0)); - - // wrist - cairo_line_to (cr, EM_POINT( 3.0, 1.5)); - cairo_line_to (cr, EM_POINT( 2.0, 4.0)); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - VECTORICONSTROKEFILL(1.0); -#undef EM_POINT -} - -/** cut icon - scissors */ -static void icon_tool_cut (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double em = std::min (x, y) * .1; // 1px at 20x20 - -#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em - - cairo_save (cr); - cairo_translate (cr, EM_POINT(4, -3)); - cairo_scale (cr, 1.6, 1.0); // ellipse - cairo_arc (cr, 0., 0., 1.5 * em, 0., 2 * M_PI); - cairo_restore (cr); - - cairo_move_to (cr, EM_POINT(-6.0, 2.5)); - cairo_line_to (cr, EM_POINT( 5.5, -2.0)); - - cairo_move_to (cr, EM_POINT(-6.0, -2.5)); - cairo_line_to (cr, EM_POINT( 5.5, 2.0)); - - cairo_save (cr); - cairo_translate (cr, EM_POINT(4, 3)); - cairo_scale (cr, 1.6, 1.0); // ellipse - cairo_arc (cr, 0., 0., 1.5 * em, 0., 2 * M_PI); - cairo_restore (cr); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - - VECTORICONSTROKEOUTLINE (1.5 * em, 0xffffffff); -#undef EM_POINT -} - -/** time stretch icon */ -static void icon_tool_stretch (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y) * .55; - - const double y0 = ceil (y); - const double bw = rint (wh); - const double lw = rint (wh / 3.0) / 2.0; - const double x0 = rint (x + lw) + .5; - - // box indication region - cairo_rectangle (cr, x0 - lw - bw - .5, y0 - bw, lw + bw, 2 * bw); - VECTORICONSTROKEFILL (0.75); - - cairo_set_line_width (cr, 1.0); - - // inside/left arrow - cairo_move_to (cr, x0, y); - cairo_line_to (cr, x0 - lw * 2, y); - cairo_line_to (cr, x0 - lw * 2, y - lw * 3.5); - cairo_line_to (cr, x0 - lw * 6, y); - cairo_line_to (cr, x0 - lw * 2, y + lw * 3.5); - cairo_line_to (cr, x0 - lw * 2, y); - - cairo_set_source_rgba (cr, 0, 0, 0, .5); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); - - // outside/right arrow - cairo_move_to (cr, x0, y); - cairo_line_to (cr, x0 + lw * 2, y); - cairo_line_to (cr, x0 + lw * 2, y - lw * 4); - cairo_line_to (cr, x0 + lw * 6, y); - cairo_line_to (cr, x0 + lw * 2, y + lw * 4); - cairo_line_to (cr, x0 + lw * 2, y); - - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 1, 1, 1, 1.0); - cairo_fill (cr); -} - -/** audition - small speaker with sound-waves*/ -static void icon_tool_audition (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double em = std::min (x, y) * .1; // 1px at 20x20 - -#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em - - cairo_move_to (cr, EM_POINT(-7.0, -2.0)); - cairo_line_to (cr, EM_POINT(-7.0, 2.0)); - cairo_line_to (cr, EM_POINT(-6.0, 3.0)); - cairo_line_to (cr, EM_POINT(-3.0, 3.0)); - cairo_line_to (cr, EM_POINT( 2.0, 6.0)); - cairo_line_to (cr, EM_POINT( 2.0, -6.0)); - cairo_line_to (cr, EM_POINT(-3.0, -3.0)); - cairo_line_to (cr, EM_POINT(-6.0, -3.0)); - cairo_close_path (cr); - - cairo_pattern_t *speaker; - speaker = cairo_pattern_create_linear (EM_POINT(0, -3.0), EM_POINT(0, 3.0)); - cairo_pattern_add_color_stop_rgba (speaker, 0.0, 0.8, 0.8, 0.8, 1.0); - cairo_pattern_add_color_stop_rgba (speaker, 0.25, 1.0, 1.0, 1.0, 1.0); - cairo_pattern_add_color_stop_rgba (speaker, 1.0, 0.6, 0.6, 0.6, 1.0); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - cairo_set_line_width (cr, 1.5); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_stroke_preserve (cr); - cairo_set_source (cr, speaker); - cairo_fill (cr); - cairo_pattern_destroy (speaker); - - // TODO use a slight curve - cairo_move_to (cr, EM_POINT(-3.0, -3.0)); - cairo_line_to (cr, EM_POINT(-3.5, 0.0)); - cairo_line_to (cr, EM_POINT(-3.0, 3.0)); - cairo_set_source_rgba (cr, 0, 0, 0, 0.7); - cairo_set_line_width (cr, 1.0); - cairo_stroke (cr); - - - cairo_save (cr); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_source_rgba (cr, 1, 1, 1, 1); - - cairo_translate (cr, EM_POINT (4.0, 0)); - cairo_scale (cr, 0.8, 1.25); // ellipse - - cairo_arc (cr, 0, 0, 4 * em, -.5 * M_PI, .5 * M_PI); - cairo_set_line_width (cr, .8 * em); - cairo_stroke (cr); - - cairo_arc (cr, 0, 0, 2 * em, -.5 * M_PI, .5 * M_PI); - cairo_set_line_width (cr, .5 * em); - cairo_stroke (cr); - cairo_restore (cr); -#undef EM_POINT -} - -/** pen top-left to bottom right */ -static void icon_tool_draw (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double em = std::min (x, y) * .1; // 1px at 20x20 - -#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em - - // pen [6,-5] to [-3, 3] - // y = -8 * x / 9 + 1/3 - - // top-right end - cairo_move_to (cr, EM_POINT( 5.0, -6.11)); - cairo_line_to (cr, EM_POINT( 6.4, -5.35)); // todo round properly. - cairo_line_to (cr, EM_POINT( 7.0, -3.88)); - - // bottom-left w/tip - cairo_line_to (cr, EM_POINT(-2.0, 4.11)); - cairo_line_to (cr, EM_POINT(-6.0, 5.66)); // pen tip - cairo_line_to (cr, EM_POINT(-4.0, 1.88)); - cairo_close_path (cr); - - cairo_pattern_t *pen; - pen = cairo_pattern_create_linear (EM_POINT(-3.0, -6.0), EM_POINT(6.0, 4.0)); - cairo_pattern_add_color_stop_rgba (pen, 0.4, 0.6, 0.6, 0.6, 1.0); - cairo_pattern_add_color_stop_rgba (pen, 0.5, 1.0, 1.0, 1.0, 1.0); - cairo_pattern_add_color_stop_rgba (pen, 0.6, 0.1, 0.1, 0.1, 1.0); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - cairo_set_line_width (cr, em + .5); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_stroke_preserve (cr); - cairo_set_source (cr, pen); - cairo_fill (cr); - - // separate the tip - cairo_move_to (cr, EM_POINT(-2.0, 4.11)); - cairo_line_to (cr, EM_POINT(-3.0, 2.8)); // slight curve [-3,3] - cairo_line_to (cr, EM_POINT(-4.0, 2.0)); - cairo_set_line_width (cr, OUTLINEWIDTH); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_stroke (cr); - - // pen tip - cairo_move_to (cr, EM_POINT(-5.0, 3.9)); - cairo_line_to (cr, EM_POINT(-6.0, 5.66)); - cairo_line_to (cr, EM_POINT(-4.1, 4.9)); - cairo_close_path (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 0.7); - cairo_set_line_width (cr, em); - cairo_stroke_preserve (cr); - cairo_fill (cr); - - cairo_pattern_destroy (pen); -#undef EM_POINT -} - -/** Toolbar icon - Time Axis View reduce height */ -static void icon_tav_shrink (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y) * .66; - const double ar = std::min (x, y) * .15; - const double tri = .7 * (wh - ar); - - cairo_rectangle (cr, x - wh, y - ar, 2 * wh, 2 * ar); - VECTORICONSTROKEFILL(.75); - - cairo_set_line_width (cr, 1.0); - - cairo_move_to (cr, x, y - ar - 0.5); - cairo_line_to (cr, x - tri, y - wh + 0.5); - cairo_line_to (cr, x + tri, y - wh + 0.5); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 1, 1, 1, .75); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); - - cairo_move_to (cr, x, y + ar + 0.5); - cairo_line_to (cr, x - tri, y + wh - 0.5); - cairo_line_to (cr, x + tri, y + wh - 0.5); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 1, 1, 1, .75); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); -} - -/** Toolbar icon - Time Axis View increase height */ -static void icon_tav_expand (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y) * .66; - const double ar = std::min (x, y) * .15; - const double tri = .7 * (wh - ar); - - cairo_rectangle (cr, x - wh, y - wh, 2 * wh, 2 * wh); - VECTORICONSTROKEFILL(.75); - - cairo_set_line_width (cr, 1.0); - - cairo_move_to (cr, x, y - wh + 0.5); - cairo_line_to (cr, x - tri, y - ar - 0.5); - cairo_line_to (cr, x + tri, y - ar - 0.5); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 1, 1, 1, .5); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); - - cairo_move_to (cr, x , y + wh - 0.5); - cairo_line_to (cr, x - tri, y + ar + 0.5); - cairo_line_to (cr, x + tri, y + ar + 0.5); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 1, 1, 1, .5); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); -} - - -/***************************************************************************** - * Record enable (transport & track header). - * - * hardcoded "red" #f46f6f - */ - -/** standard rec-enable circle */ -static void icon_rec_enable (cairo_t *cr, const int width, const int height, const Gtkmm2ext::ActiveState state) -{ - const double x = width * .5; - const double y = height * .5; - const double r = std::min (x, y) * .55; - cairo_arc (cr, x, y, r, 0, 2 * M_PI); - if (state == Gtkmm2ext::ExplicitActive) { - cairo_set_source_rgba (cr, 1.0, .1, .1, 1.0); - } - else if (state == Gtkmm2ext::ImplicitActive) { - cairo_set_source_rgba (cr, .9, .3, .3, 1.0); - } - else { - cairo_set_source_rgba (cr, .4, .3, .3, 1.0); - } - cairo_fill_preserve (cr); - cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8); // outline - cairo_set_line_width (cr, 1); - cairo_stroke (cr); -} - -/** tape-mode, "reel" */ -static void icon_rec_tape (cairo_t *cr, const int width, const int height, const Gtkmm2ext::ActiveState state) -{ - const double x = width * .5; - const double y = height * .5; - const double r = std::min (x, y) * .6; - const double slit = .11 * M_PI; - cairo_translate (cr, x, y); - - cairo_arc (cr, 0, 0, r, 0, 2 * M_PI); - if (state == Gtkmm2ext::ExplicitActive) { - cairo_set_source_rgba (cr, 1.0, .1, .1, 1.0); - } - else if (state == Gtkmm2ext::ImplicitActive) { - cairo_set_source_rgba (cr, .9, .3, .3, 1.0); - } - else { - cairo_set_source_rgba (cr, .4, .3, .3, 1.0); - } - cairo_fill_preserve (cr); - cairo_set_source_rgba (cr, .0, .0, .0, .5); - cairo_set_line_width (cr, 1); - cairo_stroke (cr); - - cairo_save (cr); - cairo_set_source_rgba (cr, .15, .07, .07, 1.0); - - cairo_rotate (cr, -.5 * M_PI); - cairo_move_to (cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to (cr, 0, 0); - cairo_close_path (cr); - - cairo_fill (cr); - cairo_rotate (cr, 2. * M_PI / 3.); - - cairo_move_to (cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to (cr, 0, 0); - cairo_close_path (cr); - cairo_fill (cr); - - cairo_rotate (cr, 2. * M_PI / 3.); - cairo_move_to (cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to (cr, 0, 0); - cairo_close_path (cr); - cairo_fill (cr); - - cairo_restore (cr); - - cairo_arc (cr, 0, 0, r * .3, 0, 2 * M_PI); - if (state == Gtkmm2ext::ExplicitActive) { - cairo_set_source_rgba (cr, 1.0, .1, .1, 1.0); - } - else if (state == Gtkmm2ext::ImplicitActive) { - cairo_set_source_rgba (cr, .9, .3, .3, 1.0); - } - else { - cairo_set_source_rgba (cr, .4, .3, .3, 1.0); - } - cairo_fill (cr); - cairo_set_source_rgba (cr, .0, .0, .0, 1.0); - cairo_arc (cr, 0, 0, r *.15, 0, 2 * M_PI); // hole in the middle - cairo_fill (cr); -} - - -/***************************************************************************** - * Transport buttons, foreground is always white - */ - -/** stop square box */ -static void icon_transport_stop (cairo_t *cr, const int width, const int height) -{ - const int wh = std::min (width, height); - cairo_rectangle (cr, - (width - wh) * .5 + wh * .25, - (height - wh) * .5 + wh * .25, - wh * .5, wh * .5); - VECTORICONSTROKEFILL(0.9); // small 'shine' -} - -/** play triangle */ -static void icon_transport_play (cairo_t *cr, const int width, const int height) -{ - const int wh = std::min (width, height) * .5; - const double y = height * .5; - const double x = width - wh; - - const double tri = ceil (.577 * wh); // 1/sqrt(3) - - cairo_move_to (cr, x + wh * .5, y); - cairo_line_to (cr, x - wh * .5, y - tri); - cairo_line_to (cr, x - wh * .5, y + tri); - cairo_close_path (cr); - - VECTORICONSTROKEFILL(0.9); -} - -/** Midi Panic "!" */ -static void icon_transport_panic (cairo_t *cr, const int width, const int height) -{ - const int wh = ceil (std::min (width, height) * .1) - .5; - const double xc = rint (width * .5); - const double yh = height; - cairo_rectangle (cr, - xc - wh, yh *.19, - wh * 2, yh *.41); - VECTORICONSTROKEFILL(0.9); - - cairo_arc (cr, xc, yh *.75, wh, 0, 2 * M_PI); - VECTORICONSTROKEFILL(0.9); -} - -/** various combinations of lines and triangles "|>|", ">|" "|>" */ -static void icon_transport_ck (cairo_t *cr, - const enum Gtkmm2ext::ArdourIcon::Icon icon, - const int width, const int height) -{ - // small play triangle - int wh = std::min (width, height); - const double y = height * .5; - const double x = width - wh * .5; - wh *= .18; - const double tri = ceil (.577 * wh * 2); // 1/sqrt(3) - - const float ln = std::min (width, height) * .07; - - if (icon == TransportStart || icon == TransportRange) { - cairo_rectangle (cr, - x - wh - ln, y - tri * 1.7, - ln * 2, tri * 3.4); - - VECTORICONSTROKEFILL(1.0); - } - - if (icon == TransportEnd || icon == TransportRange) { - cairo_rectangle (cr, - x + wh - ln, y - tri * 1.7, - ln * 2, tri * 3.4); - - VECTORICONSTROKEFILL(1.0); - } - - if (icon == TransportStart) { - cairo_move_to (cr, x - wh, y); - cairo_line_to (cr, x + wh, y - tri); - cairo_line_to (cr, x + wh, y + tri); - } else { - cairo_move_to (cr, x + wh, y); - cairo_line_to (cr, x - wh, y - tri); - cairo_line_to (cr, x - wh, y + tri); - } - - cairo_close_path (cr); - VECTORICONSTROKEFILL(1.0); -} - -/** loop spiral */ -static void icon_transport_loop (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double r = std::min (x, y); - - cairo_arc (cr, x, y, r * .62, 0, 2 * M_PI); - cairo_arc_negative (cr, x, y, r * .35, 2 * M_PI, 0); - - VECTORICONSTROKEFILL(1.0); - -#define ARCARROW(rad, ang) \ - x + (rad) * sin ((ang) * 2.0 * M_PI), y + (rad) * cos ((ang) * 2.0 * M_PI) - - cairo_move_to (cr, ARCARROW(r * .35, .72)); - cairo_line_to (cr, ARCARROW(r * .15, .72)); - cairo_line_to (cr, ARCARROW(r * .56, .60)); - cairo_line_to (cr, ARCARROW(r * .75, .72)); - cairo_line_to (cr, ARCARROW(r * .62, .72)); - - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_stroke_preserve (cr); - cairo_close_path (cr); - cairo_set_source_rgba (cr, 1, 1, 1, 1.0); - cairo_fill (cr); -#undef ARCARROW -} - -/** de-construct thorwil's metronom */ -static void icon_transport_metronom (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = .95 * std::min (x, y); - const double h = wh * .80; - const double w = wh * .55; - const double lw = w * .34; - - cairo_rectangle (cr, - x - w * .7, y + h * .25, - w * 1.4, lw); - - VECTORICONSTROKEFILL(1.0); - - cairo_move_to (cr, x - w, y + h); - cairo_line_to (cr, x + w, y + h); - cairo_line_to (cr, x + w * .35, y - h); - cairo_line_to (cr, x - w * .35, y - h); - cairo_line_to (cr, x - w, y + h); - - cairo_move_to (cr, x - w + lw, y + h -lw); - cairo_line_to (cr, x - w * .35 + lw, y - h + lw); - cairo_line_to (cr, x + w * .35 - lw, y - h + lw); - cairo_line_to (cr, x + w - lw, y + h -lw); - cairo_line_to (cr, x - w + lw, y + h -lw); - - VECTORICONSTROKEFILL(1.0); - - // Pendulum - // ddx = .70 w = .75 * .5 wh = .375 wh - // ddy = .75 h - lw = .75 * .8 wh - wh .5 * .2 = .5 wh - // ang = (ddx/ddy): - // -> angle = atan (ang) = atan (375 / .5) ~= 36deg - const double dx = lw * .2; // 1 - cos(tan^-1(ang)) - const double dy = lw * .4; // 1 - sin(tan^-1(ang)) - cairo_move_to (cr, x - w * .3 , y + h * .25 + lw * .5); - cairo_line_to (cr, x - w + dx , y - h + lw + dy); - cairo_line_to (cr, x - w + lw , y - h + lw); - cairo_line_to (cr, x - w * .3 + lw, y + h * .25 + lw * .5); - cairo_close_path (cr); - - VECTORICONSTROKEFILL(1.0); - - cairo_rectangle (cr, - x - w * .7, y + h * .25, - w * 1.4, lw); - cairo_fill (cr); -} - - -/***************************************************************************** - * Zoom: In "+", Out "-" and Full "[]" - */ -static void icon_zoom (cairo_t *cr, const enum Gtkmm2ext::ArdourIcon::Icon icon, const int width, const int height, const uint32_t fg_color) -{ - const double x = width * .5; - const double y = height * .5; - const double r = std::min (x, y) * .7; - const double wh = std::min (x, y) * .45; - - // draw handle first -#define LINE45DEG(rad) \ - x + r * (rad) * .707, y + r * (rad) * .707 // sin(45deg) = cos(45deg) = .707 - cairo_move_to (cr, LINE45DEG(.9)); - cairo_line_to (cr, LINE45DEG(1.3)); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width (cr, 3.0); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_stroke (cr); -#undef LINE45DEG - - // lens - ardour_icon_set_source_rgba (cr, fg_color); - cairo_arc (cr, x, y, r, 0, 2 * M_PI); - cairo_fill_preserve (cr); - - // add a lens gradient - cairo_pattern_t *lens; - lens = cairo_pattern_create_radial (x - r, y - r, r * .5, x - r, y - r, r * 2); - cairo_pattern_add_color_stop_rgba (lens, 0, 1, 1, 1, .4); - cairo_pattern_add_color_stop_rgba (lens, 1, 0, 0, 0, .4); - cairo_set_source (cr, lens); - cairo_fill_preserve (cr); - cairo_pattern_destroy (lens); - - // outline - cairo_set_line_width (cr, 1.5); - //ardour_icon_set_source_inv_rgba (cr, fg_color); // alpha - cairo_set_source_rgba (cr, .0, .0, .0, .8); - cairo_stroke (cr); - - // add "+", "-" or "[]" - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_set_line_width (cr, 1.5); - ardour_icon_set_source_inv_rgba (cr, fg_color); - - if (icon == ZoomIn || icon == ZoomOut) { - cairo_move_to (cr, x - wh, y); - cairo_line_to (cr, x + wh, y); - cairo_stroke (cr); - } - if (icon == ZoomIn) { - cairo_move_to (cr, x, y - wh); - cairo_line_to (cr, x, y + wh); - cairo_stroke (cr); - } - if (icon == ZoomFull) { - const double br0 = std::min (x, y) * .1; - const double br1 = std::min (x, y) * .3; - const double bry = std::min (x, y) * .3; - cairo_move_to (cr, x - br0, y - bry); - cairo_line_to (cr, x - br1, y - bry); - cairo_line_to (cr, x - br1, y + bry); - cairo_line_to (cr, x - br0, y + bry); - cairo_stroke (cr); - - cairo_move_to (cr, x + br0, y - bry); - cairo_line_to (cr, x + br1, y - bry); - cairo_line_to (cr, x + br1, y + bry); - cairo_line_to (cr, x + br0, y + bry); - cairo_stroke (cr); - } -} - -/** Toolbar icon - Mixbus Zoom Expand, rotated TimeAxisExpand */ -static void icon_zoom_expand (cairo_t *cr, const int width, const int height) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y) * .66; - const double ar = std::min (x, y) * .15; - const double tri = .7 * (wh - ar); - - cairo_rectangle (cr, x - wh, y - wh, 2 * wh, 2 * wh); - VECTORICONSTROKEFILL(.75); - - cairo_set_line_width (cr, 1.0); - - cairo_move_to (cr, x - wh + 0.5, y); - cairo_line_to (cr, x - ar - 0.5, y - tri); - cairo_line_to (cr, x - ar - 0.5, y + tri); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 1, 1, 1, .5); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); - - cairo_move_to (cr, x + wh - 0.5, y); - cairo_line_to (cr, x + ar + 0.5, y - tri); - cairo_line_to (cr, x + ar + 0.5, y + tri); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 1, 1, 1, .5); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_fill (cr); -} - - - -/***************************************************************************** - * Misc buttons - */ - -/** "close" - "X" , no outline */ -static void icon_close_cross (cairo_t *cr, const int width, const int height, const uint32_t fg_color) -{ - const double x = width * .5; - const double y = height * .5; - const double o = .5 + std::min (x, y) * .4; - ardour_icon_set_source_rgba (cr, fg_color); - cairo_set_line_width (cr, 1.0); - cairo_move_to (cr, x-o, y-o); - cairo_line_to (cr, x+o, y+o); - cairo_move_to (cr, x+o, y-o); - cairo_line_to (cr, x-o, y+o); - cairo_stroke (cr); -} - -/** "<" */ -static void icon_nudge_left (cairo_t *cr, const int width, const int height, const uint32_t fg_color) -{ - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y); - - const double tri_x = .3 * wh; - const double tri_y = .6 * wh; - - cairo_move_to (cr, x + tri_x, y - tri_y); - cairo_line_to (cr, x - tri_x, y); - cairo_line_to (cr, x + tri_x, y + tri_y); - VECTORICONSTROKEOUTLINE(1.5, fg_color); -} - -/** ">" */ -static void icon_nudge_right (cairo_t *cr, const int width, const int height, const uint32_t fg_color) -{ - - const double x = width * .5; - const double y = height * .5; - const double wh = std::min (x, y); - - const double tri_x = .3 * wh; - const double tri_y = .6 * wh; - - cairo_move_to (cr, x - tri_x, y - tri_y); - cairo_line_to (cr, x + tri_x, y); - cairo_line_to (cr, x - tri_x, y + tri_y); - VECTORICONSTROKEOUTLINE(1.5, fg_color); - -} - -/** mixer strip narrow/wide */ -static void icon_strip_width (cairo_t *cr, const int width, const int height, const uint32_t fg_color) -{ - const double x0 = width * .2; - const double x1 = width * .8; - - const double y0 = height * .25; - const double y1 = height * .75; - - const double ym = height * .5; - - // arrow - const double xa0= width * .39; - const double xa1= width * .61; - const double ya0= height * .35; - const double ya1= height * .65; - - ardour_icon_set_source_rgba (cr, fg_color); - cairo_set_line_width (cr, 1); - - // left + right - cairo_move_to (cr, x0, y0); - cairo_line_to (cr, x0, y1); - cairo_move_to (cr, x1, y0); - cairo_line_to (cr, x1, y1); - - // horiz center line - cairo_move_to (cr, x0, ym); - cairo_line_to (cr, x1, ym); - - // arrow left - cairo_move_to (cr, x0, ym); - cairo_line_to (cr, xa0, ya0); - cairo_move_to (cr, x0, ym); - cairo_line_to (cr, xa0, ya1); - - // arrow right - cairo_move_to (cr, x1, ym); - cairo_line_to (cr, xa1, ya0); - cairo_move_to (cr, x1, ym); - cairo_line_to (cr, xa1, ya1); - cairo_stroke (cr); -} - -/** 5-pin DIN MIDI socket */ -static void icon_din_midi (cairo_t *cr, const int width, const int height, const uint32_t fg_color) -{ - const double x = width * .5; - const double y = height * .5; - const double r = std::min (x, y) * .75; - ardour_icon_set_source_rgba (cr, fg_color); - cairo_set_line_width (cr, 1); - cairo_arc (cr, x, y, r, .57 * M_PI, 2.43 * M_PI); - cairo_stroke (cr); - - // pins equally spaced 45deg - cairo_arc (cr, x, y * 0.5, r * .15, 0, 2 * M_PI); - cairo_fill (cr); - cairo_arc (cr, x * 0.5, y, r * .15, 0, 2 * M_PI); - cairo_fill (cr); - cairo_arc (cr, x * 1.5, y, r * .15, 0, 2 * M_PI); - cairo_fill (cr); - // .5 + .5 * .5 * sin(45deg), 1.5 - .5 * .5 * cos(45deg) - cairo_arc (cr, x * 0.677, y * .677, r * .15, 0, 2 * M_PI); - cairo_fill (cr); - cairo_arc (cr, x * 1.323, y * .677, r * .15, 0, 2 * M_PI); - cairo_fill (cr); - - // bottom notch - cairo_arc (cr, x, y+r, r * .26, 1.05 * M_PI, 1.95 * M_PI); - cairo_stroke (cr); -} - - -/*****************************************************************************/ - -bool -Gtkmm2ext::ArdourIcon::render (cairo_t *cr, - const enum Gtkmm2ext::ArdourIcon::Icon icon, - const int width, const int height, - const Gtkmm2ext::ActiveState state, - const uint32_t fg_color) -{ - bool rv = true; - cairo_save (cr); - - if (width < 6 || height < 6) { - return false; - } - - switch (icon) { - case TransportStop: - icon_transport_stop (cr, width, height); - break; - case TransportPlay: - icon_transport_play (cr, width, height); - break; - case TransportLoop: - icon_transport_loop (cr, width, height); - break; - case TransportMetronom: - icon_transport_metronom (cr, width, height); - break; - case TransportPanic: - icon_transport_panic (cr, width, height); - break; - case TransportStart: // no break - case TransportEnd: // no break - case TransportRange: - icon_transport_ck (cr, icon, width, height); - break; - case RecTapeMode: - icon_rec_tape (cr, width, height, state); - break; - case RecButton: - icon_rec_enable (cr, width, height, state); - break; - case CloseCross: - icon_close_cross (cr, width, height, fg_color); - break; - case StripWidth: - icon_strip_width (cr, width, height, fg_color); - break; - case DinMidi: - icon_din_midi (cr, width, height, fg_color); - break; - case NudgeLeft: - icon_nudge_left (cr, width, height, fg_color); - break; - case NudgeRight: - icon_nudge_right (cr, width, height, fg_color); - break; - case ZoomIn: // no break - case ZoomOut: // no break - case ZoomFull: - icon_zoom (cr, icon, width, height, fg_color); - break; - case ZoomExpand: - icon_zoom_expand (cr, width, height); - break; - case TimeAxisShrink: - icon_tav_shrink (cr, width, height); - break; - case TimeAxisExpand: - icon_tav_expand (cr, width, height); - break; - case ToolRange: - icon_tool_range (cr, width, height); - break; - case ToolGrab: - icon_tool_grab (cr, width, height); - break; - case ToolCut: - icon_tool_cut (cr, width, height); - break; - case ToolStretch: - icon_tool_stretch (cr, width, height); - break; - case ToolAudition: - icon_tool_audition (cr, width, height); - break; - case ToolDraw: - icon_tool_draw (cr, width, height); - break; - case ToolContent: - icon_tool_content (cr, width, height); - break; - default: - rv = false; - break; - } - cairo_restore (cr); - return rv; -} - -#undef VECTORICONSTROKEFILL -#undef VECTORICONSTROKEOUTLINE diff --git a/libs/gtkmm2ext/binding_proxy.cc b/libs/gtkmm2ext/binding_proxy.cc deleted file mode 100644 index 00732a3361..0000000000 --- a/libs/gtkmm2ext/binding_proxy.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include -#include -#include - -#include - -#include -#include - -#include "pbd/i18n.h" - -using namespace Gtkmm2ext; -using namespace std; -using namespace PBD; - -guint BindingProxy::bind_button = 2; -guint BindingProxy::bind_statemask = Gdk::CONTROL_MASK; - -BindingProxy::BindingProxy (boost::shared_ptr c) - : prompter (0), - controllable (c) -{ -} - -BindingProxy::BindingProxy () - : prompter (0) -{ -} - -BindingProxy::~BindingProxy () -{ - if (prompter) { - delete prompter; - } -} - -void -BindingProxy::set_controllable (boost::shared_ptr c) -{ - learning_finished (); - controllable = c; -} - -void -BindingProxy::set_bind_button_state (guint button, guint statemask) -{ - bind_button = button; - bind_statemask = statemask; -} - -bool -BindingProxy::is_bind_action (GdkEventButton *ev) -{ - return (Keyboard::modifier_state_equals (ev->state, bind_statemask) && ev->button == bind_button ); -} - - -bool -BindingProxy::button_press_handler (GdkEventButton *ev) -{ - if ( controllable && is_bind_action(ev) ) { - if (Controllable::StartLearning (controllable.get())) { - string prompt = _("operate controller now"); - if (prompter == 0) { - prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false); - prompter->signal_unmap_event().connect (mem_fun (*this, &BindingProxy::prompter_hiding)); - } - prompter->set_text (prompt); - prompter->touch (); // shows popup - controllable->LearningFinished.connect_same_thread (learning_connection, boost::bind (&BindingProxy::learning_finished, this)); - } - return true; - } - - return false; -} - -void -BindingProxy::learning_finished () -{ - learning_connection.disconnect (); - if (prompter) { - prompter->touch (); // hides popup - } -} - - -bool -BindingProxy::prompter_hiding (GdkEventAny* /*ev*/) -{ - learning_connection.disconnect (); - if (controllable) { - Controllable::StopLearning (controllable.get()); - } - return false; -} - diff --git a/libs/gtkmm2ext/choice.cc b/libs/gtkmm2ext/choice.cc deleted file mode 100644 index 5dde9426e7..0000000000 --- a/libs/gtkmm2ext/choice.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include -#include - -using namespace std; -using namespace Gtkmm2ext; -using namespace sigc; -using namespace Gtk; - -Choice::Choice (string title, string prompt, vector choices, bool center) - : Dialog (title) -{ - int n; - vector::iterator i; - - if (center) { - set_position (Gtk::WIN_POS_CENTER); - } else { - set_position (Gtk::WIN_POS_MOUSE); - } - - set_name ("ChoiceWindow"); - - HBox* dhbox = manage (new HBox()); - Image* dimage = manage (new Gtk::Image(Stock::DIALOG_QUESTION, Gtk::ICON_SIZE_DIALOG)); - Label* label = manage (new Label (prompt)); - - dhbox->pack_start (*dimage, true, false, 10); - dhbox->pack_start (*label, true, false, 10); - - get_vbox()->set_border_width (12); - get_vbox()->pack_start (*dhbox, true, false); - - set_has_separator (false); - set_resizable (false); - show_all_children (); - - for (n = 0, i = choices.begin(); i != choices.end(); ++i, ++n) { - add_button (*i, n); - } -} - -void -Choice::on_realize () -{ - Gtk::Window::on_realize(); - get_window()->set_decorations (Gdk::WMDecoration (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH)); -} - -Choice::~Choice () -{ -} diff --git a/libs/gtkmm2ext/eventboxext.cc b/libs/gtkmm2ext/eventboxext.cc deleted file mode 100644 index 8101b9d6b5..0000000000 --- a/libs/gtkmm2ext/eventboxext.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2017 Robin Gareus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "gtkmm2ext/eventboxext.h" - -using namespace Gtkmm2ext; - -EventBoxExt::EventBoxExt () -{ -} diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc index c2210bba93..0da8438045 100644 --- a/libs/gtkmm2ext/gtk_ui.cc +++ b/libs/gtkmm2ext/gtk_ui.cc @@ -38,7 +38,6 @@ #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/textviewer.h" -#include "gtkmm2ext/popup.h" #include "gtkmm2ext/utils.h" #include "gtkmm2ext/window_title.h" #include "gtkmm2ext/actions.h" @@ -549,8 +548,6 @@ UI::receive (Transmitter::Channel chn, const char *str) } } -#define OLD_STYLE_ERRORS 1 - void UI::process_error_message (Transmitter::Channel chn, const char *str) { @@ -560,9 +557,6 @@ UI::process_error_message (Transmitter::Channel chn, const char *str) const char *prefix; size_t prefix_len; bool fatal_received = false; -#ifndef OLD_STYLE_ERRORS - PopUp* popup = new PopUp (WIN_POS_CENTER, 0, true); -#endif switch (chn) { case Transmitter::Fatal: @@ -573,44 +567,22 @@ UI::process_error_message (Transmitter::Channel chn, const char *str) fatal_received = true; break; case Transmitter::Error: -#if OLD_STYLE_ERRORS prefix = "[ERROR]: "; ptag = error_ptag; mtag = error_mtag; prefix_len = 9; -#else - popup->set_name ("ErrorMessage"); - popup->set_text (str); - popup->touch (); - return; -#endif break; case Transmitter::Info: -#if OLD_STYLE_ERRORS prefix = "[INFO]: "; ptag = info_ptag; mtag = info_mtag; prefix_len = 8; -#else - popup->set_name ("InfoMessage"); - popup->set_text (str); - popup->touch (); - return; -#endif - break; case Transmitter::Warning: -#if OLD_STYLE_ERRORS prefix = "[WARNING]: "; ptag = warning_ptag; mtag = warning_mtag; prefix_len = 11; -#else - popup->set_name ("WarningMessage"); - popup->set_text (str); - popup->touch (); - return; -#endif break; default: /* no choice but to use text/console output here */ diff --git a/libs/gtkmm2ext/gtkmm2ext/ardour_icon.h b/libs/gtkmm2ext/gtkmm2ext/ardour_icon.h deleted file mode 100644 index 255097d79a..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/ardour_icon.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _gtkmm2ext_ardour_icon_h_ -#define _gtkmm2ext_ardour_icon_h_ - -#include -#include -#include "gtkmm2ext/widget_state.h" - -namespace Gtkmm2ext { namespace ArdourIcon { - enum Icon { - NoIcon, - RecButton, - RecTapeMode, - CloseCross, - StripWidth, - DinMidi, - TransportStop, - TransportPlay, - TransportLoop, - TransportRange, - TransportStart, - TransportEnd, - TransportPanic, - TransportMetronom, - NudgeLeft, - NudgeRight, - ZoomIn, - ZoomOut, - ZoomFull, - ZoomExpand, - TimeAxisShrink, - TimeAxisExpand, - ToolGrab, - ToolRange, - ToolCut, - ToolStretch, - ToolAudition, - ToolDraw, - ToolContent, - }; - - LIBGTKMM2EXT_API bool render (cairo_t *cr, - const enum Icon icon, - const int width, const int height, - const Gtkmm2ext::ActiveState state, - const uint32_t fg_color); -}; }; - -#endif diff --git a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h deleted file mode 100644 index 7108c46eb2..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#ifndef __binding_proxy__ -#define __binding_proxy__ - -#include -#include - -#include "pbd/signals.h" - -#include "gtkmm2ext/visibility.h" -#include "gtkmm2ext/popup.h" - -namespace PBD { - class Controllable; -} - -class LIBGTKMM2EXT_API BindingProxy : public sigc::trackable -{ - public: - BindingProxy (boost::shared_ptr); - BindingProxy (); - virtual ~BindingProxy(); - - void set_bind_button_state (guint button, guint statemask); - - static bool is_bind_action (GdkEventButton *); - bool button_press_handler (GdkEventButton *); - - boost::shared_ptr get_controllable() const { return controllable; } - void set_controllable (boost::shared_ptr); - - protected: - Gtkmm2ext::PopUp* prompter; - boost::shared_ptr controllable; - - static guint bind_button; - static guint bind_statemask; - - PBD::ScopedConnection learning_connection; - void learning_finished (); - bool prompter_hiding (GdkEventAny *); -}; - -#endif diff --git a/libs/gtkmm2ext/gtkmm2ext/choice.h b/libs/gtkmm2ext/gtkmm2ext/choice.h deleted file mode 100644 index 3a888f2b9d..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/choice.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __pbd_gtkmm_choice_h__ -#define __pbd_gtkmm_choice_h__ - -#include -#include -#include -#include -#include -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API Choice : public Gtk::Dialog -{ - public: - Choice (std::string title, std::string prompt, std::vector choices, bool center = true); - virtual ~Choice (); - - protected: - void on_realize (); -}; - -} /* namespace */ - -#endif // __pbd_gtkmm_choice_h__ diff --git a/libs/gtkmm2ext/gtkmm2ext/eventboxext.h b/libs/gtkmm2ext/gtkmm2ext/eventboxext.h deleted file mode 100644 index a1a53fbdfa..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/eventboxext.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2017 Robin Gareus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __gtkmm2ext_eventbox_ext_h__ -#define __gtkmm2ext_eventbox_ext_h__ - -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API EventBoxExt : public Gtk::EventBox -{ -public: - EventBoxExt (); - virtual ~EventBoxExt () {} - -protected: - /* gtk2's gtk/gtkcontainer.c does not - * unmap child widgets if the container has a window. - * - * (this is for historical reasons and optimization - * because back in the day each GdkWindow was backed by - * an actual windowing system surface). - * - * In Ardour's case an EventBox is used in the Editor's top-level - * and child-widgets (e.g. Canvas::GtkCanvas never receive an unmap. - * - * However, when switching Tabbable pages, we do need to hide overlays - * such as ArdourCanvasOpenGLView - * - */ - void on_unmap () { - Gtk::EventBox::on_unmap(); - if (get_child ()) { - get_child()->unmap(); - } - } -}; - -} /* namespace */ - -#endif diff --git a/libs/gtkmm2ext/gtkmm2ext/pane.h b/libs/gtkmm2ext/gtkmm2ext/pane.h deleted file mode 100644 index 88eb82041b..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/pane.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (C) 2016 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libgtkmm2ext_pane_h__ -#define __libgtkmm2ext_pane_h__ - -#include -#include -#include - -#include - -#include -#include -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtk { - class Widget; -} - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API Pane : public Gtk::Container -{ - private: - class Divider; - - - public: - struct Child - { - Pane* pane; - Gtk::Widget* w; - int32_t minsize; - sigc::connection show_con; - sigc::connection hide_con; - - Child (Pane* p, Gtk::Widget* widget, uint32_t ms) : pane (p), w (widget), minsize (ms) {} - }; - - typedef std::vector > Children; - - Pane (bool horizontal); - ~Pane(); - - void set_divider (std::vector::size_type divider, float fract); - float get_divider (std::vector::size_type divider = 0); - void set_child_minsize (Gtk::Widget const &, int32_t); - - GType child_type_vfunc() const; - void set_drag_cursor (Gdk::Cursor); - - void set_check_divider_position (bool); - - protected: - bool horizontal; - - void on_add (Gtk::Widget*); - void on_remove (Gtk::Widget*); - void on_size_request (GtkRequisition*); - void on_size_allocate (Gtk::Allocation&); - bool on_expose_event (GdkEventExpose*); - - bool handle_press_event (GdkEventButton*, Divider*); - bool handle_release_event (GdkEventButton*, Divider*); - bool handle_motion_event (GdkEventMotion*, Divider*); - bool handle_enter_event (GdkEventCrossing*, Divider*); - bool handle_leave_event (GdkEventCrossing*, Divider*); - - void forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer callback_data); - - private: - Gdk::Cursor drag_cursor; - bool did_move; - - void reallocate (Gtk::Allocation const &); - - Children children; - - struct Divider : public Gtk::EventBox { - Divider (); - - float fract; - bool dragging; - - bool on_expose_event (GdkEventExpose* ev); - }; - - typedef std::list Dividers; - Dividers dividers; - int divider_width; - bool check_fract; - - void add_divider (); - void handle_child_visibility (); - float constrain_fract (Dividers::size_type, float fract); - - static void* notify_child_destroyed (void*); - void* child_destroyed (Gtk::Widget*); -}; - -class LIBGTKMM2EXT_API HPane : public Pane -{ - public: - HPane () : Pane (true) {} -}; - -class LIBGTKMM2EXT_API VPane : public Pane -{ - public: - VPane () : Pane (false) {} -}; - -} /* namespace */ - -#endif /* __libgtkmm2ext_pane_h__ */ diff --git a/libs/gtkmm2ext/gtkmm2ext/paths_dialog.h b/libs/gtkmm2ext/gtkmm2ext/paths_dialog.h deleted file mode 100644 index 120d037a27..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/paths_dialog.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2014 Robin Gareus - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#ifndef __gtkmmext_paths_dialog_h__ -#define __gtkmmext_paths_dialog_h__ - -#include -#include -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API PathsDialog : public Gtk::Dialog -{ - public: - PathsDialog (Gtk::Window& parent, std::string, std::string current_paths = "", std::string default_paths = ""); - ~PathsDialog (); - - std::string get_serialized_paths (); - - private: - void on_show (); - - Gtk::ListViewText paths_list_view; - - Gtk::Button add_path_button; - Gtk::Button remove_path_button; - Gtk::Button set_default_button; - - void selection_changed(); - void add_path(); - void remove_path(); - void set_default(); - - std::string _default_paths; -}; - -} /* namespace */ - -#endif /* __gtkmmext_paths_dialog_h__ */ diff --git a/libs/gtkmm2ext/gtkmm2ext/popup.h b/libs/gtkmm2ext/gtkmm2ext/popup.h deleted file mode 100644 index 043c563605..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/popup.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __qui_popup_h__ -#define __qui_popup_h__ - -#ifdef interface -#undef interface -#endif - -#include -#include - -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API PopUp : public Gtk::Window, public Touchable -{ - public: - PopUp (Gtk::WindowPosition pos, unsigned int show_for_msecs = 0, - bool delete_on_hide = false); - virtual ~PopUp (); - void touch (); - void remove (); - void set_text (std::string); - void set_name (std::string); - gint button_click (GdkEventButton *); - - bool on_delete_event (GdkEventAny* ); - - protected: - void on_realize (); - - private: - Gtk::Label label; - std::string my_text; - gint timeout; - static gint remove_prompt_timeout (void *); - bool delete_on_hide; - unsigned int popdown_time; - -}; - -} /* namespace */ - -#endif // __qui_popup_h__ diff --git a/libs/gtkmm2ext/gtkmm2ext/prompter.h b/libs/gtkmm2ext/gtkmm2ext/prompter.h deleted file mode 100644 index 59bad4b998..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/prompter.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 1999 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __gtkmm2ext_prompter_h__ -#define __gtkmm2ext_prompter_h__ - -#include -#include -#include -#include -#include -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtk { - class Window; -} - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API Prompter : public Gtk::Dialog - -{ - public: - Prompter (bool modal = false); - Prompter (Gtk::Window& parent, bool modal = false); - ~Prompter () {}; - - void set_prompt (std::string prompt) { - entryLabel.set_label (prompt); - } - - void set_initial_text (std::string txt) { - entry.set_text (txt); - entry.select_region (0, entry.get_text_length()); - } - - void change_labels (std::string ok, std::string cancel); - - void get_result (std::string &str, bool strip=true); - - protected: - Gtk::Entry& the_entry() { return entry; } - - void on_entry_changed (); - void on_show (); - - private: - Gtk::Entry entry; - Gtk::HBox entryBox; - Gtk::Label entryLabel; - bool first_show; - bool can_accept_from_entry; - - void init (); - void entry_activated (); -}; - -} /* namespace */ - -#endif /* __gtkmm2ext_prompter_h__ */ diff --git a/libs/gtkmm2ext/gtkmm2ext/scroomer.h b/libs/gtkmm2ext/gtkmm2ext/scroomer.h deleted file mode 100644 index 4d957b4868..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/scroomer.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2008 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __gtkmm2ext_scroomer_h__ -#define __gtkmm2ext_scroomer_h__ - -#include -#include -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API Scroomer : public Gtk::DrawingArea -{ -public: - enum Component { - TopBase = 0, - Handle1 = 1, - Slider = 2, - Handle2 = 3, - BottomBase = 4, - Total = 5, - None = 6 - }; - - Scroomer(Gtk::Adjustment& adjustment); - ~Scroomer(); - - bool on_motion_notify_event (GdkEventMotion*); - bool on_button_press_event (GdkEventButton*); - bool on_button_release_event (GdkEventButton*); - bool on_scroll_event (GdkEventScroll*); - virtual void on_size_allocate (Gtk::Allocation&); - - void set_comp_rect(GdkRectangle&, Component) const; - - Component point_in(double point) const; - - void set_min_page_size(double page_size); - int get_handle_size() { return handle_size; } - - inline int position_of(Component comp) { return position[comp]; } - - sigc::signal0 DragStarting; - sigc::signal0 DragFinishing; - - sigc::signal0 DoubleClicked; - -protected: - Gtk::Adjustment& adj; - -private: - struct UpdateRect { - GdkRectangle rect; - Component first_comp; - }; - - void update(); - void adjustment_changed (); - - int position[6]; - int old_pos[6]; - int handle_size; - double min_page_size; - GdkWindow* grab_window; - Component grab_comp; - double grab_y; - double unzoomed_val; - double unzoomed_page; - bool pinch; -}; - -} // namespace - -#endif /* __gtkmm2ext_scroomer_h__ */ diff --git a/libs/gtkmm2ext/gtkmm2ext/stateful_button.h b/libs/gtkmm2ext/gtkmm2ext/stateful_button.h deleted file mode 100644 index 63d6890df4..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/stateful_button.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (C) 2005 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __pbd_gtkmm_abutton_h__ -#define __pbd_gtkmm_abutton_h__ - -#include - -#include - -#include "gtkmm2ext/visibility.h" - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API StateButton -{ - public: - StateButton(); - virtual ~StateButton() {} - - void set_visual_state (int); - int get_visual_state () { return visual_state; } - void set_self_managed (bool yn) { _self_managed = yn; } - virtual void set_widget_name (const std::string& name) = 0; - - protected: - int visual_state; - bool _self_managed; - bool _is_realized; - bool style_changing; - Gtk::StateType state_before_prelight; - bool is_toggle; - - virtual std::string get_widget_name() const = 0; - virtual Gtk::Widget* get_child_widget () = 0; - - void avoid_prelight_on_style_changed (const Glib::RefPtr& style, GtkWidget* widget); - void avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget); -}; - - -class LIBGTKMM2EXT_API StatefulToggleButton : public StateButton, public Gtk::ToggleButton -{ - public: - StatefulToggleButton(); - explicit StatefulToggleButton(const std::string &label); - ~StatefulToggleButton() {} - void set_widget_name (const std::string& name); - - protected: - void on_realize (); - void on_toggled (); - void on_style_changed (const Glib::RefPtr& style); - void on_state_changed (Gtk::StateType old_state); - - Gtk::Widget* get_child_widget (); - std::string get_widget_name() const { return get_name(); } -}; - -class LIBGTKMM2EXT_API StatefulButton : public StateButton, public Gtk::Button -{ - public: - StatefulButton(); - explicit StatefulButton(const std::string &label); - virtual ~StatefulButton() {} - void set_widget_name (const std::string& name); - - protected: - void on_realize (); - void on_style_changed (const Glib::RefPtr& style); - void on_state_changed (Gtk::StateType old_state); - - Gtk::Widget* get_child_widget (); - std::string get_widget_name() const { return get_name(); } -}; - -}; - -#endif diff --git a/libs/gtkmm2ext/gtkmm2ext/tabbable.h b/libs/gtkmm2ext/gtkmm2ext/tabbable.h deleted file mode 100644 index 12363ccbe1..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/tabbable.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - Copyright (C) 2015 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __gtkmm2ext_tabbable_h__ -#define __gtkmm2ext_tabbable_h__ - -#include -#include -#include -#include -#include -#include - -#include "gtkmm2ext/window_proxy.h" -#include "gtkmm2ext/visibility.h" - -namespace Gtk { - class Window; - class Notebook; -} - -namespace Gtkmm2ext { - -class VisibilityTracker; - -class LIBGTKMM2EXT_API Tabbable : public WindowProxy { - public: - Tabbable (Gtk::Widget&, const std::string&, bool tabbed_by_default = true); - ~Tabbable (); - - void add_to_notebook (Gtk::Notebook& notebook, const std::string& tab_title); - void make_visible (); - void make_invisible (); - void change_visibility (); - void attach (); - void detach (); - - Gtk::Widget& contents() const { return _contents; } - - Gtk::Window* get (bool create = false); - Gtk::Window* own_window () { return get (false); } - virtual Gtk::Window* use_own_window (bool and_pack_it); - - void set_default_tabbed (bool yn); - - virtual void show_window (); - - bool window_visible () const; - bool tabbed() const; - bool tabbed_by_default () const; - - Gtk::Window* current_toplevel () const; - - Gtk::Notebook* tab_root_drop (); - - int set_state (const XMLNode&, int version); - XMLNode& get_state (); - - static std::string xml_node_name(); - - sigc::signal1 StateChange; - - protected: - bool delete_event_handler (GdkEventAny *ev); - - private: - Gtk::Widget& _contents; - Gtk::Notebook _own_notebook; - Gtk::Notebook* _parent_notebook; - std::string _tab_title; - bool tab_requested_by_state; - - void show_tab (); - void hide_tab (); - bool tab_close_clicked (GdkEventButton*); - void show_own_window (bool and_pack_it); - void window_mapped (); - void window_unmapped (); -}; - - -} - -#endif diff --git a/libs/gtkmm2ext/gtkmm2ext/tearoff.h b/libs/gtkmm2ext/gtkmm2ext/tearoff.h deleted file mode 100644 index be5c45d544..0000000000 --- a/libs/gtkmm2ext/gtkmm2ext/tearoff.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2003 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __gtkmm2ext_tearoff_h__ -#define __gtkmm2ext_tearoff_h__ - -#include -#include -#include -#include - -#include "gtkmm2ext/visibility.h" - -class XMLNode; - -namespace Gtkmm2ext { - -class LIBGTKMM2EXT_API TearOff : public Gtk::HBox -{ - public: - TearOff (Gtk::Widget& contents, bool allow_resize = false); - virtual ~TearOff (); - - void set_visible (bool yn, bool force = false); - void set_can_be_torn_off (bool); - bool can_be_torn_off () const { return _can_be_torn_off; } - bool visible () const { return _visible; } - - sigc::signal Detach; - sigc::signal Attach; - sigc::signal Visible; - sigc::signal Hidden; - - Gtk::Window& tearoff_window() { return own_window; } - bool torn_off() const; - void tear_it_off (); - void put_it_back (); - void hide_visible (); - - void set_state (const XMLNode&); - void add_state (XMLNode&) const; - - private: - Gtk::Widget& contents; - Gtk::Window own_window; - Gtk::Arrow tearoff_arrow; - Gtk::Arrow close_arrow; - Gtk::HBox window_box; - Gtk::EventBox tearoff_event_box; - Gtk::EventBox close_event_box; - double drag_x; - double drag_y; - bool dragging; - bool _visible; - bool _torn; - bool _can_be_torn_off; - int own_window_width; - int own_window_height; - int own_window_xpos; - int own_window_ypos; - - gint tearoff_click (GdkEventButton*); - gint close_click (GdkEventButton*); - - gint window_motion (GdkEventMotion*); - gint window_button_press (GdkEventButton*); - gint window_button_release (GdkEventButton*); - gint window_delete_event (GdkEventAny*); - - void own_window_realized (); - bool own_window_configured (GdkEventConfigure*); -}; - -} /* namespace */ - -#endif // __gtkmm2ext_tearoff_h__ diff --git a/libs/gtkmm2ext/pane.cc b/libs/gtkmm2ext/pane.cc deleted file mode 100644 index 76e68de5a2..0000000000 --- a/libs/gtkmm2ext/pane.cc +++ /dev/null @@ -1,670 +0,0 @@ -/* - Copyright (C) 2016 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include "gtkmm2ext/pane.h" - -#include "pbd/i18n.h" - -using namespace PBD; -using namespace Gtk; -using namespace Gtkmm2ext; -using namespace std; - -Pane::Pane (bool h) - : horizontal (h) - , did_move (false) - , divider_width (2) - , check_fract (false) -{ - using namespace Gdk; - - set_name ("Pane"); - set_has_window (false); - - if (horizontal) { - drag_cursor = Cursor (SB_H_DOUBLE_ARROW); - } else { - drag_cursor = Cursor (SB_V_DOUBLE_ARROW); - } -} - -Pane::~Pane () -{ - for (Children::iterator c = children.begin(); c != children.end(); ++c) { - (*c)->show_con.disconnect (); - (*c)->hide_con.disconnect (); - if ((*c)->w) { - (*c)->w->remove_destroy_notify_callback ((*c).get()); - (*c)->w->unparent (); - } - } - children.clear (); -} - -void -Pane::set_child_minsize (Gtk::Widget const& w, int32_t minsize) -{ - for (Children::iterator c = children.begin(); c != children.end(); ++c) { - if ((*c)->w == &w) { - (*c)->minsize = minsize; - break; - } - } -} - -void -Pane::set_drag_cursor (Gdk::Cursor c) -{ - drag_cursor = c; -} - -void -Pane::on_size_request (GtkRequisition* req) -{ - GtkRequisition largest; - - /* iterate over all children, get their size requests */ - - /* horizontal pane is as high as its tallest child, including the dividers. - * Its width is the sum of the children plus the dividers. - * - * vertical pane is as wide as its widest child, including the dividers. - * Its height is the sum of the children plus the dividers. - */ - - if (horizontal) { - largest.width = (children.size() - 1) * divider_width; - largest.height = 0; - } else { - largest.height = (children.size() - 1) * divider_width; - largest.width = 0; - } - - for (Children::iterator c = children.begin(); c != children.end(); ++c) { - GtkRequisition r; - - if (!(*c)->w->is_visible ()) { - continue; - } - - (*c)->w->size_request (r); - - if (horizontal) { - largest.height = max (largest.height, r.height); - if ((*c)->minsize) { - largest.width += (*c)->minsize; - } else { - largest.width += r.width; - } - } else { - largest.width = max (largest.width, r.width); - if ((*c)->minsize) { - largest.height += (*c)->minsize; - } else { - largest.height += r.height; - } - } - } - - *req = largest; -} - -GType -Pane::child_type_vfunc() const -{ - /* We accept any number of any types of widgets */ - return Gtk::Widget::get_type(); -} - -void -Pane::add_divider () -{ - Divider* d = new Divider; - d->set_name (X_("Divider")); - d->signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_press_event), d), false); - d->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_release_event), d), false); - d->signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_motion_event), d), false); - d->signal_enter_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_enter_event), d), false); - d->signal_leave_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_leave_event), d), false); - d->set_parent (*this); - d->show (); - d->fract = 0.5; - dividers.push_back (d); -} - -void -Pane::handle_child_visibility () -{ - reallocate (get_allocation()); -} - -void -Pane::on_add (Widget* w) -{ - children.push_back (boost::shared_ptr (new Child (this, w, 0))); - Child* kid = children.back ().get(); - - w->set_parent (*this); - /* Gtkmm 2.4 does not correctly arrange for ::on_remove() to be called - for custom containers that derive from Gtk::Container. So ... we need - to ensure that we hear about child destruction ourselves. - */ - w->add_destroy_notify_callback (kid, &Pane::notify_child_destroyed); - - kid->show_con = w->signal_show().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); - kid->hide_con = w->signal_hide().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); - - while (dividers.size() < (children.size() - 1)) { - add_divider (); - } -} - -void* -Pane::notify_child_destroyed (void* data) -{ - Child* child = reinterpret_cast (data); - return child->pane->child_destroyed (child->w); -} - -void* -Pane::child_destroyed (Gtk::Widget* w) -{ - for (Children::iterator c = children.begin(); c != children.end(); ++c) { - if ((*c)->w == w) { - (*c)->show_con.disconnect (); - (*c)->hide_con.disconnect (); - (*c)->w = NULL; // mark invalid - children.erase (c); - break; - } - } - return 0; -} - -void -Pane::on_remove (Widget* w) -{ - for (Children::iterator c = children.begin(); c != children.end(); ++c) { - if ((*c)->w == w) { - (*c)->show_con.disconnect (); - (*c)->hide_con.disconnect (); - w->remove_destroy_notify_callback ((*c).get()); - w->unparent (); - (*c)->w = NULL; // mark invalid - children.erase (c); - break; - } - } -} - -void -Pane::on_size_allocate (Gtk::Allocation& alloc) -{ - reallocate (alloc); - Container::on_size_allocate (alloc); - - /* minumum pane size constraints */ - Dividers::size_type div = 0; - for (Dividers::const_iterator d = dividers.begin(); d != dividers.end(); ++d, ++div) { - // XXX skip dividers that were just hidden in reallocate() - Pane::set_divider (div, (*d)->fract); - } - // TODO this needs tweaking for panes with > 2 children - // if a child grows, re-check the ones before it. - assert (dividers.size () < 3); -} - -void -Pane::reallocate (Gtk::Allocation const & alloc) -{ - int remaining; - int xpos = alloc.get_x(); - int ypos = alloc.get_y(); - float fract; - - if (children.empty()) { - return; - } - - if (children.size() == 1) { - /* only child gets the full allocation */ - if (children.front()->w->is_visible ()) { - children.front()->w->size_allocate (alloc); - } - return; - } - - if (horizontal) { - remaining = alloc.get_width (); - } else { - remaining = alloc.get_height (); - } - - Children::iterator child; - Children::iterator next; - Dividers::iterator div; - - child = children.begin(); - - /* skip initial hidden children */ - - while (child != children.end()) { - if ((*child)->w->is_visible()) { - break; - } - ++child; - } - - for (div = dividers.begin(); child != children.end(); ) { - - Gtk::Allocation child_alloc; - - next = child; - - /* Move on to next *visible* child */ - - while (++next != children.end()) { - if ((*next)->w->is_visible()) { - break; - } - } - - child_alloc.set_x (xpos); - child_alloc.set_y (ypos); - - if (next == children.end()) { - /* last child gets all the remaining space */ - fract = 1.0; - } else { - /* child gets the fraction of the remaining space given by the divider that follows it */ - fract = (*div)->fract; - } - - Gtk::Requisition cr; - (*child)->w->size_request (cr); - - if (horizontal) { - child_alloc.set_width ((gint) floor (remaining * fract)); - child_alloc.set_height (alloc.get_height()); - remaining = max (0, (remaining - child_alloc.get_width())); - xpos += child_alloc.get_width(); - } else { - child_alloc.set_width (alloc.get_width()); - child_alloc.set_height ((gint) floor (remaining * fract)); - remaining = max (0, (remaining - child_alloc.get_height())); - ypos += child_alloc.get_height (); - } - - if ((*child)->minsize) { - if (horizontal) { - child_alloc.set_width (max (child_alloc.get_width(), (*child)->minsize)); - } else { - child_alloc.set_height (max (child_alloc.get_height(), (*child)->minsize)); - } - } - - if ((*child)->w->is_visible ()) { - (*child)->w->size_allocate (child_alloc); - } - - if (next == children.end()) { - /* done, no more children, no need for a divider */ - break; - } - - child = next; - - /* add a divider between children */ - - Gtk::Allocation divider_allocation; - - divider_allocation.set_x (xpos); - divider_allocation.set_y (ypos); - - if (horizontal) { - divider_allocation.set_width (divider_width); - divider_allocation.set_height (alloc.get_height()); - remaining = max (0, remaining - divider_width); - xpos += divider_width; - } else { - divider_allocation.set_width (alloc.get_width()); - divider_allocation.set_height (divider_width); - remaining = max (0, remaining - divider_width); - ypos += divider_width; - } - - (*div)->size_allocate (divider_allocation); - (*div)->show (); - ++div; - } - - /* hide all remaining dividers */ - - while (div != dividers.end()) { - (*div)->hide (); - ++div; - } -} - -bool -Pane::on_expose_event (GdkEventExpose* ev) -{ - Children::iterator child; - Dividers::iterator div; - - for (child = children.begin(), div = dividers.begin(); child != children.end(); ++child) { - - if ((*child)->w->is_visible()) { - propagate_expose (*((*child)->w), ev); - } - - if (div != dividers.end()) { - if ((*div)->is_visible()) { - propagate_expose (**div, ev); - } - ++div; - } - } - - return true; -} - -bool -Pane::handle_press_event (GdkEventButton* ev, Divider* d) -{ - d->dragging = true; - d->queue_draw (); - - return false; -} - -bool -Pane::handle_release_event (GdkEventButton* ev, Divider* d) -{ - d->dragging = false; - - if (did_move && !children.empty()) { - children.front()->w->queue_resize (); - did_move = false; - } - - return false; -} -void -Pane::set_check_divider_position (bool yn) -{ - check_fract = yn; -} - -float -Pane::constrain_fract (Dividers::size_type div, float fract) -{ - if (get_allocation().get_width() == 1 && get_allocation().get_height() == 1) { - /* space not * allocated - * divider being set from startup code. Let it pass, - * since our goal is mostly to catch drags to a position that will interfere with window - * resizing. - */ - return fract; - } - - if (children.size () <= div + 1) { return fract; } // XXX remove once hidden divs are skipped - assert(children.size () > div + 1); - - const float size = horizontal ? get_allocation().get_width() : get_allocation().get_height(); - - // TODO: optimize: cache in Pane::on_size_request - Gtk::Requisition prev_req(children.at (div)->w->size_request ()); - Gtk::Requisition next_req(children.at (div + 1)->w->size_request ()); - float prev = (horizontal ? prev_req.width : prev_req.height); - float next = (horizontal ? next_req.width : next_req.height); - - if (children.at (div)->minsize) { - prev = children.at (div)->minsize; - } - if (children.at (div + 1)->minsize) { - next = children.at (div + 1)->minsize; - } - - if (size * fract < prev) { - return prev / size; - } - if (size * (1.f - fract) < next) { - return 1.f - next / size; - } - - if (!check_fract) { - return fract; - } - -#ifdef __APPLE__ - - /* On Quartz, if the pane handle (divider) gets to - be adjacent to the window edge, you can no longer grab it: - any attempt to do so is interpreted by the Quartz window - manager ("Finder") as a resize drag on the window edge. - */ - - - if (horizontal) { - if (div == dividers.size() - 1) { - if (get_allocation().get_width() * (1.0 - fract) < (divider_width*2)) { - /* too close to right edge */ - return 1.f - (divider_width * 2.f) / (float) get_allocation().get_width(); - } - } - - if (div == 0) { - if (get_allocation().get_width() * fract < (divider_width*2)) { - /* too close to left edge */ - return (divider_width * 2.f) / (float)get_allocation().get_width(); - } - } - } else { - if (div == dividers.size() - 1) { - if (get_allocation().get_height() * (1.0 - fract) < (divider_width*2)) { - /* too close to bottom */ - return 1.f - (divider_width * 2.f) / (float) get_allocation().get_height(); - } - } - - if (div == 0) { - if (get_allocation().get_height() * fract < (divider_width*2)) { - /* too close to top */ - return (divider_width * 2.f) / (float) get_allocation().get_height(); - } - } - } -#endif - return fract; -} - -bool -Pane::handle_motion_event (GdkEventMotion* ev, Divider* d) -{ - did_move = true; - - if (!d->dragging) { - return true; - } - - /* determine new position for handle */ - - float new_fract; - int px, py; - - d->translate_coordinates (*this, ev->x, ev->y, px, py); - - Dividers::iterator prev = dividers.end(); - Dividers::size_type div = 0; - - for (Dividers::iterator di = dividers.begin(); di != dividers.end(); ++di, ++div) { - if (*di == d) { - break; - } - prev = di; - } - - int space_remaining; - int prev_edge; - - if (horizontal) { - if (prev != dividers.end()) { - prev_edge = (*prev)->get_allocation().get_x() + (*prev)->get_allocation().get_width(); - } else { - prev_edge = 0; - } - space_remaining = get_allocation().get_width() - prev_edge; - new_fract = (float) (px - prev_edge) / space_remaining; - } else { - if (prev != dividers.end()) { - prev_edge = (*prev)->get_allocation().get_y() + (*prev)->get_allocation().get_height(); - } else { - prev_edge = 0; - } - space_remaining = get_allocation().get_height() - prev_edge; - new_fract = (float) (py - prev_edge) / space_remaining; - } - - new_fract = min (1.0f, max (0.0f, new_fract)); - new_fract = constrain_fract (div, new_fract); - new_fract = min (1.0f, max (0.0f, new_fract)); - - if (new_fract != d->fract) { - d->fract = new_fract; - reallocate (get_allocation ()); - queue_draw (); - } - - return true; -} - -void -Pane::set_divider (Dividers::size_type div, float fract) -{ - Dividers::iterator d = dividers.begin(); - - for (d = dividers.begin(); d != dividers.end() && div != 0; ++d, --div) { - /* relax */ - } - - if (d == dividers.end()) { - /* caller is trying to set divider that does not exist - * yet. - */ - return; - } - - fract = max (0.0f, min (1.0f, fract)); - fract = constrain_fract (div, fract); - fract = max (0.0f, min (1.0f, fract)); - - if (fract != (*d)->fract) { - (*d)->fract = fract; - /* our size hasn't changed, but our internal allocations have */ - reallocate (get_allocation()); - queue_draw (); - } -} - -float -Pane::get_divider (Dividers::size_type div) -{ - Dividers::iterator d = dividers.begin(); - - for (d = dividers.begin(); d != dividers.end() && div != 0; ++d, --div) { - /* relax */ - } - - if (d == dividers.end()) { - /* caller is trying to set divider that does not exist - * yet. - */ - return -1.0f; - } - - return (*d)->fract; -} - -void -Pane::forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer callback_data) -{ - /* since the callback could modify the child list(s), make sure we keep - * the iterators safe; - */ - Children kids (children); - for (Children::const_iterator c = kids.begin(); c != kids.end(); ++c) { - if ((*c)->w) { - callback ((*c)->w->gobj(), callback_data); - } - } - - if (include_internals) { - for (Dividers::iterator d = dividers.begin(); d != dividers.end(); ) { - Dividers::iterator next = d; - ++next; - callback (GTK_WIDGET((*d)->gobj()), callback_data); - d = next; - } - } -} - -Pane::Divider::Divider () - : fract (0.0) - , dragging (false) -{ - set_events (Gdk::EventMask (Gdk::BUTTON_PRESS| - Gdk::BUTTON_RELEASE| - Gdk::MOTION_NOTIFY| - Gdk::ENTER_NOTIFY| - Gdk::LEAVE_NOTIFY)); -} - -bool -Pane::Divider::on_expose_event (GdkEventExpose* ev) -{ - Gdk::Color c = (dragging ? get_style()->get_fg (Gtk::STATE_ACTIVE) : - get_style()->get_fg (get_state())); - - Cairo::RefPtr draw_context = get_window()->create_cairo_context (); - draw_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height); - draw_context->clip_preserve (); - draw_context->set_source_rgba (c.get_red_p(), c.get_green_p(), c.get_blue_p(), 1.0); - draw_context->fill (); - - return true; -} - -bool -Pane::handle_enter_event (GdkEventCrossing*, Divider* d) -{ - d->get_window()->set_cursor (drag_cursor); - d->set_state (Gtk::STATE_SELECTED); - return true; -} - -bool -Pane::handle_leave_event (GdkEventCrossing*, Divider* d) -{ - d->get_window()->set_cursor (); - d->set_state (Gtk::STATE_NORMAL); - d->queue_draw (); - return true; -} diff --git a/libs/gtkmm2ext/paths_dialog.cc b/libs/gtkmm2ext/paths_dialog.cc deleted file mode 100644 index 2f2ff0c5d8..0000000000 --- a/libs/gtkmm2ext/paths_dialog.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 2014 Robin Gareus - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#include - -#include "pbd/i18n.h" -#include "pbd/pathexpand.h" -#include "gtkmm2ext/paths_dialog.h" - -using namespace Gtk; -using namespace std; -using namespace Gtkmm2ext; - -PathsDialog::PathsDialog (Gtk::Window& parent, std::string title, std::string current_paths, std::string default_paths) - : Dialog (title, parent, true) - , paths_list_view(1, false, Gtk::SELECTION_SINGLE) - , add_path_button(_("Add")) - , remove_path_button(_("Delete")) - , set_default_button(_("Reset to Default")) - , _default_paths(default_paths) -{ - set_name ("PathsDialog"); - set_skip_taskbar_hint (true); - set_resizable (true); - set_size_request (400, -1); - - paths_list_view.set_border_width (4); - - add_path_button.signal_clicked().connect (sigc::mem_fun (*this, &PathsDialog::add_path)); - remove_path_button.signal_clicked().connect (sigc::mem_fun (*this, &PathsDialog::remove_path)); - set_default_button.signal_clicked().connect (sigc::mem_fun (*this, &PathsDialog::set_default)); - remove_path_button.set_sensitive(false); - - paths_list_view.set_column_title(0,"Path"); - - std::vector a = PBD::parse_path(current_paths); - for(vector::const_iterator i = a.begin(); i != a.end(); ++i) { - paths_list_view.append_text(*i); - } - - paths_list_view.get_selection()->signal_changed().connect (mem_fun (*this, &PathsDialog::selection_changed)); - - VBox *vbox = manage (new VBox); - vbox->pack_start (add_path_button, false, false); - vbox->pack_start (remove_path_button, false, false); - vbox->pack_start (set_default_button, false, false); - - /* Overall layout */ - HBox *hbox = manage (new HBox); - hbox->pack_start (*vbox, false, false); - hbox->pack_start (paths_list_view, true, true); // TODO, wrap in scroll-area ?! - hbox->set_spacing (4); - - get_vbox()->set_spacing (4); - get_vbox()->pack_start (*hbox, true, true); - - add_button (Stock::CANCEL, RESPONSE_CANCEL); - add_button (Stock::OK, RESPONSE_ACCEPT); - - show_all_children (); -} - -PathsDialog::~PathsDialog () -{ -} - -void -PathsDialog::on_show() { - Dialog::on_show (); -} - -std::string -PathsDialog::get_serialized_paths() { - std::string path; - for (unsigned int i = 0; i < paths_list_view.size(); ++i) { - if (i > 0) path += G_SEARCHPATH_SEPARATOR; - path += paths_list_view.get_text(i, 0); - } - return path; -} - -void -PathsDialog::selection_changed () { - std::vector selection = paths_list_view.get_selected(); - if (selection.size() > 0) { - remove_path_button.set_sensitive(true); - } else { - remove_path_button.set_sensitive(false); - } -} - -void -PathsDialog::add_path() { - Gtk::FileChooserDialog d (_("Add folder to search path"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); - - std::vector selection = paths_list_view.get_selected(); - if (selection.size() == 1 ) { - d.set_current_folder(paths_list_view.get_text(selection.at(0), 0)); - } - - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); - ResponseType r = (ResponseType) d.run (); - if (r == Gtk::RESPONSE_OK) { - std::string dir = d.get_filename(); - if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { - bool dup = false; - for (unsigned int i = 0; i < paths_list_view.size(); ++i) { - if (paths_list_view.get_text(i, 0) == dir) { - dup = true; - break; - } - } - if (!dup) { - paths_list_view.prepend_text(dir); - } - } - } -} - -void -PathsDialog::remove_path() { - std::vector selection = paths_list_view.get_selected(); - if (selection.size() == 0 ) { return ; } - - /* Gtk::ListViewText internals to delete row(s) */ - Gtk::TreeModel::iterator row_it = paths_list_view.get_selection()->get_selected(); - Glib::RefPtr reftm = paths_list_view.get_model(); - Glib::RefPtr refStore = Glib::RefPtr::cast_dynamic(reftm); - if(refStore) { - refStore->erase(row_it); - return; - } - Glib::RefPtr refLStore = Glib::RefPtr::cast_dynamic(reftm); - if(refLStore){ - refLStore->erase(row_it); - return; - } -} - -void -PathsDialog::set_default() { - - paths_list_view.clear_items(); - std::vector a = PBD::parse_path(_default_paths); - for(vector::const_iterator i = a.begin(); i != a.end(); ++i) { - paths_list_view.append_text(*i); - } -} diff --git a/libs/gtkmm2ext/popup.cc b/libs/gtkmm2ext/popup.cc deleted file mode 100644 index 898211c986..0000000000 --- a/libs/gtkmm2ext/popup.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include - -#include -#include -#include - -using namespace std; -using namespace Gtk; -using namespace Gtkmm2ext; - -PopUp::PopUp (Gtk::WindowPosition pos, unsigned int showfor_msecs, bool doh) - : Window (WINDOW_POPUP) -{ - add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - signal_button_press_event().connect(mem_fun(*this,&PopUp::button_click)); - set_border_width (12); - add (label); - set_position (pos); - - delete_on_hide = doh; - popdown_time = showfor_msecs; - timeout = -1; -} - - -PopUp::~PopUp () -{ -} - -void -PopUp::on_realize () -{ - Gtk::Window::on_realize(); - get_window()->set_decorations (Gdk::WMDecoration (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH)); -} - -gint -PopUp::remove_prompt_timeout (void *arg) -{ - PopUp *pup = (PopUp *) arg; - - pup->remove (); - return FALSE; -} - -static gint idle_delete (void *arg) -{ - delete static_cast (arg); - return FALSE; -} - -void -PopUp::remove () -{ - hide (); - - if (popdown_time != 0 && timeout != -1) { - g_source_remove (timeout); - } - - if (delete_on_hide) { - std::cerr << "deleting prompter\n"; - g_idle_add (idle_delete, this); - } -} -#define ENSURE_GUI_THREAD(slot) \ - if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {\ - Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, (slot)); \ - return;\ - } - - -void -PopUp::touch () -{ - ENSURE_GUI_THREAD (mem_fun (*this, &PopUp::touch)); - - if (is_visible ()) { - remove (); - } else { - set_size_request_to_display_given_text (label, my_text.c_str(), 25, 10); - label.set_text (my_text); - show_all (); - - if (popdown_time != 0) { - timeout = g_timeout_add (popdown_time, - remove_prompt_timeout, - this); - } - } -} - -gint -PopUp::button_click (GdkEventButton* /*ev*/) -{ - remove (); - return TRUE; -} - -void -PopUp::set_text (string txt) -{ - my_text = txt; -} - -void -PopUp::set_name (string name) -{ - Window::set_name (name); - label.set_name (name); -} - -bool -PopUp::on_delete_event (GdkEventAny* /*ev*/) -{ - hide(); - - if (popdown_time != 0 && timeout != -1) { - g_source_remove (timeout); - } - - if (delete_on_hide) { - std::cerr << "deleting prompter\n" << endl; - g_idle_add (idle_delete, this); - } - - return true; -} diff --git a/libs/gtkmm2ext/prompter.cc b/libs/gtkmm2ext/prompter.cc deleted file mode 100644 index 51628ab13d..0000000000 --- a/libs/gtkmm2ext/prompter.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 1999 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include - -#include - -#include -#include - -#include "pbd/i18n.h" - -using namespace std; -using namespace Gtkmm2ext; - -Prompter::Prompter (Gtk::Window& parent, bool modal) - : Gtk::Dialog ("", parent, modal) - , first_show (true) - , can_accept_from_entry (false) -{ - init (); -} - -Prompter::Prompter (bool modal) - : Gtk::Dialog ("", modal) - , first_show (true) - , can_accept_from_entry (false) -{ - init (); -} - -void -Prompter::init () -{ - set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG); - set_position (Gtk::WIN_POS_MOUSE); - set_name ("Prompter"); - - add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - - /* - Alas a generic 'affirmative' button seems a bit useless sometimes. - You will have to add your own. - After adding, use : - set_response_sensitive (Gtk::RESPONSE_ACCEPT, false) - to prevent the RESPONSE_ACCEPT button from permitting blank strings. - */ - - entryLabel.set_line_wrap (true); - entryLabel.set_name ("PrompterLabel"); - - entryBox.set_homogeneous (false); - entryBox.set_spacing (5); - entryBox.set_border_width (10); - entryBox.pack_start (entryLabel, false, false); - entryBox.pack_start (entry, true, true); - - get_vbox()->pack_start (entryBox); - show_all_children(); -} - -void -Prompter::on_show () -{ - /* don't connect to signals till shown, so that we don't change the - response sensitivity etc. when the setup of the dialog sets the text. - */ - - if (first_show) { - entry.signal_changed().connect (mem_fun (*this, &Prompter::on_entry_changed)); - entry.signal_activate().connect (mem_fun (*this, &Prompter::entry_activated)); - can_accept_from_entry = !entry.get_text().empty(); - first_show = false; - } - - Dialog::on_show (); -} - -void -Prompter::change_labels (string /*okstr*/, string /*cancelstr*/) -{ - // dynamic_cast(ok.get_child())->set_text (okstr); - // dynamic_cast(cancel.get_child())->set_text (cancelstr); -} - -void -Prompter::get_result (string &str, bool strip) -{ - str = entry.get_text (); - if (strip) { - PBD::strip_whitespace_edges (str); - } -} - -void -Prompter::entry_activated () -{ - if (can_accept_from_entry) { - response (Gtk::RESPONSE_ACCEPT); - } else { - response (Gtk::RESPONSE_CANCEL); - } -} - -void -Prompter::on_entry_changed () -{ - /* - This is set up so that entering text in the entry - field makes the RESPONSE_ACCEPT button active. - Of course if you haven't added a RESPONSE_ACCEPT - button, nothing will happen at all. - */ - - if (!entry.get_text().empty()) { - set_response_sensitive (Gtk::RESPONSE_ACCEPT, true); - set_default_response (Gtk::RESPONSE_ACCEPT); - can_accept_from_entry = true; - } else { - set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); - } -} diff --git a/libs/gtkmm2ext/scroomer.cc b/libs/gtkmm2ext/scroomer.cc deleted file mode 100644 index 69944b4bc7..0000000000 --- a/libs/gtkmm2ext/scroomer.cc +++ /dev/null @@ -1,408 +0,0 @@ -/* - Copyright (C) 2008 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include - -#include "gtkmm2ext/scroomer.h" -#include "gtkmm2ext/keyboard.h" - -using namespace Gtkmm2ext; -using namespace Gtk; -using namespace Gdk; -using namespace std; - -Scroomer::Scroomer(Gtk::Adjustment& adjustment) - : adj(adjustment) - , handle_size(0) - , grab_comp(None) -{ - position[TopBase] = 0; - position[Handle1] = 0; - position[Slider] = 0; - position[Handle2] = 0; - position[BottomBase] = 0; - position[Total] = 0; - - add_events (Gdk::BUTTON_PRESS_MASK | - Gdk::BUTTON_RELEASE_MASK | - Gdk::POINTER_MOTION_MASK | - Gdk::SCROLL_MASK); - - adjustment.signal_value_changed().connect (mem_fun (*this, &Scroomer::adjustment_changed)); - //adjustment.signal_changed().connect (mem_fun (*this, &Scroomer::adjustment_changed)); -} - -Scroomer::~Scroomer() -{ -} - -bool -Scroomer::on_motion_notify_event (GdkEventMotion* ev) -{ - double range = adj.get_upper() - adj.get_lower(); - double pixel2val = range / get_height(); - double val_at_pointer = ((get_height() - ev->y) * pixel2val) + adj.get_lower(); - double delta_y = ev->y - grab_y; - double half_min_page = min_page_size / 2; - double fract = delta_y / position[Total]; - double scale, temp, zoom; - double val, page; - - if (grab_comp == None || grab_comp == Total) { - return true; - } - - if (ev->window != grab_window) { - grab_y = ev->y; - grab_window = ev->window; - return true; - } - - if (ev->y < 0 || ev->y > get_height ()) { - return true; - } - - grab_y = ev->y; - - if (ev->state & Keyboard::PrimaryModifier) { - if (ev->state & Keyboard::SecondaryModifier) { - scale = 0.05; - } else { - scale = 0.1; - } - } else { - scale = 1.0; - } - - fract = min (1.0, fract); - fract = max (-1.0, fract); - fract = -fract; - - switch (grab_comp) { - case TopBase: - case BottomBase: - unzoomed_val += scale * fract * range; - unzoomed_val = min(unzoomed_val, adj.get_upper() - unzoomed_page); - unzoomed_val = max(unzoomed_val, adj.get_lower()); - break; - case Slider: - unzoomed_val += scale * fract * range; - unzoomed_val = min(unzoomed_val, adj.get_upper() - unzoomed_page); - unzoomed_val = max(unzoomed_val, adj.get_lower()); - break; - case Handle1: - - unzoomed_page += scale * fract * range; - unzoomed_page = min(unzoomed_page, adj.get_upper() - unzoomed_val); - unzoomed_page = max(unzoomed_page, min_page_size); - - if (pinch){ - temp = unzoomed_val + unzoomed_page; - unzoomed_val -= scale * fract * range * 0.5; - unzoomed_val = min(unzoomed_val, temp - min_page_size); - unzoomed_val = max(unzoomed_val, adj.get_lower()); - } - - break; - case Handle2: - temp = unzoomed_val + unzoomed_page; - unzoomed_val += scale * fract * range; - unzoomed_val = min(unzoomed_val, temp - min_page_size); - unzoomed_val = max(unzoomed_val, adj.get_lower()); - - unzoomed_page = temp - unzoomed_val; - - if (pinch){ - - unzoomed_page -= scale * fract * range; - } - - unzoomed_page = min(unzoomed_page, adj.get_upper() - unzoomed_val); - unzoomed_page = max(unzoomed_page, min_page_size); - break; - default: - break; - } - - /* Then we handle zoom, which is dragging horizontally. We zoom around the area that is - * the current y pointer value, not from the area that was the start of the drag. - * We don't start doing zoom until we are at least one scroomer width outside the scroomer's - * area. - */ - - if (ev->x > (get_width() * 2)) { - zoom = ev->x - get_width(); - - double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; - double lower = val_at_pointer - (unzoomed_val + half_min_page); - - higher *= zoom / 128; - lower *= zoom / 128; - - val = unzoomed_val + lower; - page = unzoomed_page - higher - lower; - - page = max(page, min_page_size); - - if (lower < 0) { - val = max(val, val_at_pointer - half_min_page); - } else if (lower > 0) { - val = min(val, val_at_pointer - half_min_page); - } - - val = min(val, adj.get_upper() - min_page_size); - page = min(page, adj.get_upper() - val); - } else if (ev->x < 0) { - /* on zoom out increase the page size as well as moving the range towards the mouse pos*/ - /*zoom = abs(ev->x); - - double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; - double lower = val_at_pointer - (unzoomed_val + half_min_page); - - higher *= zoom / 128; - lower *= zoom / 128; - - val = unzoomed_val + lower; - page = unzoomed_page - higher - lower; - - page = max(page, min_page_size); - - if (lower < 0) { - val = max(val, val_at_pointer - half_min_page); - } - else if (lower > 0) { - val = min(val, val_at_pointer - half_min_page); - } - - val = min(val, adj.get_upper() - min_page_size); - page = min(page, adj.get_upper() - val);*/ - - val = unzoomed_val; - page = unzoomed_page; - } else { - val = unzoomed_val; - page = unzoomed_page; - } - - /* Round these values to stop the scroomer handlers quivering about during drags */ - adj.set_page_size (rint (page)); - adj.set_value (rint (val)); - adj.value_changed(); - - return true; -} - -bool -Scroomer::on_scroll_event (GdkEventScroll* ev) -{ - switch (ev->direction) { - case GDK_SCROLL_UP: - adj.set_value (min (adj.get_value() + adj.get_page_size() / 10.0, adj.get_upper() - adj.get_page_size())); - break; - case GDK_SCROLL_DOWN: - adj.set_value (adj.get_value() - adj.get_page_size() / 10.0); - break; - default: - return false; - } - - return true; -} - -bool -Scroomer::on_button_press_event (GdkEventButton* ev) -{ - if (ev->button == 1 || ev->button == 3) { - Component comp = point_in(ev->y); - - if (comp == Total || comp == None) { - return false; - } - - add_modal_grab(); - grab_comp = comp; - grab_y = ev->y; - unzoomed_val = adj.get_value(); - unzoomed_page = adj.get_page_size(); - grab_window = ev->window; - - if (ev->button == 3){ - pinch = true; - } else { - pinch = false; - } - - DragStarting (); /* EMIT SIGNAL */ - } - - if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) { - DoubleClicked(); - } - - return true; -} - -bool -Scroomer::on_button_release_event (GdkEventButton* ev) -{ - if (grab_comp == None || grab_comp == Total) { - return true; - } - - if (ev->window != grab_window) { - grab_y = ev->y; - grab_window = ev->window; - return true; - } - - if (ev->button != 1 && ev->button != 3) { - return true; - } - - switch (grab_comp) { - case TopBase: - break; - case Handle1: - break; - case Slider: - break; - case Handle2: - break; - case BottomBase: - break; - default: - break; - } - - grab_comp = None; - - remove_modal_grab(); - DragFinishing (); /* EMIT SIGNAL */ - return true; -} - -void -Scroomer::on_size_allocate (Allocation& a) -{ - Gtk::DrawingArea::on_size_allocate(a); - - position[Total] = a.get_height(); - set_min_page_size(min_page_size); - update(); -} - -/** Assumes that x and width are correct, and they will not be altered. - */ -void -Scroomer::set_comp_rect(GdkRectangle& r, Component c) const -{ - int index = (int) c; - - switch (c) { - case None: - return; - case Total: - r.y = 0; - r.height = position[Total]; - break; - default: - r.y = position[index]; - r.height = position[index+1] - position[index]; - break; - } -} - -Scroomer::Component -Scroomer::point_in(double point) const -{ - for (int i = 0; i < Total; ++i) { - if (position[i+1] >= point) { - return (Component) i; - } - } - - return None; -} - -void -Scroomer::set_min_page_size(double ps) -{ - double coeff = ((double)position[Total]) / (adj.get_upper() - adj.get_lower()); - - min_page_size = ps; - handle_size = (int) floor((ps * coeff) / 2); -} - -void -Scroomer::update() -{ - double range = adj.get_upper() - adj.get_lower(); - //double value = adj.get_value() - adj.get_lower(); - int height = position[Total]; - double coeff = ((double) height) / range; - - /* save the old positions to calculate update regions later*/ - for (int i = Handle1; i < Total; ++i) { - old_pos[i] = position[i]; - } - - position[BottomBase] = (int) floor(height - (adj.get_value() * coeff)); - position[Handle2] = position[BottomBase] - handle_size; - - position[Handle1] = (int) floor(height - ((adj.get_value() + adj.get_page_size()) * coeff)); - position[Slider] = position[Handle1] + handle_size; -} - -void -Scroomer::adjustment_changed() -{ - //cerr << floor(adj.get_value()) << " " << floor(adj.get_value() + adj.get_page_size()) << endl; - Gdk::Rectangle rect; - Glib::RefPtr win = get_window(); - - update(); - - if (!win) { - return; - } - - rect.set_x(0); - rect.set_width(get_width()); - - if (position[Handle1] < old_pos[Handle1]) { - rect.set_y(position[Handle1]); - rect.set_height(old_pos[Slider] - position[Handle1]); - win->invalidate_rect(rect, false); - } else if (position[Handle1] > old_pos[Handle1]) { - rect.set_y(old_pos[Handle1]); - rect.set_height(position[Slider] - old_pos[Handle1]); - win->invalidate_rect(rect, false); - } - - if (position[Handle2] < old_pos[Handle2]) { - rect.set_y(position[Handle2]); - rect.set_height(old_pos[BottomBase] - position[Handle2]); - win->invalidate_rect(rect, false); - } else if (position[Handle2] > old_pos[Handle2]) { - rect.set_y(old_pos[Handle2]); - rect.set_height(position[BottomBase] - old_pos[Handle2]); - win->invalidate_rect(rect, false); - } -} - diff --git a/libs/gtkmm2ext/stateful_button.cc b/libs/gtkmm2ext/stateful_button.cc deleted file mode 100644 index 3c1ad2a830..0000000000 --- a/libs/gtkmm2ext/stateful_button.cc +++ /dev/null @@ -1,273 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include - - -#include - -#include - -using namespace Gtk; -using namespace Glib; -using namespace Gtkmm2ext; -using namespace std; - -StateButton::StateButton () - : visual_state (0) - , _self_managed (false) - , _is_realized (false) - , style_changing (false) - , state_before_prelight (Gtk::STATE_NORMAL) - , is_toggle (false) -{ -} - -void -StateButton::set_visual_state (int n) -{ - if (!_is_realized) { - /* not yet realized */ - visual_state = n; - return; - } - - if (n == visual_state) { - return; - } - - string name = get_widget_name (); - name = name.substr (0, name.find_last_of ('-')); - - switch (n) { - case 0: - /* relax */ - break; - case 1: - name += "-active"; - break; - - case 2: - name += "-alternate"; - break; - - case 3: - name += "-alternate2"; - break; - } - - set_widget_name (name); - visual_state = n; -} - -void -StateButton::avoid_prelight_on_style_changed (const Glib::RefPtr& /* old_style */, GtkWidget* widget) -{ - /* don't go into an endless recursive loop if we're changing - the style in response to an existing style change. - */ - - if (style_changing) { - return; - } - - if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT) { - - /* avoid PRELIGHT: make sure that the prelight colors in this new style match - the colors of the new style in whatever state we were in - before we switched to prelight. - */ - - GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget); - GtkStyle* style = gtk_widget_get_style (widget); - - rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[state_before_prelight]; - rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[state_before_prelight]; - rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG); - - style_changing = true; - g_object_ref (rcstyle); - gtk_widget_modify_style (widget, rcstyle); - - Widget* child = get_child_widget(); - if (child) { - gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle); - } - - - g_object_unref (rcstyle); - style_changing = false; - } -} - -void -StateButton::avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget) -{ - GtkStateType state = gtk_widget_get_state (widget); - - if (state == GTK_STATE_PRELIGHT) { - - state_before_prelight = old_state; - - - /* avoid PRELIGHT when currently ACTIVE: - if we just went into PRELIGHT, make sure that the colors - match those of whatever state we were in before. - */ - - GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget); - GtkStyle* style = gtk_widget_get_style (widget); - - rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[old_state]; - rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[old_state]; - rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG); - - g_object_ref (rcstyle); - gtk_widget_modify_style (widget, rcstyle); - - Widget* child = get_child_widget (); - - if (child) { - gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle); - } - - g_object_unref (rcstyle); - - } -} - -/* ----------------------------------------------------------------- */ - -StatefulToggleButton::StatefulToggleButton () -{ - is_toggle = true; -} - -StatefulToggleButton::StatefulToggleButton (const std::string& label) - : ToggleButton (label) -{ - is_toggle = true; -} - -void -StatefulToggleButton::on_realize () -{ - ToggleButton::on_realize (); - - _is_realized = true; - visual_state++; // to force transition - set_visual_state (visual_state - 1); -} - -void -StatefulButton::on_realize () -{ - Button::on_realize (); - - _is_realized = true; - visual_state++; // to force transition - set_visual_state (visual_state - 1); -} - -void -StatefulToggleButton::on_toggled () -{ - if (!_self_managed) { - if (get_active()) { - set_state (Gtk::STATE_ACTIVE); - } else { - set_state (Gtk::STATE_NORMAL); - } - } -} - - -void -StatefulToggleButton::on_style_changed (const Glib::RefPtr& style) -{ - avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj())); - Button::on_style_changed (style); -} - -void -StatefulToggleButton::on_state_changed (Gtk::StateType old_state) -{ - avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj())); - Button::on_state_changed (old_state); -} - -Widget* -StatefulToggleButton::get_child_widget () -{ - return get_child(); -} - -void -StatefulToggleButton::set_widget_name (const std::string& name) -{ - set_name (name); - Widget* w = get_child(); - - if (w) { - w->set_name (name); - } -} - -/*--------------------------------------------- */ - -StatefulButton::StatefulButton () -{ -} - -StatefulButton::StatefulButton (const std::string& label) - : Button (label) -{ -} - -void -StatefulButton::on_style_changed (const Glib::RefPtr& style) -{ - avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj())); - Button::on_style_changed (style); -} - -void -StatefulButton::on_state_changed (Gtk::StateType old_state) -{ - avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj())); - Button::on_state_changed (old_state); -} - -Widget* -StatefulButton::get_child_widget () -{ - return get_child(); -} - -void -StatefulButton::set_widget_name (const std::string& name) -{ - set_name (name); - Widget* w = get_child(); - - if (w) { - w->set_name (name); - } -} diff --git a/libs/gtkmm2ext/tabbable.cc b/libs/gtkmm2ext/tabbable.cc deleted file mode 100644 index 8653a6a29d..0000000000 --- a/libs/gtkmm2ext/tabbable.cc +++ /dev/null @@ -1,387 +0,0 @@ -/* - Copyright (C) 2015 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include - -#include "gtkmm2ext/tabbable.h" -#include "gtkmm2ext/gtk_ui.h" -#include "gtkmm2ext/utils.h" -#include "gtkmm2ext/visibility_tracker.h" - -#include "pbd/stacktrace.h" - -#include "pbd/i18n.h" - -using namespace Gtkmm2ext; -using namespace Gtk; -using std::string; - -Tabbable::Tabbable (Widget& w, const string& name, bool tabbed_by_default) - : WindowProxy (name) - , _contents (w) - , _parent_notebook (0) - , tab_requested_by_state (tabbed_by_default) -{ -} - -Tabbable::~Tabbable () -{ - if (_window) { - delete _window; - _window = 0; - } -} - -void -Tabbable::add_to_notebook (Notebook& notebook, const string& tab_title) -{ - _parent_notebook = ¬ebook; - - if (tab_requested_by_state) { - attach (); - } -} - -Window* -Tabbable::use_own_window (bool and_pack_it) -{ - Gtk::Window* win = get (true); - - if (and_pack_it) { - Gtk::Container* parent = _contents.get_parent(); - if (parent) { - _contents.hide (); - parent->remove (_contents); - } - _own_notebook.append_page (_contents); - _contents.show (); - } - - return win; - -} - -bool -Tabbable::window_visible () const -{ - if (!_window) { - return false; - } - - return _window->is_visible(); -} - -Window* -Tabbable::get (bool create) -{ - if (_window) { - return _window; - } - - if (!create) { - return 0; - } - - /* From here on, we're creating the window - */ - - if ((_window = new Window (WINDOW_TOPLEVEL)) == 0) { - return 0; - } - - _window->add (_own_notebook); - _own_notebook.show (); - _own_notebook.set_show_tabs (false); - - _window->signal_map().connect (sigc::mem_fun (*this, &Tabbable::window_mapped)); - _window->signal_unmap().connect (sigc::mem_fun (*this, &Tabbable::window_unmapped)); - - /* do other window-related setup */ - - setup (); - - /* window should be ready for derived classes to do something with it */ - - return _window; -} - -void -Tabbable::show_own_window (bool and_pack_it) -{ - Gtk::Widget* parent = _contents.get_parent(); - Gtk::Allocation alloc; - - if (parent) { - alloc = parent->get_allocation(); - } - - (void) use_own_window (and_pack_it); - - if (parent) { - _window->set_default_size (alloc.get_width(), alloc.get_height()); - } - - tab_requested_by_state = false; - - _window->present (); -} - -Gtk::Notebook* -Tabbable::tab_root_drop () -{ - /* This is called after a drop of a tab onto the root window. Its - * responsibility xois to return the notebook that this Tabbable's - * contents should be packed into before the drop handling is - * completed. It is not responsible for actually taking care of this - * packing. - */ - - show_own_window (false); - return &_own_notebook; -} - -void -Tabbable::show_window () -{ - make_visible (); - - if (_window && (current_toplevel() == _window)) { - if (!_visible) { /* was hidden, update status */ - set_pos_and_size (); - } - } -} - -/** If this Tabbable is currently parented by a tab, ensure that the tab is the - * current one. If it is parented by a window, then toggle the visibility of - * that window. - */ -void -Tabbable::change_visibility () -{ - if (tabbed()) { - _parent_notebook->set_current_page (_parent_notebook->page_num (_contents)); - return; - } - - if (tab_requested_by_state) { - /* should be tabbed, but currently isn't parented by a notebook */ - return; - } - - if (_window && (current_toplevel() == _window)) { - /* Use WindowProxy method which will rotate then hide */ - toggle(); - } -} - -void -Tabbable::make_visible () -{ - if (_window && (current_toplevel() == _window)) { - set_pos (); - _window->present (); - } else { - - if (!tab_requested_by_state) { - show_own_window (true); - } else { - show_tab (); - } - } -} - -void -Tabbable::make_invisible () -{ - if (_window && (current_toplevel() == _window)) { - _window->hide (); - } else { - hide_tab (); - } -} - -void -Tabbable::detach () -{ - show_own_window (true); -} - -void -Tabbable::attach () -{ - if (!_parent_notebook) { - return; - } - - if (tabbed()) { - /* already tabbed */ - return; - } - - - if (_window && current_toplevel() == _window) { - /* unpack Tabbable from parent, put it back in the main tabbed - * notebook - */ - - save_pos_and_size (); - - _contents.hide (); - _contents.get_parent()->remove (_contents); - - /* leave the window around */ - - _window->hide (); - } - - _parent_notebook->append_page (_contents); - _parent_notebook->set_tab_detachable (_contents); - _parent_notebook->set_tab_reorderable (_contents); - _parent_notebook->set_current_page (_parent_notebook->page_num (_contents)); - _contents.show (); - - /* have to force this on, which is semantically correct, since - * the user has effectively asked for it. - */ - - tab_requested_by_state = true; - StateChange (*this); -} - -bool -Tabbable::delete_event_handler (GdkEventAny *ev) -{ - _window->hide(); - - return true; -} - -bool -Tabbable::tabbed () const -{ - if (_window && (current_toplevel() == _window)) { - return false; - } - - if (_parent_notebook && (_parent_notebook->page_num (_contents) >= 0)) { - return true; - } - - return false; -} - -void -Tabbable::hide_tab () -{ - if (tabbed()) { - _contents.hide(); - _parent_notebook->remove_page (_contents); - StateChange (*this); - } -} - -void -Tabbable::show_tab () -{ - if (!window_visible() && _parent_notebook) { - if (_contents.get_parent() == 0) { - tab_requested_by_state = true; - add_to_notebook (*_parent_notebook, _tab_title); - } - _parent_notebook->set_current_page (_parent_notebook->page_num (_contents)); - _contents.show (); - current_toplevel()->present (); - } -} - -Gtk::Window* -Tabbable::current_toplevel () const -{ - return dynamic_cast (contents().get_toplevel()); -} - -string -Tabbable::xml_node_name() -{ - return WindowProxy::xml_node_name(); -} - -bool -Tabbable::tabbed_by_default() const -{ - return tab_requested_by_state; -} - -XMLNode& -Tabbable::get_state() -{ - XMLNode& node (WindowProxy::get_state()); - - node.set_property (X_("tabbed"), tabbed()); - - return node; -} - -int -Tabbable::set_state (const XMLNode& node, int version) -{ - int ret; - - if ((ret = WindowProxy::set_state (node, version)) != 0) { - return ret; - } - - if (_visible) { - show_own_window (true); - } - - XMLNodeList children = node.children (); - XMLNode* window_node = node.child ("Window"); - - if (window_node) { - window_node->get_property (X_("tabbed"), tab_requested_by_state); - } - - if (!_visible) { - if (tab_requested_by_state) { - attach (); - } else { - /* this does nothing if not tabbed */ - hide_tab (); - } - } - - return ret; -} - -void -Tabbable::window_mapped () -{ - StateChange (*this); -} - -void -Tabbable::window_unmapped () -{ - StateChange (*this); -} diff --git a/libs/gtkmm2ext/tearoff.cc b/libs/gtkmm2ext/tearoff.cc deleted file mode 100644 index 090d249b72..0000000000 --- a/libs/gtkmm2ext/tearoff.cc +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (C) 2003 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include -#include - -#include "pbd/xml++.h" - -#include "gtkmm2ext/tearoff.h" -#include "gtkmm2ext/utils.h" - -#include "pbd/i18n.h" - -using namespace Gtkmm2ext; -using namespace Gtk; -using namespace Gdk; -using namespace Glib; -using namespace std; - -TearOff::TearOff (Widget& c, bool allow_resize) - : contents (c) - , own_window (Gtk::WINDOW_TOPLEVEL) - , tearoff_arrow (ARROW_DOWN, SHADOW_OUT) - , close_arrow (ARROW_UP, SHADOW_OUT) - , dragging (false) - , _visible (true) - , _torn (false) - , _can_be_torn_off (true) - -{ - own_window_width = 0; - own_window_height = 0; - own_window_xpos = 0; - own_window_ypos = 0; - - tearoff_event_box.add (tearoff_arrow); - tearoff_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); - tearoff_event_box.signal_button_release_event().connect (mem_fun (*this, &TearOff::tearoff_click)); - - tearoff_event_box.set_tooltip_text (_("Click to tear this into its own window")); - - close_event_box.add (close_arrow); - close_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); - close_event_box.signal_button_release_event().connect (mem_fun (*this, &TearOff::close_click)); - - close_event_box.set_tooltip_text (_("Click to put this back in the main window")); - - VBox* box1; - box1 = manage (new VBox); - box1->pack_start (close_event_box, false, false, 2); - - window_box.pack_end (*box1, false, false, 2); - - own_window.add_events (KEY_PRESS_MASK|KEY_RELEASE_MASK|BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK|POINTER_MOTION_MASK|POINTER_MOTION_HINT_MASK); - own_window.set_resizable (allow_resize); - own_window.set_type_hint (WINDOW_TYPE_HINT_UTILITY); - - own_window.add (window_box); - - own_window.signal_button_press_event().connect (mem_fun (*this, &TearOff::window_button_press)); - own_window.signal_button_release_event().connect (mem_fun (*this, &TearOff::window_button_release)); - own_window.signal_motion_notify_event().connect (mem_fun (*this, &TearOff::window_motion)); - own_window.signal_delete_event().connect (mem_fun (*this, &TearOff::window_delete_event)); - own_window.signal_realize().connect (sigc::mem_fun (*this, &TearOff::own_window_realized)); - own_window.signal_configure_event().connect (sigc::mem_fun (*this, &TearOff::own_window_configured), false); - - tearoff_arrow.set_name ("TearOffArrow"); - close_arrow.set_name ("TearOffArrow"); - - VBox* box2; - box2 = manage (new VBox); - box2->pack_start (tearoff_event_box, false, false); - - pack_start (contents); - pack_start (*box2, false, false); -} - -TearOff::~TearOff () -{ -} - -void -TearOff::set_can_be_torn_off (bool yn) -{ - if (yn != _can_be_torn_off) { - if (yn) { - tearoff_arrow.set_no_show_all (false); - tearoff_arrow.show (); - } else { - tearoff_arrow.set_no_show_all (true); - tearoff_arrow.hide (); - } - _can_be_torn_off = yn; - } -} - -void -TearOff::set_visible (bool yn, bool force) -{ - /* don't change visibility if torn off */ - - if (_torn) { - return; - } - - if (_visible != yn || force) { - _visible = yn; - if (yn) { - show_all(); - Visible (); - } else { - hide (); - Hidden (); - } - } -} - -gint -TearOff::tearoff_click (GdkEventButton* /*ev*/) -{ - tear_it_off (); - return true; -} - -void -TearOff::tear_it_off () -{ - if (!_can_be_torn_off) { - return; - } - - if (torn_off()) { - return; - } - - remove (contents); - window_box.pack_start (contents); - own_window.set_name (get_name()); - close_event_box.set_name (get_name()); - if (own_window_width == 0) { - own_window.set_position (WIN_POS_MOUSE); - } - own_window.show_all (); - own_window.present (); - hide (); - - _torn = true; - - Detach (); -} - -gint -TearOff::close_click (GdkEventButton* /*ev*/) -{ - put_it_back (); - return true; -} - -void -TearOff::put_it_back () -{ - if (!torn_off()) { - return; - } - - window_box.remove (contents); - pack_start (contents); - reorder_child (contents, 0); - own_window.hide (); - show_all (); - - _torn = false; - - Attach (); -} - -gint -TearOff::window_button_press (GdkEventButton* ev) -{ - if (dragging || ev->button != 1) { - dragging = false; - own_window.remove_modal_grab(); - return true; - } - - dragging = true; - drag_x = ev->x_root; - drag_y = ev->y_root; - - own_window.add_modal_grab(); - - return true; -} - -gint -TearOff::window_button_release (GdkEventButton* /*ev*/) -{ - dragging = false; - own_window.remove_modal_grab(); - return true; -} - -gint -TearOff::window_delete_event (GdkEventAny* /*ev*/) -{ - return close_click(0); -} - -gint -TearOff::window_motion (GdkEventMotion* ev) -{ - gint x; - gint y; - gint mx, my; - double x_delta; - double y_delta; - RefPtr win (own_window.get_window()); - - own_window.get_pointer (mx, my); - - if (!dragging) { - return true; - } - - if (!(ev->state & GDK_BUTTON1_MASK)) { - dragging = false; - own_window.remove_modal_grab(); - return true; - } - - x_delta = ev->x_root - drag_x; - y_delta = ev->y_root - drag_y; - - win->get_root_origin (x, y); - win->move ((gint) floor (x + x_delta), (gint) floor (y + y_delta)); - - drag_x = ev->x_root; - drag_y = ev->y_root; - - return true; -} - -bool -TearOff::torn_off() const -{ - return _torn; -} - -void -TearOff::add_state (XMLNode& node) const -{ - node.set_property ("tornoff", _torn); - - if (own_window_width > 0) { - node.set_property ("width", own_window_width); - node.set_property ("height", own_window_height); - node.set_property ("xpos", own_window_xpos); - node.set_property ("ypos", own_window_ypos); - } -} - -void -TearOff::set_state (const XMLNode& node) -{ - Glib::RefPtr win; - - bool tornoff; - if (!node.get_property (X_("tornoff"), tornoff)) { - return; - } - - if (tornoff) { - tear_it_off (); - } else { - put_it_back (); - } - - node.get_property (X_("width"), own_window_width); - node.get_property (X_("height"), own_window_height); - node.get_property (X_("xpos"), own_window_xpos); - node.get_property (X_("ypos"), own_window_ypos); - - if (own_window.is_realized ()) { - own_window.set_default_size (own_window_width, own_window_height); - own_window.move (own_window_xpos, own_window_ypos); - } - /* otherwise do it once the window is realized, see below */ -} - -void -TearOff::own_window_realized () -{ - own_window.get_window()->set_decorations (WMDecoration (DECOR_BORDER|DECOR_RESIZEH)); - - if (own_window_width > 0) { - own_window.set_default_size (own_window_width, own_window_height); - own_window.move (own_window_xpos, own_window_ypos); - } -} - -bool -TearOff::own_window_configured (GdkEventConfigure*) -{ - Glib::RefPtr win; - - win = own_window.get_window (); - - if (win) { - win->get_size (own_window_width, own_window_height); - win->get_position (own_window_xpos, own_window_ypos); - } - - return false; -} - -void -TearOff::hide_visible () -{ - if (torn_off()) { - own_window.hide (); - } - - hide (); -} - - diff --git a/libs/gtkmm2ext/wscript b/libs/gtkmm2ext/wscript index 1f8c89e4e5..700d1dee14 100644 --- a/libs/gtkmm2ext/wscript +++ b/libs/gtkmm2ext/wscript @@ -25,33 +25,21 @@ I18N_PACKAGE = 'gtkmm2ext3' gtkmm2ext_sources = [ 'actions.cc', 'application.cc', - 'ardour_icon.cc', - 'binding_proxy.cc', 'bindings.cc', 'cairo_packer.cc', 'cairo_widget.cc', 'cell_renderer_color_selector.cc', 'cell_renderer_pixbuf_multi.cc', 'cell_renderer_pixbuf_toggle.cc', - 'choice.cc', 'cursors.cc', 'debug.cc', 'dndtreeview.cc', 'emscale.cc', - 'eventboxext.cc', 'gtk_ui.cc', 'gtkapplication.c', 'keyboard.cc', 'menu_elems.cc', - 'pane.cc', - 'paths_dialog.cc', 'persistent_tooltip.cc', - 'popup.cc', - 'prompter.cc', - 'scroomer.cc', - 'stateful_button.cc', - 'tabbable.cc', - 'tearoff.cc', 'textviewer.cc', 'treeutils.cc', 'utils.cc', @@ -94,7 +82,7 @@ def build(bld): obj.name = 'libgtkmm2ext' obj.target = 'gtkmm2ext' obj.uselib = 'GTKMM GTK XML' - obj.use = [ 'libpbd', 'libardour' ] + obj.use = [ 'libpbd' ] obj.vnum = GTKMM2EXT_LIB_VERSION obj.install_path = bld.env['LIBDIR'] obj.defines += [ diff --git a/libs/widgets/ardour_button.cc b/libs/widgets/ardour_button.cc index 913e18bae8..8c16bcdca1 100644 --- a/libs/widgets/ardour_button.cc +++ b/libs/widgets/ardour_button.cc @@ -22,6 +22,7 @@ #include #include +#include #include "pbd/compose.h" #include "pbd/controllable.h" @@ -60,7 +61,7 @@ ArdourButton::ArdourButton (Element e) : _sizing_text("") , _markup (false) , _elements (e) - , _icon (Gtkmm2ext::ArdourIcon::NoIcon) + , _icon (ArdourIcon::NoIcon) , _icon_render_cb (0) , _icon_render_cb_data (0) , _tweaks (Tweaks (0)) @@ -108,7 +109,7 @@ ArdourButton::ArdourButton (const std::string& str, Element e) : _sizing_text("") , _markup (false) , _elements (e) - , _icon (Gtkmm2ext::ArdourIcon::NoIcon) + , _icon (ArdourIcon::NoIcon) , _tweaks (Tweaks (0)) , _char_pixel_width (0) , _char_pixel_height (0) @@ -379,7 +380,7 @@ ArdourButton::render (Cairo::RefPtr const& ctx, cairo_rectangle_ vw -= _diameter + 4; } if (_elements & VectorIcon) { - Gtkmm2ext::ArdourIcon::render (cr, _icon, vw, vh, active_state(), text_color); + ArdourIcon::render (cr, _icon, vw, vh, active_state(), text_color); } else { cairo_save (cr); rounded_function (cr, 0, 0, get_width(), get_height(), corner_radius + 1.5); @@ -1303,7 +1304,7 @@ ArdourButton::add_elements (Element e) } void -ArdourButton::set_icon (Gtkmm2ext::ArdourIcon::Icon i) +ArdourButton::set_icon (ArdourIcon::Icon i) { _icon = i; _icon_render_cb = 0; diff --git a/libs/widgets/ardour_icon.cc b/libs/widgets/ardour_icon.cc new file mode 100644 index 0000000000..f111e8919c --- /dev/null +++ b/libs/widgets/ardour_icon.cc @@ -0,0 +1,1121 @@ +/* + Copyright (C) 2009 Paul Davis + Copyright (C) 2015 Robin Gareus + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include // M_PI +#include +#include // std:min + +#include "widgets/ardour_icon.h" + +using namespace ArdourWidgets::ArdourIcon; + +/* general style info: + * + * - geometry: icons should be centered, spanning + * wh = std::min (width * .5, height *.5) * .55; + * + * - all shapes should have a contrasting outline + * (usually white foreground, black outline) + */ + +#define OUTLINEWIDTH 1.5 // px + +#define VECTORICONSTROKEFILL(fillalpha) \ + cairo_set_line_width (cr, OUTLINEWIDTH); \ + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); \ + cairo_stroke_preserve (cr); \ + cairo_set_source_rgba (cr, 1, 1, 1, (fillalpha)); \ + cairo_fill (cr); + +#define VECTORICONSTROKEOUTLINE(LW, color) \ + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); \ + cairo_set_line_width (cr, (LW) + OUTLINEWIDTH); \ + ardour_icon_set_source_inv_rgba (cr, color); \ + cairo_stroke_preserve (cr); \ + ardour_icon_set_source_rgba (cr, color); \ + cairo_set_line_width (cr, (LW)); \ + cairo_stroke (cr); + + +/** convert 32bit 'RRGGBBAA' to cairo doubles + * from libs/canvas/utils.cc and canvas/types.h: typedef uint32_t Color; + */ +static void ardour_icon_set_source_rgba (cairo_t *cr, uint32_t color) +{ + cairo_set_source_rgba (cr, + ((color >> 24) & 0xff) / 255.0, + ((color >> 16) & 0xff) / 255.0, + ((color >> 8) & 0xff) / 255.0, + ((color >> 0) & 0xff) / 255.0 + ); +} + +/** inverse color */ +static void ardour_icon_set_source_inv_rgba (cairo_t *cr, uint32_t color) +{ + cairo_set_source_rgba (cr, + 1.0 - ((color >> 24) & 0xff) / 255.0, + 1.0 - ((color >> 16) & 0xff) / 255.0, + 1.0 - ((color >> 8) & 0xff) / 255.0, + ((color >> 0) & 0xff) / 255.0 + ); +} + +/***************************************************************************** + * Tool Icons. + * Foreground is always white, compatible with small un-blurred rendering. + */ + +/** internal edit icon */ +static void icon_tool_content (cairo_t *cr, const int width, const int height) { +#define EM_POINT(X,Y) round (x + (X) * em) + .5, round (y + (Y) * em) + .5 + + const double x = width * .5; + const double y = height * .5; + const double em = std::min (x, y) * .1; // 1px at 20x20 + + // draw dot outlines (control-points) + cairo_move_to (cr, EM_POINT(-6.0, 0.0)); + cairo_close_path (cr); + cairo_move_to (cr, EM_POINT(-2.5, 4.0)); + cairo_close_path (cr); + cairo_move_to (cr, EM_POINT( 5.0, -5.0)); + cairo_close_path (cr); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + ardour_icon_set_source_inv_rgba (cr, 0xffffffff); + cairo_set_line_width (cr, 3 * em + OUTLINEWIDTH); + cairo_stroke (cr); + + // "midi note" lines + cairo_move_to (cr, EM_POINT(-7.0, -5.0)); + cairo_line_to (cr, EM_POINT( 0.0, -5.0)); + + cairo_move_to (cr, EM_POINT( 2.0, 4.0)); + cairo_line_to (cr, EM_POINT( 6.0, 4.0)); + + // automation line (connect control-points) + cairo_move_to (cr, EM_POINT(-6.0, 0.0)); + cairo_line_to (cr, EM_POINT(-2.5, 4.0)); + cairo_line_to (cr, EM_POINT( 5.0, -5.0)); + + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + VECTORICONSTROKEOUTLINE(1 * em, 0xffffffff); + + // remove automation line outline at control-points + cairo_move_to (cr, EM_POINT(-6.0, 0.0)); + cairo_close_path (cr); + cairo_move_to (cr, EM_POINT(-2.5, 4.0)); + cairo_close_path (cr); + cairo_move_to (cr, EM_POINT( 5.0, -5.0)); + cairo_close_path (cr); + + ardour_icon_set_source_rgba (cr, 0xffffffff); + cairo_set_line_width (cr, 3 * em); + cairo_stroke (cr); +#undef EM_POINT +} + +/** range tool |<->| */ +static void icon_tool_range (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y) * .55; + const double lw = rint (wh / 6.0); // line width + const double ar = wh * .6; // arrow + + const double bw = ceil (wh) - .5; + const double y0 = ceil (y); + const double ym = rint (y0 - wh * .1) + .5; // arrow-horizontal; slightly to the top, on a px + const double x0 = rint (x) - bw; // left arrow tip + const double x1 = rint (x) + bw; // right arrow tip + + // left and right box + cairo_move_to (cr, x0, y0 - bw); + cairo_line_to (cr, x0, y0 + bw); + VECTORICONSTROKEOUTLINE(lw, 0xffffffff); + cairo_move_to (cr, x1, y0 - bw); + cairo_line_to (cr, x1, y0 + bw); + VECTORICONSTROKEOUTLINE(lw, 0xffffffff); + + // arrows + cairo_move_to (cr, x0 + ar, ym - ar); + cairo_line_to (cr, x0 + .5, ym); + cairo_line_to (cr, x0 + ar, ym + ar); + + cairo_move_to (cr, x1 - ar, ym - ar); + cairo_line_to (cr, x1 - .5, ym); + cairo_line_to (cr, x1 - ar, ym + ar); + + // line connecting the arrows + cairo_move_to (cr, x0, ym); + cairo_line_to (cr, x1, ym); + VECTORICONSTROKEOUTLINE(lw, 0xffffffff); + + cairo_set_source_rgba (cr, 1, 1, 1, 1.0); + cairo_set_line_width (cr, lw); + + cairo_move_to (cr, x0, y0 - bw); + cairo_line_to (cr, x0, y0 + bw); + cairo_stroke (cr); + + cairo_move_to (cr, x1, y0 - bw); + cairo_line_to (cr, x1, y0 + bw); + cairo_stroke (cr); + + +} + +/** Grab/Object tool - 6x8em "hand", with 'em' wide index finger. */ +static void icon_tool_grab (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double em = std::min (x, y) * .15; // 1.5px at 20x20 + +#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em + + // wrist + cairo_move_to (cr, EM_POINT( 2.0, 4.0)); + cairo_line_to (cr, EM_POINT(-1.5, 4.0)); + cairo_line_to (cr, EM_POINT(-2.5, 2.0)); + // thumb + cairo_line_to (cr, EM_POINT(-3.0, 1.0)); + + // index finger + cairo_line_to (cr, EM_POINT(-2.0, 0.0)); + cairo_line_to (cr, EM_POINT(-2.1, -4.0)); + cairo_line_to (cr, EM_POINT(-1.5, -4.5)); + cairo_line_to (cr, EM_POINT(-1.1, -4.0)); + cairo_line_to (cr, EM_POINT(-1.0, 0.1)); + + // middle finger knuckle + cairo_line_to (cr, EM_POINT(-0.6, 0.3)); + cairo_line_to (cr, EM_POINT(-0.3, 0.0)); + cairo_line_to (cr, EM_POINT(-0.2, -0.2)); + cairo_line_to (cr, EM_POINT( 0.1, -0.3)); + cairo_line_to (cr, EM_POINT( 0.4, -0.2)); + cairo_line_to (cr, EM_POINT( 0.5, 0.1)); + + // ring finger knuckle + cairo_line_to (cr, EM_POINT( 0.8, 0.4)); + cairo_line_to (cr, EM_POINT( 1.1, 0.2)); + cairo_line_to (cr, EM_POINT( 1.2, 0.0)); + cairo_line_to (cr, EM_POINT( 1.5, -0.1)); + cairo_line_to (cr, EM_POINT( 1.8, 0.0)); + cairo_line_to (cr, EM_POINT( 1.9, 0.4)); + + // pinky + cairo_line_to (cr, EM_POINT( 2.0, 0.6)); + cairo_line_to (cr, EM_POINT( 2.4, 0.4)); + cairo_line_to (cr, EM_POINT( 2.8, 0.5)); + cairo_line_to (cr, EM_POINT( 3.0, 1.0)); + + // wrist + cairo_line_to (cr, EM_POINT( 3.0, 1.5)); + cairo_line_to (cr, EM_POINT( 2.0, 4.0)); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + VECTORICONSTROKEFILL(1.0); +#undef EM_POINT +} + +/** cut icon - scissors */ +static void icon_tool_cut (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double em = std::min (x, y) * .1; // 1px at 20x20 + +#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em + + cairo_save (cr); + cairo_translate (cr, EM_POINT(4, -3)); + cairo_scale (cr, 1.6, 1.0); // ellipse + cairo_arc (cr, 0., 0., 1.5 * em, 0., 2 * M_PI); + cairo_restore (cr); + + cairo_move_to (cr, EM_POINT(-6.0, 2.5)); + cairo_line_to (cr, EM_POINT( 5.5, -2.0)); + + cairo_move_to (cr, EM_POINT(-6.0, -2.5)); + cairo_line_to (cr, EM_POINT( 5.5, 2.0)); + + cairo_save (cr); + cairo_translate (cr, EM_POINT(4, 3)); + cairo_scale (cr, 1.6, 1.0); // ellipse + cairo_arc (cr, 0., 0., 1.5 * em, 0., 2 * M_PI); + cairo_restore (cr); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + + VECTORICONSTROKEOUTLINE (1.5 * em, 0xffffffff); +#undef EM_POINT +} + +/** time stretch icon */ +static void icon_tool_stretch (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y) * .55; + + const double y0 = ceil (y); + const double bw = rint (wh); + const double lw = rint (wh / 3.0) / 2.0; + const double x0 = rint (x + lw) + .5; + + // box indication region + cairo_rectangle (cr, x0 - lw - bw - .5, y0 - bw, lw + bw, 2 * bw); + VECTORICONSTROKEFILL (0.75); + + cairo_set_line_width (cr, 1.0); + + // inside/left arrow + cairo_move_to (cr, x0, y); + cairo_line_to (cr, x0 - lw * 2, y); + cairo_line_to (cr, x0 - lw * 2, y - lw * 3.5); + cairo_line_to (cr, x0 - lw * 6, y); + cairo_line_to (cr, x0 - lw * 2, y + lw * 3.5); + cairo_line_to (cr, x0 - lw * 2, y); + + cairo_set_source_rgba (cr, 0, 0, 0, .5); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); + + // outside/right arrow + cairo_move_to (cr, x0, y); + cairo_line_to (cr, x0 + lw * 2, y); + cairo_line_to (cr, x0 + lw * 2, y - lw * 4); + cairo_line_to (cr, x0 + lw * 6, y); + cairo_line_to (cr, x0 + lw * 2, y + lw * 4); + cairo_line_to (cr, x0 + lw * 2, y); + + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 1, 1, 1, 1.0); + cairo_fill (cr); +} + +/** audition - small speaker with sound-waves*/ +static void icon_tool_audition (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double em = std::min (x, y) * .1; // 1px at 20x20 + +#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em + + cairo_move_to (cr, EM_POINT(-7.0, -2.0)); + cairo_line_to (cr, EM_POINT(-7.0, 2.0)); + cairo_line_to (cr, EM_POINT(-6.0, 3.0)); + cairo_line_to (cr, EM_POINT(-3.0, 3.0)); + cairo_line_to (cr, EM_POINT( 2.0, 6.0)); + cairo_line_to (cr, EM_POINT( 2.0, -6.0)); + cairo_line_to (cr, EM_POINT(-3.0, -3.0)); + cairo_line_to (cr, EM_POINT(-6.0, -3.0)); + cairo_close_path (cr); + + cairo_pattern_t *speaker; + speaker = cairo_pattern_create_linear (EM_POINT(0, -3.0), EM_POINT(0, 3.0)); + cairo_pattern_add_color_stop_rgba (speaker, 0.0, 0.8, 0.8, 0.8, 1.0); + cairo_pattern_add_color_stop_rgba (speaker, 0.25, 1.0, 1.0, 1.0, 1.0); + cairo_pattern_add_color_stop_rgba (speaker, 1.0, 0.6, 0.6, 0.6, 1.0); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_width (cr, 1.5); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_stroke_preserve (cr); + cairo_set_source (cr, speaker); + cairo_fill (cr); + cairo_pattern_destroy (speaker); + + // TODO use a slight curve + cairo_move_to (cr, EM_POINT(-3.0, -3.0)); + cairo_line_to (cr, EM_POINT(-3.5, 0.0)); + cairo_line_to (cr, EM_POINT(-3.0, 3.0)); + cairo_set_source_rgba (cr, 0, 0, 0, 0.7); + cairo_set_line_width (cr, 1.0); + cairo_stroke (cr); + + + cairo_save (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + + cairo_translate (cr, EM_POINT (4.0, 0)); + cairo_scale (cr, 0.8, 1.25); // ellipse + + cairo_arc (cr, 0, 0, 4 * em, -.5 * M_PI, .5 * M_PI); + cairo_set_line_width (cr, .8 * em); + cairo_stroke (cr); + + cairo_arc (cr, 0, 0, 2 * em, -.5 * M_PI, .5 * M_PI); + cairo_set_line_width (cr, .5 * em); + cairo_stroke (cr); + cairo_restore (cr); +#undef EM_POINT +} + +/** pen top-left to bottom right */ +static void icon_tool_draw (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double em = std::min (x, y) * .1; // 1px at 20x20 + +#define EM_POINT(X,Y) x + (X) * em, y + (Y) * em + + // pen [6,-5] to [-3, 3] + // y = -8 * x / 9 + 1/3 + + // top-right end + cairo_move_to (cr, EM_POINT( 5.0, -6.11)); + cairo_line_to (cr, EM_POINT( 6.4, -5.35)); // todo round properly. + cairo_line_to (cr, EM_POINT( 7.0, -3.88)); + + // bottom-left w/tip + cairo_line_to (cr, EM_POINT(-2.0, 4.11)); + cairo_line_to (cr, EM_POINT(-6.0, 5.66)); // pen tip + cairo_line_to (cr, EM_POINT(-4.0, 1.88)); + cairo_close_path (cr); + + cairo_pattern_t *pen; + pen = cairo_pattern_create_linear (EM_POINT(-3.0, -6.0), EM_POINT(6.0, 4.0)); + cairo_pattern_add_color_stop_rgba (pen, 0.4, 0.6, 0.6, 0.6, 1.0); + cairo_pattern_add_color_stop_rgba (pen, 0.5, 1.0, 1.0, 1.0, 1.0); + cairo_pattern_add_color_stop_rgba (pen, 0.6, 0.1, 0.1, 0.1, 1.0); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_width (cr, em + .5); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_stroke_preserve (cr); + cairo_set_source (cr, pen); + cairo_fill (cr); + + // separate the tip + cairo_move_to (cr, EM_POINT(-2.0, 4.11)); + cairo_line_to (cr, EM_POINT(-3.0, 2.8)); // slight curve [-3,3] + cairo_line_to (cr, EM_POINT(-4.0, 2.0)); + cairo_set_line_width (cr, OUTLINEWIDTH); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke (cr); + + // pen tip + cairo_move_to (cr, EM_POINT(-5.0, 3.9)); + cairo_line_to (cr, EM_POINT(-6.0, 5.66)); + cairo_line_to (cr, EM_POINT(-4.1, 4.9)); + cairo_close_path (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 0.7); + cairo_set_line_width (cr, em); + cairo_stroke_preserve (cr); + cairo_fill (cr); + + cairo_pattern_destroy (pen); +#undef EM_POINT +} + +/** Toolbar icon - Time Axis View reduce height */ +static void icon_tav_shrink (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y) * .66; + const double ar = std::min (x, y) * .15; + const double tri = .7 * (wh - ar); + + cairo_rectangle (cr, x - wh, y - ar, 2 * wh, 2 * ar); + VECTORICONSTROKEFILL(.75); + + cairo_set_line_width (cr, 1.0); + + cairo_move_to (cr, x, y - ar - 0.5); + cairo_line_to (cr, x - tri, y - wh + 0.5); + cairo_line_to (cr, x + tri, y - wh + 0.5); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1, 1, 1, .75); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); + + cairo_move_to (cr, x, y + ar + 0.5); + cairo_line_to (cr, x - tri, y + wh - 0.5); + cairo_line_to (cr, x + tri, y + wh - 0.5); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1, 1, 1, .75); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); +} + +/** Toolbar icon - Time Axis View increase height */ +static void icon_tav_expand (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y) * .66; + const double ar = std::min (x, y) * .15; + const double tri = .7 * (wh - ar); + + cairo_rectangle (cr, x - wh, y - wh, 2 * wh, 2 * wh); + VECTORICONSTROKEFILL(.75); + + cairo_set_line_width (cr, 1.0); + + cairo_move_to (cr, x, y - wh + 0.5); + cairo_line_to (cr, x - tri, y - ar - 0.5); + cairo_line_to (cr, x + tri, y - ar - 0.5); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1, 1, 1, .5); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); + + cairo_move_to (cr, x , y + wh - 0.5); + cairo_line_to (cr, x - tri, y + ar + 0.5); + cairo_line_to (cr, x + tri, y + ar + 0.5); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1, 1, 1, .5); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); +} + + +/***************************************************************************** + * Record enable (transport & track header). + * + * hardcoded "red" #f46f6f + */ + +/** standard rec-enable circle */ +static void icon_rec_enable (cairo_t *cr, const int width, const int height, const Gtkmm2ext::ActiveState state) +{ + const double x = width * .5; + const double y = height * .5; + const double r = std::min (x, y) * .55; + cairo_arc (cr, x, y, r, 0, 2 * M_PI); + if (state == Gtkmm2ext::ExplicitActive) { + cairo_set_source_rgba (cr, 1.0, .1, .1, 1.0); + } + else if (state == Gtkmm2ext::ImplicitActive) { + cairo_set_source_rgba (cr, .9, .3, .3, 1.0); + } + else { + cairo_set_source_rgba (cr, .4, .3, .3, 1.0); + } + cairo_fill_preserve (cr); + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8); // outline + cairo_set_line_width (cr, 1); + cairo_stroke (cr); +} + +/** tape-mode, "reel" */ +static void icon_rec_tape (cairo_t *cr, const int width, const int height, const Gtkmm2ext::ActiveState state) +{ + const double x = width * .5; + const double y = height * .5; + const double r = std::min (x, y) * .6; + const double slit = .11 * M_PI; + cairo_translate (cr, x, y); + + cairo_arc (cr, 0, 0, r, 0, 2 * M_PI); + if (state == Gtkmm2ext::ExplicitActive) { + cairo_set_source_rgba (cr, 1.0, .1, .1, 1.0); + } + else if (state == Gtkmm2ext::ImplicitActive) { + cairo_set_source_rgba (cr, .9, .3, .3, 1.0); + } + else { + cairo_set_source_rgba (cr, .4, .3, .3, 1.0); + } + cairo_fill_preserve (cr); + cairo_set_source_rgba (cr, .0, .0, .0, .5); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + + cairo_save (cr); + cairo_set_source_rgba (cr, .15, .07, .07, 1.0); + + cairo_rotate (cr, -.5 * M_PI); + cairo_move_to (cr, 0, 0); + cairo_arc (cr, 0, 0, r *.85, -slit, slit); + cairo_line_to (cr, 0, 0); + cairo_close_path (cr); + + cairo_fill (cr); + cairo_rotate (cr, 2. * M_PI / 3.); + + cairo_move_to (cr, 0, 0); + cairo_arc (cr, 0, 0, r *.85, -slit, slit); + cairo_line_to (cr, 0, 0); + cairo_close_path (cr); + cairo_fill (cr); + + cairo_rotate (cr, 2. * M_PI / 3.); + cairo_move_to (cr, 0, 0); + cairo_arc (cr, 0, 0, r *.85, -slit, slit); + cairo_line_to (cr, 0, 0); + cairo_close_path (cr); + cairo_fill (cr); + + cairo_restore (cr); + + cairo_arc (cr, 0, 0, r * .3, 0, 2 * M_PI); + if (state == Gtkmm2ext::ExplicitActive) { + cairo_set_source_rgba (cr, 1.0, .1, .1, 1.0); + } + else if (state == Gtkmm2ext::ImplicitActive) { + cairo_set_source_rgba (cr, .9, .3, .3, 1.0); + } + else { + cairo_set_source_rgba (cr, .4, .3, .3, 1.0); + } + cairo_fill (cr); + cairo_set_source_rgba (cr, .0, .0, .0, 1.0); + cairo_arc (cr, 0, 0, r *.15, 0, 2 * M_PI); // hole in the middle + cairo_fill (cr); +} + + +/***************************************************************************** + * Transport buttons, foreground is always white + */ + +/** stop square box */ +static void icon_transport_stop (cairo_t *cr, const int width, const int height) +{ + const int wh = std::min (width, height); + cairo_rectangle (cr, + (width - wh) * .5 + wh * .25, + (height - wh) * .5 + wh * .25, + wh * .5, wh * .5); + VECTORICONSTROKEFILL(0.9); // small 'shine' +} + +/** play triangle */ +static void icon_transport_play (cairo_t *cr, const int width, const int height) +{ + const int wh = std::min (width, height) * .5; + const double y = height * .5; + const double x = width - wh; + + const double tri = ceil (.577 * wh); // 1/sqrt(3) + + cairo_move_to (cr, x + wh * .5, y); + cairo_line_to (cr, x - wh * .5, y - tri); + cairo_line_to (cr, x - wh * .5, y + tri); + cairo_close_path (cr); + + VECTORICONSTROKEFILL(0.9); +} + +/** Midi Panic "!" */ +static void icon_transport_panic (cairo_t *cr, const int width, const int height) +{ + const int wh = ceil (std::min (width, height) * .1) - .5; + const double xc = rint (width * .5); + const double yh = height; + cairo_rectangle (cr, + xc - wh, yh *.19, + wh * 2, yh *.41); + VECTORICONSTROKEFILL(0.9); + + cairo_arc (cr, xc, yh *.75, wh, 0, 2 * M_PI); + VECTORICONSTROKEFILL(0.9); +} + +/** various combinations of lines and triangles "|>|", ">|" "|>" */ +static void icon_transport_ck (cairo_t *cr, + const enum ArdourWidgets::ArdourIcon::Icon icon, + const int width, const int height) +{ + // small play triangle + int wh = std::min (width, height); + const double y = height * .5; + const double x = width - wh * .5; + wh *= .18; + const double tri = ceil (.577 * wh * 2); // 1/sqrt(3) + + const float ln = std::min (width, height) * .07; + + if (icon == TransportStart || icon == TransportRange) { + cairo_rectangle (cr, + x - wh - ln, y - tri * 1.7, + ln * 2, tri * 3.4); + + VECTORICONSTROKEFILL(1.0); + } + + if (icon == TransportEnd || icon == TransportRange) { + cairo_rectangle (cr, + x + wh - ln, y - tri * 1.7, + ln * 2, tri * 3.4); + + VECTORICONSTROKEFILL(1.0); + } + + if (icon == TransportStart) { + cairo_move_to (cr, x - wh, y); + cairo_line_to (cr, x + wh, y - tri); + cairo_line_to (cr, x + wh, y + tri); + } else { + cairo_move_to (cr, x + wh, y); + cairo_line_to (cr, x - wh, y - tri); + cairo_line_to (cr, x - wh, y + tri); + } + + cairo_close_path (cr); + VECTORICONSTROKEFILL(1.0); +} + +/** loop spiral */ +static void icon_transport_loop (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double r = std::min (x, y); + + cairo_arc (cr, x, y, r * .62, 0, 2 * M_PI); + cairo_arc_negative (cr, x, y, r * .35, 2 * M_PI, 0); + + VECTORICONSTROKEFILL(1.0); + +#define ARCARROW(rad, ang) \ + x + (rad) * sin ((ang) * 2.0 * M_PI), y + (rad) * cos ((ang) * 2.0 * M_PI) + + cairo_move_to (cr, ARCARROW(r * .35, .72)); + cairo_line_to (cr, ARCARROW(r * .15, .72)); + cairo_line_to (cr, ARCARROW(r * .56, .60)); + cairo_line_to (cr, ARCARROW(r * .75, .72)); + cairo_line_to (cr, ARCARROW(r * .62, .72)); + + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_stroke_preserve (cr); + cairo_close_path (cr); + cairo_set_source_rgba (cr, 1, 1, 1, 1.0); + cairo_fill (cr); +#undef ARCARROW +} + +/** de-construct thorwil's metronom */ +static void icon_transport_metronom (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = .95 * std::min (x, y); + const double h = wh * .80; + const double w = wh * .55; + const double lw = w * .34; + + cairo_rectangle (cr, + x - w * .7, y + h * .25, + w * 1.4, lw); + + VECTORICONSTROKEFILL(1.0); + + cairo_move_to (cr, x - w, y + h); + cairo_line_to (cr, x + w, y + h); + cairo_line_to (cr, x + w * .35, y - h); + cairo_line_to (cr, x - w * .35, y - h); + cairo_line_to (cr, x - w, y + h); + + cairo_move_to (cr, x - w + lw, y + h -lw); + cairo_line_to (cr, x - w * .35 + lw, y - h + lw); + cairo_line_to (cr, x + w * .35 - lw, y - h + lw); + cairo_line_to (cr, x + w - lw, y + h -lw); + cairo_line_to (cr, x - w + lw, y + h -lw); + + VECTORICONSTROKEFILL(1.0); + + // Pendulum + // ddx = .70 w = .75 * .5 wh = .375 wh + // ddy = .75 h - lw = .75 * .8 wh - wh .5 * .2 = .5 wh + // ang = (ddx/ddy): + // -> angle = atan (ang) = atan (375 / .5) ~= 36deg + const double dx = lw * .2; // 1 - cos(tan^-1(ang)) + const double dy = lw * .4; // 1 - sin(tan^-1(ang)) + cairo_move_to (cr, x - w * .3 , y + h * .25 + lw * .5); + cairo_line_to (cr, x - w + dx , y - h + lw + dy); + cairo_line_to (cr, x - w + lw , y - h + lw); + cairo_line_to (cr, x - w * .3 + lw, y + h * .25 + lw * .5); + cairo_close_path (cr); + + VECTORICONSTROKEFILL(1.0); + + cairo_rectangle (cr, + x - w * .7, y + h * .25, + w * 1.4, lw); + cairo_fill (cr); +} + + +/***************************************************************************** + * Zoom: In "+", Out "-" and Full "[]" + */ +static void icon_zoom (cairo_t *cr, const enum ArdourWidgets::ArdourIcon::Icon icon, const int width, const int height, const uint32_t fg_color) +{ + const double x = width * .5; + const double y = height * .5; + const double r = std::min (x, y) * .7; + const double wh = std::min (x, y) * .45; + + // draw handle first +#define LINE45DEG(rad) \ + x + r * (rad) * .707, y + r * (rad) * .707 // sin(45deg) = cos(45deg) = .707 + cairo_move_to (cr, LINE45DEG(.9)); + cairo_line_to (cr, LINE45DEG(1.3)); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr, 3.0); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_stroke (cr); +#undef LINE45DEG + + // lens + ardour_icon_set_source_rgba (cr, fg_color); + cairo_arc (cr, x, y, r, 0, 2 * M_PI); + cairo_fill_preserve (cr); + + // add a lens gradient + cairo_pattern_t *lens; + lens = cairo_pattern_create_radial (x - r, y - r, r * .5, x - r, y - r, r * 2); + cairo_pattern_add_color_stop_rgba (lens, 0, 1, 1, 1, .4); + cairo_pattern_add_color_stop_rgba (lens, 1, 0, 0, 0, .4); + cairo_set_source (cr, lens); + cairo_fill_preserve (cr); + cairo_pattern_destroy (lens); + + // outline + cairo_set_line_width (cr, 1.5); + //ardour_icon_set_source_inv_rgba (cr, fg_color); // alpha + cairo_set_source_rgba (cr, .0, .0, .0, .8); + cairo_stroke (cr); + + // add "+", "-" or "[]" + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_width (cr, 1.5); + ardour_icon_set_source_inv_rgba (cr, fg_color); + + if (icon == ZoomIn || icon == ZoomOut) { + cairo_move_to (cr, x - wh, y); + cairo_line_to (cr, x + wh, y); + cairo_stroke (cr); + } + if (icon == ZoomIn) { + cairo_move_to (cr, x, y - wh); + cairo_line_to (cr, x, y + wh); + cairo_stroke (cr); + } + if (icon == ZoomFull) { + const double br0 = std::min (x, y) * .1; + const double br1 = std::min (x, y) * .3; + const double bry = std::min (x, y) * .3; + cairo_move_to (cr, x - br0, y - bry); + cairo_line_to (cr, x - br1, y - bry); + cairo_line_to (cr, x - br1, y + bry); + cairo_line_to (cr, x - br0, y + bry); + cairo_stroke (cr); + + cairo_move_to (cr, x + br0, y - bry); + cairo_line_to (cr, x + br1, y - bry); + cairo_line_to (cr, x + br1, y + bry); + cairo_line_to (cr, x + br0, y + bry); + cairo_stroke (cr); + } +} + +/** Toolbar icon - Mixbus Zoom Expand, rotated TimeAxisExpand */ +static void icon_zoom_expand (cairo_t *cr, const int width, const int height) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y) * .66; + const double ar = std::min (x, y) * .15; + const double tri = .7 * (wh - ar); + + cairo_rectangle (cr, x - wh, y - wh, 2 * wh, 2 * wh); + VECTORICONSTROKEFILL(.75); + + cairo_set_line_width (cr, 1.0); + + cairo_move_to (cr, x - wh + 0.5, y); + cairo_line_to (cr, x - ar - 0.5, y - tri); + cairo_line_to (cr, x - ar - 0.5, y + tri); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1, 1, 1, .5); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); + + cairo_move_to (cr, x + wh - 0.5, y); + cairo_line_to (cr, x + ar + 0.5, y - tri); + cairo_line_to (cr, x + ar + 0.5, y + tri); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1, 1, 1, .5); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_fill (cr); +} + + + +/***************************************************************************** + * Misc buttons + */ + +/** "close" - "X" , no outline */ +static void icon_close_cross (cairo_t *cr, const int width, const int height, const uint32_t fg_color) +{ + const double x = width * .5; + const double y = height * .5; + const double o = .5 + std::min (x, y) * .4; + ardour_icon_set_source_rgba (cr, fg_color); + cairo_set_line_width (cr, 1.0); + cairo_move_to (cr, x-o, y-o); + cairo_line_to (cr, x+o, y+o); + cairo_move_to (cr, x+o, y-o); + cairo_line_to (cr, x-o, y+o); + cairo_stroke (cr); +} + +/** "<" */ +static void icon_nudge_left (cairo_t *cr, const int width, const int height, const uint32_t fg_color) +{ + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y); + + const double tri_x = .3 * wh; + const double tri_y = .6 * wh; + + cairo_move_to (cr, x + tri_x, y - tri_y); + cairo_line_to (cr, x - tri_x, y); + cairo_line_to (cr, x + tri_x, y + tri_y); + VECTORICONSTROKEOUTLINE(1.5, fg_color); +} + +/** ">" */ +static void icon_nudge_right (cairo_t *cr, const int width, const int height, const uint32_t fg_color) +{ + + const double x = width * .5; + const double y = height * .5; + const double wh = std::min (x, y); + + const double tri_x = .3 * wh; + const double tri_y = .6 * wh; + + cairo_move_to (cr, x - tri_x, y - tri_y); + cairo_line_to (cr, x + tri_x, y); + cairo_line_to (cr, x - tri_x, y + tri_y); + VECTORICONSTROKEOUTLINE(1.5, fg_color); + +} + +/** mixer strip narrow/wide */ +static void icon_strip_width (cairo_t *cr, const int width, const int height, const uint32_t fg_color) +{ + const double x0 = width * .2; + const double x1 = width * .8; + + const double y0 = height * .25; + const double y1 = height * .75; + + const double ym = height * .5; + + // arrow + const double xa0= width * .39; + const double xa1= width * .61; + const double ya0= height * .35; + const double ya1= height * .65; + + ardour_icon_set_source_rgba (cr, fg_color); + cairo_set_line_width (cr, 1); + + // left + right + cairo_move_to (cr, x0, y0); + cairo_line_to (cr, x0, y1); + cairo_move_to (cr, x1, y0); + cairo_line_to (cr, x1, y1); + + // horiz center line + cairo_move_to (cr, x0, ym); + cairo_line_to (cr, x1, ym); + + // arrow left + cairo_move_to (cr, x0, ym); + cairo_line_to (cr, xa0, ya0); + cairo_move_to (cr, x0, ym); + cairo_line_to (cr, xa0, ya1); + + // arrow right + cairo_move_to (cr, x1, ym); + cairo_line_to (cr, xa1, ya0); + cairo_move_to (cr, x1, ym); + cairo_line_to (cr, xa1, ya1); + cairo_stroke (cr); +} + +/** 5-pin DIN MIDI socket */ +static void icon_din_midi (cairo_t *cr, const int width, const int height, const uint32_t fg_color) +{ + const double x = width * .5; + const double y = height * .5; + const double r = std::min (x, y) * .75; + ardour_icon_set_source_rgba (cr, fg_color); + cairo_set_line_width (cr, 1); + cairo_arc (cr, x, y, r, .57 * M_PI, 2.43 * M_PI); + cairo_stroke (cr); + + // pins equally spaced 45deg + cairo_arc (cr, x, y * 0.5, r * .15, 0, 2 * M_PI); + cairo_fill (cr); + cairo_arc (cr, x * 0.5, y, r * .15, 0, 2 * M_PI); + cairo_fill (cr); + cairo_arc (cr, x * 1.5, y, r * .15, 0, 2 * M_PI); + cairo_fill (cr); + // .5 + .5 * .5 * sin(45deg), 1.5 - .5 * .5 * cos(45deg) + cairo_arc (cr, x * 0.677, y * .677, r * .15, 0, 2 * M_PI); + cairo_fill (cr); + cairo_arc (cr, x * 1.323, y * .677, r * .15, 0, 2 * M_PI); + cairo_fill (cr); + + // bottom notch + cairo_arc (cr, x, y+r, r * .26, 1.05 * M_PI, 1.95 * M_PI); + cairo_stroke (cr); +} + + +/*****************************************************************************/ + +bool +ArdourWidgets::ArdourIcon::render (cairo_t *cr, + const enum ArdourWidgets::ArdourIcon::Icon icon, + const int width, const int height, + const Gtkmm2ext::ActiveState state, + const uint32_t fg_color) +{ + bool rv = true; + cairo_save (cr); + + if (width < 6 || height < 6) { + return false; + } + + switch (icon) { + case TransportStop: + icon_transport_stop (cr, width, height); + break; + case TransportPlay: + icon_transport_play (cr, width, height); + break; + case TransportLoop: + icon_transport_loop (cr, width, height); + break; + case TransportMetronom: + icon_transport_metronom (cr, width, height); + break; + case TransportPanic: + icon_transport_panic (cr, width, height); + break; + case TransportStart: // no break + case TransportEnd: // no break + case TransportRange: + icon_transport_ck (cr, icon, width, height); + break; + case RecTapeMode: + icon_rec_tape (cr, width, height, state); + break; + case RecButton: + icon_rec_enable (cr, width, height, state); + break; + case CloseCross: + icon_close_cross (cr, width, height, fg_color); + break; + case StripWidth: + icon_strip_width (cr, width, height, fg_color); + break; + case DinMidi: + icon_din_midi (cr, width, height, fg_color); + break; + case NudgeLeft: + icon_nudge_left (cr, width, height, fg_color); + break; + case NudgeRight: + icon_nudge_right (cr, width, height, fg_color); + break; + case ZoomIn: // no break + case ZoomOut: // no break + case ZoomFull: + icon_zoom (cr, icon, width, height, fg_color); + break; + case ZoomExpand: + icon_zoom_expand (cr, width, height); + break; + case TimeAxisShrink: + icon_tav_shrink (cr, width, height); + break; + case TimeAxisExpand: + icon_tav_expand (cr, width, height); + break; + case ToolRange: + icon_tool_range (cr, width, height); + break; + case ToolGrab: + icon_tool_grab (cr, width, height); + break; + case ToolCut: + icon_tool_cut (cr, width, height); + break; + case ToolStretch: + icon_tool_stretch (cr, width, height); + break; + case ToolAudition: + icon_tool_audition (cr, width, height); + break; + case ToolDraw: + icon_tool_draw (cr, width, height); + break; + case ToolContent: + icon_tool_content (cr, width, height); + break; + default: + rv = false; + break; + } + cairo_restore (cr); + return rv; +} + +#undef VECTORICONSTROKEFILL +#undef VECTORICONSTROKEOUTLINE diff --git a/libs/widgets/binding_proxy.cc b/libs/widgets/binding_proxy.cc new file mode 100644 index 0000000000..666797a0eb --- /dev/null +++ b/libs/widgets/binding_proxy.cc @@ -0,0 +1,112 @@ +/* + Copyright (C) 2006 Paul Davis + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include + +#include "pbd/controllable.h" +#include "gtkmm2ext/keyboard.h" +#include "widgets/binding_proxy.h" +#include "widgets/popup.h" + +#include "pbd/i18n.h" + +using namespace std; +using namespace PBD; +using namespace Gtkmm2ext; +using namespace ArdourWidgets; + +guint BindingProxy::bind_button = 2; +guint BindingProxy::bind_statemask = Gdk::CONTROL_MASK; + +BindingProxy::BindingProxy (boost::shared_ptr c) + : prompter (0), + controllable (c) +{ +} + +BindingProxy::BindingProxy () + : prompter (0) +{ +} + +BindingProxy::~BindingProxy () +{ + if (prompter) { + delete prompter; + } +} + +void +BindingProxy::set_controllable (boost::shared_ptr c) +{ + learning_finished (); + controllable = c; +} + +void +BindingProxy::set_bind_button_state (guint button, guint statemask) +{ + bind_button = button; + bind_statemask = statemask; +} + +bool +BindingProxy::is_bind_action (GdkEventButton *ev) +{ + return (Keyboard::modifier_state_equals (ev->state, bind_statemask) && ev->button == bind_button ); +} + +bool +BindingProxy::button_press_handler (GdkEventButton *ev) +{ + if ( controllable && is_bind_action(ev) ) { + if (Controllable::StartLearning (controllable.get())) { + string prompt = _("operate controller now"); + if (prompter == 0) { + prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false); + prompter->signal_unmap_event().connect (mem_fun (*this, &BindingProxy::prompter_hiding)); + } + prompter->set_text (prompt); + prompter->touch (); // shows popup + controllable->LearningFinished.connect_same_thread (learning_connection, boost::bind (&BindingProxy::learning_finished, this)); + } + return true; + } + + return false; +} + +void +BindingProxy::learning_finished () +{ + learning_connection.disconnect (); + if (prompter) { + prompter->touch (); // hides popup + } +} + +bool +BindingProxy::prompter_hiding (GdkEventAny* /*ev*/) +{ + learning_connection.disconnect (); + if (controllable) { + Controllable::StopLearning (controllable.get()); + } + return false; +} diff --git a/libs/widgets/choice.cc b/libs/widgets/choice.cc new file mode 100644 index 0000000000..6bfd0690b2 --- /dev/null +++ b/libs/widgets/choice.cc @@ -0,0 +1,71 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include + +using namespace std; +using namespace sigc; +using namespace Gtk; +using namespace ArdourWidgets; + +Choice::Choice (string title, string prompt, vector choices, bool center) + : Dialog (title) +{ + int n; + vector::iterator i; + + if (center) { + set_position (Gtk::WIN_POS_CENTER); + } else { + set_position (Gtk::WIN_POS_MOUSE); + } + + set_name ("ChoiceWindow"); + + HBox* dhbox = manage (new HBox()); + Image* dimage = manage (new Gtk::Image(Stock::DIALOG_QUESTION, Gtk::ICON_SIZE_DIALOG)); + Label* label = manage (new Label (prompt)); + + dhbox->pack_start (*dimage, true, false, 10); + dhbox->pack_start (*label, true, false, 10); + + get_vbox()->set_border_width (12); + get_vbox()->pack_start (*dhbox, true, false); + + set_has_separator (false); + set_resizable (false); + show_all_children (); + + for (n = 0, i = choices.begin(); i != choices.end(); ++i, ++n) { + add_button (*i, n); + } +} + +void +Choice::on_realize () +{ + Gtk::Window::on_realize(); + get_window()->set_decorations (Gdk::WMDecoration (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH)); +} + +Choice::~Choice () +{ +} diff --git a/libs/widgets/eventboxext.cc b/libs/widgets/eventboxext.cc new file mode 100644 index 0000000000..6cbd0b7427 --- /dev/null +++ b/libs/widgets/eventboxext.cc @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2017 Robin Gareus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "widgets/eventboxext.h" + +using namespace ArdourWidgets; + +EventBoxExt::EventBoxExt () +{ +} diff --git a/libs/widgets/pane.cc b/libs/widgets/pane.cc new file mode 100644 index 0000000000..2968f7bfaa --- /dev/null +++ b/libs/widgets/pane.cc @@ -0,0 +1,671 @@ +/* + Copyright (C) 2016 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "widgets/pane.h" + +#include "pbd/i18n.h" + +using namespace std; +using namespace Gtk; +using namespace PBD; +using namespace ArdourWidgets; + +Pane::Pane (bool h) + : horizontal (h) + , did_move (false) + , divider_width (2) + , check_fract (false) +{ + using namespace Gdk; + + set_name ("Pane"); + set_has_window (false); + + if (horizontal) { + drag_cursor = Cursor (SB_H_DOUBLE_ARROW); + } else { + drag_cursor = Cursor (SB_V_DOUBLE_ARROW); + } +} + +Pane::~Pane () +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + (*c)->show_con.disconnect (); + (*c)->hide_con.disconnect (); + if ((*c)->w) { + (*c)->w->remove_destroy_notify_callback ((*c).get()); + (*c)->w->unparent (); + } + } + children.clear (); +} + +void +Pane::set_child_minsize (Gtk::Widget const& w, int32_t minsize) +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + if ((*c)->w == &w) { + (*c)->minsize = minsize; + break; + } + } +} + +void +Pane::set_drag_cursor (Gdk::Cursor c) +{ + drag_cursor = c; +} + +void +Pane::on_size_request (GtkRequisition* req) +{ + GtkRequisition largest; + + /* iterate over all children, get their size requests */ + + /* horizontal pane is as high as its tallest child, including the dividers. + * Its width is the sum of the children plus the dividers. + * + * vertical pane is as wide as its widest child, including the dividers. + * Its height is the sum of the children plus the dividers. + */ + + if (horizontal) { + largest.width = (children.size() - 1) * divider_width; + largest.height = 0; + } else { + largest.height = (children.size() - 1) * divider_width; + largest.width = 0; + } + + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + GtkRequisition r; + + if (!(*c)->w->is_visible ()) { + continue; + } + + (*c)->w->size_request (r); + + if (horizontal) { + largest.height = max (largest.height, r.height); + if ((*c)->minsize) { + largest.width += (*c)->minsize; + } else { + largest.width += r.width; + } + } else { + largest.width = max (largest.width, r.width); + if ((*c)->minsize) { + largest.height += (*c)->minsize; + } else { + largest.height += r.height; + } + } + } + + *req = largest; +} + +GType +Pane::child_type_vfunc() const +{ + /* We accept any number of any types of widgets */ + return Gtk::Widget::get_type(); +} + +void +Pane::add_divider () +{ + Divider* d = new Divider; + d->set_name (X_("Divider")); + d->signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_press_event), d), false); + d->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_release_event), d), false); + d->signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_motion_event), d), false); + d->signal_enter_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_enter_event), d), false); + d->signal_leave_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_leave_event), d), false); + d->set_parent (*this); + d->show (); + d->fract = 0.5; + dividers.push_back (d); +} + +void +Pane::handle_child_visibility () +{ + reallocate (get_allocation()); +} + +void +Pane::on_add (Widget* w) +{ + children.push_back (boost::shared_ptr (new Child (this, w, 0))); + Child* kid = children.back ().get(); + + w->set_parent (*this); + /* Gtkmm 2.4 does not correctly arrange for ::on_remove() to be called + for custom containers that derive from Gtk::Container. So ... we need + to ensure that we hear about child destruction ourselves. + */ + w->add_destroy_notify_callback (kid, &Pane::notify_child_destroyed); + + kid->show_con = w->signal_show().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); + kid->hide_con = w->signal_hide().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); + + while (dividers.size() < (children.size() - 1)) { + add_divider (); + } +} + +void* +Pane::notify_child_destroyed (void* data) +{ + Child* child = reinterpret_cast (data); + return child->pane->child_destroyed (child->w); +} + +void* +Pane::child_destroyed (Gtk::Widget* w) +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + if ((*c)->w == w) { + (*c)->show_con.disconnect (); + (*c)->hide_con.disconnect (); + (*c)->w = NULL; // mark invalid + children.erase (c); + break; + } + } + return 0; +} + +void +Pane::on_remove (Widget* w) +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + if ((*c)->w == w) { + (*c)->show_con.disconnect (); + (*c)->hide_con.disconnect (); + w->remove_destroy_notify_callback ((*c).get()); + w->unparent (); + (*c)->w = NULL; // mark invalid + children.erase (c); + break; + } + } +} + +void +Pane::on_size_allocate (Gtk::Allocation& alloc) +{ + reallocate (alloc); + Container::on_size_allocate (alloc); + + /* minumum pane size constraints */ + Dividers::size_type div = 0; + for (Dividers::const_iterator d = dividers.begin(); d != dividers.end(); ++d, ++div) { + // XXX skip dividers that were just hidden in reallocate() + Pane::set_divider (div, (*d)->fract); + } + // TODO this needs tweaking for panes with > 2 children + // if a child grows, re-check the ones before it. + assert (dividers.size () < 3); +} + +void +Pane::reallocate (Gtk::Allocation const & alloc) +{ + int remaining; + int xpos = alloc.get_x(); + int ypos = alloc.get_y(); + float fract; + + if (children.empty()) { + return; + } + + if (children.size() == 1) { + /* only child gets the full allocation */ + if (children.front()->w->is_visible ()) { + children.front()->w->size_allocate (alloc); + } + return; + } + + if (horizontal) { + remaining = alloc.get_width (); + } else { + remaining = alloc.get_height (); + } + + Children::iterator child; + Children::iterator next; + Dividers::iterator div; + + child = children.begin(); + + /* skip initial hidden children */ + + while (child != children.end()) { + if ((*child)->w->is_visible()) { + break; + } + ++child; + } + + for (div = dividers.begin(); child != children.end(); ) { + + Gtk::Allocation child_alloc; + + next = child; + + /* Move on to next *visible* child */ + + while (++next != children.end()) { + if ((*next)->w->is_visible()) { + break; + } + } + + child_alloc.set_x (xpos); + child_alloc.set_y (ypos); + + if (next == children.end()) { + /* last child gets all the remaining space */ + fract = 1.0; + } else { + /* child gets the fraction of the remaining space given by the divider that follows it */ + fract = (*div)->fract; + } + + Gtk::Requisition cr; + (*child)->w->size_request (cr); + + if (horizontal) { + child_alloc.set_width ((gint) floor (remaining * fract)); + child_alloc.set_height (alloc.get_height()); + remaining = max (0, (remaining - child_alloc.get_width())); + xpos += child_alloc.get_width(); + } else { + child_alloc.set_width (alloc.get_width()); + child_alloc.set_height ((gint) floor (remaining * fract)); + remaining = max (0, (remaining - child_alloc.get_height())); + ypos += child_alloc.get_height (); + } + + if ((*child)->minsize) { + if (horizontal) { + child_alloc.set_width (max (child_alloc.get_width(), (*child)->minsize)); + } else { + child_alloc.set_height (max (child_alloc.get_height(), (*child)->minsize)); + } + } + + if ((*child)->w->is_visible ()) { + (*child)->w->size_allocate (child_alloc); + } + + if (next == children.end()) { + /* done, no more children, no need for a divider */ + break; + } + + child = next; + + /* add a divider between children */ + + Gtk::Allocation divider_allocation; + + divider_allocation.set_x (xpos); + divider_allocation.set_y (ypos); + + if (horizontal) { + divider_allocation.set_width (divider_width); + divider_allocation.set_height (alloc.get_height()); + remaining = max (0, remaining - divider_width); + xpos += divider_width; + } else { + divider_allocation.set_width (alloc.get_width()); + divider_allocation.set_height (divider_width); + remaining = max (0, remaining - divider_width); + ypos += divider_width; + } + + (*div)->size_allocate (divider_allocation); + (*div)->show (); + ++div; + } + + /* hide all remaining dividers */ + + while (div != dividers.end()) { + (*div)->hide (); + ++div; + } +} + +bool +Pane::on_expose_event (GdkEventExpose* ev) +{ + Children::iterator child; + Dividers::iterator div; + + for (child = children.begin(), div = dividers.begin(); child != children.end(); ++child) { + + if ((*child)->w->is_visible()) { + propagate_expose (*((*child)->w), ev); + } + + if (div != dividers.end()) { + if ((*div)->is_visible()) { + propagate_expose (**div, ev); + } + ++div; + } + } + + return true; +} + +bool +Pane::handle_press_event (GdkEventButton* ev, Divider* d) +{ + d->dragging = true; + d->queue_draw (); + + return false; +} + +bool +Pane::handle_release_event (GdkEventButton* ev, Divider* d) +{ + d->dragging = false; + + if (did_move && !children.empty()) { + children.front()->w->queue_resize (); + did_move = false; + } + + return false; +} +void +Pane::set_check_divider_position (bool yn) +{ + check_fract = yn; +} + +float +Pane::constrain_fract (Dividers::size_type div, float fract) +{ + if (get_allocation().get_width() == 1 && get_allocation().get_height() == 1) { + /* space not * allocated - * divider being set from startup code. Let it pass, + * since our goal is mostly to catch drags to a position that will interfere with window + * resizing. + */ + return fract; + } + + if (children.size () <= div + 1) { return fract; } // XXX remove once hidden divs are skipped + assert(children.size () > div + 1); + + const float size = horizontal ? get_allocation().get_width() : get_allocation().get_height(); + + // TODO: optimize: cache in Pane::on_size_request + Gtk::Requisition prev_req(children.at (div)->w->size_request ()); + Gtk::Requisition next_req(children.at (div + 1)->w->size_request ()); + float prev = (horizontal ? prev_req.width : prev_req.height); + float next = (horizontal ? next_req.width : next_req.height); + + if (children.at (div)->minsize) { + prev = children.at (div)->minsize; + } + if (children.at (div + 1)->minsize) { + next = children.at (div + 1)->minsize; + } + + if (size * fract < prev) { + return prev / size; + } + if (size * (1.f - fract) < next) { + return 1.f - next / size; + } + + if (!check_fract) { + return fract; + } + +#ifdef __APPLE__ + + /* On Quartz, if the pane handle (divider) gets to + be adjacent to the window edge, you can no longer grab it: + any attempt to do so is interpreted by the Quartz window + manager ("Finder") as a resize drag on the window edge. + */ + + + if (horizontal) { + if (div == dividers.size() - 1) { + if (get_allocation().get_width() * (1.0 - fract) < (divider_width*2)) { + /* too close to right edge */ + return 1.f - (divider_width * 2.f) / (float) get_allocation().get_width(); + } + } + + if (div == 0) { + if (get_allocation().get_width() * fract < (divider_width*2)) { + /* too close to left edge */ + return (divider_width * 2.f) / (float)get_allocation().get_width(); + } + } + } else { + if (div == dividers.size() - 1) { + if (get_allocation().get_height() * (1.0 - fract) < (divider_width*2)) { + /* too close to bottom */ + return 1.f - (divider_width * 2.f) / (float) get_allocation().get_height(); + } + } + + if (div == 0) { + if (get_allocation().get_height() * fract < (divider_width*2)) { + /* too close to top */ + return (divider_width * 2.f) / (float) get_allocation().get_height(); + } + } + } +#endif + return fract; +} + +bool +Pane::handle_motion_event (GdkEventMotion* ev, Divider* d) +{ + did_move = true; + + if (!d->dragging) { + return true; + } + + /* determine new position for handle */ + + float new_fract; + int px, py; + + d->translate_coordinates (*this, ev->x, ev->y, px, py); + + Dividers::iterator prev = dividers.end(); + Dividers::size_type div = 0; + + for (Dividers::iterator di = dividers.begin(); di != dividers.end(); ++di, ++div) { + if (*di == d) { + break; + } + prev = di; + } + + int space_remaining; + int prev_edge; + + if (horizontal) { + if (prev != dividers.end()) { + prev_edge = (*prev)->get_allocation().get_x() + (*prev)->get_allocation().get_width(); + } else { + prev_edge = 0; + } + space_remaining = get_allocation().get_width() - prev_edge; + new_fract = (float) (px - prev_edge) / space_remaining; + } else { + if (prev != dividers.end()) { + prev_edge = (*prev)->get_allocation().get_y() + (*prev)->get_allocation().get_height(); + } else { + prev_edge = 0; + } + space_remaining = get_allocation().get_height() - prev_edge; + new_fract = (float) (py - prev_edge) / space_remaining; + } + + new_fract = min (1.0f, max (0.0f, new_fract)); + new_fract = constrain_fract (div, new_fract); + new_fract = min (1.0f, max (0.0f, new_fract)); + + if (new_fract != d->fract) { + d->fract = new_fract; + reallocate (get_allocation ()); + queue_draw (); + } + + return true; +} + +void +Pane::set_divider (Dividers::size_type div, float fract) +{ + Dividers::iterator d = dividers.begin(); + + for (d = dividers.begin(); d != dividers.end() && div != 0; ++d, --div) { + /* relax */ + } + + if (d == dividers.end()) { + /* caller is trying to set divider that does not exist + * yet. + */ + return; + } + + fract = max (0.0f, min (1.0f, fract)); + fract = constrain_fract (div, fract); + fract = max (0.0f, min (1.0f, fract)); + + if (fract != (*d)->fract) { + (*d)->fract = fract; + /* our size hasn't changed, but our internal allocations have */ + reallocate (get_allocation()); + queue_draw (); + } +} + +float +Pane::get_divider (Dividers::size_type div) +{ + Dividers::iterator d = dividers.begin(); + + for (d = dividers.begin(); d != dividers.end() && div != 0; ++d, --div) { + /* relax */ + } + + if (d == dividers.end()) { + /* caller is trying to set divider that does not exist + * yet. + */ + return -1.0f; + } + + return (*d)->fract; +} + +void +Pane::forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer callback_data) +{ + /* since the callback could modify the child list(s), make sure we keep + * the iterators safe; + */ + Children kids (children); + for (Children::const_iterator c = kids.begin(); c != kids.end(); ++c) { + if ((*c)->w) { + callback ((*c)->w->gobj(), callback_data); + } + } + + if (include_internals) { + for (Dividers::iterator d = dividers.begin(); d != dividers.end(); ) { + Dividers::iterator next = d; + ++next; + callback (GTK_WIDGET((*d)->gobj()), callback_data); + d = next; + } + } +} + +Pane::Divider::Divider () + : fract (0.0) + , dragging (false) +{ + set_events (Gdk::EventMask (Gdk::BUTTON_PRESS| + Gdk::BUTTON_RELEASE| + Gdk::MOTION_NOTIFY| + Gdk::ENTER_NOTIFY| + Gdk::LEAVE_NOTIFY)); +} + +bool +Pane::Divider::on_expose_event (GdkEventExpose* ev) +{ + Gdk::Color c = (dragging ? get_style()->get_fg (Gtk::STATE_ACTIVE) : + get_style()->get_fg (get_state())); + + Cairo::RefPtr draw_context = get_window()->create_cairo_context (); + draw_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height); + draw_context->clip_preserve (); + draw_context->set_source_rgba (c.get_red_p(), c.get_green_p(), c.get_blue_p(), 1.0); + draw_context->fill (); + + return true; +} + +bool +Pane::handle_enter_event (GdkEventCrossing*, Divider* d) +{ + d->get_window()->set_cursor (drag_cursor); + d->set_state (Gtk::STATE_SELECTED); + return true; +} + +bool +Pane::handle_leave_event (GdkEventCrossing*, Divider* d) +{ + d->get_window()->set_cursor (); + d->set_state (Gtk::STATE_NORMAL); + d->queue_draw (); + return true; +} diff --git a/libs/widgets/paths_dialog.cc b/libs/widgets/paths_dialog.cc new file mode 100644 index 0000000000..cf366a7c7c --- /dev/null +++ b/libs/widgets/paths_dialog.cc @@ -0,0 +1,164 @@ +/* + Copyright (C) 2014 Robin Gareus + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#include + +#include "pbd/i18n.h" +#include "pbd/pathexpand.h" +#include "widgets/paths_dialog.h" + +using namespace Gtk; +using namespace std; +using namespace ArdourWidgets; + +PathsDialog::PathsDialog (Gtk::Window& parent, std::string title, std::string current_paths, std::string default_paths) + : Dialog (title, parent, true) + , paths_list_view(1, false, Gtk::SELECTION_SINGLE) + , add_path_button(_("Add")) + , remove_path_button(_("Delete")) + , set_default_button(_("Reset to Default")) + , _default_paths(default_paths) +{ + set_name ("PathsDialog"); + set_skip_taskbar_hint (true); + set_resizable (true); + set_size_request (400, -1); + + paths_list_view.set_border_width (4); + + add_path_button.signal_clicked().connect (sigc::mem_fun (*this, &PathsDialog::add_path)); + remove_path_button.signal_clicked().connect (sigc::mem_fun (*this, &PathsDialog::remove_path)); + set_default_button.signal_clicked().connect (sigc::mem_fun (*this, &PathsDialog::set_default)); + remove_path_button.set_sensitive(false); + + paths_list_view.set_column_title(0,"Path"); + + std::vector a = PBD::parse_path(current_paths); + for(vector::const_iterator i = a.begin(); i != a.end(); ++i) { + paths_list_view.append_text(*i); + } + + paths_list_view.get_selection()->signal_changed().connect (mem_fun (*this, &PathsDialog::selection_changed)); + + VBox *vbox = manage (new VBox); + vbox->pack_start (add_path_button, false, false); + vbox->pack_start (remove_path_button, false, false); + vbox->pack_start (set_default_button, false, false); + + /* Overall layout */ + HBox *hbox = manage (new HBox); + hbox->pack_start (*vbox, false, false); + hbox->pack_start (paths_list_view, true, true); // TODO, wrap in scroll-area ?! + hbox->set_spacing (4); + + get_vbox()->set_spacing (4); + get_vbox()->pack_start (*hbox, true, true); + + add_button (Stock::CANCEL, RESPONSE_CANCEL); + add_button (Stock::OK, RESPONSE_ACCEPT); + + show_all_children (); +} + +PathsDialog::~PathsDialog () +{ +} + +void +PathsDialog::on_show() { + Dialog::on_show (); +} + +std::string +PathsDialog::get_serialized_paths() { + std::string path; + for (unsigned int i = 0; i < paths_list_view.size(); ++i) { + if (i > 0) path += G_SEARCHPATH_SEPARATOR; + path += paths_list_view.get_text(i, 0); + } + return path; +} + +void +PathsDialog::selection_changed () { + std::vector selection = paths_list_view.get_selected(); + if (selection.size() > 0) { + remove_path_button.set_sensitive(true); + } else { + remove_path_button.set_sensitive(false); + } +} + +void +PathsDialog::add_path() { + Gtk::FileChooserDialog d (_("Add folder to search path"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + + std::vector selection = paths_list_view.get_selected(); + if (selection.size() == 1 ) { + d.set_current_folder(paths_list_view.get_text(selection.at(0), 0)); + } + + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); + ResponseType r = (ResponseType) d.run (); + if (r == Gtk::RESPONSE_OK) { + std::string dir = d.get_filename(); + if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { + bool dup = false; + for (unsigned int i = 0; i < paths_list_view.size(); ++i) { + if (paths_list_view.get_text(i, 0) == dir) { + dup = true; + break; + } + } + if (!dup) { + paths_list_view.prepend_text(dir); + } + } + } +} + +void +PathsDialog::remove_path() { + std::vector selection = paths_list_view.get_selected(); + if (selection.size() == 0 ) { return ; } + + /* Gtk::ListViewText internals to delete row(s) */ + Gtk::TreeModel::iterator row_it = paths_list_view.get_selection()->get_selected(); + Glib::RefPtr reftm = paths_list_view.get_model(); + Glib::RefPtr refStore = Glib::RefPtr::cast_dynamic(reftm); + if(refStore) { + refStore->erase(row_it); + return; + } + Glib::RefPtr refLStore = Glib::RefPtr::cast_dynamic(reftm); + if(refLStore){ + refLStore->erase(row_it); + return; + } +} + +void +PathsDialog::set_default() { + + paths_list_view.clear_items(); + std::vector a = PBD::parse_path(_default_paths); + for(vector::const_iterator i = a.begin(); i != a.end(); ++i) { + paths_list_view.append_text(*i); + } +} diff --git a/libs/widgets/popup.cc b/libs/widgets/popup.cc new file mode 100644 index 0000000000..49d33dd8af --- /dev/null +++ b/libs/widgets/popup.cc @@ -0,0 +1,149 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include + +#include +#include + +#include + +using namespace std; +using namespace Gtk; +using namespace ArdourWidgets; + +PopUp::PopUp (Gtk::WindowPosition pos, unsigned int showfor_msecs, bool doh) + : Window (WINDOW_POPUP) +{ + add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); + signal_button_press_event().connect(mem_fun(*this,&PopUp::button_click)); + set_border_width (12); + add (label); + set_position (pos); + + delete_on_hide = doh; + popdown_time = showfor_msecs; + timeout = -1; +} + + +PopUp::~PopUp () +{ +} + +void +PopUp::on_realize () +{ + Gtk::Window::on_realize(); + get_window()->set_decorations (Gdk::WMDecoration (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH)); +} + +gint +PopUp::remove_prompt_timeout (void *arg) +{ + PopUp *pup = (PopUp *) arg; + + pup->remove (); + return FALSE; +} + +static gint idle_delete (void *arg) +{ + delete static_cast (arg); + return FALSE; +} + +void +PopUp::remove () +{ + hide (); + + if (popdown_time != 0 && timeout != -1) { + g_source_remove (timeout); + } + + if (delete_on_hide) { + std::cerr << "deleting prompter\n"; + g_idle_add (idle_delete, this); + } +} +#define ENSURE_GUI_THREAD(slot) \ + if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {\ + Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, (slot)); \ + return;\ + } + + +void +PopUp::touch () +{ + ENSURE_GUI_THREAD (mem_fun (*this, &PopUp::touch)); + + if (is_visible ()) { + remove (); + } else { + Gtkmm2ext::set_size_request_to_display_given_text (label, my_text.c_str(), 25, 10); + label.set_text (my_text); + show_all (); + + if (popdown_time != 0) { + timeout = g_timeout_add (popdown_time, + remove_prompt_timeout, + this); + } + } +} + +gint +PopUp::button_click (GdkEventButton* /*ev*/) +{ + remove (); + return TRUE; +} + +void +PopUp::set_text (string txt) +{ + my_text = txt; +} + +void +PopUp::set_name (string name) +{ + Window::set_name (name); + label.set_name (name); +} + +bool +PopUp::on_delete_event (GdkEventAny* /*ev*/) +{ + hide(); + + if (popdown_time != 0 && timeout != -1) { + g_source_remove (timeout); + } + + if (delete_on_hide) { + std::cerr << "deleting prompter\n" << endl; + g_idle_add (idle_delete, this); + } + + return true; +} diff --git a/libs/widgets/prompter.cc b/libs/widgets/prompter.cc new file mode 100644 index 0000000000..73b3bf9e49 --- /dev/null +++ b/libs/widgets/prompter.cc @@ -0,0 +1,138 @@ +/* + Copyright (C) 1999 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include + +#include "pbd/whitespace.h" +#include "widgets/prompter.h" + +#include "pbd/i18n.h" + +using namespace std; +using namespace ArdourWidgets; + +Prompter::Prompter (Gtk::Window& parent, bool modal) + : Gtk::Dialog ("", parent, modal) + , first_show (true) + , can_accept_from_entry (false) +{ + init (); +} + +Prompter::Prompter (bool modal) + : Gtk::Dialog ("", modal) + , first_show (true) + , can_accept_from_entry (false) +{ + init (); +} + +void +Prompter::init () +{ + set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG); + set_position (Gtk::WIN_POS_MOUSE); + set_name ("Prompter"); + + add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + + /* + Alas a generic 'affirmative' button seems a bit useless sometimes. + You will have to add your own. + After adding, use : + set_response_sensitive (Gtk::RESPONSE_ACCEPT, false) + to prevent the RESPONSE_ACCEPT button from permitting blank strings. + */ + + entryLabel.set_line_wrap (true); + entryLabel.set_name ("PrompterLabel"); + + entryBox.set_homogeneous (false); + entryBox.set_spacing (5); + entryBox.set_border_width (10); + entryBox.pack_start (entryLabel, false, false); + entryBox.pack_start (entry, true, true); + + get_vbox()->pack_start (entryBox); + show_all_children(); +} + +void +Prompter::on_show () +{ + /* don't connect to signals till shown, so that we don't change the + response sensitivity etc. when the setup of the dialog sets the text. + */ + + if (first_show) { + entry.signal_changed().connect (mem_fun (*this, &Prompter::on_entry_changed)); + entry.signal_activate().connect (mem_fun (*this, &Prompter::entry_activated)); + can_accept_from_entry = !entry.get_text().empty(); + first_show = false; + } + + Dialog::on_show (); +} + +void +Prompter::change_labels (string /*okstr*/, string /*cancelstr*/) +{ + // dynamic_cast(ok.get_child())->set_text (okstr); + // dynamic_cast(cancel.get_child())->set_text (cancelstr); +} + +void +Prompter::get_result (string &str, bool strip) +{ + str = entry.get_text (); + if (strip) { + PBD::strip_whitespace_edges (str); + } +} + +void +Prompter::entry_activated () +{ + if (can_accept_from_entry) { + response (Gtk::RESPONSE_ACCEPT); + } else { + response (Gtk::RESPONSE_CANCEL); + } +} + +void +Prompter::on_entry_changed () +{ + /* + This is set up so that entering text in the entry + field makes the RESPONSE_ACCEPT button active. + Of course if you haven't added a RESPONSE_ACCEPT + button, nothing will happen at all. + */ + + if (!entry.get_text().empty()) { + set_response_sensitive (Gtk::RESPONSE_ACCEPT, true); + set_default_response (Gtk::RESPONSE_ACCEPT); + can_accept_from_entry = true; + } else { + set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); + } +} diff --git a/libs/widgets/scroomer.cc b/libs/widgets/scroomer.cc new file mode 100644 index 0000000000..98c456dc74 --- /dev/null +++ b/libs/widgets/scroomer.cc @@ -0,0 +1,408 @@ +/* + Copyright (C) 2008 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +#include "gtkmm2ext/keyboard.h" +#include "widgets/scroomer.h" + +using namespace std; +using namespace Gdk; +using namespace Gtk; +using namespace ArdourWidgets; + +Scroomer::Scroomer(Gtk::Adjustment& adjustment) + : adj(adjustment) + , handle_size(0) + , grab_comp(None) +{ + position[TopBase] = 0; + position[Handle1] = 0; + position[Slider] = 0; + position[Handle2] = 0; + position[BottomBase] = 0; + position[Total] = 0; + + add_events (Gdk::BUTTON_PRESS_MASK | + Gdk::BUTTON_RELEASE_MASK | + Gdk::POINTER_MOTION_MASK | + Gdk::SCROLL_MASK); + + adjustment.signal_value_changed().connect (mem_fun (*this, &Scroomer::adjustment_changed)); + //adjustment.signal_changed().connect (mem_fun (*this, &Scroomer::adjustment_changed)); +} + +Scroomer::~Scroomer() +{ +} + +bool +Scroomer::on_motion_notify_event (GdkEventMotion* ev) +{ + double range = adj.get_upper() - adj.get_lower(); + double pixel2val = range / get_height(); + double val_at_pointer = ((get_height() - ev->y) * pixel2val) + adj.get_lower(); + double delta_y = ev->y - grab_y; + double half_min_page = min_page_size / 2; + double fract = delta_y / position[Total]; + double scale, temp, zoom; + double val, page; + + if (grab_comp == None || grab_comp == Total) { + return true; + } + + if (ev->window != grab_window) { + grab_y = ev->y; + grab_window = ev->window; + return true; + } + + if (ev->y < 0 || ev->y > get_height ()) { + return true; + } + + grab_y = ev->y; + + if (ev->state & Gtkmm2ext::Keyboard::PrimaryModifier) { + if (ev->state & Gtkmm2ext::Keyboard::SecondaryModifier) { + scale = 0.05; + } else { + scale = 0.1; + } + } else { + scale = 1.0; + } + + fract = min (1.0, fract); + fract = max (-1.0, fract); + fract = -fract; + + switch (grab_comp) { + case TopBase: + case BottomBase: + unzoomed_val += scale * fract * range; + unzoomed_val = min(unzoomed_val, adj.get_upper() - unzoomed_page); + unzoomed_val = max(unzoomed_val, adj.get_lower()); + break; + case Slider: + unzoomed_val += scale * fract * range; + unzoomed_val = min(unzoomed_val, adj.get_upper() - unzoomed_page); + unzoomed_val = max(unzoomed_val, adj.get_lower()); + break; + case Handle1: + + unzoomed_page += scale * fract * range; + unzoomed_page = min(unzoomed_page, adj.get_upper() - unzoomed_val); + unzoomed_page = max(unzoomed_page, min_page_size); + + if (pinch){ + temp = unzoomed_val + unzoomed_page; + unzoomed_val -= scale * fract * range * 0.5; + unzoomed_val = min(unzoomed_val, temp - min_page_size); + unzoomed_val = max(unzoomed_val, adj.get_lower()); + } + + break; + case Handle2: + temp = unzoomed_val + unzoomed_page; + unzoomed_val += scale * fract * range; + unzoomed_val = min(unzoomed_val, temp - min_page_size); + unzoomed_val = max(unzoomed_val, adj.get_lower()); + + unzoomed_page = temp - unzoomed_val; + + if (pinch){ + + unzoomed_page -= scale * fract * range; + } + + unzoomed_page = min(unzoomed_page, adj.get_upper() - unzoomed_val); + unzoomed_page = max(unzoomed_page, min_page_size); + break; + default: + break; + } + + /* Then we handle zoom, which is dragging horizontally. We zoom around the area that is + * the current y pointer value, not from the area that was the start of the drag. + * We don't start doing zoom until we are at least one scroomer width outside the scroomer's + * area. + */ + + if (ev->x > (get_width() * 2)) { + zoom = ev->x - get_width(); + + double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; + double lower = val_at_pointer - (unzoomed_val + half_min_page); + + higher *= zoom / 128; + lower *= zoom / 128; + + val = unzoomed_val + lower; + page = unzoomed_page - higher - lower; + + page = max(page, min_page_size); + + if (lower < 0) { + val = max(val, val_at_pointer - half_min_page); + } else if (lower > 0) { + val = min(val, val_at_pointer - half_min_page); + } + + val = min(val, adj.get_upper() - min_page_size); + page = min(page, adj.get_upper() - val); + } else if (ev->x < 0) { + /* on zoom out increase the page size as well as moving the range towards the mouse pos*/ + /*zoom = abs(ev->x); + + double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; + double lower = val_at_pointer - (unzoomed_val + half_min_page); + + higher *= zoom / 128; + lower *= zoom / 128; + + val = unzoomed_val + lower; + page = unzoomed_page - higher - lower; + + page = max(page, min_page_size); + + if (lower < 0) { + val = max(val, val_at_pointer - half_min_page); + } + else if (lower > 0) { + val = min(val, val_at_pointer - half_min_page); + } + + val = min(val, adj.get_upper() - min_page_size); + page = min(page, adj.get_upper() - val);*/ + + val = unzoomed_val; + page = unzoomed_page; + } else { + val = unzoomed_val; + page = unzoomed_page; + } + + /* Round these values to stop the scroomer handlers quivering about during drags */ + adj.set_page_size (rint (page)); + adj.set_value (rint (val)); + adj.value_changed(); + + return true; +} + +bool +Scroomer::on_scroll_event (GdkEventScroll* ev) +{ + switch (ev->direction) { + case GDK_SCROLL_UP: + adj.set_value (min (adj.get_value() + adj.get_page_size() / 10.0, adj.get_upper() - adj.get_page_size())); + break; + case GDK_SCROLL_DOWN: + adj.set_value (adj.get_value() - adj.get_page_size() / 10.0); + break; + default: + return false; + } + + return true; +} + +bool +Scroomer::on_button_press_event (GdkEventButton* ev) +{ + if (ev->button == 1 || ev->button == 3) { + Component comp = point_in(ev->y); + + if (comp == Total || comp == None) { + return false; + } + + add_modal_grab(); + grab_comp = comp; + grab_y = ev->y; + unzoomed_val = adj.get_value(); + unzoomed_page = adj.get_page_size(); + grab_window = ev->window; + + if (ev->button == 3){ + pinch = true; + } else { + pinch = false; + } + + DragStarting (); /* EMIT SIGNAL */ + } + + if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) { + DoubleClicked(); + } + + return true; +} + +bool +Scroomer::on_button_release_event (GdkEventButton* ev) +{ + if (grab_comp == None || grab_comp == Total) { + return true; + } + + if (ev->window != grab_window) { + grab_y = ev->y; + grab_window = ev->window; + return true; + } + + if (ev->button != 1 && ev->button != 3) { + return true; + } + + switch (grab_comp) { + case TopBase: + break; + case Handle1: + break; + case Slider: + break; + case Handle2: + break; + case BottomBase: + break; + default: + break; + } + + grab_comp = None; + + remove_modal_grab(); + DragFinishing (); /* EMIT SIGNAL */ + return true; +} + +void +Scroomer::on_size_allocate (Allocation& a) +{ + Gtk::DrawingArea::on_size_allocate(a); + + position[Total] = a.get_height(); + set_min_page_size(min_page_size); + update(); +} + +/** Assumes that x and width are correct, and they will not be altered. + */ +void +Scroomer::set_comp_rect(GdkRectangle& r, Component c) const +{ + int index = (int) c; + + switch (c) { + case None: + return; + case Total: + r.y = 0; + r.height = position[Total]; + break; + default: + r.y = position[index]; + r.height = position[index+1] - position[index]; + break; + } +} + +Scroomer::Component +Scroomer::point_in(double point) const +{ + for (int i = 0; i < Total; ++i) { + if (position[i+1] >= point) { + return (Component) i; + } + } + + return None; +} + +void +Scroomer::set_min_page_size(double ps) +{ + double coeff = ((double)position[Total]) / (adj.get_upper() - adj.get_lower()); + + min_page_size = ps; + handle_size = (int) floor((ps * coeff) / 2); +} + +void +Scroomer::update() +{ + double range = adj.get_upper() - adj.get_lower(); + //double value = adj.get_value() - adj.get_lower(); + int height = position[Total]; + double coeff = ((double) height) / range; + + /* save the old positions to calculate update regions later*/ + for (int i = Handle1; i < Total; ++i) { + old_pos[i] = position[i]; + } + + position[BottomBase] = (int) floor(height - (adj.get_value() * coeff)); + position[Handle2] = position[BottomBase] - handle_size; + + position[Handle1] = (int) floor(height - ((adj.get_value() + adj.get_page_size()) * coeff)); + position[Slider] = position[Handle1] + handle_size; +} + +void +Scroomer::adjustment_changed() +{ + //cerr << floor(adj.get_value()) << " " << floor(adj.get_value() + adj.get_page_size()) << endl; + Gdk::Rectangle rect; + Glib::RefPtr win = get_window(); + + update(); + + if (!win) { + return; + } + + rect.set_x(0); + rect.set_width(get_width()); + + if (position[Handle1] < old_pos[Handle1]) { + rect.set_y(position[Handle1]); + rect.set_height(old_pos[Slider] - position[Handle1]); + win->invalidate_rect(rect, false); + } else if (position[Handle1] > old_pos[Handle1]) { + rect.set_y(old_pos[Handle1]); + rect.set_height(position[Slider] - old_pos[Handle1]); + win->invalidate_rect(rect, false); + } + + if (position[Handle2] < old_pos[Handle2]) { + rect.set_y(position[Handle2]); + rect.set_height(old_pos[BottomBase] - position[Handle2]); + win->invalidate_rect(rect, false); + } else if (position[Handle2] > old_pos[Handle2]) { + rect.set_y(old_pos[Handle2]); + rect.set_height(position[BottomBase] - old_pos[Handle2]); + win->invalidate_rect(rect, false); + } +} + diff --git a/libs/widgets/stateful_button.cc b/libs/widgets/stateful_button.cc new file mode 100644 index 0000000000..f0ba91f38e --- /dev/null +++ b/libs/widgets/stateful_button.cc @@ -0,0 +1,273 @@ +/* + Copyright (C) 2000-2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + + +#include + +#include "widgets/stateful_button.h" + +using namespace Gtk; +using namespace Glib; +using namespace ArdourWidgets; +using namespace std; + +StateButton::StateButton () + : visual_state (0) + , _self_managed (false) + , _is_realized (false) + , style_changing (false) + , state_before_prelight (Gtk::STATE_NORMAL) + , is_toggle (false) +{ +} + +void +StateButton::set_visual_state (int n) +{ + if (!_is_realized) { + /* not yet realized */ + visual_state = n; + return; + } + + if (n == visual_state) { + return; + } + + string name = get_widget_name (); + name = name.substr (0, name.find_last_of ('-')); + + switch (n) { + case 0: + /* relax */ + break; + case 1: + name += "-active"; + break; + + case 2: + name += "-alternate"; + break; + + case 3: + name += "-alternate2"; + break; + } + + set_widget_name (name); + visual_state = n; +} + +void +StateButton::avoid_prelight_on_style_changed (const Glib::RefPtr& /* old_style */, GtkWidget* widget) +{ + /* don't go into an endless recursive loop if we're changing + the style in response to an existing style change. + */ + + if (style_changing) { + return; + } + + if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT) { + + /* avoid PRELIGHT: make sure that the prelight colors in this new style match + the colors of the new style in whatever state we were in + before we switched to prelight. + */ + + GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget); + GtkStyle* style = gtk_widget_get_style (widget); + + rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[state_before_prelight]; + rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[state_before_prelight]; + rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG); + + style_changing = true; + g_object_ref (rcstyle); + gtk_widget_modify_style (widget, rcstyle); + + Widget* child = get_child_widget(); + if (child) { + gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle); + } + + + g_object_unref (rcstyle); + style_changing = false; + } +} + +void +StateButton::avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget) +{ + GtkStateType state = gtk_widget_get_state (widget); + + if (state == GTK_STATE_PRELIGHT) { + + state_before_prelight = old_state; + + + /* avoid PRELIGHT when currently ACTIVE: + if we just went into PRELIGHT, make sure that the colors + match those of whatever state we were in before. + */ + + GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget); + GtkStyle* style = gtk_widget_get_style (widget); + + rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[old_state]; + rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[old_state]; + rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG); + + g_object_ref (rcstyle); + gtk_widget_modify_style (widget, rcstyle); + + Widget* child = get_child_widget (); + + if (child) { + gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle); + } + + g_object_unref (rcstyle); + + } +} + +/* ----------------------------------------------------------------- */ + +StatefulToggleButton::StatefulToggleButton () +{ + is_toggle = true; +} + +StatefulToggleButton::StatefulToggleButton (const std::string& label) + : ToggleButton (label) +{ + is_toggle = true; +} + +void +StatefulToggleButton::on_realize () +{ + ToggleButton::on_realize (); + + _is_realized = true; + visual_state++; // to force transition + set_visual_state (visual_state - 1); +} + +void +StatefulButton::on_realize () +{ + Button::on_realize (); + + _is_realized = true; + visual_state++; // to force transition + set_visual_state (visual_state - 1); +} + +void +StatefulToggleButton::on_toggled () +{ + if (!_self_managed) { + if (get_active()) { + set_state (Gtk::STATE_ACTIVE); + } else { + set_state (Gtk::STATE_NORMAL); + } + } +} + + +void +StatefulToggleButton::on_style_changed (const Glib::RefPtr& style) +{ + avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj())); + Button::on_style_changed (style); +} + +void +StatefulToggleButton::on_state_changed (Gtk::StateType old_state) +{ + avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj())); + Button::on_state_changed (old_state); +} + +Widget* +StatefulToggleButton::get_child_widget () +{ + return get_child(); +} + +void +StatefulToggleButton::set_widget_name (const std::string& name) +{ + set_name (name); + Widget* w = get_child(); + + if (w) { + w->set_name (name); + } +} + +/*--------------------------------------------- */ + +StatefulButton::StatefulButton () +{ +} + +StatefulButton::StatefulButton (const std::string& label) + : Button (label) +{ +} + +void +StatefulButton::on_style_changed (const Glib::RefPtr& style) +{ + avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj())); + Button::on_style_changed (style); +} + +void +StatefulButton::on_state_changed (Gtk::StateType old_state) +{ + avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj())); + Button::on_state_changed (old_state); +} + +Widget* +StatefulButton::get_child_widget () +{ + return get_child(); +} + +void +StatefulButton::set_widget_name (const std::string& name) +{ + set_name (name); + Widget* w = get_child(); + + if (w) { + w->set_name (name); + } +} diff --git a/libs/widgets/tabbable.cc b/libs/widgets/tabbable.cc new file mode 100644 index 0000000000..ea31e6f713 --- /dev/null +++ b/libs/widgets/tabbable.cc @@ -0,0 +1,389 @@ +/* + Copyright (C) 2015 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include + +#include "pbd/stacktrace.h" + +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/visibility_tracker.h" + +#include "widgets/tabbable.h" + +#include "pbd/i18n.h" + +using std::string; +using namespace Gtk; +using namespace Gtkmm2ext; +using namespace ArdourWidgets; + +Tabbable::Tabbable (Widget& w, const string& name, bool tabbed_by_default) + : WindowProxy (name) + , _contents (w) + , _parent_notebook (0) + , tab_requested_by_state (tabbed_by_default) +{ +} + +Tabbable::~Tabbable () +{ + if (_window) { + delete _window; + _window = 0; + } +} + +void +Tabbable::add_to_notebook (Notebook& notebook, const string& tab_title) +{ + _parent_notebook = ¬ebook; + + if (tab_requested_by_state) { + attach (); + } +} + +Window* +Tabbable::use_own_window (bool and_pack_it) +{ + Gtk::Window* win = get (true); + + if (and_pack_it) { + Gtk::Container* parent = _contents.get_parent(); + if (parent) { + _contents.hide (); + parent->remove (_contents); + } + _own_notebook.append_page (_contents); + _contents.show (); + } + + return win; + +} + +bool +Tabbable::window_visible () const +{ + if (!_window) { + return false; + } + + return _window->is_visible(); +} + +Window* +Tabbable::get (bool create) +{ + if (_window) { + return _window; + } + + if (!create) { + return 0; + } + + /* From here on, we're creating the window + */ + + if ((_window = new Window (WINDOW_TOPLEVEL)) == 0) { + return 0; + } + + _window->add (_own_notebook); + _own_notebook.show (); + _own_notebook.set_show_tabs (false); + + _window->signal_map().connect (sigc::mem_fun (*this, &Tabbable::window_mapped)); + _window->signal_unmap().connect (sigc::mem_fun (*this, &Tabbable::window_unmapped)); + + /* do other window-related setup */ + + setup (); + + /* window should be ready for derived classes to do something with it */ + + return _window; +} + +void +Tabbable::show_own_window (bool and_pack_it) +{ + Gtk::Widget* parent = _contents.get_parent(); + Gtk::Allocation alloc; + + if (parent) { + alloc = parent->get_allocation(); + } + + (void) use_own_window (and_pack_it); + + if (parent) { + _window->set_default_size (alloc.get_width(), alloc.get_height()); + } + + tab_requested_by_state = false; + + _window->present (); +} + +Gtk::Notebook* +Tabbable::tab_root_drop () +{ + /* This is called after a drop of a tab onto the root window. Its + * responsibility xois to return the notebook that this Tabbable's + * contents should be packed into before the drop handling is + * completed. It is not responsible for actually taking care of this + * packing. + */ + + show_own_window (false); + return &_own_notebook; +} + +void +Tabbable::show_window () +{ + make_visible (); + + if (_window && (current_toplevel() == _window)) { + if (!_visible) { /* was hidden, update status */ + set_pos_and_size (); + } + } +} + +/** If this Tabbable is currently parented by a tab, ensure that the tab is the + * current one. If it is parented by a window, then toggle the visibility of + * that window. + */ +void +Tabbable::change_visibility () +{ + if (tabbed()) { + _parent_notebook->set_current_page (_parent_notebook->page_num (_contents)); + return; + } + + if (tab_requested_by_state) { + /* should be tabbed, but currently isn't parented by a notebook */ + return; + } + + if (_window && (current_toplevel() == _window)) { + /* Use WindowProxy method which will rotate then hide */ + toggle(); + } +} + +void +Tabbable::make_visible () +{ + if (_window && (current_toplevel() == _window)) { + set_pos (); + _window->present (); + } else { + + if (!tab_requested_by_state) { + show_own_window (true); + } else { + show_tab (); + } + } +} + +void +Tabbable::make_invisible () +{ + if (_window && (current_toplevel() == _window)) { + _window->hide (); + } else { + hide_tab (); + } +} + +void +Tabbable::detach () +{ + show_own_window (true); +} + +void +Tabbable::attach () +{ + if (!_parent_notebook) { + return; + } + + if (tabbed()) { + /* already tabbed */ + return; + } + + + if (_window && current_toplevel() == _window) { + /* unpack Tabbable from parent, put it back in the main tabbed + * notebook + */ + + save_pos_and_size (); + + _contents.hide (); + _contents.get_parent()->remove (_contents); + + /* leave the window around */ + + _window->hide (); + } + + _parent_notebook->append_page (_contents); + _parent_notebook->set_tab_detachable (_contents); + _parent_notebook->set_tab_reorderable (_contents); + _parent_notebook->set_current_page (_parent_notebook->page_num (_contents)); + _contents.show (); + + /* have to force this on, which is semantically correct, since + * the user has effectively asked for it. + */ + + tab_requested_by_state = true; + StateChange (*this); +} + +bool +Tabbable::delete_event_handler (GdkEventAny *ev) +{ + _window->hide(); + + return true; +} + +bool +Tabbable::tabbed () const +{ + if (_window && (current_toplevel() == _window)) { + return false; + } + + if (_parent_notebook && (_parent_notebook->page_num (_contents) >= 0)) { + return true; + } + + return false; +} + +void +Tabbable::hide_tab () +{ + if (tabbed()) { + _contents.hide(); + _parent_notebook->remove_page (_contents); + StateChange (*this); + } +} + +void +Tabbable::show_tab () +{ + if (!window_visible() && _parent_notebook) { + if (_contents.get_parent() == 0) { + tab_requested_by_state = true; + add_to_notebook (*_parent_notebook, _tab_title); + } + _parent_notebook->set_current_page (_parent_notebook->page_num (_contents)); + _contents.show (); + current_toplevel()->present (); + } +} + +Gtk::Window* +Tabbable::current_toplevel () const +{ + return dynamic_cast (contents().get_toplevel()); +} + +string +Tabbable::xml_node_name() +{ + return WindowProxy::xml_node_name(); +} + +bool +Tabbable::tabbed_by_default() const +{ + return tab_requested_by_state; +} + +XMLNode& +Tabbable::get_state() +{ + XMLNode& node (WindowProxy::get_state()); + + node.set_property (X_("tabbed"), tabbed()); + + return node; +} + +int +Tabbable::set_state (const XMLNode& node, int version) +{ + int ret; + + if ((ret = WindowProxy::set_state (node, version)) != 0) { + return ret; + } + + if (_visible) { + show_own_window (true); + } + + XMLNodeList children = node.children (); + XMLNode* window_node = node.child ("Window"); + + if (window_node) { + window_node->get_property (X_("tabbed"), tab_requested_by_state); + } + + if (!_visible) { + if (tab_requested_by_state) { + attach (); + } else { + /* this does nothing if not tabbed */ + hide_tab (); + } + } + + return ret; +} + +void +Tabbable::window_mapped () +{ + StateChange (*this); +} + +void +Tabbable::window_unmapped () +{ + StateChange (*this); +} diff --git a/libs/widgets/tearoff.cc b/libs/widgets/tearoff.cc new file mode 100644 index 0000000000..5fae7bcf3b --- /dev/null +++ b/libs/widgets/tearoff.cc @@ -0,0 +1,341 @@ +/* + Copyright (C) 2003 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "pbd/xml++.h" + +#include "gtkmm2ext/utils.h" + +#include "widgets/tearoff.h" + +#include "pbd/i18n.h" + +using namespace std; +using namespace Glib; +using namespace Gdk; +using namespace Gtk; +using namespace ArdourWidgets; + +TearOff::TearOff (Widget& c, bool allow_resize) + : contents (c) + , own_window (Gtk::WINDOW_TOPLEVEL) + , tearoff_arrow (ARROW_DOWN, SHADOW_OUT) + , close_arrow (ARROW_UP, SHADOW_OUT) + , dragging (false) + , _visible (true) + , _torn (false) + , _can_be_torn_off (true) + +{ + own_window_width = 0; + own_window_height = 0; + own_window_xpos = 0; + own_window_ypos = 0; + + tearoff_event_box.add (tearoff_arrow); + tearoff_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); + tearoff_event_box.signal_button_release_event().connect (mem_fun (*this, &TearOff::tearoff_click)); + + tearoff_event_box.set_tooltip_text (_("Click to tear this into its own window")); + + close_event_box.add (close_arrow); + close_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); + close_event_box.signal_button_release_event().connect (mem_fun (*this, &TearOff::close_click)); + + close_event_box.set_tooltip_text (_("Click to put this back in the main window")); + + VBox* box1; + box1 = manage (new VBox); + box1->pack_start (close_event_box, false, false, 2); + + window_box.pack_end (*box1, false, false, 2); + + own_window.add_events (KEY_PRESS_MASK|KEY_RELEASE_MASK|BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK|POINTER_MOTION_MASK|POINTER_MOTION_HINT_MASK); + own_window.set_resizable (allow_resize); + own_window.set_type_hint (WINDOW_TYPE_HINT_UTILITY); + + own_window.add (window_box); + + own_window.signal_button_press_event().connect (mem_fun (*this, &TearOff::window_button_press)); + own_window.signal_button_release_event().connect (mem_fun (*this, &TearOff::window_button_release)); + own_window.signal_motion_notify_event().connect (mem_fun (*this, &TearOff::window_motion)); + own_window.signal_delete_event().connect (mem_fun (*this, &TearOff::window_delete_event)); + own_window.signal_realize().connect (sigc::mem_fun (*this, &TearOff::own_window_realized)); + own_window.signal_configure_event().connect (sigc::mem_fun (*this, &TearOff::own_window_configured), false); + + tearoff_arrow.set_name ("TearOffArrow"); + close_arrow.set_name ("TearOffArrow"); + + VBox* box2; + box2 = manage (new VBox); + box2->pack_start (tearoff_event_box, false, false); + + pack_start (contents); + pack_start (*box2, false, false); +} + +TearOff::~TearOff () +{ +} + +void +TearOff::set_can_be_torn_off (bool yn) +{ + if (yn != _can_be_torn_off) { + if (yn) { + tearoff_arrow.set_no_show_all (false); + tearoff_arrow.show (); + } else { + tearoff_arrow.set_no_show_all (true); + tearoff_arrow.hide (); + } + _can_be_torn_off = yn; + } +} + +void +TearOff::set_visible (bool yn, bool force) +{ + /* don't change visibility if torn off */ + + if (_torn) { + return; + } + + if (_visible != yn || force) { + _visible = yn; + if (yn) { + show_all(); + Visible (); + } else { + hide (); + Hidden (); + } + } +} + +gint +TearOff::tearoff_click (GdkEventButton* /*ev*/) +{ + tear_it_off (); + return true; +} + +void +TearOff::tear_it_off () +{ + if (!_can_be_torn_off) { + return; + } + + if (torn_off()) { + return; + } + + remove (contents); + window_box.pack_start (contents); + own_window.set_name (get_name()); + close_event_box.set_name (get_name()); + if (own_window_width == 0) { + own_window.set_position (WIN_POS_MOUSE); + } + own_window.show_all (); + own_window.present (); + hide (); + + _torn = true; + + Detach (); +} + +gint +TearOff::close_click (GdkEventButton* /*ev*/) +{ + put_it_back (); + return true; +} + +void +TearOff::put_it_back () +{ + if (!torn_off()) { + return; + } + + window_box.remove (contents); + pack_start (contents); + reorder_child (contents, 0); + own_window.hide (); + show_all (); + + _torn = false; + + Attach (); +} + +gint +TearOff::window_button_press (GdkEventButton* ev) +{ + if (dragging || ev->button != 1) { + dragging = false; + own_window.remove_modal_grab(); + return true; + } + + dragging = true; + drag_x = ev->x_root; + drag_y = ev->y_root; + + own_window.add_modal_grab(); + + return true; +} + +gint +TearOff::window_button_release (GdkEventButton* /*ev*/) +{ + dragging = false; + own_window.remove_modal_grab(); + return true; +} + +gint +TearOff::window_delete_event (GdkEventAny* /*ev*/) +{ + return close_click(0); +} + +gint +TearOff::window_motion (GdkEventMotion* ev) +{ + gint x; + gint y; + gint mx, my; + double x_delta; + double y_delta; + RefPtr win (own_window.get_window()); + + own_window.get_pointer (mx, my); + + if (!dragging) { + return true; + } + + if (!(ev->state & GDK_BUTTON1_MASK)) { + dragging = false; + own_window.remove_modal_grab(); + return true; + } + + x_delta = ev->x_root - drag_x; + y_delta = ev->y_root - drag_y; + + win->get_root_origin (x, y); + win->move ((gint) floor (x + x_delta), (gint) floor (y + y_delta)); + + drag_x = ev->x_root; + drag_y = ev->y_root; + + return true; +} + +bool +TearOff::torn_off() const +{ + return _torn; +} + +void +TearOff::add_state (XMLNode& node) const +{ + node.set_property ("tornoff", _torn); + + if (own_window_width > 0) { + node.set_property ("width", own_window_width); + node.set_property ("height", own_window_height); + node.set_property ("xpos", own_window_xpos); + node.set_property ("ypos", own_window_ypos); + } +} + +void +TearOff::set_state (const XMLNode& node) +{ + Glib::RefPtr win; + + bool tornoff; + if (!node.get_property (X_("tornoff"), tornoff)) { + return; + } + + if (tornoff) { + tear_it_off (); + } else { + put_it_back (); + } + + node.get_property (X_("width"), own_window_width); + node.get_property (X_("height"), own_window_height); + node.get_property (X_("xpos"), own_window_xpos); + node.get_property (X_("ypos"), own_window_ypos); + + if (own_window.is_realized ()) { + own_window.set_default_size (own_window_width, own_window_height); + own_window.move (own_window_xpos, own_window_ypos); + } + /* otherwise do it once the window is realized, see below */ +} + +void +TearOff::own_window_realized () +{ + own_window.get_window()->set_decorations (WMDecoration (DECOR_BORDER|DECOR_RESIZEH)); + + if (own_window_width > 0) { + own_window.set_default_size (own_window_width, own_window_height); + own_window.move (own_window_xpos, own_window_ypos); + } +} + +bool +TearOff::own_window_configured (GdkEventConfigure*) +{ + Glib::RefPtr win; + + win = own_window.get_window (); + + if (win) { + win->get_size (own_window_width, own_window_height); + win->get_position (own_window_xpos, own_window_ypos); + } + + return false; +} + +void +TearOff::hide_visible () +{ + if (torn_off()) { + own_window.hide (); + } + + hide (); +} diff --git a/libs/widgets/widgets/ardour_button.h b/libs/widgets/widgets/ardour_button.h index a51575e616..6630c19450 100644 --- a/libs/widgets/widgets/ardour_button.h +++ b/libs/widgets/widgets/ardour_button.h @@ -25,11 +25,11 @@ #include #include "pbd/signals.h" -#include "gtkmm2ext/ardour_icon.h" -#include "gtkmm2ext/binding_proxy.h" #include "gtkmm2ext/activatable.h" #include "gtkmm2ext/cairo_widget.h" +#include "widgets/ardour_icon.h" +#include "widgets/binding_proxy.h" #include "widgets/visibility.h" namespace ArdourWidgets { @@ -80,8 +80,8 @@ class LIBWIDGETS_API ArdourButton : public CairoWidget , public Gtkmm2ext::Activ void set_elements (Element); void add_elements (Element); - Gtkmm2ext::ArdourIcon::Icon icon() const { return _icon; } - void set_icon (Gtkmm2ext::ArdourIcon::Icon); + ArdourIcon::Icon icon() const { return _icon; } + void set_icon (ArdourIcon::Icon); void set_icon (rendercallback_t, void*); void set_corner_radius (float); @@ -155,7 +155,7 @@ class LIBWIDGETS_API ArdourButton : public CairoWidget , public Gtkmm2ext::Activ std::string _sizing_text; bool _markup; Element _elements; - Gtkmm2ext::ArdourIcon::Icon _icon; + ArdourIcon::Icon _icon; rendercallback_t _icon_render_cb; void* _icon_render_cb_data; Tweaks _tweaks; diff --git a/libs/widgets/widgets/ardour_icon.h b/libs/widgets/widgets/ardour_icon.h new file mode 100644 index 0000000000..c49c5b833a --- /dev/null +++ b/libs/widgets/widgets/ardour_icon.h @@ -0,0 +1,50 @@ +#ifndef _WIDGETS_ARDOUR_ICON_H_ +#define _WIDGETS_ARDOUR_ICON_H_ + +#include +#include + +#include "gtkmm2ext/widget_state.h" +#include "widgets/visibility.h" + +namespace ArdourWidgets { namespace ArdourIcon { + enum Icon { + NoIcon, + RecButton, + RecTapeMode, + CloseCross, + StripWidth, + DinMidi, + TransportStop, + TransportPlay, + TransportLoop, + TransportRange, + TransportStart, + TransportEnd, + TransportPanic, + TransportMetronom, + NudgeLeft, + NudgeRight, + ZoomIn, + ZoomOut, + ZoomFull, + ZoomExpand, + TimeAxisShrink, + TimeAxisExpand, + ToolGrab, + ToolRange, + ToolCut, + ToolStretch, + ToolAudition, + ToolDraw, + ToolContent, + }; + + LIBWIDGETS_API bool render (cairo_t *cr, + const enum Icon icon, + const int width, const int height, + const Gtkmm2ext::ActiveState state, + const uint32_t fg_color); +}; } /* end namespace */ + +#endif diff --git a/libs/widgets/widgets/ardour_knob.h b/libs/widgets/widgets/ardour_knob.h index 84bb974adf..c07b0447cb 100644 --- a/libs/widgets/widgets/ardour_knob.h +++ b/libs/widgets/widgets/ardour_knob.h @@ -26,11 +26,11 @@ #include "pbd/signals.h" -#include "gtkmm2ext/binding_proxy.h" #include "gtkmm2ext/activatable.h" #include "gtkmm2ext/cairo_widget.h" #include "gtkmm2ext/persistent_tooltip.h" +#include "widgets/binding_proxy.h" #include "widgets/visibility.h" namespace ArdourWidgets { diff --git a/libs/widgets/widgets/barcontroller.h b/libs/widgets/widgets/barcontroller.h index fc2ac358cc..5fdbae6f2f 100644 --- a/libs/widgets/widgets/barcontroller.h +++ b/libs/widgets/widgets/barcontroller.h @@ -22,7 +22,7 @@ #include #include -#include "gtkmm2ext/binding_proxy.h" +#include "widgets/binding_proxy.h" #include "widgets/slider_controller.h" #include "widgets/visibility.h" diff --git a/libs/widgets/widgets/binding_proxy.h b/libs/widgets/widgets/binding_proxy.h new file mode 100644 index 0000000000..8ac49edb9f --- /dev/null +++ b/libs/widgets/widgets/binding_proxy.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _WIDGETS_BINDING_PROXY_ +#define _WIDGETS_BINDING_PROXY_ + +#include +#include + +#include "pbd/signals.h" + +#include "widgets/visibility.h" + +namespace PBD { + class Controllable; +} + +namespace ArdourWidgets { + class PopUp; +} + +namespace ArdourWidgets { + +class LIBWIDGETS_API BindingProxy : public sigc::trackable +{ +public: + BindingProxy (boost::shared_ptr); + BindingProxy (); + virtual ~BindingProxy(); + + void set_bind_button_state (guint button, guint statemask); + + static bool is_bind_action (GdkEventButton *); + bool button_press_handler (GdkEventButton *); + + boost::shared_ptr get_controllable() const { return controllable; } + void set_controllable (boost::shared_ptr); + +protected: + ArdourWidgets::PopUp* prompter; + boost::shared_ptr controllable; + + static guint bind_button; + static guint bind_statemask; + + PBD::ScopedConnection learning_connection; + void learning_finished (); + bool prompter_hiding (GdkEventAny *); +}; + +} + +#endif diff --git a/libs/widgets/widgets/choice.h b/libs/widgets/widgets/choice.h new file mode 100644 index 0000000000..a33c93ae00 --- /dev/null +++ b/libs/widgets/widgets/choice.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2000-2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_CHOICE_H_ +#define _WIDGETS_CHOICE_H_ + +#include +#include + +#include +#include +#include +#include + +#include "widgets/visibility.h" + +namespace ArdourWidgets { + +class LIBWIDGETS_API Choice : public Gtk::Dialog +{ +public: + Choice (std::string title, std::string prompt, std::vector choices, bool center = true); + virtual ~Choice (); + +protected: + void on_realize (); +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/widgets/click_box.h b/libs/widgets/widgets/click_box.h index fa4868467f..c83db83858 100644 --- a/libs/widgets/widgets/click_box.h +++ b/libs/widgets/widgets/click_box.h @@ -27,9 +27,8 @@ #include #include -#include "gtkmm2ext/binding_proxy.h" - #include "widgets/auto_spin.h" +#include "widgets/binding_proxy.h" #include "widgets/visibility.h" namespace PBD { diff --git a/libs/widgets/widgets/eventboxext.h b/libs/widgets/widgets/eventboxext.h new file mode 100644 index 0000000000..3e7402f3d3 --- /dev/null +++ b/libs/widgets/widgets/eventboxext.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2017 Robin Gareus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _WIDGETS_EVENTBOX_EXT_H_ +#define _WIDGETS_EVENTBOX_EXT_H_ + +#include + +#include "widgets/visibility.h" + +namespace ArdourWidgets { + +class LIBWIDGETS_API EventBoxExt : public Gtk::EventBox +{ +public: + EventBoxExt (); + virtual ~EventBoxExt () {} + +protected: + /* gtk2's gtk/gtkcontainer.c does not + * unmap child widgets if the container has a window. + * + * (this is for historical reasons and optimization + * because back in the day each GdkWindow was backed by + * an actual windowing system surface). + * + * In Ardour's case an EventBox is used in the Editor's top-level + * and child-widgets (e.g. Canvas::GtkCanvas never receive an unmap. + * + * However, when switching Tabbable pages, we do need to hide overlays + * such as ArdourCanvasOpenGLView + * + */ + void on_unmap () { + Gtk::EventBox::on_unmap(); + if (get_child ()) { + get_child()->unmap(); + } + } +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/widgets/pane.h b/libs/widgets/widgets/pane.h new file mode 100644 index 0000000000..bc971e6802 --- /dev/null +++ b/libs/widgets/widgets/pane.h @@ -0,0 +1,133 @@ +/* + Copyright (C) 2016 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_PANE_H_ +#define _WIDGETS_PANE_H_ + +#include +#include +#include + +#include + +#include +#include +#include + +#include "widgets/visibility.h" + +namespace Gtk { + class Widget; +} + +namespace ArdourWidgets { + +class LIBWIDGETS_API Pane : public Gtk::Container +{ +private: + class Divider; + +public: + struct Child + { + Pane* pane; + Gtk::Widget* w; + int32_t minsize; + sigc::connection show_con; + sigc::connection hide_con; + + Child (Pane* p, Gtk::Widget* widget, uint32_t ms) : pane (p), w (widget), minsize (ms) {} + }; + + typedef std::vector > Children; + + Pane (bool horizontal); + ~Pane(); + + void set_divider (std::vector::size_type divider, float fract); + float get_divider (std::vector::size_type divider = 0); + void set_child_minsize (Gtk::Widget const &, int32_t); + + GType child_type_vfunc() const; + void set_drag_cursor (Gdk::Cursor); + + void set_check_divider_position (bool); + +protected: + bool horizontal; + + void on_add (Gtk::Widget*); + void on_remove (Gtk::Widget*); + void on_size_request (GtkRequisition*); + void on_size_allocate (Gtk::Allocation&); + bool on_expose_event (GdkEventExpose*); + + bool handle_press_event (GdkEventButton*, Divider*); + bool handle_release_event (GdkEventButton*, Divider*); + bool handle_motion_event (GdkEventMotion*, Divider*); + bool handle_enter_event (GdkEventCrossing*, Divider*); + bool handle_leave_event (GdkEventCrossing*, Divider*); + + void forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer callback_data); + +private: + Gdk::Cursor drag_cursor; + bool did_move; + + void reallocate (Gtk::Allocation const &); + + Children children; + + struct Divider : public Gtk::EventBox { + Divider (); + + float fract; + bool dragging; + + bool on_expose_event (GdkEventExpose* ev); + }; + + typedef std::list Dividers; + Dividers dividers; + int divider_width; + bool check_fract; + + void add_divider (); + void handle_child_visibility (); + float constrain_fract (Dividers::size_type, float fract); + + static void* notify_child_destroyed (void*); + void* child_destroyed (Gtk::Widget*); +}; + +class LIBWIDGETS_API HPane : public Pane +{ + public: + HPane () : Pane (true) {} +}; + +class LIBWIDGETS_API VPane : public Pane +{ + public: + VPane () : Pane (false) {} +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/widgets/paths_dialog.h b/libs/widgets/widgets/paths_dialog.h new file mode 100644 index 0000000000..8757c8b032 --- /dev/null +++ b/libs/widgets/widgets/paths_dialog.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2014 Robin Gareus + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#ifndef _WIDGETS_PATHS_DIALOG_H_ +#define _WIDGETS_PATHS_DIALOG_H_ + +#include +#include +#include + +#include "widgets/visibility.h" + +namespace ArdourWidgets { + +class LIBWIDGETS_API PathsDialog : public Gtk::Dialog +{ +public: + PathsDialog (Gtk::Window& parent, std::string, std::string current_paths = "", std::string default_paths = ""); + ~PathsDialog (); + + std::string get_serialized_paths (); + +private: + void on_show (); + + Gtk::ListViewText paths_list_view; + + Gtk::Button add_path_button; + Gtk::Button remove_path_button; + Gtk::Button set_default_button; + + void selection_changed(); + void add_path(); + void remove_path(); + void set_default(); + + std::string _default_paths; +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/widgets/popup.h b/libs/widgets/widgets/popup.h new file mode 100644 index 0000000000..769a1a56fd --- /dev/null +++ b/libs/widgets/widgets/popup.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_POPUP_H_ +#define _WIDGETS_POPUP_H_ + +#ifdef interface +#undef interface +#endif + +#include +#include + +#include + +#include "widgets/visibility.h" + +namespace ArdourWidgets { + +class LIBWIDGETS_API PopUp : public Gtk::Window, public Touchable +{ +public: + PopUp (Gtk::WindowPosition pos, unsigned int show_for_msecs = 0, + bool delete_on_hide = false); + virtual ~PopUp (); + void touch (); + void remove (); + void set_text (std::string); + void set_name (std::string); + gint button_click (GdkEventButton *); + + bool on_delete_event (GdkEventAny* ); + +protected: + void on_realize (); + +private: + Gtk::Label label; + std::string my_text; + gint timeout; + static gint remove_prompt_timeout (void *); + bool delete_on_hide; + unsigned int popdown_time; +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/widgets/prompter.h b/libs/widgets/widgets/prompter.h new file mode 100644 index 0000000000..064a9e4b29 --- /dev/null +++ b/libs/widgets/widgets/prompter.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 1999 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_PROMPTER_H_ +#define _WIDGETS_PROMPTER_H_ + +#include +#include +#include +#include +#include +#include + +#include "widgets/visibility.h" + +namespace Gtk { + class Window; +} + +namespace ArdourWidgets { + +class LIBWIDGETS_API Prompter : public Gtk::Dialog +{ +public: + Prompter (bool modal = false); + Prompter (Gtk::Window& parent, bool modal = false); + ~Prompter () {}; + + void set_prompt (std::string prompt) { + entryLabel.set_label (prompt); + } + + void set_initial_text (std::string txt) { + entry.set_text (txt); + entry.select_region (0, entry.get_text_length()); + } + + void change_labels (std::string ok, std::string cancel); + + void get_result (std::string &str, bool strip=true); + +protected: + Gtk::Entry& the_entry() { return entry; } + + void on_entry_changed (); + void on_show (); + +private: + Gtk::Entry entry; + Gtk::HBox entryBox; + Gtk::Label entryLabel; + bool first_show; + bool can_accept_from_entry; + + void init (); + void entry_activated (); +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/widgets/scroomer.h b/libs/widgets/widgets/scroomer.h new file mode 100644 index 0000000000..c4c3cd3ade --- /dev/null +++ b/libs/widgets/widgets/scroomer.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2008 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_SCROOMER_H_ +#define _WIDGETS_SCROOMER_H_ + +#include +#include +#include + +#include "widgets/visibility.h" + +namespace ArdourWidgets { + +class LIBWIDGETS_API Scroomer : public Gtk::DrawingArea +{ +public: + enum Component { + TopBase = 0, + Handle1 = 1, + Slider = 2, + Handle2 = 3, + BottomBase = 4, + Total = 5, + None = 6 + }; + + Scroomer(Gtk::Adjustment& adjustment); + ~Scroomer(); + + bool on_motion_notify_event (GdkEventMotion*); + bool on_button_press_event (GdkEventButton*); + bool on_button_release_event (GdkEventButton*); + bool on_scroll_event (GdkEventScroll*); + virtual void on_size_allocate (Gtk::Allocation&); + + void set_comp_rect(GdkRectangle&, Component) const; + + Component point_in(double point) const; + + void set_min_page_size(double page_size); + int get_handle_size() { return handle_size; } + + inline int position_of(Component comp) { return position[comp]; } + + sigc::signal0 DragStarting; + sigc::signal0 DragFinishing; + + sigc::signal0 DoubleClicked; + +protected: + Gtk::Adjustment& adj; + +private: + struct UpdateRect { + GdkRectangle rect; + Component first_comp; + }; + + void update(); + void adjustment_changed (); + + int position[6]; + int old_pos[6]; + int handle_size; + double min_page_size; + GdkWindow* grab_window; + Component grab_comp; + double grab_y; + double unzoomed_val; + double unzoomed_page; + bool pinch; +}; + +} /* end namespace */ + +#endif diff --git a/libs/widgets/widgets/slider_controller.h b/libs/widgets/widgets/slider_controller.h index e80e76d7bc..f8414ce4b4 100644 --- a/libs/widgets/widgets/slider_controller.h +++ b/libs/widgets/widgets/slider_controller.h @@ -26,10 +26,8 @@ #include #include -#include "gtkmm2ext/popup.h" -#include "gtkmm2ext/binding_proxy.h" - #include "widgets/ardour_fader.h" +#include "widgets/binding_proxy.h" #include "widgets/visibility.h" namespace PBD { diff --git a/libs/widgets/widgets/stateful_button.h b/libs/widgets/widgets/stateful_button.h new file mode 100644 index 0000000000..6bbbf6f7f0 --- /dev/null +++ b/libs/widgets/widgets/stateful_button.h @@ -0,0 +1,95 @@ +/* + Copyright (C) 2005 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_STATEFUL_BUTTON_H_ +#define _WIDGETS_STATEFUL_BUTTON_H_ + +#include + +#include + +#include "widgets/visibility.h" + +namespace ArdourWidgets { + +class LIBWIDGETS_API StateButton +{ +public: + StateButton(); + virtual ~StateButton() {} + + void set_visual_state (int); + int get_visual_state () { return visual_state; } + void set_self_managed (bool yn) { _self_managed = yn; } + virtual void set_widget_name (const std::string& name) = 0; + +protected: + int visual_state; + bool _self_managed; + bool _is_realized; + bool style_changing; + Gtk::StateType state_before_prelight; + bool is_toggle; + + virtual std::string get_widget_name() const = 0; + virtual Gtk::Widget* get_child_widget () = 0; + + void avoid_prelight_on_style_changed (const Glib::RefPtr& style, GtkWidget* widget); + void avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget); +}; + + +class LIBWIDGETS_API StatefulToggleButton : public StateButton, public Gtk::ToggleButton +{ +public: + StatefulToggleButton(); + explicit StatefulToggleButton(const std::string &label); + ~StatefulToggleButton() {} + void set_widget_name (const std::string& name); + +protected: + void on_realize (); + void on_toggled (); + void on_style_changed (const Glib::RefPtr& style); + void on_state_changed (Gtk::StateType old_state); + + Gtk::Widget* get_child_widget (); + std::string get_widget_name() const { return get_name(); } +}; + +class LIBWIDGETS_API StatefulButton : public StateButton, public Gtk::Button +{ +public: + StatefulButton(); + explicit StatefulButton(const std::string &label); + virtual ~StatefulButton() {} + void set_widget_name (const std::string& name); + +protected: + void on_realize (); + void on_style_changed (const Glib::RefPtr& style); + void on_state_changed (Gtk::StateType old_state); + + Gtk::Widget* get_child_widget (); + std::string get_widget_name() const { return get_name(); } +}; + +} /* end namespace */ + +#endif diff --git a/libs/widgets/widgets/tabbable.h b/libs/widgets/widgets/tabbable.h new file mode 100644 index 0000000000..cb4cb1eaa9 --- /dev/null +++ b/libs/widgets/widgets/tabbable.h @@ -0,0 +1,102 @@ +/* + Copyright (C) 2015 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_TABBABLE_H_ +#define _WIDGETS_TABBABLE_H_ + +#include +#include +#include +#include +#include +#include + +#include "gtkmm2ext/window_proxy.h" +#include "widgets/visibility.h" + +namespace Gtk { + class Window; + class Notebook; +} + +namespace Gtkmm2ext { + class VisibilityTracker; +} + +namespace ArdourWidgets { + +class LIBWIDGETS_API Tabbable : public Gtkmm2ext::WindowProxy +{ +public: + Tabbable (Gtk::Widget&, const std::string&, bool tabbed_by_default = true); + ~Tabbable (); + + void add_to_notebook (Gtk::Notebook& notebook, const std::string& tab_title); + void make_visible (); + void make_invisible (); + void change_visibility (); + void attach (); + void detach (); + + Gtk::Widget& contents() const { return _contents; } + + Gtk::Window* get (bool create = false); + Gtk::Window* own_window () { return get (false); } + virtual Gtk::Window* use_own_window (bool and_pack_it); + + void set_default_tabbed (bool yn); + + virtual void show_window (); + + bool window_visible () const; + bool tabbed() const; + bool tabbed_by_default () const; + + Gtk::Window* current_toplevel () const; + + Gtk::Notebook* tab_root_drop (); + + int set_state (const XMLNode&, int version); + XMLNode& get_state (); + + static std::string xml_node_name(); + + sigc::signal1 StateChange; + +protected: + bool delete_event_handler (GdkEventAny *ev); + +private: + Gtk::Widget& _contents; + Gtk::Notebook _own_notebook; + Gtk::Notebook* _parent_notebook; + std::string _tab_title; + bool tab_requested_by_state; + + void show_tab (); + void hide_tab (); + bool tab_close_clicked (GdkEventButton*); + void show_own_window (bool and_pack_it); + void window_mapped (); + void window_unmapped (); +}; + +} /* end namespace */ + +#endif diff --git a/libs/widgets/widgets/tearoff.h b/libs/widgets/widgets/tearoff.h new file mode 100644 index 0000000000..6b4dc77634 --- /dev/null +++ b/libs/widgets/widgets/tearoff.h @@ -0,0 +1,92 @@ +/* + Copyright (C) 2003 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _WIDGETS_TEAROFF_H_ +#define _WIDGETS_TEAROFF_H_ + +#include +#include +#include +#include + +#include "widgets/visibility.h" + +class XMLNode; + +namespace ArdourWidgets { + +class LIBWIDGETS_API TearOff : public Gtk::HBox +{ +public: + TearOff (Gtk::Widget& contents, bool allow_resize = false); + virtual ~TearOff (); + + void set_visible (bool yn, bool force = false); + void set_can_be_torn_off (bool); + bool can_be_torn_off () const { return _can_be_torn_off; } + bool visible () const { return _visible; } + + sigc::signal Detach; + sigc::signal Attach; + sigc::signal Visible; + sigc::signal Hidden; + + Gtk::Window& tearoff_window() { return own_window; } + bool torn_off() const; + void tear_it_off (); + void put_it_back (); + void hide_visible (); + + void set_state (const XMLNode&); + void add_state (XMLNode&) const; + +private: + Gtk::Widget& contents; + Gtk::Window own_window; + Gtk::Arrow tearoff_arrow; + Gtk::Arrow close_arrow; + Gtk::HBox window_box; + Gtk::EventBox tearoff_event_box; + Gtk::EventBox close_event_box; + double drag_x; + double drag_y; + bool dragging; + bool _visible; + bool _torn; + bool _can_be_torn_off; + int own_window_width; + int own_window_height; + int own_window_xpos; + int own_window_ypos; + + gint tearoff_click (GdkEventButton*); + gint close_click (GdkEventButton*); + + gint window_motion (GdkEventMotion*); + gint window_button_press (GdkEventButton*); + gint window_button_release (GdkEventButton*); + gint window_delete_event (GdkEventAny*); + + void own_window_realized (); + bool own_window_configured (GdkEventConfigure*); +}; + +} /* namespace */ + +#endif diff --git a/libs/widgets/wscript b/libs/widgets/wscript index dd2ee9587b..cf274e418c 100644 --- a/libs/widgets/wscript +++ b/libs/widgets/wscript @@ -30,16 +30,28 @@ widgets_sources = [ 'ardour_display.cc', 'ardour_dropdown.cc', 'ardour_fader.cc', + 'ardour_icon.cc', 'ardour_knob.cc', 'ardour_spacer.cc', 'ardour_spinner.cc', 'auto_spin.cc', 'barcontroller.cc', + 'binding_proxy.cc', + 'eventboxext.cc', + 'choice.cc', 'click_box.cc', 'fastmeter.cc', 'focus_entry.cc', + 'pane.cc', + 'paths_dialog.cc', + 'popup.cc', + 'prompter.cc', + 'scroomer.cc', 'searchbar.cc', 'slider_controller.cc', + 'stateful_button.cc', + 'tabbable.cc', + 'tearoff.cc', 'tooltips.cc', 'ui_config.cc', ] -- cgit v1.2.3