summaryrefslogtreecommitdiff
path: root/gtk2_ardour/ardour_button.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-10-29 15:54:30 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-10-29 15:54:30 +0000
commitbde8437387ccd5bfd86d641d15444f76532b5e2b (patch)
treeadd3dc5a9cf3dec8c7164dadc6d7924532ff900c /gtk2_ardour/ardour_button.cc
parentd7b685cc5fa0b87e2c5569d97772605759daa586 (diff)
make ArdourButtons be MIDI-learnable; tweaks to ArdourButton design and implementation; use ArdourButtons (all gray for now) in the Monitor section.
git-svn-id: svn://localhost/ardour2/branches/3.0@10338 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/ardour_button.cc')
-rw-r--r--gtk2_ardour/ardour_button.cc154
1 files changed, 132 insertions, 22 deletions
diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc
index d72e9549c0..f925ecf6bc 100644
--- a/gtk2_ardour/ardour_button.cc
+++ b/gtk2_ardour/ardour_button.cc
@@ -24,36 +24,44 @@
#include <pangomm/layout.h>
#include "pbd/compose.h"
+#include "pbd/error.h"
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/rgb_macros.h"
+#include "gtkmm2ext/gui_thread.h"
#include "ardour_button.h"
#include "ardour_ui.h"
#include "global_signals.h"
+#include "i18n.h"
+
using namespace Gdk;
using namespace Gtk;
using namespace Glib;
+using namespace PBD;
using std::max;
using std::min;
+using namespace std;
ArdourButton::Element ArdourButton::default_elements = ArdourButton::Element (ArdourButton::Edge|ArdourButton::Body|ArdourButton::Text);
ArdourButton::Element ArdourButton::led_default_elements = ArdourButton::Element (ArdourButton::default_elements|ArdourButton::Indicator);
+ArdourButton::Element ArdourButton::just_led_default_elements = ArdourButton::Element (ArdourButton::Edge|ArdourButton::Body|ArdourButton::Indicator);
ArdourButton::ArdourButton (Element e)
: _elements (e)
+ , _act_on_release (true)
, _text_width (0)
, _text_height (0)
- , _diameter (0.0)
- , _corner_radius (9)
+ , _diameter (11.0)
+ , _corner_radius (9.0)
, edge_pattern (0)
, fill_pattern (0)
, led_inset_pattern (0)
, reflection_pattern (0)
, _led_left (false)
- , _fixed_diameter (false)
- , _distinct_led_click (true)
+ , _fixed_diameter (true)
+ , _distinct_led_click (false)
{
ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler));
StateChanged.connect (sigc::mem_fun (*this, &ArdourButton::state_handler));
@@ -115,9 +123,9 @@ ArdourButton::render (cairo_t* cr)
if (_elements & Body) {
if (_elements & Edge) {
- Gtkmm2ext::rounded_rectangle (cr, 1, 1, _width-2, _height-2, _corner_radius);
+ Gtkmm2ext::rounded_rectangle (cr, 1, 1, _width-2, _height-2, _corner_radius - 1.0);
} else {
- Gtkmm2ext::rounded_rectangle (cr, 0, 0, _width, _height, _corner_radius);
+ Gtkmm2ext::rounded_rectangle (cr, 0, 0, _width, _height, _corner_radius - 1.0);
}
cairo_set_source (cr, fill_pattern);
cairo_fill (cr);
@@ -145,11 +153,17 @@ ArdourButton::render (cairo_t* cr)
if (_elements & Indicator) {
/* move to the center of the indicator/led */
-
- if (_led_left) {
- cairo_translate (cr, 3 + (_diameter/2.0), _height/2.0);
+
+ cairo_save (cr);
+
+ if (_elements & Text) {
+ if (_led_left) {
+ cairo_translate (cr, 3 + (_diameter/2.0), _height/2.0);
+ } else {
+ cairo_translate (cr, _width - ((_diameter/2.0) + 4.0), _height/2.0);
+ }
} else {
- cairo_translate (cr, _width - ((_diameter/2.0) + 4.0), _height/2.0);
+ cairo_translate (cr, _width/2.0, _height/2.0);
}
//inset
@@ -172,6 +186,17 @@ ArdourButton::render (cairo_t* cr)
cairo_arc (cr, 0, 0, _diameter/2-3, 0, 2 * M_PI);
cairo_set_source (cr, reflection_pattern);
cairo_fill (cr);
+
+ cairo_restore (cr);
+
+ }
+
+ /* a partially transparent gray layer to indicate insensitivity */
+
+ if ((visual_state() & Insensitive)) {
+ cairo_rectangle (cr, 0, 0, _width, _height);
+ cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.5);
+ cairo_fill (cr);
}
}
@@ -206,16 +231,22 @@ ArdourButton::on_size_request (Gtk::Requisition* req)
int xpad = 0;
int ypad = 6;
- if (!_text.empty()) {
+ CairoWidget::on_size_request (req);
+
+ if ((_elements & Text) && !_text.empty()) {
_layout->get_pixel_size (_text_width, _text_height);
xpad += 6;
+ } else {
+ _text_width = 0;
+ _text_height = 0;
}
- if (_fixed_diameter) {
- req->width = _text_width + (int) _diameter + xpad;
- req->height = max (_text_height, (int) _diameter) + ypad;
- } else {
- CairoWidget::on_size_request (req);
+ if ((_elements & Indicator) && _fixed_diameter) {
+ req->width = _text_width + lrint (_diameter) + xpad;
+ req->height = max (_text_height, (int) lrint (_diameter)) + ypad;
+ } else {
+ req->width = _text_width + xpad;
+ req->height = _text_height + ypad;
}
}
@@ -341,12 +372,17 @@ ArdourButton::on_button_press_event (GdkEventButton *ev)
int left;
int right;
- if (_led_left) {
- left = 4;
- right = left + _diameter;
+ if (_elements & Text) {
+ if (_led_left) {
+ left = 4;
+ right = left + _diameter;
+ } else {
+ left = lrint (_width - 4 - _diameter/2.0);
+ right = left + _diameter;
+ }
} else {
- left = lrint (_width - 4 - _diameter/2.0);
- right = left + _diameter;
+ left = _width/2.0 - (_diameter/2.0);
+ right = _width/2.0 + (_diameter/2.0);
}
if (ev->x >= left && ev->x <= right && ev->y <= bottom && ev->y >= top) {
@@ -354,13 +390,23 @@ ArdourButton::on_button_press_event (GdkEventButton *ev)
}
}
+ if (binding_proxy.button_press_handler (ev)) {
+ return true;
+ }
+
+ if (!_act_on_release) {
+ if (_action) {
+ _action->activate ();
+ return true;
+ }
+ }
+
return false;
}
bool
ArdourButton::on_button_release_event (GdkEventButton *ev)
{
-
if ((_elements & Indicator) && _distinct_led_click) {
/* if within LED, emit signal */
@@ -383,6 +429,13 @@ ArdourButton::on_button_release_event (GdkEventButton *ev)
}
}
+ if (_act_on_release) {
+ if (_action) {
+ _action->activate ();
+ return true;
+ }
+ }
+
return false;
}
@@ -405,3 +458,60 @@ ArdourButton::on_size_allocate (Allocation& alloc)
CairoWidget::on_size_allocate (alloc);
set_colors ();
}
+
+void
+ArdourButton::set_controllable (boost::shared_ptr<Controllable> c)
+{
+ watch_connection.disconnect ();
+ binding_proxy.set_controllable (c);
+}
+
+void
+ArdourButton::watch ()
+{
+ boost::shared_ptr<Controllable> c (binding_proxy.get_controllable ());
+
+ if (!c) {
+ warning << _("button cannot watch state of non-existing Controllable\n") << endmsg;
+ return;
+ }
+
+ c->Changed.connect (watch_connection, invalidator(*this), boost::bind (&ArdourButton::controllable_changed, this), gui_context());
+}
+
+void
+ArdourButton::controllable_changed ()
+{
+ float val = binding_proxy.get_controllable()->get_value();
+
+ if (fabs (val) >= 0.5f) {
+ set_active_state (CairoWidget::Active);
+ } else {
+ unset_active_state ();
+ }
+}
+
+void
+ArdourButton::set_related_action (RefPtr<Action> act)
+{
+ _action = act;
+
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (_action);
+ if (tact) {
+ tact->signal_toggled().connect (sigc::mem_fun (*this, &ArdourButton::action_toggled));
+ }
+}
+
+void
+ArdourButton::action_toggled ()
+{
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (_action);
+
+ if (tact) {
+ if (tact->get_active()) {
+ set_active_state (CairoWidget::Active);
+ } else {
+ unset_active_state ();
+ }
+ }
+}