1 /* spectool generic gtk widget
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Library General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Library General Public License for more details.
12  *
13  * You should have received a copy of the GNU Library General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 02111-1307, USA.
17  */
18 
19 #include "config.h"
20 
21 #ifndef __SPECTOOL_GTK_WIDGET_H__
22 #define __SPECTOOL_GTK_WIDGET_H__
23 
24 #ifdef HAVE_GTK
25 
26 #include <glib.h>
27 #include <glib-object.h>
28 #include <cairo.h>
29 
30 #include "spectool_container.h"
31 #include "spectool_gtk_hw_registry.h"
32 
33 /*
34  * Common GTK widget layer, provides functions for handling picking a device,
35  * determining and printing channels, etc
36  *
37  * Should save several hundred lines of shared code off descendant widgets
38  * (Spectral, Planar, Topographic, Foo)
39  *
40  */
41 
42 G_BEGIN_DECLS
43 
44 /* Hex color to cairo color */
45 #define HC2CC(x)				((double) ((double) (x) / (double) 0xFF))
46 
47 #define SPECTOOL_TYPE_WIDGET \
48 	(spectool_widget_get_type())
49 #define SPECTOOL_WIDGET(obj) \
50 	(G_TYPE_CHECK_INSTANCE_CAST((obj), \
51 	SPECTOOL_TYPE_WIDGET, SpectoolWidget))
52 #define SPECTOOL_WIDGET_CLASS(klass) \
53 	(G_TYPE_CHECK_CLASS_CAST((klass), \
54 	SPECTOOL_TYPE_WIDGET, SpectoolWidgetClass))
55 #define IS_SPECTOOL_WIDGET(obj) \
56 	(G_TYPE_CHECK_INSTANCE_TYPE((obj), \
57 	SPECTOOL_TYPE_WIDGET))
58 #define IS_SPECTOOL_WIDGET_CLASS(klass) \
59 	(G_TYPE_CHECK_CLASS_TYPE((class), \
60 	SPECTOOL_TYPE_WIDGET))
61 
62 typedef struct _SpectoolWidget SpectoolWidget;
63 typedef struct _SpectoolWidgetClass SpectoolWidgetClass;
64 
65 typedef struct _SpectoolChannelOpts {
66 	int chan_h;
67 	int *chanhit;
68 	double *chancolors;
69 	struct spectool_channels *chanset;
70 
71 	/* Hilighted channel, if we're showing channels */
72 	int hi_chan;
73 } SpectoolChannelOpts;
74 
75 void spectoolchannelopts_init(SpectoolChannelOpts *in);
76 
77 struct _SpectoolWidget {
78 	GtkBinClass parent;
79 
80 	int hlines;
81 	/* Top of DB graph, max sample reported */
82 	int base_db_offset;
83 	/* Bottom of db graph, min sample reported */
84 	int min_db_draw;
85 
86 	/* Conversion data */
87 	int amp_offset_mdbm;
88 	int amp_res_mdbm;
89 
90 	/* Graph elements we've calculated */
91 	int g_start_x, g_start_y, g_end_x, g_end_y,
92 		g_len_x, g_len_y;
93 	int dbm_w;
94 	double wbar;
95 
96 	gint timeout_ref;
97 
98 	GtkWidget *vbox, *hbox, *infoeb;
99 	GtkWidget *sweepinfo;
100 	GtkWidget *draw, *menubutton;
101 
102 	spectool_sweep_cache *sweepcache;
103 
104 	/* To be set by children to control behavior */
105 	int sweep_num_samples;
106 	int sweep_keep_avg;
107 	int sweep_keep_peak;
108 	int sweep_roll_peak;
109 	int sweep_num_aggregate;
110 
111 	/* Callbacks used by open, sweep */
112 	void (* wdr_sweep_func)(int, int, spectool_sample_sweep *, void *);
113 	void (* wdr_devbind_func)(GtkWidget *, spectool_device_registry *, int);
114 
115 	spectool_device_registry *wdr;
116 	int wdr_slot;
117 	spectool_phy *phydev;
118 
119 	/* Graph title (INCLUDING formatting) */
120 	char *graph_title;
121 
122 	/* Graph background colors */
123 	char *graph_title_bg, *graph_control_bg;
124 
125 	/* Menu callback, allows for adding custom items to the widget dropdown
126 	 * arrow menu
127 	 * arg1 - widget
128 	 * arg2 - menu */
129 	void (* menu_func)(GtkWidget *, GtkWidget *);
130 
131 	void (* help_func)(gpointer *);
132 
133 	/* Offscreen surface for regular drawing to be copied back during an expose */
134 	cairo_surface_t *offscreen;
135 	int old_width, old_height;
136 
137 	/* Callbacks for drawing */
138 	int draw_timeout;
139 	void (* draw_func)(GtkWidget *, cairo_t *, SpectoolWidget *);
140 
141 	/* Callbacks on size change */
142 	void (* sizechange_func)(GtkWidget *, GtkAllocation *);
143 
144 	/* Plot channels on the bottom */
145 	int show_channels;
146 	/* Show DBM */
147 	int show_dbm;
148 	/* Show DBM lines */
149 	int show_dbm_lines;
150 
151 	/* Callbacks for mouse events */
152 	gint (* draw_mouse_click_func)(GtkWidget *, GdkEventButton *, gpointer *);
153 	gboolean (* draw_mouse_move_func)(GtkWidget *, GdkEventMotion *, gpointer *);
154 
155 	/* Update function */
156 	void (* update_func)(GtkWidget *);
157 
158 	SpectoolChannelOpts *chanopts;
159 
160 	/* Have we gotten a sweep? */
161 	int dirty;
162 };
163 
164 struct _SpectoolWidgetClass {
165 	GtkBinClass parent_class;
166 };
167 
168 /* Controller item - didn't feel like making this a full widget, so you ask
169  * the widget to make you a controller then embed the box prior to the widget */
170 typedef struct _SpectoolWidgetController {
171 	/* Main widget */
172 	GtkWidget *evbox;
173 
174 	GtkWidget *label, *arrow, *menubutton;
175 	SpectoolWidget *wwidget;
176 } SpectoolWidgetController;
177 
178 GType spectool_widget_get_type(void);
179 GtkWidget *spectool_widget_new(void);
180 void spectool_widget_bind_dev(GtkWidget *widget, spectool_device_registry *wdr,
181 						   int slot);
182 
183 /* Do the heavy lifting of actually constructing the GUI, so that child
184  * classes can trigger this after setting up titles, etc.  I'm sure this
185  * isn't the most elegant method, someone can send me a patch */
186 void spectool_widget_buildgui(SpectoolWidget *widget);
187 
188 /* Update the backing graphics */
189 void spectool_widget_graphics_update(SpectoolWidget *wwidget);
190 
191 SpectoolWidgetController *spectool_widget_buildcontroller(GtkWidget *widget);
192 
193 void spectool_widget_link_channel(GtkWidget *widget, SpectoolChannelOpts *opts);
194 
195 /* Timeout function */
196 gint spectool_widget_timeout(gpointer *data);
197 
198 /* Calculate the channel clicked in */
199 int spectool_widget_find_chan_pt(SpectoolWidget *wwidget, int x, int y);
200 
201 void spectool_widget_context_channels(gpointer *aux);
202 void spectool_widget_context_dbm(gpointer *aux);
203 void spectool_widget_context_dbmlines(gpointer *aux);
204 
205 /* Color space conversion tools */
206 void rgb_to_hsv(double r, double g, double b,
207 					   double *h, double *s, double *v);
208 void hsv_to_rgb(double *r, double *g, double *b,
209 					   double h, double s, double v);
210 
211 G_END_DECLS
212 
213 #endif
214 #endif
215 
216