#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"
#include <gtkmm/eventbox.h>
#include <gtkmm/menu.h>
#include <gtkmm/menuitem.h>
+#include <gtkmm/messagedialog.h>
+#include <gtkmm/notebook.h>
#include <gtkmm/button.h>
#include <gtkmm/togglebutton.h>
#include <gtkmm/treeview.h>
class ProgressBar;
}
-namespace Gtkmm2ext {
+namespace ArdourWidgets {
class Tabbable;
}
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 ();
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())) {
#include <gtkmm/accelmap.h>
#include <gtk/gtk.h>
+#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"
#include <gtkmm/menuitem.h>
#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"
#include "canvas/text.h"
#include "widgets/ardour_spacer.h"
+#include "widgets/eventboxext.h"
#include "widgets/tooltips.h"
#include "control_protocol/control_protocol.h"
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);
#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/dndtreeview.h"
-#include "gtkmm2ext/pane.h"
#include "pbd/stateful.h"
#include "pbd/signals.h"
#include "widgets/ardour_button.h"
#include "widgets/ardour_dropdown.h"
+#include "widgets/pane.h"
#include "ardour_dialog.h"
#include "public_editor.h"
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;
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");
}
#include "pbd/shortpath.h"
#include "pbd/stateful_diff_command.h"
-#include <gtkmm2ext/choice.h>
+#include "widgets/choice.h"
#include "ardour/audio_track.h"
#include "ardour/audiofilesource.h"
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)),
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
#include "pbd/gstdio_compat.h"
-#include "gtkmm2ext/choice.h"
-
#include "pbd/pthread_utils.h"
#include "ardour/audio_track.h"
#include "pbd/whitespace.h"
#include "pbd/stateful_diff_command.h"
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/choice.h>
-#include <gtkmm2ext/popup.h>
+#include "gtkmm2ext/utils.h"
+
+#include "widgets/choice.h"
+#include "widgets/popup.h"
#include "ardour/audio_track.h"
#include "ardour/audioregion.h"
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 ();
#include "pbd/shortpath.h"
#include "pbd/stateful_diff_command.h"
-#include <gtkmm2ext/choice.h>
-
#include "ardour/audio_track.h"
#include "ardour/audiofilesource.h"
#include "ardour/audioregion.h"
#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"
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;
#include <gtkmm/liststore.h>
-#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"
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);
#include <vector>
#include <string>
+#include <gtkmm/box.h>
+#include <gtkmm/button.h>
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/comboboxtext.h>
#include <gtkmm/checkbutton.h>
+#include <gtkmm/expander.h>
+#include <gtkmm/notebook.h>
#include <gtkmm/spinbutton.h>
-#include <gtkmm/comboboxtext.h>
#include <gtkmm/table.h>
-#include <gtkmm/expander.h>
-#include <gtkmm/box.h>
-#include <gtkmm/buttonbox.h>
-#include <gtkmm/button.h>
#include "pbd/signals.h"
#include "pbd/enumwriter.h"
-#include "gtkmm2ext/ardour_icon.h"
+#include "widgets/ardour_icon.h"
#include "audio_clock.h"
#include "editing.h"
using namespace PBD;
using namespace ARDOUR;
using namespace Editing;
-using namespace Gtkmm2ext;
+using namespace ArdourWidgets;
void
setup_gtk_ardour_enums ()
#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"
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;
#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"
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);
#include <gtkmm/box.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/label.h>
+#include <gtkmm/textview.h>
#include <gtkmm/window.h>
#include "pbd/signals.h"
#include "ardour/filesystem_paths.h"
#include <gtkmm/main.h>
+#include <gtkmm/stock.h>
+
#include <gtkmm2ext/application.h>
-#include <gtkmm2ext/popup.h>
#include <gtkmm2ext/utils.h>
#include "ardour_ui.h"
#include "gtkmm/radiobutton.h"
#include "gtkmm/label.h"
-#include "gtkmm2ext/stateful_button.h"
+#include "widgets/stateful_button.h"
#include "ardour/types.h"
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
#include "midi_scroomer.h"
#include "ui_config.h"
-using namespace Gtkmm2ext;
using namespace Gtk;
using namespace std;
//std::map<int, Glib::RefPtr<Gdk::Pixmap> > MidiScroomer::piano_pixmaps;
MidiScroomer::MidiScroomer(Adjustment& adj)
- : Gtkmm2ext::Scroomer(adj)
+ : ArdourWidgets::Scroomer(adj)
{
adj.set_lower(0);
#ifndef __ardour_midi_scroomer_h__
#define __ardour_midi_scroomer_h__
-#include <gtkmm2ext/scroomer.h>
-#include <gdkmm/pixbuf.h>
+#include "widgets/scroomer.h"
-class MidiScroomer : public Gtkmm2ext::Scroomer
+class MidiScroomer : public ArdourWidgets::Scroomer
{
public:
MidiScroomer(Gtk::Adjustment&);
#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"
#include "pbd/stacktrace.h"
#include "pbd/unwind.h"
-#include <glibmm/threads.h>
-
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/keyboard.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/tearoff.h>
-#include <gtkmm2ext/window_title.h>
-#include <gtkmm2ext/doi.h>
-
#include "ardour/amp.h"
#include "ardour/debug.h"
#include "ardour/audio_track.h"
#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"
#include <gtkmm/frame.h>
#include <gtkmm/menu.h>
#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
#include <gtkmm/liststore.h>
#include "pbd/stateful.h"
#include <gtkmm2ext/bindings.h>
#include "gtkmm2ext/dndtreeview.h"
-#include <gtkmm2ext/pane.h>
-#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"
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();
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;
Gtk::Label vca_label;
Gtk::EventBox vca_scroller_base;
Gtk::HBox out_packer;
- Gtkmm2ext::HPane list_hpane;
+ ArdourWidgets::HPane list_hpane;
MixerGroupTabs* _group_tabs;
#include "pbd/error.h"
#include "pbd/replace_all.h"
-#include "gtkmm2ext/tearoff.h"
#include "gtkmm2ext/actions.h"
#include "gtkmm2ext/utils.h"
#include <gtkmm/menu.h>
#include <gtkmm/menuitem.h>
+#include "widgets/tearoff.h"
#include "widgets/tooltips.h"
#include "ardour/amp.h"
#include "processor_box.h"
#include "processor_selection.h"
-namespace Gtkmm2ext {
+namespace ArdourWidgets {
class TearOff;
}
void set_session (ARDOUR::Session*);
- Gtkmm2ext::TearOff& tearoff() const { return *_tearoff; }
+ ArdourWidgets::TearOff& tearoff() const { return *_tearoff; }
std::string state_id() const;
private:
Gtk::HBox hpacker;
Gtk::VBox vpacker;
- Gtkmm2ext::TearOff* _tearoff;
+ ArdourWidgets::TearOff* _tearoff;
Gtk::HBox channel_table_packer;
Gtk::HBox table_hpacker;
#include <boost/shared_ptr.hpp>
-#include "gtkmm2ext/binding_proxy.h"
+#include "widgets/binding_proxy.h"
#include "panner_interface.h"
double accumulated_delta;
bool detented;
- BindingProxy position_binder;
+ ArdourWidgets::BindingProxy position_binder;
void set_tooltip ();
#include <algorithm>
-#include <gtkmm/table.h>
-#include <gtkmm/stock.h>
#include <gtkmm/button.h>
+#include <gtkmm/comboboxtext.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/messagedialog.h>
#include <gtkmm/notebook.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
#include "gtkmm2ext/utils.h"
#include "pbd/convert.h"
#include <gtkmm/dialog.h>
#include <gtkmm/notebook.h>
#include <gtkmm/treeview.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/liststore.h>
+
#include "gtkmm2ext/dndtreeview.h"
#include "ardour/plugin.h"
#include <gtkmm/frame.h>
#include <gtkmm/label.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
#include "plugin_setup_dialog.h"
#include "pbd/i18n.h"
#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"
boost::shared_ptr<ARDOUR::PortInsert> _pi;
Gtk::Notebook notebook;
- Gtkmm2ext::StatefulToggleButton latency_button;
+ ArdourWidgets::StatefulToggleButton latency_button;
IOSelector input_selector;
IOSelector output_selector;
Gtk::Label latency_display;
#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"
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);
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);
#include "prompter.h"
ArdourPrompter::ArdourPrompter (bool modal)
- : Gtkmm2ext::Prompter (modal)
+ : ArdourWidgets::Prompter (modal)
{
}
#ifndef __ardour_gtk_prompter_h__
#define __ardour_gtk_prompter_h__
-#include <gtkmm2ext/prompter.h>
+#include "widgets/prompter.h"
-class ArdourPrompter : public Gtkmm2ext::Prompter
+class ArdourPrompter : public ArdourWidgets::Prompter
{
public:
ArdourPrompter (bool modal = false);
#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"
* 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);
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/gtk_ui.h"
-#include "gtkmm2ext/paths_dialog.h"
#include "gtkmm2ext/window_title.h"
#include "pbd/fpu.h"
#include "control_protocol/control_protocol.h"
#include "canvas/wave_view.h"
+
+#include "widgets/paths_dialog.h"
#include "widgets/tooltips.h"
#include "ardour_dialog.h"
void RCOptionEditor::edit_lxvst_path () {
Glib::RefPtr<Gdk::Window> 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()
}
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()
#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"
*/
/** 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 ();
#include "ardour/ardour.h"
-#include <gtkmm2ext/pane.h>
+#include <widgets/pane.h>
#include "ardour_window.h"
#include "processor_box.h"
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;
#include <boost/algorithm/string.hpp>
#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"
}
//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;
}
//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;
}
//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()) {
#include <glibmm/datetime.h>
#include <gtkmm/filechooser.h>
+#include <gtkmm/stock.h>
#include "pbd/basename.h"
#include "pbd/failed_constructor.h"
#include <gtkmm/drawingarea.h>
-#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;
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();
#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 {
double accumulated_delta;
bool detented;
- BindingProxy position_binder;
- BindingProxy width_binder;
+ ArdourWidgets::BindingProxy position_binder;
+ ArdourWidgets::BindingProxy width_binder;
void set_tooltip ();
#include <gtkmm/table.h>
#include <gtkmm/label.h>
+#include <gtkmm/progressbar.h>
#include <gtkmm/stock.h>
#include "ardour/audioregion.h"
/* ***************************************************************************/
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<Gtk::Action> act;
}
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);
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);
+++ /dev/null
-/*
- Copyright (C) 2009 Paul Davis
- Copyright (C) 2015 Robin Gareus <robin@gareus.org>
-
- 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 <math.h> // M_PI
-#include <assert.h>
-#include <algorithm> // 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
+++ /dev/null
-/*
- 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 <string>
-#include <climits>
-#include <iostream>
-
-#include <pbd/controllable.h>
-
-#include <gtkmm2ext/binding_proxy.h>
-#include <gtkmm2ext/keyboard.h>
-
-#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<Controllable> c)
- : prompter (0),
- controllable (c)
-{
-}
-
-BindingProxy::BindingProxy ()
- : prompter (0)
-{
-}
-
-BindingProxy::~BindingProxy ()
-{
- if (prompter) {
- delete prompter;
- }
-}
-
-void
-BindingProxy::set_controllable (boost::shared_ptr<Controllable> 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;
-}
-
+++ /dev/null
-/*
- 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 <gtkmm/label.h>
-#include <gtkmm2ext/choice.h>
-
-using namespace std;
-using namespace Gtkmm2ext;
-using namespace sigc;
-using namespace Gtk;
-
-Choice::Choice (string title, string prompt, vector<string> choices, bool center)
- : Dialog (title)
-{
- int n;
- vector<string>::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 ()
-{
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
- *
- * 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 ()
-{
-}
#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"
}
}
-#define OLD_STYLE_ERRORS 1
-
void
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:
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 */
+++ /dev/null
-#ifndef _gtkmm2ext_ardour_icon_h_
-#define _gtkmm2ext_ardour_icon_h_
-
-#include <stdint.h>
-#include <cairo.h>
-#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
+++ /dev/null
-/*
- 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 <string>
-#include <boost/shared_ptr.hpp>
-
-#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<PBD::Controllable>);
- 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<PBD::Controllable> get_controllable() const { return controllable; }
- void set_controllable (boost::shared_ptr<PBD::Controllable>);
-
- protected:
- Gtkmm2ext::PopUp* prompter;
- boost::shared_ptr<PBD::Controllable> controllable;
-
- static guint bind_button;
- static guint bind_statemask;
-
- PBD::ScopedConnection learning_connection;
- void learning_finished ();
- bool prompter_hiding (GdkEventAny *);
-};
-
-#endif
+++ /dev/null
-/*
- 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 <gtkmm/dialog.h>
-#include <gtkmm/image.h>
-#include <gtkmm/stock.h>
-#include <gtkmm/box.h>
-#include <string>
-#include <vector>
-
-#include "gtkmm2ext/visibility.h"
-
-namespace Gtkmm2ext {
-
-class LIBGTKMM2EXT_API Choice : public Gtk::Dialog
-{
- public:
- Choice (std::string title, std::string prompt, std::vector<std::string> choices, bool center = true);
- virtual ~Choice ();
-
- protected:
- void on_realize ();
-};
-
-} /* namespace */
-
-#endif // __pbd_gtkmm_choice_h__
+++ /dev/null
-/*
- * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
- *
- * 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 <gtkmm/eventbox.h>
-
-#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
+++ /dev/null
-/*
- 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 <vector>
-#include <algorithm>
-#include <boost/shared_ptr.hpp>
-
-#include <stdint.h>
-
-#include <gdkmm/cursor.h>
-#include <gtkmm/container.h>
-#include <gtkmm/eventbox.h>
-
-#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<boost::shared_ptr<Child> > Children;
-
- Pane (bool horizontal);
- ~Pane();
-
- void set_divider (std::vector<float>::size_type divider, float fract);
- float get_divider (std::vector<float>::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<Divider*> 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__ */
+++ /dev/null
-/*
- Copyright (C) 2014 Robin Gareus <robin@gareus.org>
-
- 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 <string>
-#include <vector>
-#include <gtkmm.h>
-
-#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__ */
+++ /dev/null
-/*
- 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 <string>
-#include <gtkmm.h>
-
-#include <pbd/touchable.h>
-
-#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__
+++ /dev/null
-/*
- 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 <string>
-#include <gtkmm/box.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/label.h>
-#include <gtkmm/dialog.h>
-#include <sigc++/sigc++.h>
-
-#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__ */
+++ /dev/null
-/*
- 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 <gtkmm/drawingarea.h>
-#include <gtkmm/adjustment.h>
-#include <gdkmm.h>
-
-#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<void> DragStarting;
- sigc::signal0<void> DragFinishing;
-
- sigc::signal0<void> 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__ */
+++ /dev/null
-/*
- 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 <vector>
-
-#include <gtkmm/togglebutton.h>
-
-#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<Gtk::Style>& 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<Gtk::Style>& 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<Gtk::Style>& style);
- void on_state_changed (Gtk::StateType old_state);
-
- Gtk::Widget* get_child_widget ();
- std::string get_widget_name() const { return get_name(); }
-};
-
-};
-
-#endif
+++ /dev/null
-/*
- 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 <gtkmm/bin.h>
-#include <gtkmm/box.h>
-#include <gtkmm/button.h>
-#include <gtkmm/image.h>
-#include <gtkmm/label.h>
-#include <gtkmm/notebook.h>
-
-#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<void,Tabbable&> 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
+++ /dev/null
-/*
- 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 <gtkmm/window.h>
-#include <gtkmm/arrow.h>
-#include <gtkmm/box.h>
-#include <gtkmm/eventbox.h>
-
-#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<void> Detach;
- sigc::signal<void> Attach;
- sigc::signal<void> Visible;
- sigc::signal<void> 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__
+++ /dev/null
-/*
- 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 <assert.h>
-#include <gdkmm/cursor.h>
-#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<Child> (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<Child*> (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<Cairo::Context> 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;
-}
+++ /dev/null
-/*
- Copyright (C) 2014 Robin Gareus <robin@gareus.org>
-
- 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 <cstdio>
-
-#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 <std::string> a = PBD::parse_path(current_paths);
- for(vector<std::string>::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<int> 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<int> 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<int> 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<Gtk::TreeModel> reftm = paths_list_view.get_model();
- Glib::RefPtr<Gtk::TreeStore> refStore = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(reftm);
- if(refStore) {
- refStore->erase(row_it);
- return;
- }
- Glib::RefPtr<Gtk::ListStore> refLStore = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(reftm);
- if(refLStore){
- refLStore->erase(row_it);
- return;
- }
-}
-
-void
-PathsDialog::set_default() {
-
- paths_list_view.clear_items();
- std::vector <std::string> a = PBD::parse_path(_default_paths);
- for(vector<std::string>::const_iterator i = a.begin(); i != a.end(); ++i) {
- paths_list_view.append_text(*i);
- }
-}
+++ /dev/null
-/*
- 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 <iostream>
-
-#include <gtkmm2ext/popup.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/gtk_ui.h>
-
-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<PopUp*> (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;
-}
+++ /dev/null
-/*
- 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 <string>
-
-#include <pbd/whitespace.h>
-
-#include <gtkmm/stock.h>
-#include <gtkmm2ext/prompter.h>
-
-#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<Gtk::Label*>(ok.get_child())->set_text (okstr);
- // dynamic_cast<Gtk::Label*>(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);
- }
-}
+++ /dev/null
-/*
- 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 <iostream>
-
-#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<Gdk::Window> 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);
- }
-}
-
+++ /dev/null
-/*
- 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 <string>
-#include <iostream>
-
-
-#include <gtkmm/main.h>
-
-#include <gtkmm2ext/stateful_button.h>
-
-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<Gtk::Style>& /* 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<Gtk::Style>& 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<Gtk::Style>& 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);
- }
-}
+++ /dev/null
-/*
- 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 <gtkmm/action.h>
-#include <gtkmm/notebook.h>
-#include <gtkmm/window.h>
-#include <gtkmm/stock.h>
-
-#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<Gtk::Window*> (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);
-}
+++ /dev/null
-/*
- 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 <cmath>
-#include <iostream>
-
-#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<Gdk::Window> 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<Gdk::Window> 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<const Gdk::Window> 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 ();
-}
-
-
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',
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 += [
#include <algorithm>
#include <pangomm/layout.h>
+#include <gtkmm/toggleaction.h>
#include "pbd/compose.h"
#include "pbd/controllable.h"
: _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))
: _sizing_text("")
, _markup (false)
, _elements (e)
- , _icon (Gtkmm2ext::ArdourIcon::NoIcon)
+ , _icon (ArdourIcon::NoIcon)
, _tweaks (Tweaks (0))
, _char_pixel_width (0)
, _char_pixel_height (0)
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);
}
void
-ArdourButton::set_icon (Gtkmm2ext::ArdourIcon::Icon i)
+ArdourButton::set_icon (ArdourIcon::Icon i)
{
_icon = i;
_icon_render_cb = 0;
--- /dev/null
+/*
+ Copyright (C) 2009 Paul Davis
+ Copyright (C) 2015 Robin Gareus <robin@gareus.org>
+
+ 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 <math.h> // M_PI
+#include <assert.h>
+#include <algorithm> // 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
--- /dev/null
+/*
+ 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 <string>
+#include <climits>
+#include <iostream>
+
+#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<Controllable> c)
+ : prompter (0),
+ controllable (c)
+{
+}
+
+BindingProxy::BindingProxy ()
+ : prompter (0)
+{
+}
+
+BindingProxy::~BindingProxy ()
+{
+ if (prompter) {
+ delete prompter;
+ }
+}
+
+void
+BindingProxy::set_controllable (boost::shared_ptr<Controllable> 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;
+}
--- /dev/null
+/*
+ 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 <gtkmm/label.h>
+#include <widgets/choice.h>
+
+using namespace std;
+using namespace sigc;
+using namespace Gtk;
+using namespace ArdourWidgets;
+
+Choice::Choice (string title, string prompt, vector<string> choices, bool center)
+ : Dialog (title)
+{
+ int n;
+ vector<string>::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 ()
+{
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
+ *
+ * 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 ()
+{
+}
--- /dev/null
+/*
+ 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 <assert.h>
+#include <gdkmm/cursor.h>
+
+#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<Child> (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<Child*> (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<Cairo::Context> 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;
+}
--- /dev/null
+/*
+ Copyright (C) 2014 Robin Gareus <robin@gareus.org>
+
+ 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 <cstdio>
+
+#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 <std::string> a = PBD::parse_path(current_paths);
+ for(vector<std::string>::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<int> 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<int> 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<int> 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<Gtk::TreeModel> reftm = paths_list_view.get_model();
+ Glib::RefPtr<Gtk::TreeStore> refStore = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(reftm);
+ if(refStore) {
+ refStore->erase(row_it);
+ return;
+ }
+ Glib::RefPtr<Gtk::ListStore> refLStore = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(reftm);
+ if(refLStore){
+ refLStore->erase(row_it);
+ return;
+ }
+}
+
+void
+PathsDialog::set_default() {
+
+ paths_list_view.clear_items();
+ std::vector <std::string> a = PBD::parse_path(_default_paths);
+ for(vector<std::string>::const_iterator i = a.begin(); i != a.end(); ++i) {
+ paths_list_view.append_text(*i);
+ }
+}
--- /dev/null
+/*
+ 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 <iostream>
+
+#include <gtkmm2ext/gtk_ui.h>
+#include <gtkmm2ext/utils.h>
+
+#include <widgets/popup.h>
+
+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<PopUp*> (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;
+}
--- /dev/null
+/*
+ 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 <string>
+#include <gtkmm/stock.h>
+
+#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<Gtk::Label*>(ok.get_child())->set_text (okstr);
+ // dynamic_cast<Gtk::Label*>(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);
+ }
+}
--- /dev/null
+/*
+ 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 <iostream>
+
+#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<Gdk::Window> 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);
+ }
+}
+
--- /dev/null
+/*
+ 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 <string>
+#include <iostream>
+
+
+#include <gtkmm/main.h>
+
+#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<Gtk::Style>& /* 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<Gtk::Style>& 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<Gtk::Style>& 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);
+ }
+}
--- /dev/null
+/*
+ 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 <gtkmm/action.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/window.h>
+#include <gtkmm/stock.h>
+
+#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<Gtk::Window*> (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);
+}
--- /dev/null
+/*
+ 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 <cmath>
+#include <iostream>
+
+#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<Gdk::Window> 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<Gdk::Window> 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<const Gdk::Window> 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 ();
+}
#include <gtkmm/action.h>
#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 {
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);
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;
--- /dev/null
+#ifndef _WIDGETS_ARDOUR_ICON_H_
+#define _WIDGETS_ARDOUR_ICON_H_
+
+#include <stdint.h>
+#include <cairo.h>
+
+#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
#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 {
#include <gtkmm/alignment.h>
#include <cairo.h>
-#include "gtkmm2ext/binding_proxy.h"
+#include "widgets/binding_proxy.h"
#include "widgets/slider_controller.h"
#include "widgets/visibility.h"
--- /dev/null
+/*
+ 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 <string>
+#include <boost/shared_ptr.hpp>
+
+#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<PBD::Controllable>);
+ 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<PBD::Controllable> get_controllable() const { return controllable; }
+ void set_controllable (boost::shared_ptr<PBD::Controllable>);
+
+protected:
+ ArdourWidgets::PopUp* prompter;
+ boost::shared_ptr<PBD::Controllable> controllable;
+
+ static guint bind_button;
+ static guint bind_statemask;
+
+ PBD::ScopedConnection learning_connection;
+ void learning_finished ();
+ bool prompter_hiding (GdkEventAny *);
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ 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 <string>
+#include <vector>
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/image.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/box.h>
+
+#include "widgets/visibility.h"
+
+namespace ArdourWidgets {
+
+class LIBWIDGETS_API Choice : public Gtk::Dialog
+{
+public:
+ Choice (std::string title, std::string prompt, std::vector<std::string> choices, bool center = true);
+ virtual ~Choice ();
+
+protected:
+ void on_realize ();
+};
+
+} /* namespace */
+
+#endif
#include <string>
#include <gtkmm.h>
-#include "gtkmm2ext/binding_proxy.h"
-
#include "widgets/auto_spin.h"
+#include "widgets/binding_proxy.h"
#include "widgets/visibility.h"
namespace PBD {
--- /dev/null
+/*
+ * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
+ *
+ * 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 <gtkmm/eventbox.h>
+
+#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
--- /dev/null
+/*
+ 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 <vector>
+#include <algorithm>
+#include <boost/shared_ptr.hpp>
+
+#include <stdint.h>
+
+#include <gdkmm/cursor.h>
+#include <gtkmm/container.h>
+#include <gtkmm/eventbox.h>
+
+#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<boost::shared_ptr<Child> > Children;
+
+ Pane (bool horizontal);
+ ~Pane();
+
+ void set_divider (std::vector<float>::size_type divider, float fract);
+ float get_divider (std::vector<float>::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<Divider*> 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
--- /dev/null
+/*
+ Copyright (C) 2014 Robin Gareus <robin@gareus.org>
+
+ 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 <string>
+#include <vector>
+#include <gtkmm.h>
+
+#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
--- /dev/null
+/*
+ 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 <string>
+#include <gtkmm.h>
+
+#include <pbd/touchable.h>
+
+#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
--- /dev/null
+/*
+ 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 <string>
+#include <gtkmm/box.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/label.h>
+#include <gtkmm/dialog.h>
+#include <sigc++/sigc++.h>
+
+#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
--- /dev/null
+/*
+ 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 <gdkmm.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/adjustment.h>
+
+#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<void> DragStarting;
+ sigc::signal0<void> DragFinishing;
+
+ sigc::signal0<void> 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
#include <gtkmm.h>
#include <boost/shared_ptr.hpp>
-#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 {
--- /dev/null
+/*
+ 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 <vector>
+
+#include <gtkmm/togglebutton.h>
+
+#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<Gtk::Style>& 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<Gtk::Style>& 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<Gtk::Style>& 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
--- /dev/null
+/*
+ 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 <gtkmm/bin.h>
+#include <gtkmm/box.h>
+#include <gtkmm/button.h>
+#include <gtkmm/image.h>
+#include <gtkmm/label.h>
+#include <gtkmm/notebook.h>
+
+#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<void,Tabbable&> 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
--- /dev/null
+/*
+ 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 <gtkmm/arrow.h>
+#include <gtkmm/box.h>
+#include <gtkmm/eventbox.h>
+#include <gtkmm/window.h>
+
+#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<void> Detach;
+ sigc::signal<void> Attach;
+ sigc::signal<void> Visible;
+ sigc::signal<void> 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
'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',
]