From fa9d3b72f38fab673c1f6e72201b5ea728d93cc7 Mon Sep 17 00:00:00 2001 From: Ben Loftis Date: Tue, 23 Feb 2021 11:27:23 -0600 Subject: [PATCH] ArdourKnob: use ArdourCtrlBase --- libs/widgets/ardour_knob.cc | 532 ++++++----------------------- libs/widgets/widgets/ardour_knob.h | 110 +----- 2 files changed, 122 insertions(+), 520 deletions(-) diff --git a/libs/widgets/ardour_knob.cc b/libs/widgets/ardour_knob.cc index bffb42d64b..db2032c7cf 100644 --- a/libs/widgets/ardour_knob.cc +++ b/libs/widgets/ardour_knob.cc @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Paul Davis - * Copyright (C) 2017 Robin Gareus + * Copyright (C) 2017-2021 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,19 +17,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include #include #include #include "pbd/compose.h" -#include "pbd/controllable.h" -#include "pbd/error.h" -#include "gtkmm2ext/colors.h" -#include "gtkmm2ext/gui_thread.h" -#include "gtkmm2ext/keyboard.h" #include "gtkmm2ext/rgb_macros.h" #include "gtkmm2ext/utils.h" @@ -38,53 +31,30 @@ #include "pbd/i18n.h" -using namespace Gtkmm2ext; using namespace ArdourWidgets; -using namespace Gtk; -using namespace Glib; using namespace PBD; -using std::max; -using std::min; -using namespace std; ArdourKnob::Element ArdourKnob::default_elements = ArdourKnob::Element (ArdourKnob::Arc); ArdourKnob::ArdourKnob (Element e, Flags flags) - : _elements (e) - , _hovering (false) - , _grabbed_x (0) - , _grabbed_y (0) - , _val (0) - , _normal (0) - , _dead_zone_delta (0) - , _flags (flags) - , _tooltip (this) -{ - UIConfigurationBase::instance().ColorsChanged.connect (sigc::mem_fun (*this, &ArdourKnob::color_handler)); - - // watch automation :( - // TODO only use for GainAutomation - //Timers::rapid_connect (sigc::bind (sigc::mem_fun (*this, &ArdourKnob::controllable_changed), false)); -} - -ArdourKnob::~ArdourKnob() + : ArdourCtrlBase (flags) + , _elements (e) { } void ArdourKnob::render (Cairo::RefPtr const& ctx, cairo_rectangle_t*) { - cairo_t* cr = ctx->cobj(); - cairo_pattern_t* shade_pattern; + cairo_t* cr = ctx->cobj (); - float width = get_width(); - float height = get_height(); + float width = get_width (); + float height = get_height (); - const float scale = min(width, height); - const float pointer_thickness = 3.0 * (scale/80); //(if the knob is 80 pixels wide, we want a 3-pix line on it) + const float scale = std::min (width, height); + const float pointer_thickness = 3.0 * (scale / 80); // if the knob is 80 pixels wide, we want a 3-pix line on it const float start_angle = ((180 - 65) * G_PI) / 180; - const float end_angle = ((360 + 65) * G_PI) / 180; + const float end_angle = ((360 + 65) * G_PI) / 180; float zero = 0; if (_flags & ArcToZero) { @@ -92,57 +62,59 @@ ArdourKnob::render (Cairo::RefPtr const& ctx, cairo_rectangle_t* } const float value_angle = start_angle + (_val * (end_angle - start_angle)); - const float zero_angle = start_angle + (zero * (end_angle - start_angle)); + const float zero_angle = start_angle + (zero * (end_angle - start_angle)); float value_x = cos (value_angle); float value_y = sin (value_angle); - float xc = 0.5 + width/ 2.0; - float yc = 0.5 + height/ 2.0; + float xc = 0.5 + width / 2.0; + float yc = 0.5 + height / 2.0; - cairo_translate (cr, xc, yc); //after this, everything is based on the center of the knob + cairo_translate (cr, xc, yc); - //get the knob color from the theme - Gtkmm2ext::Color knob_color = UIConfigurationBase::instance().color (string_compose ("%1", get_name())); + /* get the knob color from the theme */ + Gtkmm2ext::Color knob_color = UIConfigurationBase::instance ().color (string_compose ("%1", get_name ())); - float center_radius = 0.48*scale; - float border_width = 0.8; + float center_radius = 0.48 * scale; + float border_width = 0.8; - bool arc = (_elements & Arc)==Arc; - bool bevel = (_elements & Bevel)==Bevel; - bool flat = flat_buttons (); + bool arc = (_elements & Arc) == Arc; + bool bevel = (_elements & Bevel) == Bevel; + bool flat = flat_buttons (); - if ( arc ) { - center_radius = scale*0.33; + if (arc) { + center_radius = scale * 0.33; - float inner_progress_radius = scale*0.38; - float outer_progress_radius = scale*0.48; - float progress_width = (outer_progress_radius-inner_progress_radius); - float progress_radius = inner_progress_radius + progress_width/2.0; + float inner_progress_radius = scale * 0.38; + float outer_progress_radius = scale * 0.48; + float progress_width = (outer_progress_radius - inner_progress_radius); + float progress_radius = inner_progress_radius + progress_width / 2.0; - //dark arc background - cairo_set_source_rgb (cr, 0.3, 0.3, 0.3 ); + /* dark arc background */ + cairo_set_source_rgb (cr, 0.3, 0.3, 0.3); cairo_set_line_width (cr, progress_width); cairo_arc (cr, 0, 0, progress_radius, start_angle, end_angle); cairo_stroke (cr); - //look up the arc colors from the config + /* look up the arc colors from the config */ double red_start, green_start, blue_start, unused; - Gtkmm2ext::Color arc_start_color = UIConfigurationBase::instance().color ( string_compose ("%1: arc start", get_name())); - Gtkmm2ext::color_to_rgba( arc_start_color, red_start, green_start, blue_start, unused ); double red_end, green_end, blue_end; - Gtkmm2ext::Color arc_end_color = UIConfigurationBase::instance().color ( string_compose ("%1: arc end", get_name()) ); - Gtkmm2ext::color_to_rgba( arc_end_color, red_end, green_end, blue_end, unused ); - //vary the arc color over the travel of the knob - float intensity = fabsf (_val - zero) / std::max(zero, (1.f - zero)); + Gtkmm2ext::Color arc_start_color = UIConfigurationBase::instance ().color (string_compose ("%1: arc start", get_name ())); + Gtkmm2ext::color_to_rgba (arc_start_color, red_start, green_start, blue_start, unused); + Gtkmm2ext::Color arc_end_color = UIConfigurationBase::instance ().color (string_compose ("%1: arc end", get_name ())); + Gtkmm2ext::color_to_rgba (arc_end_color, red_end, green_end, blue_end, unused); + + /* vary the arc color over the travel of the knob */ + float intensity = fabsf (_val - zero) / std::max (zero, (1.f - zero)); const float intensity_inv = 1.0 - intensity; + float r = intensity_inv * red_end + intensity * red_start; float g = intensity_inv * green_end + intensity * green_start; float b = intensity_inv * blue_end + intensity * blue_start; - //draw the arc - cairo_set_source_rgb (cr, r,g,b); + /* draw the arc */ + cairo_set_source_rgb (cr, r, g, b); cairo_set_line_width (cr, progress_width); if (zero_angle > value_angle) { cairo_arc (cr, 0, 0, progress_radius, value_angle, zero_angle); @@ -151,14 +123,15 @@ ArdourKnob::render (Cairo::RefPtr const& ctx, cairo_rectangle_t* } cairo_stroke (cr); - //shade the arc + /* shade the arc */ if (!flat) { - shade_pattern = cairo_pattern_create_linear (0.0, -yc, 0.0, yc); //note we have to offset the pattern from our centerpoint - cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1,1,1, 0.15); - cairo_pattern_add_color_stop_rgba (shade_pattern, 0.5, 1,1,1, 0.0); - cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 1,1,1, 0.0); + cairo_pattern_t* shade_pattern; + shade_pattern = cairo_pattern_create_linear (0.0, -yc, 0.0, yc); + cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1, 1, 1, 0.15); + cairo_pattern_add_color_stop_rgba (shade_pattern, 0.5, 1, 1, 1, 0.0); + cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 1, 1, 1, 0.0); cairo_set_source (cr, shade_pattern); - cairo_arc (cr, 0, 0, outer_progress_radius-1, 0, 2.0*G_PI); + cairo_arc (cr, 0, 0, outer_progress_radius - 1, 0, 2.0 * G_PI); cairo_fill (cr); cairo_pattern_destroy (shade_pattern); } @@ -183,387 +156,115 @@ ArdourKnob::render (Cairo::RefPtr const& ctx, cairo_rectangle_t* } if (!flat) { - //knob shadow - cairo_save(cr); - cairo_translate(cr, pointer_thickness+1, pointer_thickness+1 ); - cairo_set_source_rgba (cr, 0, 0, 0, 0.1 ); - cairo_arc (cr, 0, 0, center_radius-1, 0, 2.0*G_PI); + /* knob shadow */ + cairo_save (cr); + cairo_translate (cr, pointer_thickness + 1, pointer_thickness + 1); + cairo_set_source_rgba (cr, 0, 0, 0, 0.1); + cairo_arc (cr, 0, 0, center_radius - 1, 0, 2.0 * G_PI); cairo_fill (cr); - cairo_restore(cr); + cairo_restore (cr); - //inner circle - Gtkmm2ext::set_source_rgba(cr, knob_color); - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); + /* inner circle */ + Gtkmm2ext::set_source_rgba (cr, knob_color); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); cairo_fill (cr); - //gradient if (bevel) { - //knob gradient - shade_pattern = cairo_pattern_create_linear (0.0, -yc, 0.0, yc); //note we have to offset the gradient from our centerpoint - cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1,1,1, 0.2); - cairo_pattern_add_color_stop_rgba (shade_pattern, 0.2, 1,1,1, 0.2); - cairo_pattern_add_color_stop_rgba (shade_pattern, 0.8, 0,0,0, 0.2); - cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 0,0,0, 0.2); + /* knob gradient */ + cairo_pattern_t* shade_pattern; + shade_pattern = cairo_pattern_create_linear (0.0, -yc, 0.0, yc); + cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1, 1, 1, 0.2); + cairo_pattern_add_color_stop_rgba (shade_pattern, 0.2, 1, 1, 1, 0.2); + cairo_pattern_add_color_stop_rgba (shade_pattern, 0.8, 0, 0, 0, 0.2); + cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 0, 0, 0, 0.2); cairo_set_source (cr, shade_pattern); - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); cairo_fill (cr); cairo_pattern_destroy (shade_pattern); - //flat top over beveled edge - Gtkmm2ext::set_source_rgb_a (cr, knob_color, 0.5 ); - cairo_arc (cr, 0, 0, center_radius-pointer_thickness, 0, 2.0*G_PI); + /* flat top over beveled edge */ + Gtkmm2ext::set_source_rgb_a (cr, knob_color, 0.5); + cairo_arc (cr, 0, 0, center_radius - pointer_thickness, 0, 2.0 * G_PI); cairo_fill (cr); } else { - //radial gradient - shade_pattern = cairo_pattern_create_radial ( -center_radius, -center_radius, 1, -center_radius, -center_radius, center_radius*2.5 ); //note we have to offset the gradient from our centerpoint - cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1,1,1, 0.2); - cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 0,0,0, 0.3); + /* radial gradient */ + cairo_pattern_t* shade_pattern; + shade_pattern = cairo_pattern_create_radial (-center_radius, -center_radius, 1, -center_radius, -center_radius, center_radius * 2.5); + cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1, 1, 1, 0.2); + cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 0, 0, 0, 0.3); cairo_set_source (cr, shade_pattern); - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); cairo_fill (cr); cairo_pattern_destroy (shade_pattern); } } else { - //inner circle - Gtkmm2ext::set_source_rgba(cr, knob_color); - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); + /* inner circle */ + Gtkmm2ext::set_source_rgba (cr, knob_color); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); cairo_fill (cr); } - - //black knob border + /* black knob border */ cairo_set_line_width (cr, border_width); - cairo_set_source_rgba (cr, 0,0,0, 1 ); - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); + cairo_set_source_rgba (cr, 0, 0, 0, 1); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); cairo_stroke (cr); - //line shadow + /* line shadow */ if (!flat) { - cairo_save(cr); - cairo_translate(cr, 1, 1 ); - cairo_set_source_rgba (cr, 0,0,0,0.3 ); + cairo_save (cr); + cairo_translate (cr, 1, 1); + cairo_set_source_rgba (cr, 0, 0, 0, 0.3); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, pointer_thickness); cairo_move_to (cr, (center_radius * value_x), (center_radius * value_y)); - cairo_line_to (cr, ((center_radius*0.4) * value_x), ((center_radius*0.4) * value_y)); + cairo_line_to (cr, ((center_radius * 0.4) * value_x), ((center_radius * 0.4) * value_y)); cairo_stroke (cr); - cairo_restore(cr); + cairo_restore (cr); } - //line - cairo_set_source_rgba (cr, 1,1,1, 1 ); + /* line */ + cairo_set_source_rgba (cr, 1, 1, 1, 1); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, pointer_thickness); cairo_move_to (cr, (center_radius * value_x), (center_radius * value_y)); - cairo_line_to (cr, ((center_radius*0.4) * value_x), ((center_radius*0.4) * value_y)); + cairo_line_to (cr, ((center_radius * 0.4) * value_x), ((center_radius * 0.4) * value_y)); cairo_stroke (cr); - // a transparent overlay to indicate insensitivity + /* a transparent overlay to indicate insensitivity */ if (!get_sensitive ()) { - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); - uint32_t ins_color = UIConfigurationBase::instance().color ("gtk_background"); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); + uint32_t ins_color = UIConfigurationBase::instance ().color ("gtk_background"); Gtkmm2ext::set_source_rgb_a (cr, ins_color, 0.6); cairo_fill (cr); } - //highlight if grabbed or if mouse is hovering over me - if (_tooltip.dragging() || (_hovering && UIConfigurationBase::instance().get_widget_prelight() ) ) { - cairo_set_source_rgba (cr, 1,1,1, 0.12); - cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI); + /* highlight if grabbed or if mouse is hovering over me */ + if (_tooltip.dragging () || (_hovering && UIConfigurationBase::instance ().get_widget_prelight ())) { + cairo_set_source_rgba (cr, 1, 1, 1, 0.12); + cairo_arc (cr, 0, 0, center_radius, 0, 2.0 * G_PI); cairo_fill (cr); } - cairo_identity_matrix(cr); + cairo_identity_matrix (cr); } void ArdourKnob::on_size_request (Gtk::Requisition* req) { - // see ardour-button VectorIcon size, use font scaling as default - CairoWidget::on_size_request (req); // allow to override - - // we're square - if (req->width < req->height) { - req->width = req->height; + req->width = _req_width; + req->height = _req_height; + if (req->width < 1) { + req->width = 13; } - if (req->height < req->width) { - req->height = req->width; - } -} - -bool -ArdourKnob::on_scroll_event (GdkEventScroll* ev) -{ - /* mouse wheel */ - - float scale = 0.05; //by default, we step in 1/20ths of the knob travel - if (ev->state & Keyboard::GainFineScaleModifier) { - if (ev->state & Keyboard::GainExtraFineScaleModifier) { - scale *= 0.01; - } else { - scale *= 0.10; - } + if (req->height < 1) { + req->height = 13; } - boost::shared_ptr c = binding_proxy.get_controllable(); - if (c) { - float val = c->get_interface (true); - - if ( ev->direction == GDK_SCROLL_UP ) - val += scale; - else - val -= scale; - - c->set_interface (val, true); - } - - return true; -} - -bool -ArdourKnob::on_motion_notify_event (GdkEventMotion *ev) -{ - if (!(ev->state & Gdk::BUTTON1_MASK)) { - return true; - } - - boost::shared_ptr c = binding_proxy.get_controllable(); - if (!c) { - return true; - } - - - //scale the adjustment based on keyboard modifiers & GUI size - const float ui_scale = max (1.f, UIConfigurationBase::instance().get_ui_scale()); - float scale = 0.0025 / ui_scale; - - if (ev->state & Keyboard::GainFineScaleModifier) { - if (ev->state & Keyboard::GainExtraFineScaleModifier) { - scale *= 0.01; - } else { - scale *= 0.10; - } - } - - //calculate the travel of the mouse - int delta = (_grabbed_y - ev->y) - (_grabbed_x - ev->x); - if (delta == 0) { - return true; - } - - _grabbed_x = ev->x; - _grabbed_y = ev->y; - float val = c->get_interface (true); - - if (_flags & Detent) { - const float px_deadzone = 42.f * ui_scale; - - if ((val - _normal) * (val - _normal + delta * scale) < 0) { - /* detent */ - const int tozero = (_normal - val) * scale; - int remain = delta - tozero; - if (abs (remain) > px_deadzone) { - /* slow down passing the default value */ - remain += (remain > 0) ? px_deadzone * -.5 : px_deadzone * .5; - delta = tozero + remain; - _dead_zone_delta = 0; - } else { - c->set_value (c->normal(), Controllable::NoGroup); - _dead_zone_delta = remain / px_deadzone; - return true; - } - } - - if (fabsf (rintf((val - _normal) / scale) + _dead_zone_delta) < 1) { - c->set_value (c->normal(), Controllable::NoGroup); - _dead_zone_delta += delta / px_deadzone; - return true; - } - - _dead_zone_delta = 0; - } - - val += delta * scale; - c->set_interface (val, true); - - return true; -} - -bool -ArdourKnob::on_button_press_event (GdkEventButton *ev) -{ - _grabbed_x = ev->x; - _grabbed_y = ev->y; - _dead_zone_delta = 0; - - if (ev->type != GDK_BUTTON_PRESS) { - if (_grabbed) { - remove_modal_grab(); - _grabbed = false; - StopGesture (); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - } - return true; - } - - if (binding_proxy.button_press_handler (ev)) { - return true; - } - - if (ev->button != 1 && ev->button != 2) { - return false; - } - - set_active_state (Gtkmm2ext::ExplicitActive); - _tooltip.start_drag(); - add_modal_grab(); - _grabbed = true; - StartGesture (); - gdk_pointer_grab(ev->window,false, - GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK), - NULL,NULL,ev->time); - return true; -} - -bool -ArdourKnob::on_button_release_event (GdkEventButton *ev) -{ - _tooltip.stop_drag(); - _grabbed = false; - StopGesture (); - remove_modal_grab(); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - - if ( (_grabbed_y == ev->y && _grabbed_x == ev->x) && Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { //no move, shift-click sets to default - boost::shared_ptr c = binding_proxy.get_controllable(); - if (!c) return false; - c->set_value (c->normal(), Controllable::NoGroup); - return true; - } - - unset_active_state (); - - return true; -} - -void -ArdourKnob::color_handler () -{ - set_dirty (); -} - -void -ArdourKnob::on_size_allocate (Allocation& alloc) -{ - CairoWidget::on_size_allocate (alloc); -} - -void -ArdourKnob::set_controllable (boost::shared_ptr c) -{ - watch_connection.disconnect (); //stop watching the old controllable - - if (!c) return; - - binding_proxy.set_controllable (c); - - c->Changed.connect (watch_connection, invalidator(*this), boost::bind (&ArdourKnob::controllable_changed, this, false), gui_context()); - - _normal = c->internal_to_interface(c->normal()); - - controllable_changed(); -} - -void -ArdourKnob::controllable_changed (bool force_update) -{ - boost::shared_ptr c = binding_proxy.get_controllable(); - if (!c) return; - - float val = c->get_interface (true); - val = min( max(0.0f, val), 1.0f); // clamp - - if (val == _val && !force_update) { - return; - } - - _val = val; - if (!_tooltip_prefix.empty()) { - _tooltip.set_tip (_tooltip_prefix + c->get_user_string()); - } - set_dirty(); -} - -void -ArdourKnob::on_style_changed (const RefPtr&) -{ - set_dirty (); -} - -void -ArdourKnob::on_name_changed () -{ - set_dirty (); -} - - -void -ArdourKnob::set_active_state (Gtkmm2ext::ActiveState s) -{ - if (_active_state != s) - CairoWidget::set_active_state (s); -} - -void -ArdourKnob::set_visual_state (Gtkmm2ext::VisualState s) -{ - if (_visual_state != s) - CairoWidget::set_visual_state (s); -} - - -bool -ArdourKnob::on_focus_in_event (GdkEventFocus* ev) -{ - set_dirty (); - return CairoWidget::on_focus_in_event (ev); -} - -bool -ArdourKnob::on_focus_out_event (GdkEventFocus* ev) -{ - set_dirty (); - return CairoWidget::on_focus_out_event (ev); -} - -bool -ArdourKnob::on_enter_notify_event (GdkEventCrossing* ev) -{ - _hovering = true; - - set_dirty (); - - boost::shared_ptr c (binding_proxy.get_controllable ()); - if (c) { - PBD::Controllable::GUIFocusChanged (boost::weak_ptr (c)); - } - - return CairoWidget::on_enter_notify_event (ev); -} - -bool -ArdourKnob::on_leave_notify_event (GdkEventCrossing* ev) -{ - _hovering = false; - - set_dirty (); - - if (binding_proxy.get_controllable()) { - PBD::Controllable::GUIFocusChanged (boost::weak_ptr ()); - } - - return CairoWidget::on_leave_notify_event (ev); + /* knob is square */ + req->width = std::max (req->width, req->height); + req->height = std::max (req->width, req->height); } void @@ -577,28 +278,3 @@ ArdourKnob::add_elements (Element e) { _elements = (ArdourKnob::Element) (_elements | e); } - - -KnobPersistentTooltip::KnobPersistentTooltip (Gtk::Widget* w) - : PersistentTooltip (w, true, 3) - , _dragging (false) -{ -} - -void -KnobPersistentTooltip::start_drag () -{ - _dragging = true; -} - -void -KnobPersistentTooltip::stop_drag () -{ - _dragging = false; -} - -bool -KnobPersistentTooltip::dragging () const -{ - return _dragging; -} diff --git a/libs/widgets/widgets/ardour_knob.h b/libs/widgets/widgets/ardour_knob.h index 73e213e89c..b1ff4ad8c1 100644 --- a/libs/widgets/widgets/ardour_knob.h +++ b/libs/widgets/widgets/ardour_knob.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Paul Davis - * Copyright (C) 2017-2019 Robin Gareus + * Copyright (C) 2017-2021 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,121 +17,47 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __gtk2_ardour_ardour_knob_h__ -#define __gtk2_ardour_ardour_knob_h__ +#ifndef _WIDGETS_ARDOUR_KNOB_H_ +#define _WIDGETS_ARDOUR_KNOB_H_ -#include -#include - -#include - -#include "pbd/signals.h" - -#include "gtkmm2ext/activatable.h" -#include "gtkmm2ext/cairo_widget.h" -#include "gtkmm2ext/persistent_tooltip.h" - -#include "widgets/binding_proxy.h" +#include "widgets/ardour_ctrl_base.h" #include "widgets/visibility.h" namespace ArdourWidgets { -class LIBWIDGETS_API KnobPersistentTooltip : public Gtkmm2ext::PersistentTooltip +class LIBWIDGETS_API ArdourKnob : public ArdourCtrlBase { public: - KnobPersistentTooltip (Gtk::Widget* w); - - void start_drag (); - void stop_drag (); - bool dragging () const; - -private: - bool _dragging; -}; - - -class LIBWIDGETS_API ArdourKnob : public CairoWidget , public Gtkmm2ext::Activatable -{ -public: - enum Element { - Arc = 0x1, - Bevel = 0x2, + Arc = 0x1, + Bevel = 0x2, unused2 = 0x4, unused3 = 0x8, unused4 = 0x10, unused5 = 0x20, }; - enum Flags { - NoFlags = 0, - Detent = 0x1, - ArcToZero = 0x2, - }; - ArdourKnob (Element e = default_elements, Flags flags = NoFlags); - virtual ~ArdourKnob (); - void set_active_state (Gtkmm2ext::ActiveState); - void set_visual_state (Gtkmm2ext::VisualState); - - Element elements() const { return _elements; } + Element elements () const + { + return _elements; + } void set_elements (Element); void add_elements (Element); + static Element default_elements; - void set_tooltip_prefix (std::string pfx) { _tooltip_prefix = pfx; controllable_changed (true); } + void gen_faceplate (Pango::FontDescription const&, std::string const&, std::string const&, std::string const&); - boost::shared_ptr get_controllable() { return binding_proxy.get_controllable(); } - void set_controllable (boost::shared_ptr c); +protected: + virtual void render (Cairo::RefPtr const&, cairo_rectangle_t*); + void on_size_request (Gtk::Requisition* req); - bool on_button_press_event (GdkEventButton*); - bool on_button_release_event (GdkEventButton*); - bool on_scroll_event (GdkEventScroll* ev); - bool on_motion_notify_event (GdkEventMotion *ev) ; - - void color_handler (); - - sigc::signal StartGesture; - sigc::signal StopGesture; - - protected: - void render (Cairo::RefPtr const&, cairo_rectangle_t*); - void on_size_request (Gtk::Requisition* req); - void on_size_allocate (Gtk::Allocation&); - void on_style_changed (const Glib::RefPtr&); - void on_name_changed (); - bool on_enter_notify_event (GdkEventCrossing*); - bool on_leave_notify_event (GdkEventCrossing*); - bool on_focus_in_event (GdkEventFocus*); - bool on_focus_out_event (GdkEventFocus*); - - void controllable_changed (bool force_update = false); - PBD::ScopedConnection watch_connection; - - - private: +private: Element _elements; - BindingProxy binding_proxy; - - bool _hovering; - float _grabbed_x; - float _grabbed_y; - - float _val; // current value [0..1] - float _normal; // default value, arc - float _dead_zone_delta; - - Flags _flags; - - void action_sensitivity_changed (); - void action_visibility_changed (); - void action_tooltip_changed (); - - std::string _tooltip_prefix; - KnobPersistentTooltip _tooltip; }; -} /* namespace */ +} // namespace ArdourWidgets #endif /* __gtk2_ardour_ardour_knob_h__ */