summaryrefslogtreecommitdiff
path: root/libs/gtkmm2ext/gtkmm2ext/pixfader.h
blob: 5454ac53bed6baa639dec31d64d7b21f1cad1059 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
    Copyright (C) 2006 Paul Davis

    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
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __gtkmm2ext_pixfader_h__
#define __gtkmm2ext_pixfader_h__

#include <cmath>
#include <stdint.h>

#include "gtkmm2ext/cairo_widget.h"
#include <gtkmm/adjustment.h>
#include <gdkmm.h>

#include "gtkmm2ext/visibility.h"

namespace Gtkmm2ext {

class LIBGTKMM2EXT_API PixFader : public CairoWidget
{
	public:
	PixFader (Gtk::Adjustment& adjustment, int orientation, int span, int girth);
	virtual ~PixFader ();
	static void flush_pattern_cache();

	sigc::signal<void> StartGesture;
	sigc::signal<void> StopGesture;
	sigc::signal<void> OnExpose;

	void set_default_value (float);
	void set_text (const std::string&, bool centered = true, bool expose = true);

	enum Tweaks {
		NoShowUnityLine = 0x1,
		NoButtonForward = 0x2,
		NoVerticalScroll = 0x4,
	};

	Tweaks tweaks() const { return _tweaks; }
	void set_tweaks (Tweaks);

	protected:
	void on_size_request (GtkRequisition*);
	void on_size_allocate (Gtk::Allocation& alloc);

	void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
	bool on_grab_broken_event (GdkEventGrabBroken*);
	bool on_button_press_event (GdkEventButton*);
	bool on_button_release_event (GdkEventButton*);
	bool on_motion_notify_event (GdkEventMotion*);
	bool on_scroll_event (GdkEventScroll* ev);
	bool on_enter_notify_event (GdkEventCrossing* ev);
	bool on_leave_notify_event (GdkEventCrossing* ev);

	void on_state_changed (Gtk::StateType);
	void on_style_changed (const Glib::RefPtr<Gtk::Style>&);

	enum Orientation {
		VERT,
		HORIZ,
	};

	private:

	Glib::RefPtr<Pango::Layout> _layout;
	std::string                 _text;
	Tweaks                      _tweaks;
	Gtk::Adjustment&            _adjustment;
	int _text_width;
	int _text_height;

	int _span, _girth;
	int _min_span, _min_girth;
	int _orien;
	cairo_pattern_t* _pattern;
	bool _hovering;
	GdkWindow* _grab_window;
	double _grab_loc;
	double _grab_start;
	bool _dragging;
	float _default_value;
	int _unity_loc;
	bool _centered_text;

	sigc::connection _parent_style_change;
	Widget * _current_parent;
	Gdk::Color get_parent_bg ();

	void create_patterns();
	void adjustment_changed ();
	void set_adjustment_from_event (GdkEventButton *);
	void update_unity_position ();
	int  display_span ();

	struct FaderImage {
		cairo_pattern_t* pattern;
		double fr;
		double fg;
		double fb;
		double br;
		double bg;
		double bb;
		int width;
		int height;

		FaderImage (cairo_pattern_t* p,
				double afr, double afg, double afb,
				double abr, double abg, double abb,
				int w, int h)
			: pattern (p)
				, fr (afr)
				 , fg (afg)
				 , fb (afb)
				 , br (abr)
				 , bg (abg)
				 , bb (abb)
				 , width (w)
				 , height (h)
		{}

		bool matches (double afr, double afg, double afb,
				double abr, double abg, double abb,
				int w, int h) {
			return width == w &&
				height == h &&
				afr == fr &&
				afg == fg &&
				afb == fb &&
				abr == br &&
				abg == bg &&
				abb == bb;
		}
	};

	static std::list<FaderImage*> _patterns;
	static cairo_pattern_t* find_pattern (double afr, double afg, double afb,
			double abr, double abg, double abb,
			int w, int h);

};


} /* namespace */

#endif /* __gtkmm2ext_pixfader_h__ */