2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2003 Alexander König
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.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Description: This contains the implementation of the tx_flash_flash widget.
26 #include <gtk/gtkwindow.h>
30 #include "tX_global.h"
39 #endif /* __cplusplus */
41 #define MAX_VALUE 32767
42 #define RED_BORDER 25000
43 #define TX_FLASH_DEFAULT_SIZE_X 17
44 #define TX_FLASH_DEFAULT_SIZE_Y 30
51 #define MAX_MAX_CYCLES 20;
54 static void gtk_tx_flash_class_init (GtkTxFlashClass *);
55 static void gtk_tx_flash_init (GtkTxFlash *tx_flash);
56 GtkWidget* gtk_tx_flash_new ();
57 static void gtk_tx_flash_destroy (GtkObject *object);
58 static void gtk_tx_flash_realize (GtkWidget *widget);
59 static void gtk_tx_flash_size_request (GtkWidget *widget, GtkRequisition *requisition);
60 static void gtk_tx_flash_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
61 static gint gtk_tx_flash_expose (GtkWidget *widget, GdkEventExpose *event);
62 //static void gtk_tx_flash_prepare (GtkWidget *widget);
63 //static void gtk_tx_flash_set_level(GtkWidget *widget, f_prec new_value);
67 static GtkWidgetClass *parent_class = NULL;
70 gtk_tx_flash_get_type ()
72 static guint tx_flash_type = 0;
76 GtkTypeInfo tx_flash_info =
80 sizeof (GtkTxFlashClass),
81 (GtkClassInitFunc) gtk_tx_flash_class_init,
82 (GtkObjectInitFunc) gtk_tx_flash_init,
88 tx_flash_type = gtk_type_unique (gtk_widget_get_type (), &tx_flash_info);
95 gtk_tx_flash_class_init (GtkTxFlashClass *gclass)
97 GtkObjectClass *object_class;
98 GtkWidgetClass *widget_class;
100 object_class = (GtkObjectClass*) gclass;
101 widget_class = (GtkWidgetClass*) gclass;
103 parent_class = gtk_type_class (gtk_widget_get_type ());
105 object_class->destroy = gtk_tx_flash_destroy;
107 widget_class->realize = gtk_tx_flash_realize;
108 widget_class->expose_event = gtk_tx_flash_expose;
109 widget_class->size_request = gtk_tx_flash_size_request;
110 widget_class->size_allocate = gtk_tx_flash_size_allocate;
111 // widget_class->button_press_event = gtk_tx_flash_button_press;
112 // widget_class->button_release_event = gtk_tx_flash_button_release;
113 // widget_class->motion_notify_event = gtk_tx_flash_motion_notify;
127 inline void mk_half(double s, GdkColor *a, GdkColor *b, GdkColor *c)
129 c->red=a->red-(a->red-b->red)*s;
130 c->green=a->green-(a->green-b->green)*s;
131 c->blue=a->blue-(a->blue-b->blue)*s;
134 void gtk_tx_flash_update_colors(GtkTxFlash *tx)
138 if (tx->colors_allocated) {
139 gdk_colormap_free_colors(gtk_widget_get_colormap(GTK_WIDGET(tx)), tx->colors, NO_COLS);
142 gdk_color_parse(globals.vu_meter_bg, &tx->colors[COL_BG]);
143 gdk_color_parse(globals.vu_meter_loud, &tx->colors[COL_LOUD]);
144 gdk_color_parse(globals.vu_meter_normal, &tx->colors[COL_NORM]);
145 mk_half(globals.vu_meter_border_intensity, &tx->colors[COL_BG], &tx->colors[COL_LOUD], &tx->colors[COL_LOUD_HALF]);
146 mk_half(globals.vu_meter_border_intensity, &tx->colors[COL_BG], &tx->colors[COL_NORM], &tx->colors[COL_NORM_HALF]);
148 for (i=0; i<NO_COLS; i++) {
149 gdk_colormap_alloc_color(gtk_widget_get_colormap(GTK_WIDGET(tx)), &tx->colors[i], 0, 1);
152 tx->colors_allocated=1;
156 gtk_tx_flash_init (GtkTxFlash *tx_flash)
160 tx_flash->colors_allocated=0;
161 priv=gdk_colormap_new(gtk_widget_get_visual(GTK_WIDGET(tx_flash)), 6);
163 gtk_widget_set_colormap(GTK_WIDGET(tx_flash), priv);
164 gtk_tx_flash_update_colors(tx_flash);
170 GtkTxFlash *tx_flash;
172 tx_flash = gtk_type_new (gtk_tx_flash_get_type ());
174 return GTK_WIDGET (tx_flash);
178 gtk_tx_flash_destroy (GtkObject *object)
180 g_return_if_fail (object != NULL);
181 g_return_if_fail (GTK_IS_TX_FLASH (object));
183 if (GTK_OBJECT_CLASS (parent_class)->destroy)
184 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
188 gtk_tx_flash_realize (GtkWidget *widget)
190 GtkTxFlash *tx_flash;
191 GdkWindowAttr attributes;
192 gint attributes_mask;
194 g_return_if_fail (widget != NULL);
195 g_return_if_fail (GTK_IS_TX_FLASH (widget));
197 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
198 tx_flash = GTK_TX_FLASH (widget);
200 attributes.x = widget->allocation.x;
201 attributes.y = widget->allocation.y;
202 attributes.width = widget->allocation.width;
203 attributes.height = widget->allocation.height;
204 attributes.wclass = GDK_INPUT_OUTPUT;
205 attributes.window_type = GDK_WINDOW_CHILD;
206 attributes.event_mask = gtk_widget_get_events (widget) |
208 attributes.visual = gtk_widget_get_visual (widget);
209 attributes.colormap = gtk_widget_get_colormap (widget);
211 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
213 widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
215 widget->style = gtk_style_attach (widget->style, widget->window);
217 gdk_window_set_user_data (widget->window, widget);
219 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
223 gtk_tx_flash_size_request (GtkWidget *widget, GtkRequisition *requisition)
225 requisition->width = TX_FLASH_DEFAULT_SIZE_X;
226 requisition->height = TX_FLASH_DEFAULT_SIZE_Y;
230 gtk_tx_flash_prepare (GtkWidget *widget)
232 GtkTxFlash *tx_flash;
234 g_return_if_fail (widget != NULL);
235 g_return_if_fail (GTK_IS_TX_FLASH (widget));
237 tx_flash=GTK_TX_FLASH(widget);
239 tx_flash->levels=(widget->allocation.height-(2*DY))/DLEVEL;
240 tx_flash->last_level=0;
241 tx_flash->level_value=MAX_VALUE/(f_prec) tx_flash->levels;
242 tx_flash->red_level=(RED_BORDER/tx_flash->level_value);
244 tx_flash->x1=DMINIX+S_MINIX+2;
245 tx_flash->x2=widget->allocation.width-tx_flash->x1-1;
250 gtk_tx_flash_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
252 GtkTxFlash *tx_flash;
254 g_return_if_fail (widget != NULL);
255 g_return_if_fail (GTK_IS_TX_FLASH (widget));
256 g_return_if_fail (allocation != NULL);
258 widget->allocation = *allocation;
260 gtk_tx_flash_prepare(widget);
262 if (GTK_WIDGET_REALIZED (widget))
264 tx_flash = GTK_TX_FLASH (widget);
266 gdk_window_move_resize (widget->window,
267 allocation->x, allocation->y,
268 allocation->width, allocation->height);
273 static void gtk_tx_flash_paint_yourself(GtkWidget *widget)
275 GtkTxFlash *tx_flash;
276 gint i, x11, x12,x21, x22, y;
279 tx_flash = GTK_TX_FLASH (widget);
281 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_BG]);
283 gdk_draw_rectangle(widget->window, widget->style->fg_gc[widget->state], 1, 0, 0, widget->allocation.width,widget->allocation.height);
285 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_NORM_HALF]);
288 x21=widget->allocation.width-1-x12;
290 for (i=0, y=widget->allocation.height-DY; i<=tx_flash->levels; y-=DLEVEL, i++)
296 else if (i==tx_flash->red_level-1)
300 else if (i==tx_flash->red_level)
303 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_LOUD_HALF]);
305 else if (i==tx_flash->levels)
322 gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], x11, y, x12, y);
323 gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], x21, y, x22, y);
327 static gint gtk_tx_flash_expose (GtkWidget *widget, GdkEventExpose *event)
330 g_return_val_if_fail (widget != NULL, FALSE);
331 g_return_val_if_fail (GTK_IS_TX_FLASH (widget), FALSE);
332 g_return_val_if_fail (event != NULL, FALSE);
334 if (event->count > 0)
337 gtk_tx_flash_prepare(widget);
338 gtk_tx_flash_paint_yourself(widget);
344 gtk_tx_flash_set_level(GtkWidget *widget, f_prec new_value)
346 GtkTxFlash *tx_flash;
351 g_return_if_fail (widget != NULL);
352 g_return_if_fail (GTK_IS_TX_FLASH (widget));
354 tx_flash = GTK_TX_FLASH (widget);
356 new_level=(int) (new_value/tx_flash->level_value);
358 if (new_level>tx_flash->levels) new_level=tx_flash->levels;
360 // printf ("%f, %i, %i\n", tx_flash->level_value,new_level, tx_flash->last_level);
363 if (new_level>tx_flash->max)
365 tx_flash->max=new_level;
366 tx_flash->max_cycles=MAX_MAX_CYCLES;
370 tx_flash->max_cycles--;
373 if (tx_flash->max_cycles <= 0)
375 y=widget->allocation.height-(DY+(tx_flash->max)*DLEVEL);
376 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_BG]);
377 gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], tx_flash->x1, y, tx_flash->x2, y);
383 if (tx_flash->max>tx_flash->red_level)
385 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_LOUD]);
389 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_NORM]);
391 gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], tx_flash->x1, y, tx_flash->x2, y);
395 if (new_level==tx_flash->last_level) return;
397 if (new_level<tx_flash->last_level) // make it look more realistic
399 new_level=tx_flash->last_level*globals.flash_response;
402 if (new_level>tx_flash->last_level)
404 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_NORM]);
406 for (i=tx_flash->last_level, y=widget->allocation.height-(DY+tx_flash->last_level*DLEVEL); i<=new_level; y-=DLEVEL, i++)
410 if (i>=tx_flash->red_level)
412 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_LOUD]);
416 gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], tx_flash->x1, y, tx_flash->x2, y);
421 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &tx_flash->colors[COL_BG]);
423 if (tx_flash->last_level==tx_flash->max)
425 i=tx_flash->last_level-1;
429 i=tx_flash->last_level;
432 for (y=widget->allocation.height-(DY+i*DLEVEL); i>new_level; y+=DLEVEL, i--)
434 gdk_draw_line(widget->window, widget->style->fg_gc[widget->state], tx_flash->x1, y, tx_flash->x2, y);
437 tx_flash->last_level=new_level;
441 gtk_tx_flash_clear (GtkWidget *widget)
443 GtkTxFlash *tx_flash;
445 tx_flash = GTK_TX_FLASH (widget);
448 tx_flash->max_cycles=0;
449 tx_flash->last_level=0;
451 gtk_tx_flash_paint_yourself(widget);
456 #endif /* __cplusplus */