1 /*
2  * Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2017 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 _WIDGETS_ARDOUR_FADER_H_
21 #define _WIDGETS_ARDOUR_FADER_H_
22 
23 #include <cmath>
24 #include <stdint.h>
25 
26 #include <gdkmm.h>
27 #include <gtkmm/adjustment.h>
28 
29 #include "gtkmm2ext/cairo_widget.h"
30 #include "widgets/visibility.h"
31 
32 namespace ArdourWidgets {
33 
34 class LIBWIDGETS_API ArdourFader : public CairoWidget
35 {
36 public:
37 	ArdourFader (Gtk::Adjustment& adjustment, int orientation, int span, int girth);
38 	virtual ~ArdourFader ();
39 	static void flush_pattern_cache();
40 
41 	sigc::signal<void> StartGesture;
42 	sigc::signal<void> StopGesture;
43 	sigc::signal<void> OnExpose;
44 
45 	void set_default_value (float);
46 	void set_text (const std::string&, bool centered = true, bool expose = true);
47 
48 	enum Tweaks {
49 		NoShowUnityLine = 0x1,
50 		NoButtonForward = 0x2,
51 		NoVerticalScroll = 0x4,
52 	};
53 
tweaks()54 	Tweaks tweaks() const { return _tweaks; }
55 	void set_tweaks (Tweaks);
56 
57 protected:
58 	void on_size_request (GtkRequisition*);
59 	void on_size_allocate (Gtk::Allocation& alloc);
60 
61 	void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
62 	bool on_grab_broken_event (GdkEventGrabBroken*);
63 	bool on_button_press_event (GdkEventButton*);
64 	bool on_button_release_event (GdkEventButton*);
65 	bool on_motion_notify_event (GdkEventMotion*);
66 	bool on_scroll_event (GdkEventScroll* ev);
67 	bool on_enter_notify_event (GdkEventCrossing* ev);
68 	bool on_leave_notify_event (GdkEventCrossing* ev);
69 
70 	void on_state_changed (Gtk::StateType);
71 	void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
72 
73 	enum Orientation {
74 		VERT,
75 		HORIZ,
76 	};
77 
78 private:
79 	Glib::RefPtr<Pango::Layout> _layout;
80 	std::string                 _text;
81 	Tweaks                      _tweaks;
82 	Gtk::Adjustment&            _adjustment;
83 	int _text_width;
84 	int _text_height;
85 
86 	int _span, _girth;
87 	int _min_span, _min_girth;
88 	int _orien;
89 	cairo_pattern_t* _pattern;
90 	bool _hovering;
91 	GdkWindow* _grab_window;
92 	double _grab_loc;
93 	double _grab_start;
94 	bool _dragging;
95 	float _default_value;
96 	int _unity_loc;
97 	bool _centered_text;
98 
99 	sigc::connection _parent_style_change;
100 	Widget * _current_parent;
101 	Gdk::Color get_parent_bg ();
102 
103 	void create_patterns();
104 	void adjustment_changed ();
105 	void set_adjustment_from_event (GdkEventButton *);
106 	void update_unity_position ();
107 	int  display_span ();
108 
109 	struct FaderImage {
110 		cairo_pattern_t* pattern;
111 		double fr;
112 		double fg;
113 		double fb;
114 		double br;
115 		double bg;
116 		double bb;
117 		int width;
118 		int height;
119 
FaderImageFaderImage120 		FaderImage (cairo_pattern_t* p,
121 				double afr, double afg, double afb,
122 				double abr, double abg, double abb,
123 				int w, int h)
124 			: pattern (p)
125 				, fr (afr)
126 				 , fg (afg)
127 				 , fb (afb)
128 				 , br (abr)
129 				 , bg (abg)
130 				 , bb (abb)
131 				 , width (w)
132 				 , height (h)
133 		{}
134 
matchesFaderImage135 		bool matches (double afr, double afg, double afb,
136 				double abr, double abg, double abb,
137 				int w, int h) {
138 			return width == w &&
139 				height == h &&
140 				afr == fr &&
141 				afg == fg &&
142 				afb == fb &&
143 				abr == br &&
144 				abg == bg &&
145 				abb == bb;
146 		}
147 	};
148 
149 	static std::list<FaderImage*> _patterns;
150 	static cairo_pattern_t* find_pattern (double afr, double afg, double afb,
151 			double abr, double abg, double abb,
152 			int w, int h);
153 
154 };
155 
156 } /* namespace */
157 
158 #endif /* __gtkmm2ext_pixfader_h__ */
159