summaryrefslogtreecommitdiff
path: root/libs/gtkmm2ext
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gtkmm2ext')
-rw-r--r--libs/gtkmm2ext/MSVCgtkmm2ext/gtkmm2ext.vcproj8
-rw-r--r--libs/gtkmm2ext/actions.cc102
-rw-r--r--libs/gtkmm2ext/application.cc6
-rw-r--r--libs/gtkmm2ext/auto_spin.cc24
-rw-r--r--libs/gtkmm2ext/cairo_widget.cc97
-rw-r--r--libs/gtkmm2ext/click_box.cc7
-rwxr-xr-xlibs/gtkmm2ext/fader.cc448
-rw-r--r--libs/gtkmm2ext/gtk_ui.cc32
-rw-r--r--libs/gtkmm2ext/gtkapplication_quartz.mm15
-rw-r--r--libs/gtkmm2ext/gtkapplication_win32.c5
-rw-r--r--libs/gtkmm2ext/gtkapplication_x11.c5
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/actions.h6
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/application.h1
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/auto_spin.h1
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/click_box.h1
-rwxr-xr-xlibs/gtkmm2ext/gtkmm2ext/fader.h111
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/gtk_ui.h6
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/gtkapplication.h1
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h16
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/utils.h1
-rw-r--r--libs/gtkmm2ext/macosx/gtkmm2ext/gtkmm2ext.xcodeproj/project.pbxproj254
-rw-r--r--libs/gtkmm2ext/persistent_tooltip.cc51
-rw-r--r--libs/gtkmm2ext/utils.cc12
-rw-r--r--libs/gtkmm2ext/waves_fastmeter.cc909
-rw-r--r--libs/gtkmm2ext/wscript13
25 files changed, 2061 insertions, 71 deletions
diff --git a/libs/gtkmm2ext/MSVCgtkmm2ext/gtkmm2ext.vcproj b/libs/gtkmm2ext/MSVCgtkmm2ext/gtkmm2ext.vcproj
index 00513e6f11..0fe12e1304 100644
--- a/libs/gtkmm2ext/MSVCgtkmm2ext/gtkmm2ext.vcproj
+++ b/libs/gtkmm2ext/MSVCgtkmm2ext/gtkmm2ext.vcproj
@@ -342,6 +342,10 @@
>
</File>
<File
+ RelativePath="..\fader.cc"
+ >
+ </File>
+ <File
RelativePath="..\fastmeter.cc"
>
</File>
@@ -548,6 +552,10 @@
>
</File>
<File
+ RelativePath="..\gtkmm2ext\fader.h"
+ >
+ </File>
+ <File
RelativePath="..\gtkmm2ext\fastmeter.h"
>
</File>
diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc
index 666ac29c5c..60ca2f0910 100644
--- a/libs/gtkmm2ext/actions.cc
+++ b/libs/gtkmm2ext/actions.cc
@@ -139,11 +139,11 @@ ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key)
}
struct SortActionsByLabel {
- bool operator() (Glib::RefPtr<Gtk::Action> a, Glib::RefPtr<Gtk::Action> b) {
- ustring astr = a->get_accel_path();
- ustring bstr = b->get_accel_path();
- return astr < bstr;
- }
+ bool operator() (Glib::RefPtr<Gtk::Action> a, Glib::RefPtr<Gtk::Action> b) {
+ ustring astr = a->get_accel_path();
+ ustring bstr = b->get_accel_path();
+ return astr < bstr;
+ }
};
void
@@ -289,71 +289,63 @@ struct ActionState {
typedef std::vector<ActionState> ActionStates;
-static std::stack<boost::shared_ptr<ActionStates> > state_stack;
+static ActionStates action_states_to_restore;
+static bool actions_disabled = false;
-static boost::shared_ptr<ActionStates>
-get_action_state ()
+void
+ActionManager::save_action_states ()
{
- boost::shared_ptr<ActionStates> state = boost::shared_ptr<ActionStates>(new ActionStates);
-
/* the C++ API for functions used here appears to be broken in
gtkmm2.6, so we fall back to the C level.
*/
-
GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj());
GList* node;
GList* acts;
for (node = list; node; node = g_list_next (node)) {
-
+
GtkActionGroup* group = (GtkActionGroup*) node->data;
-
- /* first pass: collect them all */
-
- typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
- action_list the_acts;
-
+
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
GtkAction* action = (GtkAction*) acts->data;
-
- state->push_back (ActionState (action, gtk_action_get_sensitive (action)));
+ action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action)));
}
}
-
- return state;
}
void
-ActionManager::push_action_state ()
+ActionManager::enable_active_actions ()
{
- state_stack.push (get_action_state());
-}
-
-void
-ActionManager::pop_action_state ()
-{
- if (state_stack.empty()) {
- warning << string_compose (_("programming error: %1"), X_("ActionManager::pop_action_state called with empty stack")) << endmsg;
- return;
+ if (!actions_disabled) {
+ return ;
}
- boost::shared_ptr<ActionStates> as = state_stack.top ();
- state_stack.pop ();
-
- for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) {
- gtk_action_set_sensitive ((*i).action, (*i).sensitive);
+ for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) {
+ if ((*i).action && (*i).sensitive) {
+ gtk_action_set_sensitive ((*i).action, true);
+ }
}
+
+ action_states_to_restore.clear ();
+ actions_disabled = false;
}
void
-ActionManager::disable_all_actions ()
+ActionManager::disable_active_actions ()
{
- push_action_state ();
- boost::shared_ptr<ActionStates> as = state_stack.top ();
+ if (actions_disabled == true ) {
+ return ;
+ }
+ // save all action's states to action_states_to_restore
+ save_action_states ();
- for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) {
- gtk_action_set_sensitive ((*i).action, false);
+ // set all action's states disabled
+ for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) {
+ if ((*i).sensitive) {
+ gtk_action_set_sensitive ((*i).action, false);
+ }
}
+ actions_disabled = true;
}
void
@@ -464,8 +456,24 @@ ActionManager::get_action_from_name (const char* name)
void
ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
{
- for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) {
- (*i)->set_sensitive (state);
+ // if actions weren't disabled
+ if (!actions_disabled) {
+ for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) {
+ (*i)->set_sensitive (state);
+ }
+ }
+ else {
+ // actions were disabled
+ // so we should just set necessary action's states in action_states_to_restore
+ for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) {
+ // go through action_states_to_restore and set state of actions
+ for (ActionStates::iterator j = action_states_to_restore.begin(); j != action_states_to_restore.end(); ++j) {
+ // all actions should have their individual name, so we can use it for comparison
+ if (gtk_action_get_name ((*j).action) == (*i)->get_name ()) {
+ (*j).sensitive = state;
+ }
+ }
+ }
}
}
@@ -503,10 +511,10 @@ ActionManager::set_toggleaction_state (string n, bool s)
const char* action_name = last_slash + 1;
- RefPtr<Action> act = get_action (group_name, action_name);
+ RefPtr<Action> act = get_action (group_name, action_name);
if (act) {
- RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
- tact->set_active (s);
+ RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
+ tact->set_active (s);
} else {
error << string_compose (_("Unknown action name: %1"), name) << endmsg;
}
diff --git a/libs/gtkmm2ext/application.cc b/libs/gtkmm2ext/application.cc
index 54efb4773f..eb1cea1b5f 100644
--- a/libs/gtkmm2ext/application.cc
+++ b/libs/gtkmm2ext/application.cc
@@ -59,6 +59,12 @@ Application::ready ()
}
void
+Application::hide ()
+{
+ gtk_application_hide ();
+}
+
+void
Application::cleanup ()
{
gtk_application_cleanup ();
diff --git a/libs/gtkmm2ext/auto_spin.cc b/libs/gtkmm2ext/auto_spin.cc
index 0f4c371a09..2c70cb4293 100644
--- a/libs/gtkmm2ext/auto_spin.cc
+++ b/libs/gtkmm2ext/auto_spin.cc
@@ -143,6 +143,30 @@ AutoSpin::button_press (GdkEventButton *ev)
return TRUE;
}
+gint
+AutoSpin::scroll_event (GdkEventScroll *ev)
+{
+ stop_spinning (0);
+
+ gfloat increment = step_increment;
+
+ if (ev->state & Keyboard::TertiaryModifier) {
+ increment = page_increment;
+ }
+
+ switch (ev->direction) {
+ case GDK_SCROLL_DOWN:
+ case GDK_SCROLL_LEFT:
+ adjust_value (-increment);
+ break;
+ case GDK_SCROLL_RIGHT:
+ case GDK_SCROLL_UP:
+ adjust_value (increment);
+ break;
+ }
+ return TRUE;
+}
+
void
AutoSpin::start_spinning (bool decrement, bool page)
{
diff --git a/libs/gtkmm2ext/cairo_widget.cc b/libs/gtkmm2ext/cairo_widget.cc
index 2ffb2b47f3..aa8f883a7d 100644
--- a/libs/gtkmm2ext/cairo_widget.cc
+++ b/libs/gtkmm2ext/cairo_widget.cc
@@ -65,6 +65,99 @@ CairoWidget::on_button_press_event (GdkEventButton*)
return false;
}
+
+#ifdef USE_TRACKS_CODE_FEATURES
+
+/* This is Tracks version of this method.
+
+ The use of get_visible_window() in this method is an abuse of the GDK/GTK
+ semantics. It can and may break on different GDK backends, and uses a
+ side-effect/unintended behaviour in GDK/GTK to try to accomplish something
+ which should be done differently. I (Paul) have confirmed this with the GTK
+ development team.
+
+ For this reason, this code is not acceptable for ordinary merging into the Ardour libraries.
+
+ Ardour Developers: you are not obligated to maintain the internals of this
+ implementation in the face of build-time environment changes (e.g. -D
+ defines etc).
+*/
+
+bool
+CairoWidget::on_expose_event (GdkEventExpose *ev)
+{
+ cairo_rectangle_t expose_area;
+ expose_area.width = ev->area.width;
+ expose_area.height = ev->area.height;
+
+#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
+ Cairo::RefPtr<Cairo::Context> cr;
+ if (get_visible_window ()) {
+ expose_area.x = 0;
+ expose_area.y = 0;
+ if (!_image_surface) {
+ _image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
+ }
+ cr = Cairo::Context::create (_image_surface);
+ } else {
+ expose_area.x = ev->area.x;
+ expose_area.y = ev->area.y;
+ cr = get_window()->create_cairo_context ();
+ }
+#else
+ expose_area.x = ev->area.x;
+ expose_area.y = ev->area.y;
+ Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context ();
+#endif
+
+ cr->rectangle (expose_area.x, expose_area.y, expose_area.width, expose_area.height);
+ cr->clip ();
+
+ /* paint expose area the color of the parent window bg
+ */
+
+ if (get_visible_window ()) {
+ Gdk::Color bg (get_parent_bg());
+ cr->rectangle (expose_area.x, expose_area.y, expose_area.width, expose_area.height);
+ cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
+ cr->fill ();
+ }
+
+ render (cr->cobj(), &expose_area);
+
+#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
+ if(get_visible_window ()) {
+ _image_surface->flush();
+ /* now blit our private surface back to the GDK one */
+
+ Cairo::RefPtr<Cairo::Context> cairo_context = get_window()->create_cairo_context ();
+
+ cairo_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+ cairo_context->clip ();
+ cairo_context->set_source (_image_surface, ev->area.x, ev->area.y);
+ cairo_context->set_operator (Cairo::OPERATOR_OVER);
+ cairo_context->paint ();
+ }
+#endif
+
+ Gtk::Widget* child = get_child ();
+
+ if (child) {
+ propagate_expose (*child, ev);
+ }
+
+ return true;
+}
+
+#else
+
+/* Ardour mainline: not using Tracks code features.
+
+ Tracks Developers: please do not modify this version of
+ ::on_expose_event(). The version used by Tracks is before the preceding
+ #else and contains hacks required for the Tracks GUI to work.
+*/
+
bool
CairoWidget::on_expose_event (GdkEventExpose *ev)
{
@@ -126,10 +219,12 @@ CairoWidget::on_expose_event (GdkEventExpose *ev)
#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
}
#endif
-
+
return true;
}
+#endif
+
/** Marks the widget as dirty, so that render () will be called on
* the next GTK expose event.
*/
diff --git a/libs/gtkmm2ext/click_box.cc b/libs/gtkmm2ext/click_box.cc
index 63ab3db7ba..383fa6e583 100644
--- a/libs/gtkmm2ext/click_box.cc
+++ b/libs/gtkmm2ext/click_box.cc
@@ -63,6 +63,13 @@ ClickBox::button_press_handler (GdkEventButton* ev)
}
bool
+ClickBox::on_scroll_event (GdkEventScroll* ev)
+{
+ AutoSpin::scroll_event (ev);
+ return true;
+}
+
+bool
ClickBox::button_release_handler (GdkEventButton* ev)
{
switch (ev->button) {
diff --git a/libs/gtkmm2ext/fader.cc b/libs/gtkmm2ext/fader.cc
new file mode 100755
index 0000000000..0fedd33696
--- /dev/null
+++ b/libs/gtkmm2ext/fader.cc
@@ -0,0 +1,448 @@
+/*
+ Copyright (C) 2014 Waves Audio Ltd.
+
+ 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: fastmeter.h 570 2006-06-07 21:21:21Z sampo $
+*/
+
+
+#include <iostream>
+
+#include "pbd/stacktrace.h"
+
+#include "gtkmm2ext/fader.h"
+#include "gtkmm2ext/keyboard.h"
+#include "gtkmm2ext/rgb_macros.h"
+#include "gtkmm2ext/utils.h"
+#include "pbd/failed_constructor.h"
+#include "pbd/file_utils.h"
+#include "ardour/filesystem_paths.h"
+
+using namespace Gtkmm2ext;
+using namespace Gtk;
+using namespace std;
+
+#define CORNER_RADIUS 4
+#define CORNER_SIZE 2
+#define CORNER_OFFSET 1
+#define FADER_RESERVE 5
+
+
+static void get_closest_point_on_line(double xa, double ya, double xb, double yb, double xp, double yp, double& xl, double& yl )
+{
+ // Storing vector A->B
+ double a_to_b_x = xb - xa;
+ double a_to_b_y = yb - ya;
+
+ // Storing vector A->P
+ double a_to_p_x = xp - xa;
+ double a_to_p_y = yp - ya;
+
+
+ // Basically finding the squared magnitude
+ // of a_to_b
+ double atb2 = a_to_b_x * a_to_b_x + a_to_b_y * a_to_b_y;
+
+ // The dot product of a_to_p and a_to_b
+ double atp_dot_atb = a_to_p_x * a_to_b_x + a_to_p_y * a_to_b_y;
+
+ // The normalized "distance" from a to
+ // your closest point
+ double t = atp_dot_atb / atb2;
+
+ // Add the distance to A, moving
+ // towards B
+ double x = xa + a_to_b_x * t;
+ double y = ya + a_to_b_y * t;
+
+ if ((xa != xb)) {
+ if ((x < xa) && (x < xb)) {
+ if (xa < xb) {
+ x = xa;
+ y = ya;
+ } else {
+ x = xb;
+ y = yb;
+ }
+ } else if ((x > xa) && (x > xb)) {
+ if (xb > xa) {
+ x = xb;
+ y = yb;
+ } else {
+ x = xa;
+ y = ya;
+ }
+ }
+ } else {
+ if ((y < ya) && (y < yb)) {
+ if (ya < yb) {
+ x = xa;
+ y = ya;
+ } else {
+ x = xb;
+ y = yb;
+ }
+ } else if ((y > ya) && (y > yb)) {
+ if (yb > ya) {
+ x = xb;
+ y = yb;
+ } else {
+ x = xa;
+ y = ya;
+ }
+ }
+ }
+
+ xl = x;
+ yl = y;
+}
+
+Fader::Fader (Gtk::Adjustment& adj,
+ const Glib::RefPtr<Gdk::Pixbuf>& face_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& active_face_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& underlay_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& handle_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& active_handle_pixbuf,
+ int min_pos_x,
+ int min_pos_y,
+ int max_pos_x,
+ int max_pos_y,
+ bool read_only)
+ : adjustment (adj)
+ , _face_pixbuf (face_pixbuf)
+ , _active_face_pixbuf (active_face_pixbuf)
+ , _underlay_pixbuf (underlay_pixbuf)
+ , _handle_pixbuf (handle_pixbuf)
+ , _active_handle_pixbuf (active_handle_pixbuf)
+ , _min_pos_x (min_pos_x)
+ , _min_pos_y (min_pos_y)
+ , _max_pos_x (max_pos_x)
+ , _max_pos_y (max_pos_y)
+ , _grab_window (0)
+ , _touch_cursor (0)
+ , _dragging (false)
+ , _default_value (adjustment.get_value())
+ , _read_only (read_only)
+{
+ update_unity_position ();
+
+ if (!_read_only) {
+ add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
+ }
+
+ adjustment.signal_value_changed().connect (mem_fun (*this, &Fader::adjustment_changed));
+ adjustment.signal_changed().connect (mem_fun (*this, &Fader::adjustment_changed));
+ CairoWidget::set_size_request(_face_pixbuf->get_width(), _face_pixbuf->get_height());
+}
+
+Fader::~Fader ()
+{
+ if (_touch_cursor) {
+ delete _touch_cursor;
+ }
+}
+
+void
+Fader::get_image_scales (double &x_scale, double &y_scale)
+{
+ int pbwidth = _face_pixbuf->get_width ();
+ int pbheight = _face_pixbuf->get_height ();
+ int width = get_width ();
+ int height = get_height ();
+
+ if ((width != pbwidth) || (height != pbheight)) {
+ x_scale = double (width) / double (pbwidth);
+ if (x_scale == 0.0) {
+ x_scale = 1.0;
+ }
+ y_scale = double (height) / double (pbheight);
+ if (y_scale == 0.0) {
+ y_scale = 1.0;
+ }
+ } else {
+ x_scale = y_scale = 1.0;
+ }
+}
+
+void
+Fader::set_touch_cursor (const Glib::RefPtr<Gdk::Pixbuf>& touch_cursor)
+{
+ _touch_cursor = new Gdk::Cursor (Gdk::Display::get_default(), touch_cursor, 12, 12);
+}
+
+void
+Fader::render (cairo_t* cr, cairo_rectangle_t*)
+{
+
+ double xscale = 1.0;
+ double yscale = 1.0;
+
+ get_image_scales (xscale, yscale);
+
+ cairo_matrix_t matrix;
+ cairo_get_matrix (cr, &matrix);
+ cairo_matrix_scale (&matrix, xscale, yscale);
+ cairo_set_matrix (cr, &matrix);
+
+ get_handle_position (_last_drawn_x, _last_drawn_y);
+
+ if (_underlay_pixbuf != 0) {
+ gdk_cairo_set_source_pixbuf (cr,
+ _underlay_pixbuf->gobj(),
+ (_last_drawn_x - (int)((_underlay_pixbuf->get_width() * xscale) / 2.0 + 0.5)) / xscale,
+ (_last_drawn_y - (int)((_underlay_pixbuf->get_height() * yscale) / 2.0 + 0.5)) / yscale);
+ cairo_paint (cr);
+ }
+
+ gdk_cairo_set_source_pixbuf (cr,
+ ((get_state () == Gtk::STATE_ACTIVE) && (_active_face_pixbuf != 0)) ?
+ _active_face_pixbuf->gobj() :
+ _face_pixbuf->gobj(),
+ 0,
+ 0);
+ cairo_paint (cr);
+
+ const Glib::RefPtr<Gdk::Pixbuf> handle_pixbuf (_dragging ? _active_handle_pixbuf : _handle_pixbuf);
+ gdk_cairo_set_source_pixbuf (cr,
+ handle_pixbuf->gobj(),
+ (_last_drawn_x - (int)((handle_pixbuf->get_width() * xscale) / 2.0 + 0.5)) / xscale,
+ (_last_drawn_y - (int)((handle_pixbuf->get_height() * yscale) / 2.0 + 0.5)) / yscale);
+ cairo_paint (cr);
+}
+
+void
+Fader::on_size_request (GtkRequisition* req)
+{
+ req->width = _face_pixbuf->get_width();
+ req->height = _face_pixbuf->get_height();
+}
+
+void
+Fader::on_size_allocate (Gtk::Allocation& alloc)
+{
+ CairoWidget::on_size_allocate(alloc);
+ update_unity_position ();
+}
+
+bool
+Fader::on_button_press_event (GdkEventButton* ev)
+{
+ focus_handler();
+
+ if (_read_only) {
+ return false;
+ }
+
+ if (ev->type != GDK_BUTTON_PRESS) {
+ return false;
+ }
+
+ if (ev->button != 1 && ev->button != 2) {
+ return false;
+ }
+
+ if (_touch_cursor) {
+ get_window()->set_cursor (*_touch_cursor);
+ }
+
+ _grab_start_mouse_x = ev->x;
+ _grab_start_mouse_y = ev->y;
+ get_handle_position (_grab_start_handle_x, _grab_start_handle_y);
+
+ double xscale = 1.0;
+ double yscale = 1.0;
+
+ get_image_scales (xscale, yscale);
+
+ double hw = _handle_pixbuf->get_width() * xscale;
+ double hh = _handle_pixbuf->get_height() * yscale;
+
+ if ((ev->x < (_grab_start_handle_x - hw/2)) || (ev->x > (_grab_start_handle_x + hw/2)) || (ev->y < (_grab_start_handle_y - hh/2)) || (ev->y > (_grab_start_handle_y + hh/2))) {
+ return false;
+ }
+
+ double ev_pos_x;
+ double ev_pos_y;
+
+ get_closest_point_on_line(_min_pos_x, _min_pos_y,
+ _max_pos_x, _max_pos_y,
+ ev->x, ev->y,
+ ev_pos_x, ev_pos_y );
+ add_modal_grab ();
+
+ _grab_window = ev->window;
+ _dragging = true;
+
+ gdk_pointer_grab(ev->window,false,
+ GdkEventMask (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK),
+ NULL,
+ NULL,
+ ev->time);
+
+ queue_draw();
+
+ return true;
+}
+
+bool
+Fader::on_button_release_event (GdkEventButton* ev)
+{
+ if (_read_only) {
+ return false;
+ }
+
+ if (_touch_cursor) {
+ get_window()->set_cursor ();
+ }
+
+ if (_dragging) { //temp
+ remove_modal_grab();
+ _dragging = false;
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ queue_draw ();
+ }
+ return false;
+}
+
+bool
+Fader::on_scroll_event (GdkEventScroll* ev)
+{
+ if (_read_only) {
+ return false;
+ }
+
+ int step_factor = 1;
+
+ switch (ev->direction) {
+ case GDK_SCROLL_RIGHT:
+ case GDK_SCROLL_UP:
+#ifdef __APPLE__
+ if ( ev->state & GDK_SHIFT_MASK ) {
+ step_factor = -1;
+ } else {
+ step_factor = 1;
+ }
+#else
+ step_factor = 1;
+#endif
+ break;
+ case GDK_SCROLL_LEFT:
+ case GDK_SCROLL_DOWN:
+#ifdef __APPLE__
+ if ( ev->state & GDK_SHIFT_MASK ) {
+ step_factor = 1;
+ } else {
+ step_factor = -1;
+ }
+#else
+ step_factor = -1;
+#endif
+ break;
+ default:
+ return false;
+ }
+ adjustment.set_value (adjustment.get_value() + step_factor * (adjustment.get_step_increment() ));
+ return true;
+}
+
+bool
+Fader::on_motion_notify_event (GdkEventMotion* ev)
+{
+ if (_read_only) {
+ return false;
+ }
+
+ if (_dragging) {
+ double ev_pos_x;
+ double ev_pos_y;
+
+ if (ev->window != _grab_window) {
+ _grab_window = ev->window;
+ return true;
+ }
+
+ get_closest_point_on_line(_min_pos_x, _min_pos_y,
+ _max_pos_x, _max_pos_y,
+ _grab_start_handle_x + (ev->x - _grab_start_mouse_x), _grab_start_handle_y + (ev->y - _grab_start_mouse_y),
+ ev_pos_x, ev_pos_y );
+
+ double const fract = sqrt((ev_pos_x - _min_pos_x) * (ev_pos_x - _min_pos_x) +
+ (ev_pos_y - _min_pos_y) * (ev_pos_y - _min_pos_y)) /
+ sqrt((double)((_max_pos_x - _min_pos_x) * (_max_pos_x - _min_pos_x) +
+ (_max_pos_y - _min_pos_y) * (_max_pos_y - _min_pos_y)));
+
+ adjustment.set_value (adjustment.get_lower() + (adjustment.get_upper() - adjustment.get_lower()) * fract);
+ }
+ return true;
+}
+
+void
+Fader::adjustment_changed ()
+{
+ double handle_x;
+ double handle_y;
+ get_handle_position (handle_x, handle_y);
+
+ if ((handle_x != _last_drawn_x) || (handle_y != _last_drawn_y)) {
+ queue_draw ();
+ }
+}
+
+/** @return pixel offset of the current value from the right or bottom of the fader */
+void
+Fader::get_handle_position (double& x, double& y)
+{
+ double fract = (adjustment.get_value () - adjustment.get_lower()) / ((adjustment.get_upper() - adjustment.get_lower()));
+
+ x = (int)(_min_pos_x + (_max_pos_x - _min_pos_x) * fract);
+ y = (int)(_min_pos_y + (_max_pos_y - _min_pos_y) * fract);
+}
+
+bool
+Fader::on_enter_notify_event (GdkEventCrossing*)
+{
+ _hovering = true;
+ Keyboard::magic_widget_grab_focus ();
+ queue_draw ();
+ return false;
+}
+
+bool
+Fader::on_leave_notify_event (GdkEventCrossing*)
+{
+ if (_read_only) {
+ return false;
+ }
+
+ if (!_dragging) {
+ _hovering = false;
+ Keyboard::magic_widget_drop_focus();
+ queue_draw ();
+ }
+ return false;
+}
+
+void
+Fader::set_default_value (float d)
+{
+ _default_value = d;
+ update_unity_position ();
+}
+
+void
+Fader::update_unity_position ()
+{
+}
diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc
index b5319fbea7..c4df2b7d5c 100644
--- a/libs/gtkmm2ext/gtk_ui.cc
+++ b/libs/gtkmm2ext/gtk_ui.cc
@@ -482,8 +482,40 @@ UI::do_request (UIRequest* req)
======================================================================*/
void
+UI::dump_errors (std::ostream& ostr)
+{
+ Glib::Threads::Mutex::Lock lm (error_lock);
+ ostr << endl << X_("Errors/Messages:") << endl;
+ for (list<string>::const_iterator i = error_stack.begin(); i != error_stack.end(); ++i) {
+ ostr << *i << endl;
+ }
+ ostr << endl;
+}
+
+void
UI::receive (Transmitter::Channel chn, const char *str)
{
+ {
+ Glib::Threads::Mutex::Lock lm (error_lock);
+ switch (chn) {
+ case Transmitter::Fatal:
+ error_stack.push_back (string (X_("FATAL: ")) + str);
+ break;
+ case Transmitter::Error:
+ error_stack.push_back (string (X_("ERROR: ")) + str);
+ break;
+ case Transmitter::Warning:
+ error_stack.push_back (string (X_("WARNING: ")) + str);
+ break;
+ case Transmitter::Info:
+ error_stack.push_back (string (X_("INFO: ")) + str);
+ break;
+ case Transmitter::Throw:
+ error_stack.push_back (string (X_("THROW: ")) + str);
+ break;
+ }
+ }
+
if (caller_is_ui_thread()) {
process_error_message (chn, str);
} else {
diff --git a/libs/gtkmm2ext/gtkapplication_quartz.mm b/libs/gtkmm2ext/gtkapplication_quartz.mm
index 932eaa71c9..5809355ad9 100644
--- a/libs/gtkmm2ext/gtkapplication_quartz.mm
+++ b/libs/gtkmm2ext/gtkapplication_quartz.mm
@@ -573,7 +573,9 @@ idle_call_activate (gpointer data)
- (void) activate:(id) sender
{
UNUSED_PARAMETER(sender);
- g_idle_add (idle_call_activate, gtk_menu_item);
+ // Hot Fix. Increase Priority.
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_call_activate, gtk_menu_item, NULL);
+// g_idle_add (idle_call_activate, gtk_menu_item);
}
@end
@@ -1221,7 +1223,7 @@ create_apple_menu ()
[menuitem release];
[_app_menu addItem: [NSMenuItem separatorItem]];
menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide"
- action:@selector(hide:) keyEquivalent:@""];
+ action:@selector(hide:) keyEquivalent:@"h"];
[menuitem setTarget: NSApp];
[_app_menu addItem: menuitem];
[menuitem release];
@@ -1424,9 +1426,10 @@ namespace Gtk {
@end
-@interface GtkApplicationDelegate : NSObject
+@interface GtkApplicationDelegate : NSObject
-(BOOL) application:(NSApplication*) app openFile:(NSString*) file;
- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *) app;
+- (void) startApp;
@end
@implementation GtkApplicationDelegate
@@ -1476,6 +1479,12 @@ gtk_application_ready ()
}
extern "C" void
+gtk_application_hide ()
+{
+ [NSApp performSelector:@selector(hide:)];
+}
+
+extern "C" void
gtk_application_cleanup()
{
_exiting = 1;
diff --git a/libs/gtkmm2ext/gtkapplication_win32.c b/libs/gtkmm2ext/gtkapplication_win32.c
index 78d538b334..7dd9db4a8d 100644
--- a/libs/gtkmm2ext/gtkapplication_win32.c
+++ b/libs/gtkmm2ext/gtkapplication_win32.c
@@ -47,3 +47,8 @@ void
gtk_application_ready (void)
{
}
+
+void
+gtk_application_hide (void)
+{
+}
diff --git a/libs/gtkmm2ext/gtkapplication_x11.c b/libs/gtkmm2ext/gtkapplication_x11.c
index 2b85677073..6cf1055c5c 100644
--- a/libs/gtkmm2ext/gtkapplication_x11.c
+++ b/libs/gtkmm2ext/gtkapplication_x11.c
@@ -50,3 +50,8 @@ void
gtk_application_ready (void)
{
}
+
+void
+gtk_application_hide (void)
+{
+}
diff --git a/libs/gtkmm2ext/gtkmm2ext/actions.h b/libs/gtkmm2ext/gtkmm2ext/actions.h
index d13a16f2d5..9ed1480546 100644
--- a/libs/gtkmm2ext/gtkmm2ext/actions.h
+++ b/libs/gtkmm2ext/gtkmm2ext/actions.h
@@ -94,9 +94,9 @@ namespace ActionManager {
LIBGTKMM2EXT_API extern void set_toggleaction_state (std::string, bool);
- LIBGTKMM2EXT_API extern void push_action_state ();
- LIBGTKMM2EXT_API extern void pop_action_state ();
- LIBGTKMM2EXT_API extern void disable_all_actions ();
+ LIBGTKMM2EXT_API extern void save_action_states ();
+ LIBGTKMM2EXT_API extern void enable_active_actions ();
+ LIBGTKMM2EXT_API extern void disable_active_actions ();
};
#endif /* __libgtkmm2ext_actions_h__ */
diff --git a/libs/gtkmm2ext/gtkmm2ext/application.h b/libs/gtkmm2ext/gtkmm2ext/application.h
index f0d029d3e7..e66b6ea2ff 100644
--- a/libs/gtkmm2ext/gtkmm2ext/application.h
+++ b/libs/gtkmm2ext/gtkmm2ext/application.h
@@ -45,6 +45,7 @@ public:
~Application ();
void ready ();
+ void hide ();
void cleanup ();
void set_menu_bar (Gtk::MenuShell&);
GtkApplicationMenuGroup* add_app_menu_group ();
diff --git a/libs/gtkmm2ext/gtkmm2ext/auto_spin.h b/libs/gtkmm2ext/gtkmm2ext/auto_spin.h
index 8a6c9ab3b0..0f5a9467c6 100644
--- a/libs/gtkmm2ext/gtkmm2ext/auto_spin.h
+++ b/libs/gtkmm2ext/gtkmm2ext/auto_spin.h
@@ -47,6 +47,7 @@ class LIBGTKMM2EXT_API AutoSpin
gint button_press (GdkEventButton *);
gint stop_spinning (GdkEventButton *ignored_but_here_for_clicked);
void start_spinning (bool decrementing, bool use_page);
+ gint scroll_event (GdkEventScroll *);
private:
Gtk::Adjustment &adjustment;
diff --git a/libs/gtkmm2ext/gtkmm2ext/click_box.h b/libs/gtkmm2ext/gtkmm2ext/click_box.h
index c2afa2dd12..3b7fd0f498 100644
--- a/libs/gtkmm2ext/gtkmm2ext/click_box.h
+++ b/libs/gtkmm2ext/gtkmm2ext/click_box.h
@@ -57,6 +57,7 @@ class LIBGTKMM2EXT_API ClickBox : public Gtk::DrawingArea, public AutoSpin
void style_changed (const Glib::RefPtr<Gtk::Style> &);
bool button_press_handler (GdkEventButton *);
bool button_release_handler (GdkEventButton *);
+ bool on_scroll_event (GdkEventScroll*);
sigc::slot<bool, char *, Gtk::Adjustment &> _printer;
};
diff --git a/libs/gtkmm2ext/gtkmm2ext/fader.h b/libs/gtkmm2ext/gtkmm2ext/fader.h
new file mode 100755
index 0000000000..84175d5942
--- /dev/null
+++ b/libs/gtkmm2ext/gtkmm2ext/fader.h
@@ -0,0 +1,111 @@
+/*
+ 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 __gtkmm2ext_fader_h__
+#define __gtkmm2ext_fader_h__
+
+#include <cmath>
+#include <stdint.h>
+
+#include <gtkmm/adjustment.h>
+#include <gdkmm.h>
+#include <gtkmm2ext/binding_proxy.h>
+#include "gtkmm2ext/cairo_widget.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include "gtkmm2ext/visibility.h"
+
+namespace Gtkmm2ext {
+
+class LIBGTKMM2EXT_API Fader : public CairoWidget
+{
+ public:
+ Fader (Gtk::Adjustment& adjustment,
+ const Glib::RefPtr<Gdk::Pixbuf>& face_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& active_face_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& underlay_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& handle_pixbuf,
+ const Glib::RefPtr<Gdk::Pixbuf>& active_handle_pixbuf,
+ int min_pos_x,
+ int min_pos_y,
+ int max_pos_x,
+ int max_pos_y,
+ bool read_only);
+
+ virtual ~Fader ();
+
+ void set_controllable (boost::shared_ptr<PBD::Controllable> c) { binding_proxy.set_controllable (c); }
+ void set_default_value (float);
+ void set_touch_cursor (const Glib::RefPtr<Gdk::Pixbuf>& touch_cursor);
+ void get_image_scales (double &x_scale, double &y_scale);
+
+ protected:
+ void get_handle_position (double& x, double& y);
+
+ void on_size_request (GtkRequisition*);
+ void on_size_allocate (Gtk::Allocation& alloc);
+
+ void render (cairo_t* cr, cairo_rectangle_t*);
+ bool on_button_press_event (GdkEventButton*);
+ bool on_button_release_event (GdkEventButton*);
+ bool on_motion_notify_event (GdkEventMotion*);
+ bool on_scroll_event (GdkEventScroll* ev);
+ bool on_enter_notify_event (GdkEventCrossing* ev);
+ bool on_leave_notify_event (GdkEventCrossing* ev);
+
+ protected:
+ Gtk::Adjustment& adjustment;
+ BindingProxy binding_proxy;
+
+ private:
+
+ const Glib::RefPtr<Gdk::Pixbuf> _face_pixbuf;
+ const Glib::RefPtr<Gdk::Pixbuf> _active_face_pixbuf;
+ const Glib::RefPtr<Gdk::Pixbuf> _underlay_pixbuf;
+ const Glib::RefPtr<Gdk::Pixbuf> _handle_pixbuf;
+ const Glib::RefPtr<Gdk::Pixbuf> _active_handle_pixbuf;
+ int _min_pos_x;
+ int _min_pos_y;
+ int _max_pos_x;
+ int _max_pos_y;
+
+ bool _hovering;
+
+ GdkWindow* _grab_window;
+ Gdk::Cursor *_touch_cursor;
+
+ double _grab_start_mouse_x;
+ double _grab_start_mouse_y;
+ double _grab_start_handle_x;
+ double _grab_start_handle_y;
+ double _last_drawn_x;
+ double _last_drawn_y;
+ bool _dragging;
+ float _default_value;
+ bool _read_only;
+
+ void adjustment_changed ();
+ void update_unity_position ();
+};
+
+
+} /* namespace */
+
+#endif /* __gtkmm2ext_fader_h__ */
diff --git a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
index 0a66accaef..177adb00ff 100644
--- a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
+++ b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
@@ -138,6 +138,7 @@ class LIBGTKMM2EXT_API UI : public AbstractUI<UIRequest>
void flush_pending ();
void toggle_errors ();
void show_errors ();
+ void dump_errors (std::ostream&);
void touch_display (Touchable *);
void set_tip (Gtk::Widget &w, const gchar *tip);
void set_tip (Gtk::Widget &w, const std::string &tip);
@@ -166,7 +167,7 @@ class LIBGTKMM2EXT_API UI : public AbstractUI<UIRequest>
sigc::signal<void> theme_changed;
static bool just_hide_it (GdkEventAny *, Gtk::Window *);
-
+
protected:
virtual void handle_fatal (const char *);
virtual void display_message (const char *prefix, gint prefix_len,
@@ -195,6 +196,9 @@ class LIBGTKMM2EXT_API UI : public AbstractUI<UIRequest>
void process_error_message (Transmitter::Channel, const char *);
void do_quit ();
+ Glib::Threads::Mutex error_lock;
+ std::list<std::string> error_stack;
+
void color_selection_done (bool status);
bool color_selection_deleted (GdkEventAny *);
bool color_picked;
diff --git a/libs/gtkmm2ext/gtkmm2ext/gtkapplication.h b/libs/gtkmm2ext/gtkmm2ext/gtkapplication.h
index 83594fefbe..4e977de8a9 100644
--- a/libs/gtkmm2ext/gtkmm2ext/gtkapplication.h
+++ b/libs/gtkmm2ext/gtkmm2ext/gtkapplication.h
@@ -34,6 +34,7 @@ typedef struct _GtkApplicationMenuGroup GtkApplicationMenuGroup;
LIBGTKMM2EXT_API int gtk_application_init (void);
LIBGTKMM2EXT_API void gtk_application_ready (void);
+LIBGTKMM2EXT_API void gtk_application_hide (void);
LIBGTKMM2EXT_API void gtk_application_cleanup (void);
LIBGTKMM2EXT_API void gtk_application_set_menu_bar (GtkMenuShell *menu_shell);
diff --git a/libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h b/libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h
index 6507bbb479..9df2614095 100644
--- a/libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h
+++ b/libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h
@@ -31,15 +31,17 @@ namespace Gtkmm2ext {
*/
class LIBGTKMM2EXT_API PersistentTooltip : public sigc::trackable
{
-public:
- PersistentTooltip (Gtk::Widget *, int margin_y = 0);
+ public:
+ PersistentTooltip (Gtk::Widget *, bool draggable = false, int margin_y = 0);
virtual ~PersistentTooltip ();
void set_tip (std::string);
-
+ void set_font (Pango::FontDescription font);
+ void set_center_alignment (bool align_to_center);
+
virtual bool dragging () const;
-private:
+ private:
bool timeout ();
void show ();
void hide ();
@@ -54,6 +56,10 @@ private:
Gtk::Window* _window;
/** Our label */
Gtk::Label* _label;
+
+ /** allow to drag
+ */
+ bool _draggable;
/** true if we are `dragging', in the sense that button 1
is being held over _target.
*/
@@ -62,6 +68,8 @@ private:
sigc::connection _timeout;
/** The tip text */
std::string _tip;
+ Pango::FontDescription _font;
+ bool _align_to_center;
int _margin_y;
};
diff --git a/libs/gtkmm2ext/gtkmm2ext/utils.h b/libs/gtkmm2ext/gtkmm2ext/utils.h
index 5832c914f6..ab70464ea0 100644
--- a/libs/gtkmm2ext/gtkmm2ext/utils.h
+++ b/libs/gtkmm2ext/gtkmm2ext/utils.h
@@ -54,6 +54,7 @@ namespace Gtkmm2ext {
LIBGTKMM2EXT_API std::string fit_to_pixels (const std::string&, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses = false);
LIBGTKMM2EXT_API std::pair<std::string, double> fit_to_pixels (cairo_t *, std::string, double);
LIBGTKMM2EXT_API int pixel_width (const std::string& str, Pango::FontDescription& font);
+ LIBGTKMM2EXT_API void pixel_size (const std::string& str, Pango::FontDescription& font, int& width, int& height);
LIBGTKMM2EXT_API void get_ink_pixel_size (Glib::RefPtr<Pango::Layout>,
int& width, int& height);
diff --git a/libs/gtkmm2ext/macosx/gtkmm2ext/gtkmm2ext.xcodeproj/project.pbxproj b/libs/gtkmm2ext/macosx/gtkmm2ext/gtkmm2ext.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..c7d75400a3
--- /dev/null
+++ b/libs/gtkmm2ext/macosx/gtkmm2ext/gtkmm2ext.xcodeproj/project.pbxproj
@@ -0,0 +1,254 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXFileReference section */
+ 4397599D19CB06D100740098 /* actions.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = actions.cc; path = ../../actions.cc; sourceTree = "<group>"; };
+ 4397599E19CB06D100740098 /* application.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = application.cc; path = ../../application.cc; sourceTree = "<group>"; };
+ 4397599F19CB06D100740098 /* auto_spin.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = auto_spin.cc; path = ../../auto_spin.cc; sourceTree = "<group>"; };
+ 439759A019CB06D100740098 /* barcontroller.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = barcontroller.cc; path = ../../barcontroller.cc; sourceTree = "<group>"; };
+ 439759A119CB06D100740098 /* bindable_button.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = bindable_button.cc; path = ../../bindable_button.cc; sourceTree = "<group>"; };
+ 439759A219CB06D100740098 /* binding_proxy.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = binding_proxy.cc; path = ../../binding_proxy.cc; sourceTree = "<group>"; };
+ 439759A319CB06D100740098 /* bindings.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = bindings.cc; path = ../../bindings.cc; sourceTree = "<group>"; };
+ 439759A419CB06D100740098 /* cairo_packer.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cairo_packer.cc; path = ../../cairo_packer.cc; sourceTree = "<group>"; };
+ 439759A519CB06D100740098 /* cairo_widget.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cairo_widget.cc; path = ../../cairo_widget.cc; sourceTree = "<group>"; };
+ 439759A619CB06D100740098 /* cairocell.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cairocell.cc; path = ../../cairocell.cc; sourceTree = "<group>"; };
+ 439759A719CB06D100740098 /* cell_renderer_color_selector.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cell_renderer_color_selector.cc; path = ../../cell_renderer_color_selector.cc; sourceTree = "<group>"; };
+ 439759A819CB06D100740098 /* cell_renderer_pixbuf_multi.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cell_renderer_pixbuf_multi.cc; path = ../../cell_renderer_pixbuf_multi.cc; sourceTree = "<group>"; };
+ 439759A919CB06D100740098 /* cell_renderer_pixbuf_toggle.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cell_renderer_pixbuf_toggle.cc; path = ../../cell_renderer_pixbuf_toggle.cc; sourceTree = "<group>"; };
+ 439759AA19CB06D100740098 /* choice.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = choice.cc; path = ../../choice.cc; sourceTree = "<group>"; };
+ 439759AB19CB06D100740098 /* click_box.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = click_box.cc; path = ../../click_box.cc; sourceTree = "<group>"; };
+ 439759AC19CB06D100740098 /* cursors.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cursors.cc; path = ../../cursors.cc; sourceTree = "<group>"; };
+ 439759AD19CB06D100740098 /* debug.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = debug.cc; path = ../../debug.cc; sourceTree = "<group>"; };
+ 439759AE19CB06D100740098 /* dndtreeview.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = dndtreeview.cc; path = ../../dndtreeview.cc; sourceTree = "<group>"; };
+ 439759AF19CB06D100740098 /* fader.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = fader.cc; path = ../../fader.cc; sourceTree = "<group>"; };
+ 439759B019CB06D100740098 /* fastmeter.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = fastmeter.cc; path = ../../fastmeter.cc; sourceTree = "<group>"; };
+ 439759B119CB06D100740098 /* focus_entry.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = focus_entry.cc; path = ../../focus_entry.cc; sourceTree = "<group>"; };
+ 439759B219CB06D100740098 /* grouped_buttons.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = grouped_buttons.cc; path = ../../grouped_buttons.cc; sourceTree = "<group>"; };
+ 439759B319CB06D100740098 /* gtk_ui.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = gtk_ui.cc; path = ../../gtk_ui.cc; sourceTree = "<group>"; };
+ 439759B419CB06D100740098 /* gtkapplication_quartz.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = gtkapplication_quartz.mm; path = ../../gtkapplication_quartz.mm; sourceTree = "<group>"; };
+ 439759B519CB06D100740098 /* gtkapplication_win32.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = gtkapplication_win32.c; path = ../../gtkapplication_win32.c; sourceTree = "<group>"; };
+ 439759B619CB06D100740098 /* gtkapplication_x11.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = gtkapplication_x11.c; path = ../../gtkapplication_x11.c; sourceTree = "<group>"; };
+ 439759B719CB06D100740098 /* gtkapplication.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = gtkapplication.c; path = ../../gtkapplication.c; sourceTree = "<group>"; };
+ 439759B819CB06D100740098 /* idle_adjustment.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = idle_adjustment.cc; path = ../../idle_adjustment.cc; sourceTree = "<group>"; };
+ 439759B919CB06D100740098 /* keyboard.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = keyboard.cc; path = ../../keyboard.cc; sourceTree = "<group>"; };
+ 439759BB19CB070500740098 /* actions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = actions.h; path = ../../gtkmm2ext/actions.h; sourceTree = "<group>"; };
+ 439759BC19CB070500740098 /* activatable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = activatable.h; path = ../../gtkmm2ext/activatable.h; sourceTree = "<group>"; };
+ 439759BD19CB070500740098 /* application.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = application.h; path = ../../gtkmm2ext/application.h; sourceTree = "<group>"; };
+ 439759BE19CB070500740098 /* auto_spin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = auto_spin.h; path = ../../gtkmm2ext/auto_spin.h; sourceTree = "<group>"; };
+ 439759BF19CB070500740098 /* barcontroller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = barcontroller.h; path = ../../gtkmm2ext/barcontroller.h; sourceTree = "<group>"; };
+ 439759C019CB070500740098 /* bindable_button.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bindable_button.h; path = ../../gtkmm2ext/bindable_button.h; sourceTree = "<group>"; };
+ 439759C119CB070500740098 /* binding_proxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = binding_proxy.h; path = ../../gtkmm2ext/binding_proxy.h; sourceTree = "<group>"; };
+ 439759C219CB070500740098 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bindings.h; path = ../../gtkmm2ext/bindings.h; sourceTree = "<group>"; };
+ 439759C319CB070500740098 /* cairo_packer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cairo_packer.h; path = ../../gtkmm2ext/cairo_packer.h; sourceTree = "<group>"; };
+ 439759C419CB070500740098 /* cairo_widget.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cairo_widget.h; path = ../../gtkmm2ext/cairo_widget.h; sourceTree = "<group>"; };
+ 439759C519CB070500740098 /* cairocell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cairocell.h; path = ../../gtkmm2ext/cairocell.h; sourceTree = "<group>"; };
+ 439759C619CB070500740098 /* cell_renderer_color_selector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cell_renderer_color_selector.h; path = ../../gtkmm2ext/cell_renderer_color_selector.h; sourceTree = "<group>"; };
+ 439759C719CB070500740098 /* cell_renderer_pixbuf_multi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cell_renderer_pixbuf_multi.h; path = ../../gtkmm2ext/cell_renderer_pixbuf_multi.h; sourceTree = "<group>"; };
+ 439759C819CB070500740098 /* cell_renderer_pixbuf_toggle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cell_renderer_pixbuf_toggle.h; path = ../../gtkmm2ext/cell_renderer_pixbuf_toggle.h; sourceTree = "<group>"; };
+ 439759C919CB070500740098 /* choice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = choice.h; path = ../../gtkmm2ext/choice.h; sourceTree = "<group>"; };
+ 439759CA19CB070500740098 /* click_box.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = click_box.h; path = ../../gtkmm2ext/click_box.h; sourceTree = "<group>"; };
+ 439759CB19CB070500740098 /* cursors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cursors.h; path = ../../gtkmm2ext/cursors.h; sourceTree = "<group>"; };
+ 439759CC19CB070500740098 /* debug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = debug.h; path = ../../gtkmm2ext/debug.h; sourceTree = "<group>"; };
+ 439759CD19CB070500740098 /* dndtreeview.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = dndtreeview.h; path = ../../gtkmm2ext/dndtreeview.h; sourceTree = "<group>"; };
+ 439759CE19CB070500740098 /* dndvbox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = dndvbox.h; path = ../../gtkmm2ext/dndvbox.h; sourceTree = "<group>"; };
+ 439759CF19CB070500740098 /* doi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = doi.h; path = ../../gtkmm2ext/doi.h; sourceTree = "<group>"; };
+ 439759D019CB070500740098 /* fader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fader.h; path = ../../gtkmm2ext/fader.h; sourceTree = "<group>"; };
+ 439759D119CB070500740098 /* fastmeter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fastmeter.h; path = ../../gtkmm2ext/fastmeter.h; sourceTree = "<group>"; };
+ 439759D219CB070500740098 /* focus_entry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = focus_entry.h; path = ../../gtkmm2ext/focus_entry.h; sourceTree = "<group>"; };
+ 439759D319CB070500740098 /* grouped_buttons.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = grouped_buttons.h; path = ../../gtkmm2ext/grouped_buttons.h; sourceTree = "<group>"; };
+ 439759D419CB070500740098 /* gtk_ui.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = gtk_ui.h; path = ../../gtkmm2ext/gtk_ui.h; sourceTree = "<group>"; };
+ 439759D519CB070500740098 /* gtkapplication-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "gtkapplication-private.h"; path = "../../gtkmm2ext/gtkapplication-private.h"; sourceTree = "<group>"; };
+ 439759D619CB070500740098 /* gtkapplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = gtkapplication.h; path = ../../gtkmm2ext/gtkapplication.h; sourceTree = "<group>"; };
+ 439759D719CB070500740098 /* gtkutils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = gtkutils.h; path = ../../gtkmm2ext/gtkutils.h; sourceTree = "<group>"; };
+ 439759D819CB070500740098 /* gui_thread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = gui_thread.h; path = ../../gtkmm2ext/gui_thread.h; sourceTree = "<group>"; };
+ 439759D919CB070500740098 /* idle_adjustment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = idle_adjustment.h; path = ../../gtkmm2ext/idle_adjustment.h; sourceTree = "<group>"; };
+ 439759DA19CB070500740098 /* keyboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = keyboard.h; path = ../../gtkmm2ext/keyboard.h; sourceTree = "<group>"; };
+ 439759DB19CB070500740098 /* motionfeedback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = motionfeedback.h; path = ../../gtkmm2ext/motionfeedback.h; sourceTree = "<group>"; };
+ 439759DC19CB070500740098 /* paths_dialog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = paths_dialog.h; path = ../../gtkmm2ext/paths_dialog.h; sourceTree = "<group>"; };
+ 439759DD19CB070500740098 /* persistent_tooltip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = persistent_tooltip.h; path = ../../gtkmm2ext/persistent_tooltip.h; sourceTree = "<group>"; };
+ 439759DE19CB070500740098 /* pixfader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = pixfader.h; path = ../../gtkmm2ext/pixfader.h; sourceTree = "<group>"; };
+ 439759DF19CB070500740098 /* pixscroller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = pixscroller.h; path = ../../gtkmm2ext/pixscroller.h; sourceTree = "<group>"; };
+ 439759E019CB070500740098 /* popup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = popup.h; path = ../../gtkmm2ext/popup.h; sourceTree = "<group>"; };
+ 439759E119CB070500740098 /* prolooks-helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "prolooks-helpers.h"; path = "../../gtkmm2ext/prolooks-helpers.h"; sourceTree = "<group>"; };
+ 439759E219CB070500740098 /* prompter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = prompter.h; path = ../../gtkmm2ext/prompter.h; sourceTree = "<group>"; };
+ 439759E319CB070500740098 /* rgb_macros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = rgb_macros.h; path = ../../gtkmm2ext/rgb_macros.h; sourceTree = "<group>"; };
+ 439759E419CB070500740098 /* scroomer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = scroomer.h; path = ../../gtkmm2ext/scroomer.h; sourceTree = "<group>"; };
+ 439759E519CB070500740098 /* selector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = selector.h; path = ../../gtkmm2ext/selector.h; sourceTree = "<group>"; };
+ 439759E619CB070500740098 /* slider_controller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = slider_controller.h; path = ../../gtkmm2ext/slider_controller.h; sourceTree = "<group>"; };
+ 439759E719CB070500740098 /* stateful_button.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = stateful_button.h; path = ../../gtkmm2ext/stateful_button.h; sourceTree = "<group>"; };
+ 439759E819CB070500740098 /* sync-menu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "sync-menu.h"; path = "../../gtkmm2ext/sync-menu.h"; sourceTree = "<group>"; };
+ 439759E919CB070500740098 /* tearoff.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tearoff.h; path = ../../gtkmm2ext/tearoff.h; sourceTree = "<group>"; };
+ 439759EA19CB070500740098 /* textviewer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = textviewer.h; path = ../../gtkmm2ext/textviewer.h; sourceTree = "<group>"; };
+ 439759EB19CB070500740098 /* treeutils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = treeutils.h; path = ../../gtkmm2ext/treeutils.h; sourceTree = "<group>"; };
+ 439759EC19CB070500740098 /* utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = utils.h; path = ../../gtkmm2ext/utils.h; sourceTree = "<group>"; };
+ 439759ED19CB070500740098 /* version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = version.h; path = ../../gtkmm2ext/version.h; sourceTree = "<group>"; };
+ 439759EE19CB070500740098 /* visibility_tracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = visibility_tracker.h; path = ../../gtkmm2ext/visibility_tracker.h; sourceTree = "<group>"; };
+ 439759EF19CB070500740098 /* visibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = visibility.h; path = ../../gtkmm2ext/visibility.h; sourceTree = "<group>"; };
+ 439759F019CB070500740098 /* widget_state.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = widget_state.h; path = ../../gtkmm2ext/widget_state.h; sourceTree = "<group>"; };
+ 439759F119CB070500740098 /* window_title.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = window_title.h; path = ../../gtkmm2ext/window_title.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXGroup section */
+ 4397598F19CB06AC00740098 = {
+ isa = PBXGroup;
+ children = (
+ 439759BA19CB06F000740098 /* headers */,
+ 4397599C19CB06B200740098 /* source */,
+ );
+ sourceTree = "<group>";
+ };
+ 4397599C19CB06B200740098 /* source */ = {
+ isa = PBXGroup;
+ children = (
+ 4397599D19CB06D100740098 /* actions.cc */,
+ 4397599E19CB06D100740098 /* application.cc */,
+ 4397599F19CB06D100740098 /* auto_spin.cc */,
+ 439759A019CB06D100740098 /* barcontroller.cc */,
+ 439759A119CB06D100740098 /* bindable_button.cc */,
+ 439759A219CB06D100740098 /* binding_proxy.cc */,
+ 439759A319CB06D100740098 /* bindings.cc */,
+ 439759A419CB06D100740098 /* cairo_packer.cc */,
+ 439759A519CB06D100740098 /* cairo_widget.cc */,
+ 439759A619CB06D100740098 /* cairocell.cc */,
+ 439759A719CB06D100740098 /* cell_renderer_color_selector.cc */,
+ 439759A819CB06D100740098 /* cell_renderer_pixbuf_multi.cc */,
+ 439759A919CB06D100740098 /* cell_renderer_pixbuf_toggle.cc */,
+ 439759AA19CB06D100740098 /* choice.cc */,
+ 439759AB19CB06D100740098 /* click_box.cc */,
+ 439759AC19CB06D100740098 /* cursors.cc */,
+ 439759AD19CB06D100740098 /* debug.cc */,
+ 439759AE19CB06D100740098 /* dndtreeview.cc */,
+ 439759AF19CB06D100740098 /* fader.cc */,
+ 439759B019CB06D100740098 /* fastmeter.cc */,
+ 439759B119CB06D100740098 /* focus_entry.cc */,
+ 439759B219CB06D100740098 /* grouped_buttons.cc */,
+ 439759B319CB06D100740098 /* gtk_ui.cc */,
+ 439759B419CB06D100740098 /* gtkapplication_quartz.mm */,
+ 439759B519CB06D100740098 /* gtkapplication_win32.c */,
+ 439759B619CB06D100740098 /* gtkapplication_x11.c */,
+ 439759B719CB06D100740098 /* gtkapplication.c */,
+ 439759B819CB06D100740098 /* idle_adjustment.cc */,
+ 439759B919CB06D100740098 /* keyboard.cc */,
+ );
+ name = source;
+ sourceTree = "<group>";
+ };
+ 439759BA19CB06F000740098 /* headers */ = {
+ isa = PBXGroup;
+ children = (
+ 439759BB19CB070500740098 /* actions.h */,
+ 439759BC19CB070500740098 /* activatable.h */,
+ 439759BD19CB070500740098 /* application.h */,
+ 439759BE19CB070500740098 /* auto_spin.h */,
+ 439759BF19CB070500740098 /* barcontroller.h */,
+ 439759C019CB070500740098 /* bindable_button.h */,
+ 439759C119CB070500740098 /* binding_proxy.h */,
+ 439759C219CB070500740098 /* bindings.h */,
+ 439759C319CB070500740098 /* cairo_packer.h */,
+ 439759C419CB070500740098 /* cairo_widget.h */,
+ 439759C519CB070500740098 /* cairocell.h */,
+ 439759C619CB070500740098 /* cell_renderer_color_selector.h */,
+ 439759C719CB070500740098 /* cell_renderer_pixbuf_multi.h */,
+ 439759C819CB070500740098 /* cell_renderer_pixbuf_toggle.h */,
+ 439759C919CB070500740098 /* choice.h */,
+ 439759CA19CB070500740098 /* click_box.h */,
+ 439759CB19CB070500740098 /* cursors.h */,
+ 439759CC19CB070500740098 /* debug.h */,
+ 439759CD19CB070500740098 /* dndtreeview.h */,
+ 439759CE19CB070500740098 /* dndvbox.h */,
+ 439759CF19CB070500740098 /* doi.h */,
+ 439759D019CB070500740098 /* fader.h */,
+ 439759D119CB070500740098 /* fastmeter.h */,
+ 439759D219CB070500740098 /* focus_entry.h */,
+ 439759D319CB070500740098 /* grouped_buttons.h */,
+ 439759D419CB070500740098 /* gtk_ui.h */,
+ 439759D519CB070500740098 /* gtkapplication-private.h */,
+ 439759D619CB070500740098 /* gtkapplication.h */,
+ 439759D719CB070500740098 /* gtkutils.h */,
+ 439759D819CB070500740098 /* gui_thread.h */,
+ 439759D919CB070500740098 /* idle_adjustment.h */,
+ 439759DA19CB070500740098 /* keyboard.h */,
+ 439759DB19CB070500740098 /* motionfeedback.h */,
+ 439759DC19CB070500740098 /* paths_dialog.h */,
+ 439759DD19CB070500740098 /* persistent_tooltip.h */,
+ 439759DE19CB070500740098 /* pixfader.h */,
+ 439759DF19CB070500740098 /* pixscroller.h */,
+ 439759E019CB070500740098 /* popup.h */,
+ 439759E119CB070500740098 /* prolooks-helpers.h */,
+ 439759E219CB070500740098 /* prompter.h */,
+ 439759E319CB070500740098 /* rgb_macros.h */,
+ 439759E419CB070500740098 /* scroomer.h */,
+ 439759E519CB070500740098 /* selector.h */,
+ 439759E619CB070500740098 /* slider_controller.h */,
+ 439759E719CB070500740098 /* stateful_button.h */,
+ 439759E819CB070500740098 /* sync-menu.h */,
+ 439759E919CB070500740098 /* tearoff.h */,
+ 439759EA19CB070500740098 /* textviewer.h */,
+ 439759EB19CB070500740098 /* treeutils.h */,
+ 439759EC19CB070500740098 /* utils.h */,
+ 439759ED19CB070500740098 /* version.h */,
+ 439759EE19CB070500740098 /* visibility_tracker.h */,
+ 439759EF19CB070500740098 /* visibility.h */,
+ 439759F019CB070500740098 /* widget_state.h */,
+ 439759F119CB070500740098 /* window_title.h */,
+ );
+ name = headers;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXProject section */
+ 4397599019CB06AC00740098 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0510;
+ };
+ buildConfigurationList = 4397599319CB06AC00740098 /* Build configuration list for PBXProject "gtkmm2ext" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 4397598F19CB06AC00740098;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ );
+ };
+/* End PBXProject section */
+
+/* Begin XCBuildConfiguration section */
+ 4397599419CB06AC00740098 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 4397599519CB06AC00740098 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 4397599319CB06AC00740098 /* Build configuration list for PBXProject "gtkmm2ext" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4397599419CB06AC00740098 /* Debug */,
+ 4397599519CB06AC00740098 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 4397599019CB06AC00740098 /* Project object */;
+}
diff --git a/libs/gtkmm2ext/persistent_tooltip.cc b/libs/gtkmm2ext/persistent_tooltip.cc
index d9ccfa15f7..88be6ef100 100644
--- a/libs/gtkmm2ext/persistent_tooltip.cc
+++ b/libs/gtkmm2ext/persistent_tooltip.cc
@@ -21,6 +21,8 @@
#include <gtkmm/label.h>
#include "gtkmm2ext/persistent_tooltip.h"
+#include "pbd/stacktrace.h"
+
#include "i18n.h"
using namespace std;
@@ -28,11 +30,13 @@ using namespace Gtk;
using namespace Gtkmm2ext;
/** @param target The widget to provide the tooltip for */
-PersistentTooltip::PersistentTooltip (Gtk::Widget* target, int margin_y)
+PersistentTooltip::PersistentTooltip (Gtk::Widget* target, bool draggable, int margin_y)
: _target (target)
, _window (0)
, _label (0)
+ , _draggable (draggable)
, _maybe_dragging (false)
+ , _align_to_center (true)
, _margin_y (margin_y)
{
target->signal_enter_notify_event().connect (sigc::mem_fun (*this, &PersistentTooltip::enter), false);
@@ -97,7 +101,7 @@ PersistentTooltip::release (GdkEventButton* ev)
bool
PersistentTooltip::dragging () const
{
- return _maybe_dragging;
+ return _maybe_dragging && _draggable;
}
void
@@ -114,6 +118,7 @@ PersistentTooltip::show ()
if (_tip.empty()) {
return;
}
+
if (!_window) {
_window = new Window (WINDOW_POPUP);
_window->set_name (X_("ContrastingPopup"));
@@ -121,6 +126,7 @@ PersistentTooltip::show ()
_window->set_decorated (false);
_label = manage (new Label);
+ _label->modify_font (_font);
_label->set_use_markup (true);
_window->set_border_width (6);
@@ -136,19 +142,32 @@ PersistentTooltip::show ()
set_tip (_tip);
if (!_window->is_visible ()) {
- int rx, ry, sw;
- sw= gdk_screen_width();
- _target->get_window()->get_origin (rx, ry);
- _window->move (rx, ry + _target->get_height() + _margin_y);
- _window->present ();
+ int rx, ry;
+ int sw = gdk_screen_width ();
+ _target->get_window()->get_origin (rx, ry);
+
/* the window needs to be realized first
* for _window->get_width() to be correct.
*/
+
+
if (sw < rx + _window->get_width()) {
+ /* right edge of window would be off the right edge of
+ the screen, so don't show it in the usual place.
+ */
rx = sw - _window->get_width();
- _window->move (rx, ry + _target->get_height());
+ _window->move (rx, ry + _target->get_height() + _margin_y);
+ } else {
+ if (_align_to_center) {
+ _window->move (rx + (_target->get_width () - _window->get_width ()) / 2, ry + _target->get_height());
+ } else {
+ _window->move (rx, ry + _target->get_height());
+ }
}
+
+ _window->present ();
+
}
}
@@ -161,3 +180,19 @@ PersistentTooltip::set_tip (string t)
_label->set_markup (t);
}
}
+
+void
+PersistentTooltip::set_font (Pango::FontDescription font)
+{
+ _font = font;
+
+ if (_label) {
+ _label->modify_font (_font);
+ }
+}
+
+void
+PersistentTooltip::set_center_alignment (bool align_to_center)
+{
+ _align_to_center = align_to_center;
+}
diff --git a/libs/gtkmm2ext/utils.cc b/libs/gtkmm2ext/utils.cc
index 03396a4af9..6efa95ac1a 100644
--- a/libs/gtkmm2ext/utils.cc
+++ b/libs/gtkmm2ext/utils.cc
@@ -705,6 +705,18 @@ Gtkmm2ext::pixel_width (const string& str, Pango::FontDescription& font)
return width;
}
+void
+Gtkmm2ext::pixel_size (const string& str, Pango::FontDescription& font, int& width, int& height)
+{
+ Gtk::Label foo;
+ Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout ("");
+
+ layout->set_font_description (font);
+ layout->set_text (str);
+
+ Gtkmm2ext::get_ink_pixel_size (layout, width, height);
+}
+
#if 0
string
Gtkmm2ext::fit_to_pixels (const string& str, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses)
diff --git a/libs/gtkmm2ext/waves_fastmeter.cc b/libs/gtkmm2ext/waves_fastmeter.cc
new file mode 100644
index 0000000000..d97a92aac2
--- /dev/null
+++ b/libs/gtkmm2ext/waves_fastmeter.cc
@@ -0,0 +1,909 @@
+/*
+ Copyright (C) 2003-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 <iostream>
+#include <cmath>
+#include <algorithm>
+#include <cstring>
+
+#include <stdlib.h>
+
+#include <glibmm.h>
+#include <gdkmm.h>
+#include <gdkmm/rectangle.h>
+#include <gtkmm2ext/fastmeter.h>
+#include <gtkmm2ext/utils.h>
+
+#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
+#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
+
+using namespace Gtk;
+using namespace Glib;
+using namespace Gtkmm2ext;
+using namespace std;
+
+int FastMeter::min_pattern_metric_size = 16;
+int FastMeter::max_pattern_metric_size = 1024;
+bool FastMeter::no_rgba_overlay = false;
+
+FastMeter::Pattern10Map FastMeter::vm_pattern_cache;
+FastMeter::PatternBgMap FastMeter::vb_pattern_cache;
+
+FastMeter::Pattern10Map FastMeter::hm_pattern_cache;
+FastMeter::PatternBgMap FastMeter::hb_pattern_cache;
+
+FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
+ int clr0, int clr1, int clr2, int clr3,
+ int clr4, int clr5, int clr6, int clr7,
+ int clr8, int clr9,
+ int bgc0, int bgc1,
+ int bgh0, int bgh1,
+ float stp0, float stp1,
+ float stp2, float stp3,
+ int styleflags
+ )
+ : pixheight(0)
+ , pixwidth(0)
+ , _styleflags(1)
+ , orientation(o)
+ , hold_cnt(hold)
+ , hold_state(0)
+ , bright_hold(false)
+ , current_level(0)
+ , current_peak(0)
+ , highlight(false)
+{
+ last_peak_rect.width = 0;
+ last_peak_rect.height = 0;
+ last_peak_rect.x = 0;
+ last_peak_rect.y = 0;
+
+ no_rgba_overlay = ! Glib::getenv("NO_METER_SHADE").empty();
+
+ _clr[0] = clr0;
+ _clr[1] = clr1;
+ _clr[2] = clr2;
+ _clr[3] = clr3;
+ _clr[4] = clr4;
+ _clr[5] = clr5;
+ _clr[6] = clr6;
+ _clr[7] = clr7;
+ _clr[8] = clr8;
+ _clr[9] = clr9;
+
+ _bgc[0] = bgc0;
+ _bgc[1] = bgc1;
+
+ _bgh[0] = bgh0;
+ _bgh[1] = bgh1;
+
+ _stp[0] = stp0;
+ _stp[1] = stp1;
+ _stp[2] = stp2;
+ _stp[3] = stp3;
+
+ set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
+
+ pixrect.x = 0;
+ pixrect.y = 0;
+
+ if (!len) {
+ len = 250;
+ }
+ if (orientation == Vertical) {
+ pixheight = len;
+ pixwidth = dimen;
+ fgpattern = request_vertical_meter(pixwidth, pixheight, _clr, _stp, _styleflags);
+ bgpattern = request_vertical_background (pixwidth, pixheight, _bgc, false);
+
+ } else {
+ pixheight = dimen;
+ pixwidth = len;
+ fgpattern = request_horizontal_meter(pixwidth, pixheight, _clr, _stp, _styleflags);
+ bgpattern = request_horizontal_background (pixwidth, pixheight, _bgc, false);
+ }
+
+ pixrect.width = pixwidth;
+ pixrect.height = pixheight;
+
+ request_width = pixrect.width;
+ request_height= pixrect.height;
+
+ clear ();
+}
+
+FastMeter::~FastMeter ()
+{
+}
+
+void
+FastMeter::flush_pattern_cache ()
+{
+ Pattern10Map::iterator i1;
+ PatternBgMap::iterator ib;
+
+ for (ib = hb_pattern_cache.begin(); ib != hb_pattern_cache.end(); ++ib) {
+ hb_pattern_cache.erase(ib);
+ }
+
+ for (i1 = hm_pattern_cache.begin(); i1 != hm_pattern_cache.end(); ++i1) {
+ hm_pattern_cache.erase(i1);
+ }
+
+ for (ib = vb_pattern_cache.begin(); ib != vb_pattern_cache.end(); ++ib) {
+ vb_pattern_cache.erase(ib);
+ }
+
+ for (i1 = vm_pattern_cache.begin(); i1 != vm_pattern_cache.end(); ++i1) {
+ vm_pattern_cache.erase(i1);
+ }
+}
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::generate_meter_pattern (
+ int width, int height, int *clr, float *stp, int styleflags, bool horiz)
+{
+ guint8 r,g,b,a;
+ double knee;
+ const double soft = 3.0 / (double) height;
+ const double offs = -1.0 / (double) height;
+
+ cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, height);
+
+ /*
+ Cairo coordinate space goes downwards as y value goes up, so invert
+ knee-based positions by using (1.0 - y)
+ */
+
+ UINT_TO_RGBA (clr[9], &r, &g, &b, &a); // top/clip
+ cairo_pattern_add_color_stop_rgb (pat, 0.0,
+ r/255.0, g/255.0, b/255.0);
+
+ knee = offs + stp[3] / 115.0f; // -0dB
+
+ UINT_TO_RGBA (clr[8], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[7], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
+ r/255.0, g/255.0, b/255.0);
+
+ knee = offs + stp[2]/ 115.0f; // -3dB || -2dB
+
+ UINT_TO_RGBA (clr[6], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[5], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
+ r/255.0, g/255.0, b/255.0);
+
+ knee = offs + stp[1] / 115.0f; // -9dB
+
+ UINT_TO_RGBA (clr[4], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[3], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
+ r/255.0, g/255.0, b/255.0);
+
+ knee = offs + stp[0] / 115.0f; // -18dB
+
+ UINT_TO_RGBA (clr[2], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[1], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[0], &r, &g, &b, &a); // bottom
+ cairo_pattern_add_color_stop_rgb (pat, 1.0,
+ r/255.0, g/255.0, b/255.0);
+
+ if ((styleflags & 1) && !no_rgba_overlay) {
+ cairo_pattern_t* shade_pattern = cairo_pattern_create_linear (0.0, 0.0, width, 0.0);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 0, 0.0, 0.0, 0.0, 0.15);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 0.4, 1.0, 1.0, 1.0, 0.05);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 1, 0.0, 0.0, 0.0, 0.25);
+
+ cairo_surface_t* surface;
+ cairo_t* tc = 0;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ tc = cairo_create (surface);
+ cairo_set_source (tc, pat);
+ cairo_rectangle (tc, 0, 0, width, height);
+ cairo_fill (tc);
+ cairo_pattern_destroy (pat);
+
+ cairo_set_source (tc, shade_pattern);
+ cairo_rectangle (tc, 0, 0, width, height);
+ cairo_fill (tc);
+ cairo_pattern_destroy (shade_pattern);
+
+ if (styleflags & 2) { // LED stripes
+ cairo_save (tc);
+ cairo_set_line_width(tc, 1.0);
+ cairo_set_source_rgba(tc, .0, .0, .0, 0.4);
+ //cairo_set_operator (tc, CAIRO_OPERATOR_SOURCE);
+ for (float y=0.5; y < height; y+= 2.0) {
+ cairo_move_to(tc, 0, y);
+ cairo_line_to(tc, width, y);
+ cairo_stroke (tc);
+ }
+ cairo_restore (tc);
+ }
+
+ pat = cairo_pattern_create_for_surface (surface);
+ cairo_destroy (tc);
+ cairo_surface_destroy (surface);
+ }
+
+ if (horiz) {
+ cairo_surface_t* surface;
+ cairo_t* tc = 0;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, height, width);
+ tc = cairo_create (surface);
+
+ cairo_matrix_t m;
+ cairo_matrix_init_rotate (&m, -M_PI/2.0);
+ cairo_matrix_translate (&m, -height, 0);
+ cairo_pattern_set_matrix (pat, &m);
+ cairo_set_source (tc, pat);
+ cairo_rectangle (tc, 0, 0, height, width);
+ cairo_fill (tc);
+ cairo_pattern_destroy (pat);
+ pat = cairo_pattern_create_for_surface (surface);
+ cairo_destroy (tc);
+ cairo_surface_destroy (surface);
+ }
+ Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
+
+ return p;
+}
+
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::generate_meter_background (
+ int width, int height, int *clr, bool shade, bool horiz)
+{
+ guint8 r0,g0,b0,r1,g1,b1,a;
+
+ cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, height);
+
+ UINT_TO_RGBA (clr[0], &r0, &g0, &b0, &a);
+ UINT_TO_RGBA (clr[1], &r1, &g1, &b1, &a);
+
+ cairo_pattern_add_color_stop_rgb (pat, 0.0,
+ r1/255.0, g1/255.0, b1/255.0);
+
+ cairo_pattern_add_color_stop_rgb (pat, 1.0,
+ r0/255.0, g0/255.0, b0/255.0);
+
+ if (shade && !no_rgba_overlay) {
+ cairo_pattern_t* shade_pattern = cairo_pattern_create_linear (0.0, 0.0, width, 0.0);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1.0, 1.0, 1.0, 0.15);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 0.6, 0.0, 0.0, 0.0, 0.10);
+ cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 1.0, 1.0, 1.0, 0.20);
+
+ cairo_surface_t* surface;
+ cairo_t* tc = 0;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ tc = cairo_create (surface);
+ cairo_set_source (tc, pat);
+ cairo_rectangle (tc, 0, 0, width, height);
+ cairo_fill (tc);
+ cairo_set_source (tc, shade_pattern);
+ cairo_rectangle (tc, 0, 0, width, height);
+ cairo_fill (tc);
+
+ cairo_pattern_destroy (pat);
+ cairo_pattern_destroy (shade_pattern);
+
+ pat = cairo_pattern_create_for_surface (surface);
+
+ cairo_destroy (tc);
+ cairo_surface_destroy (surface);
+ }
+
+ if (horiz) {
+ cairo_surface_t* surface;
+ cairo_t* tc = 0;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, height, width);
+ tc = cairo_create (surface);
+
+ cairo_matrix_t m;
+ cairo_matrix_init_rotate (&m, -M_PI/2.0);
+ cairo_matrix_translate (&m, -height, 0);
+ cairo_pattern_set_matrix (pat, &m);
+ cairo_set_source (tc, pat);
+ cairo_rectangle (tc, 0, 0, height, width);
+ cairo_fill (tc);
+ cairo_pattern_destroy (pat);
+ pat = cairo_pattern_create_for_surface (surface);
+ cairo_destroy (tc);
+ cairo_surface_destroy (surface);
+ }
+
+ Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
+
+ return p;
+}
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_vertical_meter(
+ int width, int height, int *clr, float *stp, int styleflags)
+{
+ height = max(height, min_pattern_metric_size);
+ height = min(height, max_pattern_metric_size);
+
+ const Pattern10MapKey key (width, height,
+ stp[0], stp[1], stp[2], stp[3],
+ clr[0], clr[1], clr[2], clr[3],
+ clr[4], clr[5], clr[6], clr[7],
+ clr[8], clr[9], styleflags);
+
+ Pattern10Map::iterator i;
+ if ((i = vm_pattern_cache.find (key)) != vm_pattern_cache.end()) {
+ return i->second;
+ }
+ // TODO flush pattern cache if it gets too large
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
+ width, height, clr, stp, styleflags, false);
+ vm_pattern_cache[key] = p;
+
+ return p;
+}
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_vertical_background(
+ int width, int height, int *bgc, bool /*shade */)
+{
+ height = max(height, min_pattern_metric_size);
+ height = min(height, max_pattern_metric_size);
+ height += 2;
+
+ const PatternBgMapKey key (width, height, bgc[0], bgc[1], false);
+ PatternBgMap::iterator i;
+ if ((i = vb_pattern_cache.find (key)) != vb_pattern_cache.end()) {
+ return i->second;
+ }
+ // TODO flush pattern cache if it gets too large
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
+ width, height, bgc, false, false);
+ vb_pattern_cache[key] = p;
+
+ return p;
+}
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_horizontal_meter(
+ int width, int height, int *clr, float *stp, int styleflags)
+{
+ width = max(width, min_pattern_metric_size);
+ width = min(width, max_pattern_metric_size);
+
+ const Pattern10MapKey key (width, height,
+ stp[0], stp[1], stp[2], stp[3],
+ clr[0], clr[1], clr[2], clr[3],
+ clr[4], clr[5], clr[6], clr[7],
+ clr[8], clr[9], styleflags);
+
+ Pattern10Map::iterator i;
+ if ((i = hm_pattern_cache.find (key)) != hm_pattern_cache.end()) {
+ return i->second;
+ }
+ // TODO flush pattern cache if it gets too large
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
+ height, width, clr, stp, styleflags, true);
+
+ hm_pattern_cache[key] = p;
+ return p;
+}
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_horizontal_background(
+ int width, int height, int *bgc, bool /* shade */)
+{
+ width = max(width, min_pattern_metric_size);
+ width = min(width, max_pattern_metric_size);
+ width += 2;
+
+ const PatternBgMapKey key (width, height, bgc[0], bgc[1], false);
+ PatternBgMap::iterator i;
+ if ((i = hb_pattern_cache.find (key)) != hb_pattern_cache.end()) {
+ return i->second;
+ }
+ // TODO flush pattern cache if it gets too large
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
+ height, width, bgc, false, true);
+
+ hb_pattern_cache[key] = p;
+
+ return p;
+}
+
+
+
+void
+FastMeter::set_hold_count (long val)
+{
+ if (val < 1) {
+ val = 1;
+ }
+
+ hold_cnt = val;
+ hold_state = 0;
+ current_peak = 0;
+
+ queue_draw ();
+}
+
+void
+FastMeter::on_size_request (GtkRequisition* req)
+{
+ if (orientation == Vertical) {
+ vertical_size_request (req);
+ } else {
+ horizontal_size_request (req);
+ }
+}
+
+void
+FastMeter::vertical_size_request (GtkRequisition* req)
+{
+ req->height = request_height;
+ req->height = max(req->height, min_pattern_metric_size);
+ req->height = min(req->height, max_pattern_metric_size);
+ req->height += 2;
+
+ req->width = request_width;
+}
+
+void
+FastMeter::horizontal_size_request (GtkRequisition* req)
+{
+ req->width = request_width;
+ req->width = max(req->width, min_pattern_metric_size);
+ req->width = min(req->width, max_pattern_metric_size);
+ req->width += 2;
+
+ req->height = request_height;
+}
+
+void
+FastMeter::on_size_allocate (Gtk::Allocation &alloc)
+{
+ if (orientation == Vertical) {
+ vertical_size_allocate (alloc);
+ } else {
+ horizontal_size_allocate (alloc);
+ }
+ queue_draw ();
+}
+
+void
+FastMeter::vertical_size_allocate (Gtk::Allocation &alloc)
+{
+ if (alloc.get_width() != request_width) {
+ alloc.set_width (request_width);
+ }
+
+ int h = alloc.get_height();
+ h = max (h, min_pattern_metric_size + 2);
+ h = min (h, max_pattern_metric_size + 2);
+
+ if (h != alloc.get_height()) {
+ alloc.set_height (h);
+ }
+
+ if (pixheight != h) {
+ fgpattern = request_vertical_meter (request_width, h, _clr, _stp, _styleflags);
+ bgpattern = request_vertical_background (request_width, h, highlight ? _bgh : _bgc, false);
+ pixheight = h;
+ pixwidth = request_width;
+ }
+
+ CairoWidget::on_size_allocate (alloc);
+}
+
+void
+FastMeter::horizontal_size_allocate (Gtk::Allocation &alloc)
+{
+ if (alloc.get_height() != request_height) {
+ alloc.set_height (request_height);
+ }
+
+ int w = alloc.get_width();
+ w = max (w, min_pattern_metric_size + 2);
+ w = min (w, max_pattern_metric_size + 2);
+
+ if (w != alloc.get_width()) {
+ alloc.set_width (w);
+ }
+
+ if (pixwidth != w) {
+ fgpattern = request_horizontal_meter (w, request_height, _clr, _stp, _styleflags);
+ bgpattern = request_horizontal_background (w, request_height, highlight ? _bgh : _bgc, false);
+ pixwidth = w;
+ pixheight = request_height;
+ }
+
+ CairoWidget::on_size_allocate (alloc);
+}
+
+void
+FastMeter::render (cairo_t* cr, cairo_rectangle_t* area)
+{
+ if (orientation == Vertical) {
+ return vertical_expose (cr, area);
+ } else {
+ return horizontal_expose (cr, area);
+ }
+}
+
+void
+FastMeter::vertical_expose (cairo_t* cr, cairo_rectangle_t* area)
+{
+ gint top_of_meter;
+ // GdkRectangle background;
+ // GdkRectangle eventarea;
+
+ //cairo_set_source_rgb (cr, 0, 0, 0); // black
+ //rounded_rectangle (cr, 0, 0, pixwidth + 2, pixheight + 2, 2);
+ //cairo_stroke (cr);
+
+ top_of_meter = (gint) floor (pixheight * current_level);
+
+ /* reset the height & origin of the rect that needs to show the pixbuf
+ */
+
+ pixrect.height = top_of_meter;
+ pixrect.y = pixheight - top_of_meter;
+
+ // background.x = 0;
+ // background.y = 0;
+ // background.width = pixrect.width;
+ // background.height = pixheight - top_of_meter;
+
+ // eventarea.x = area->x;
+ // eventarea.y = area->y;
+ // eventarea.width = area->width;
+ // eventarea.height = area->height;
+
+ // Switching to CAIRO we would like to draw on the container's bkg.
+ // if (gdk_rectangle_intersect (&background, &eventarea, &intersection)) {
+ // cairo_set_source (cr, bgpattern->cobj());
+ // cairo_rectangle (cr, intersection.x, intersection.y, intersection.width, intersection.height);
+ // cairo_fill (cr);
+ // }
+
+ // MEMO: Normaly MATURE OS clips so called invalidated rects itself making APP free of
+ // heavy operations which OS does with graphic HW
+
+ // NOTE FROM PAUL: GTK does clip already. The invalidated rect isn't the only area
+ // we want to clip to however, which is why this object/class is called FastMeter.
+ // I have left stuff commented out as I found it when I merged from Ardour in August 2014,
+ // but this commenting and the previous MEMO comment represent a misunderstanding
+ // of what this code is doing.
+
+ // if (gdk_rectangle_intersect (&pixrect, &eventarea, &intersection)) {
+ // draw the part of the meter image that we need. the area we draw is bounded "in reverse" (top->bottom)
+ //cairo_set_source (cr, fgpattern->cobj());
+ cairo_set_source_rgba (cr, 0.69, 0.69, 0.69, 1);
+ cairo_rectangle (cr, pixrect.x, pixrect.y, pixrect.width, pixrect.height);
+ cairo_fill (cr);
+ //}
+
+ // draw peak bar
+
+ if (hold_state) {
+ last_peak_rect.x = 0;
+ last_peak_rect.width = pixwidth;
+ last_peak_rect.y = max(0, pixheight - (gint) floor (pixheight * current_peak));
+ if (bright_hold || (_styleflags & 2)) {
+ last_peak_rect.height = max(0, min(3, pixheight - last_peak_rect.y ));
+ } else {
+ last_peak_rect.height = max(0, min(2, pixheight - last_peak_rect.y ));
+ }
+
+ cairo_set_source (cr, fgpattern->cobj());
+ cairo_rectangle (cr, last_peak_rect.x, last_peak_rect.y, last_peak_rect.width, last_peak_rect.height);
+
+ if (bright_hold && !no_rgba_overlay) {
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.3);
+ }
+ cairo_fill (cr);
+
+ } else {
+ last_peak_rect.width = 0;
+ last_peak_rect.height = 0;
+ }
+}
+
+void
+FastMeter::horizontal_expose (cairo_t* cr, cairo_rectangle_t* area)
+{
+ gint right_of_meter;
+
+ //cairo_set_source_rgb (cr, 0, 0, 0); // black
+ //rounded_rectangle (cr, 0, 0, pixwidth + 2, pixheight + 2, 2);
+ //cairo_stroke (cr);
+
+ right_of_meter = (gint) floor (pixwidth * current_level);
+
+ /* reset the height & origin of the rect that needs to show the pixbuf
+ */
+
+ pixrect.width = right_of_meter;
+
+ // draw peak bar
+
+ if (hold_state) {
+ last_peak_rect.y = 1;
+ last_peak_rect.height = pixheight;
+ const int xpos = floor (pixwidth * current_peak);
+ if (bright_hold || (_styleflags & 2)) {
+ last_peak_rect.width = min(3, xpos );
+ } else {
+ last_peak_rect.width = min(2, xpos );
+ }
+ last_peak_rect.x = 1 + max(0, xpos - last_peak_rect.width);
+
+ cairo_set_source (cr, fgpattern->cobj());
+ cairo_rectangle (cr, last_peak_rect.x, last_peak_rect.y, last_peak_rect.width, last_peak_rect.height);
+
+ if (bright_hold && !no_rgba_overlay) {
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.3);
+ }
+ cairo_fill (cr);
+
+ } else {
+ last_peak_rect.width = 0;
+ last_peak_rect.height = 0;
+ }
+}
+
+void
+FastMeter::set (float lvl, float peak)
+{
+ float old_level = current_level;
+ float old_peak = current_peak;
+
+ if (pixwidth <= 0 || pixheight <=0) return;
+
+ if (peak == -1) {
+ if (lvl >= current_peak) {
+ current_peak = lvl;
+ hold_state = hold_cnt;
+ }
+
+ if (hold_state > 0) {
+ if (--hold_state == 0) {
+ current_peak = lvl;
+ }
+ }
+ bright_hold = false;
+ } else {
+ current_peak = peak;
+ hold_state = 1;
+ bright_hold = true;
+ }
+
+ current_level = lvl;
+
+ if (current_level == old_level && current_peak == old_peak && (hold_state == 0 || peak != -1)) {
+ return;
+ }
+
+ Glib::RefPtr<Gdk::Window> win;
+
+ if ((win = get_window()) == 0) {
+ queue_draw ();
+ return;
+ }
+
+ if (orientation == Vertical) {
+ queue_vertical_redraw (win, old_level);
+ } else {
+ queue_horizontal_redraw (win, old_level);
+ }
+}
+
+void
+FastMeter::queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>& win, float old_level)
+{
+ GdkRectangle rect;
+
+ gint new_top = (gint) floor (pixheight * current_level);
+
+ rect.x = 0;
+ rect.width = pixwidth;
+ rect.height = new_top;
+ rect.y = pixheight - new_top;
+
+ if (current_level > old_level) {
+ /* colored/pixbuf got larger, just draw the new section */
+ /* rect.y stays where it is because of X coordinates */
+ /* height of invalidated area is between new.y (smaller) and old.y
+ (larger).
+ X coordinates just make my brain hurt.
+ */
+ rect.height = pixrect.y - rect.y;
+ } else {
+ /* it got smaller, compute the difference */
+ /* rect.y becomes old.y (the smaller value) */
+ rect.y = pixrect.y;
+ /* rect.height is the old.y (smaller) minus the new.y (larger)
+ */
+ rect.height = pixrect.height - rect.height;
+ }
+
+ GdkRegion* region = 0;
+ bool queue = false;
+
+ if (rect.height != 0) {
+
+ /* ok, first region to draw ... */
+
+ region = gdk_region_rectangle (&rect);
+ queue = true;
+ }
+
+ /* redraw the last place where the last peak hold bar was;
+ the next expose will draw the new one whether its part of
+ expose region or not.
+ */
+
+ if (last_peak_rect.width * last_peak_rect.height != 0) {
+ if (!queue) {
+ region = gdk_region_new ();
+ queue = true;
+ }
+ gdk_region_union_with_rect (region, &last_peak_rect);
+ }
+
+ if (hold_state && current_peak > 0) {
+ if (!queue) {
+ region = gdk_region_new ();
+ queue = true;
+ }
+ rect.x = 1;
+ rect.y = max(1, 1 + pixheight - (gint) floor (pixheight * current_peak));
+ if (bright_hold || (_styleflags & 2)) {
+ rect.height = max(0, min(3, pixheight - last_peak_rect.y -1 ));
+ } else {
+ rect.height = max(0, min(2, pixheight - last_peak_rect.y -1 ));
+ }
+ rect.width = pixwidth;
+ gdk_region_union_with_rect (region, &rect);
+ }
+
+ if (queue) {
+ gdk_window_invalidate_region (win->gobj(), region, true);
+ }
+ if (region) {
+ gdk_region_destroy(region);
+ region = 0;
+ }
+}
+
+void
+FastMeter::queue_horizontal_redraw (const Glib::RefPtr<Gdk::Window>& win, float old_level)
+{
+ GdkRectangle rect;
+
+ gint new_right = (gint) floor (pixwidth * current_level);
+
+ rect.height = pixheight;
+ rect.y = 1;
+
+ if (current_level > old_level) {
+ rect.x = 1 + pixrect.width;
+ /* colored/pixbuf got larger, just draw the new section */
+ rect.width = new_right - pixrect.width;
+ } else {
+ /* it got smaller, compute the difference */
+ rect.x = 1 + new_right;
+ /* rect.height is the old.x (smaller) minus the new.x (larger) */
+ rect.width = pixrect.width - new_right;
+ }
+
+ GdkRegion* region = 0;
+ bool queue = false;
+
+ if (rect.height != 0) {
+
+ /* ok, first region to draw ... */
+
+ region = gdk_region_rectangle (&rect);
+ queue = true;
+ }
+
+ /* redraw the last place where the last peak hold bar was;
+ the next expose will draw the new one whether its part of
+ expose region or not.
+ */
+
+ if (last_peak_rect.width * last_peak_rect.height != 0) {
+ if (!queue) {
+ region = gdk_region_new ();
+ queue = true;
+ }
+ gdk_region_union_with_rect (region, &last_peak_rect);
+ }
+
+ if (hold_state && current_peak > 0) {
+ if (!queue) {
+ region = gdk_region_new ();
+ queue = true;
+ }
+ rect.y = 1;
+ rect.height = pixheight;
+ const int xpos = floor (pixwidth * current_peak);
+ if (bright_hold || (_styleflags & 2)) {
+ rect.width = min(3, xpos);
+ } else {
+ rect.width = min(2, xpos);
+ }
+ rect.x = 1 + max(0, xpos - rect.width);
+ gdk_region_union_with_rect (region, &rect);
+ }
+
+ if (queue) {
+ gdk_window_invalidate_region (win->gobj(), region, true);
+ }
+ if (region) {
+ gdk_region_destroy(region);
+ region = 0;
+ }
+}
+
+void
+FastMeter::set_highlight (bool onoff)
+{
+ if (highlight == onoff) {
+ return;
+ }
+ highlight = onoff;
+ if (orientation == Vertical) {
+ bgpattern = request_vertical_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, false);
+ } else {
+ bgpattern = request_horizontal_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, false);
+ }
+ queue_draw ();
+}
+
+void
+FastMeter::clear ()
+{
+ current_level = 0;
+ current_peak = 0;
+ hold_state = 0;
+ queue_draw ();
+}
diff --git a/libs/gtkmm2ext/wscript b/libs/gtkmm2ext/wscript
index bbe4ae535e..b7545c33c5 100644
--- a/libs/gtkmm2ext/wscript
+++ b/libs/gtkmm2ext/wscript
@@ -41,7 +41,6 @@ gtkmm2ext_sources = [
'debug.cc',
'dndtreeview.cc',
'emscale.cc',
- 'fastmeter.cc',
'focus_entry.cc',
'grouped_buttons.cc',
'gtk_ui.cc',
@@ -85,12 +84,18 @@ def configure(conf):
def build(bld):
+ sources = gtkmm2ext_sources
+ if bld.is_tracks_build():
+ sources += [ 'waves_fastmeter.cc', 'fader.cc' ]
+ else:
+ sources += [ 'fastmeter.cc' ]
+
if bld.is_defined ('INTERNAL_SHARED_LIBS'):
- obj = bld.shlib(features = 'c cxx cshlib cxxshlib', source=gtkmm2ext_sources)
+ obj = bld.shlib(features = 'c cxx cshlib cxxshlib', source=sources)
# defines for this library
obj.defines = [ 'LIBGTKMM2EXT_DLL_EXPORTS', 'ABSTRACT_UI_EXPORTS' ]
else:
- obj = bld.stlib(features = 'c cxx cstlib cxxstlib', source=gtkmm2ext_sources)
+ obj = bld.stlib(features = 'c cxx cstlib cxxstlib', source=sources)
obj.cxxflags = [ '-fPIC' ]
obj.defines = [ ]
@@ -99,7 +104,7 @@ def build(bld):
obj.name = 'libgtkmm2ext'
obj.target = 'gtkmm2ext'
obj.uselib = 'GTKMM GTK GTKOSX OSX GDK'
- obj.use = [ 'libpbd' ]
+ obj.use = [ 'libpbd', 'libardour' ]
obj.vnum = GTKMM2EXT_LIB_VERSION
obj.install_path = bld.env['LIBDIR']
obj.defines += [