24 #include <pangomm/layout.h>
42 #include "canvas/colors.h"
43 #include "canvas/utils.h"
65 , _dead_zone_delta (0)
82 cairo_pattern_t* shade_pattern;
84 float width = get_width();
85 float height = get_height();
87 const float scale = min(width, height);
88 const float pointer_thickness = 3.0 * (scale/80);
90 const float start_angle = ((180 - 65) * G_PI) / 180;
91 const float end_angle = ((360 + 65) * G_PI) / 180;
98 const float value_angle = start_angle + (
_val * (end_angle - start_angle));
99 const float zero_angle = start_angle + (zero * (end_angle - start_angle));
101 float value_x = cos (value_angle);
102 float value_y = sin (value_angle);
104 float xc = 0.5 + width/ 2.0;
105 float yc = 0.5 + height/ 2.0;
107 cairo_translate (cr, xc, yc);
112 float center_radius = 0.48*scale;
113 float border_width = 0.8;
120 center_radius = scale*0.33;
122 float inner_progress_radius = scale*0.38;
123 float outer_progress_radius = scale*0.48;
124 float progress_width = (outer_progress_radius-inner_progress_radius);
125 float progress_radius = inner_progress_radius + progress_width/2.0;
128 cairo_set_source_rgb (cr, 0.3, 0.3, 0.3 );
129 cairo_set_line_width (cr, progress_width);
130 cairo_arc (cr, 0, 0, progress_radius, start_angle, end_angle);
134 double red_start, green_start, blue_start, unused;
136 ArdourCanvas::color_to_rgba( arc_start_color, red_start, green_start, blue_start, unused );
137 double red_end, green_end, blue_end;
139 ArdourCanvas::color_to_rgba( arc_end_color, red_end, green_end, blue_end, unused );
142 float intensity = fabsf (
_val - zero) / std::max(zero, (1.
f - zero));
143 const float intensity_inv = 1.0 - intensity;
144 float r = intensity_inv * red_end + intensity * red_start;
145 float g = intensity_inv * green_end + intensity * green_start;
146 float b = intensity_inv * blue_end + intensity * blue_start;
149 cairo_set_source_rgb (cr, r,g,b);
150 cairo_set_line_width (cr, progress_width);
151 if (zero_angle > value_angle) {
152 cairo_arc (cr, 0, 0, progress_radius, value_angle, zero_angle);
154 cairo_arc (cr, 0, 0, progress_radius, zero_angle, value_angle);
160 shade_pattern = cairo_pattern_create_linear (0.0, -yc, 0.0, yc);
161 cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1,1,1, 0.15);
162 cairo_pattern_add_color_stop_rgba (shade_pattern, 0.5, 1,1,1, 0.0);
163 cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 1,1,1, 0.0);
164 cairo_set_source (cr, shade_pattern);
165 cairo_arc (cr, 0, 0, outer_progress_radius-1, 0, 2.0*G_PI);
167 cairo_pattern_destroy (shade_pattern);
171 const float start_angle_x = cos (start_angle);
172 const float start_angle_y = sin (start_angle);
173 const float end_angle_x = cos (end_angle);
174 const float end_angle_y = sin (end_angle);
176 cairo_set_source_rgb (cr, 0, 0, 0 );
177 cairo_set_line_width (cr, border_width);
178 cairo_move_to (cr, (outer_progress_radius * start_angle_x), (outer_progress_radius * start_angle_y));
179 cairo_line_to (cr, (inner_progress_radius * start_angle_x), (inner_progress_radius * start_angle_y));
181 cairo_move_to (cr, (outer_progress_radius * end_angle_x), (outer_progress_radius * end_angle_y));
182 cairo_line_to (cr, (inner_progress_radius * end_angle_x), (inner_progress_radius * end_angle_y));
184 cairo_arc (cr, 0, 0, outer_progress_radius, start_angle, end_angle);
192 cairo_translate(cr, pointer_thickness+1, pointer_thickness+1 );
193 cairo_set_source_rgba (cr, 0, 0, 0, 0.1 );
194 cairo_arc (cr, 0, 0, center_radius-1, 0, 2.0*G_PI);
199 ArdourCanvas::set_source_rgba(cr, knob_color);
200 cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI);
206 shade_pattern = cairo_pattern_create_linear (0.0, -yc, 0.0, yc);
207 cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1,1,1, 0.2);
208 cairo_pattern_add_color_stop_rgba (shade_pattern, 0.2, 1,1,1, 0.2);
209 cairo_pattern_add_color_stop_rgba (shade_pattern, 0.8, 0,0,0, 0.2);
210 cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 0,0,0, 0.2);
211 cairo_set_source (cr, shade_pattern);
212 cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI);
214 cairo_pattern_destroy (shade_pattern);
217 ArdourCanvas::set_source_rgb_a (cr, knob_color, 0.5 );
218 cairo_arc (cr, 0, 0, center_radius-pointer_thickness, 0, 2.0*G_PI);
222 shade_pattern = cairo_pattern_create_radial ( -center_radius, -center_radius, 1, -center_radius, -center_radius, center_radius*2.5 );
223 cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1,1,1, 0.2);
224 cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 0,0,0, 0.3);
225 cairo_set_source (cr, shade_pattern);
226 cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI);
228 cairo_pattern_destroy (shade_pattern);
233 ArdourCanvas::set_source_rgba(cr, knob_color);
234 cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI);
240 cairo_set_line_width (cr, border_width);
241 cairo_set_source_rgba (cr, 0,0,0, 1 );
242 cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI);
248 cairo_translate(cr, 1, 1 );
249 cairo_set_source_rgba (cr, 0,0,0,0.3 );
250 cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
251 cairo_set_line_width (cr, pointer_thickness);
252 cairo_move_to (cr, (center_radius * value_x), (center_radius * value_y));
253 cairo_line_to (cr, ((center_radius*0.4) * value_x), ((center_radius*0.4) * value_y));
259 cairo_set_source_rgba (cr, 1,1,1, 1 );
260 cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
261 cairo_set_line_width (cr, pointer_thickness);
262 cairo_move_to (cr, (center_radius * value_x), (center_radius * value_y));
263 cairo_line_to (cr, ((center_radius*0.4) * value_x), ((center_radius*0.4) * value_y));
268 cairo_set_source_rgba (cr, 1,1,1, 0.12 );
269 cairo_arc (cr, 0, 0, center_radius, 0, 2.0*G_PI);
273 cairo_identity_matrix(cr);
280 CairoWidget::on_size_request (req);
283 if (req->width < req->height) {
284 req->width = req->height;
286 if (req->height < req->width) {
287 req->height = req->width;
297 if (ev->state & Keyboard::GainFineScaleModifier) {
298 if (ev->state & Keyboard::GainExtraFineScaleModifier) {
309 if ( ev->direction == GDK_SCROLL_UP )
323 if (!(ev->state & Gdk::BUTTON1_MASK)) {
335 float scale = 0.0025 / ui_scale;
337 if (ev->state & Keyboard::GainFineScaleModifier) {
338 if (ev->state & Keyboard::GainExtraFineScaleModifier) {
356 const float px_deadzone = 42.f * ui_scale;
360 const int tozero = (
_normal - val) * scale;
361 int remain = delta - tozero;
362 if (abs (remain) > px_deadzone) {
364 remain += (remain > 0) ? px_deadzone * -.5 : px_deadzone * .5;
365 delta = tozero + remain;
383 val += delta * scale;
396 if (ev->type != GDK_BUTTON_PRESS) {
399 gdk_pointer_ungrab (GDK_CURRENT_TIME);
408 if (ev->button != 1 && ev->button != 2) {
416 gdk_pointer_grab(ev->window,
false,
417 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
428 gdk_pointer_ungrab (GDK_CURRENT_TIME);
430 if ( (
_grabbed_y == ev->y &&
_grabbed_x == ev->x) && Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
432 if (!c)
return false;
477 val = min( max(0.0
f, val), 1.0
f);
522 return CairoWidget::on_focus_in_event (ev);
529 return CairoWidget::on_focus_out_event (ev);
539 return CairoWidget::on_enter_notify_event (ev);
549 return CairoWidget::on_leave_notify_event (ev);
virtual float get_interface() const
bool on_focus_in_event(GdkEventFocus *)
KnobPersistentTooltip _tooltip
ArdourCanvas::Color color(const std::string &, bool *failed=0) const
void set_elements(Element)
void on_style_changed(const Glib::RefPtr< Gtk::Style > &)
boost::shared_ptr< PBD::Controllable > get_controllable() const
bool on_scroll_event(GdkEventScroll *ev)
virtual void set_interface(float percent)
void add_elements(Element)
void set_controllable(boost::shared_ptr< PBD::Controllable >)
virtual std::string get_user_string() const
void render(cairo_t *, cairo_rectangle_t *)
static Element default_elements
std::string _tooltip_prefix
void on_size_request(Gtk::Requisition *req)
bool on_focus_out_event(GdkEventFocus *)
void set_controllable(boost::shared_ptr< PBD::Controllable > c)
virtual double internal_to_interface(double i) const
virtual double normal() const
bool on_leave_notify_event(GdkEventCrossing *)
void set_active_state(Gtkmm2ext::ActiveState)
bool button_press_handler(GdkEventButton *)
void set_visual_state(Gtkmm2ext::VisualState)
void on_size_allocate(Gtk::Allocation &)
bool on_button_press_event(GdkEventButton *)
void controllable_changed()
virtual void set_value(double)=0
static UIConfiguration * config()
PBD::Signal0< void > Changed
ArdourKnob(Element e=default_elements, Flags flags=NoFlags)
sigc::signal< void > ColorsChanged
PBD::ScopedConnection watch_connection
bool on_button_release_event(GdkEventButton *)
BindingProxy binding_proxy
bool on_enter_notify_event(GdkEventCrossing *)
sigc::connection rapid_connect(const sigc::slot< void > &slot)
std::string string_compose(const std::string &fmt, const T1 &o1)
bool on_motion_notify_event(GdkEventMotion *ev)