1 /*
2  * Copyright (C) 2014 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2017-2019 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __gtk2_ardour_ardour_knob_h__
21 #define __gtk2_ardour_ardour_knob_h__
22 
23 #include <list>
24 #include <stdint.h>
25 
26 #include <gtkmm/action.h>
27 
28 #include "pbd/signals.h"
29 
30 #include "gtkmm2ext/activatable.h"
31 #include "gtkmm2ext/cairo_widget.h"
32 #include "gtkmm2ext/persistent_tooltip.h"
33 
34 #include "widgets/binding_proxy.h"
35 #include "widgets/visibility.h"
36 
37 namespace ArdourWidgets {
38 
39 class LIBWIDGETS_API KnobPersistentTooltip : public Gtkmm2ext::PersistentTooltip
40 {
41 public:
42 	KnobPersistentTooltip (Gtk::Widget* w);
43 
44 	void start_drag ();
45 	void stop_drag ();
46 	bool dragging () const;
47 
48 private:
49 	bool _dragging;
50 };
51 
52 
53 class LIBWIDGETS_API ArdourKnob : public CairoWidget , public Gtkmm2ext::Activatable
54 {
55 public:
56 
57 	enum Element {
58 		Arc = 0x1,
59 		Bevel = 0x2,
60 		unused2 = 0x4,
61 		unused3 = 0x8,
62 		unused4 = 0x10,
63 		unused5 = 0x20,
64 	};
65 
66 	enum Flags {
67 		NoFlags = 0,
68 		Detent = 0x1,
69 		ArcToZero = 0x2,
70 	};
71 
72 	ArdourKnob (Element e = default_elements, Flags flags = NoFlags);
73 	virtual ~ArdourKnob ();
74 
75 	void set_active_state (Gtkmm2ext::ActiveState);
76 	void set_visual_state (Gtkmm2ext::VisualState);
77 
elements()78 	Element elements() const { return _elements; }
79 	void set_elements (Element);
80 	void add_elements (Element);
81 	static Element default_elements;
82 
set_tooltip_prefix(std::string pfx)83 	void set_tooltip_prefix (std::string pfx) { _tooltip_prefix = pfx; controllable_changed (true); }
84 
get_controllable()85 	boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
86 	void set_controllable (boost::shared_ptr<PBD::Controllable> c);
87 
88 	bool on_button_press_event (GdkEventButton*);
89 	bool on_button_release_event (GdkEventButton*);
90 	bool on_scroll_event (GdkEventScroll* ev);
91 	bool on_motion_notify_event (GdkEventMotion *ev) ;
92 
93 	void color_handler ();
94 
95 	sigc::signal<void> StartGesture;
96 	sigc::signal<void> StopGesture;
97 
98   protected:
99 	void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
100 	void on_size_request (Gtk::Requisition* req);
101 	void on_size_allocate (Gtk::Allocation&);
102 	void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
103 	void on_name_changed ();
104 	bool on_enter_notify_event (GdkEventCrossing*);
105 	bool on_leave_notify_event (GdkEventCrossing*);
106 	bool on_focus_in_event (GdkEventFocus*);
107 	bool on_focus_out_event (GdkEventFocus*);
108 
109 	void controllable_changed (bool force_update = false);
110 	PBD::ScopedConnection watch_connection;
111 
112 
113   private:
114 	Element _elements;
115 	BindingProxy binding_proxy;
116 
117 	bool _hovering;
118 	float _grabbed_x;
119 	float _grabbed_y;
120 
121 	float _val; // current value [0..1]
122 	float _normal; // default value, arc
123 	float _dead_zone_delta;
124 
125 	Flags _flags;
126 
127 	void action_sensitivity_changed ();
128 	void action_visibility_changed ();
129 	void action_tooltip_changed ();
130 
131 	std::string _tooltip_prefix;
132 	KnobPersistentTooltip _tooltip;
133 };
134 
135 } /* namespace */
136 
137 #endif /* __gtk2_ardour_ardour_knob_h__ */
138