3 * The Real SoundTracker - GTK+ sample display widget
5 * Copyright (C) 1998-2000 Michael Krause
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "sample-display.h"
28 #include <gtk/gtksignal.h>
29 #include <gtk/gtkmain.h>
31 #define XPOS_TO_OFFSET(x) (s->win_start + ((guint64)(x)) * s->win_length / s->width)
32 #define OFFSET_RANGE(l, x) (x < 0 ? 0 : (x >= l ? l - 1 : x))
34 static const int default_colors
[] = {
43 SELECTING_NOTHING
= 0,
44 SELECTING_SELECTION_START
,
45 SELECTING_SELECTION_END
,
52 SIG_SELECTION_CHANGED
,
58 #define IS_INITIALIZED(s) (s->datalen != 0)
60 static guint sample_display_signals
[LAST_SIGNAL
] = { 0 };
62 static int sample_display_startoffset_to_xpos (SampleDisplay
*s
,
64 static gint
sample_display_idle_draw_function (SampleDisplay
*s
);
67 sample_display_idle_draw (SampleDisplay
*s
)
69 if(!s
->idle_handler
) {
70 s
->idle_handler
= gtk_idle_add((GtkFunction
)sample_display_idle_draw_function
,
72 g_assert(s
->idle_handler
!= 0);
77 sample_display_enable_zero_line (SampleDisplay
*s
,
80 s
->display_zero_line
= enable
;
83 gtk_widget_queue_draw(GTK_WIDGET(s
));
88 sample_display_set_data (SampleDisplay
*s
,
94 g_return_if_fail(s
!= NULL
);
95 g_return_if_fail(IS_SAMPLE_DISPLAY(s
));
97 gboolean len_changed
= ( s
->datalen
!= len
);
103 if(s
->datacopylen
< len
* type
/ 8) {
105 s
->data
= g_new(gint8
, len
* type
/ 8);
106 s
->datacopylen
= len
* type
/ 8;
109 s
->data
= g_new(gint8
, len
* type
/ 8);
110 s
->datacopylen
= len
* type
/ 8;
112 g_assert(s
->data
!= NULL
);
113 memcpy(s
->data
, data
, len
* type
/ 8);
126 s
->old_mixerpos
= -1;
132 gtk_signal_emit(GTK_OBJECT(s
), sample_display_signals
[SIG_WINDOW_CHANGED
], s
->win_start
, s
->win_start
+ s
->win_length
);
135 s
->old_ss
= s
->old_se
= -1;
141 gtk_widget_queue_draw(GTK_WIDGET(s
));
145 sample_display_set_data_16 (SampleDisplay
*s
,
150 sample_display_set_data(s
, data
, 16, len
, copy
);
154 sample_display_set_data_8 (SampleDisplay
*s
,
159 sample_display_set_data(s
, data
, 8, len
, copy
);
163 sample_display_set_loop (SampleDisplay
*s
,
167 g_return_if_fail(s
!= NULL
);
168 g_return_if_fail(IS_SAMPLE_DISPLAY(s
));
170 if(!s
->edit
|| !IS_INITIALIZED(s
))
173 g_return_if_fail(start
>= -1 && start
< s
->datalen
);
174 g_return_if_fail(end
> 0 && end
<= s
->datalen
);
175 g_return_if_fail(end
> start
);
177 s
->loop_start
= start
;
180 gtk_widget_queue_draw(GTK_WIDGET(s
));
181 gtk_signal_emit(GTK_OBJECT(s
), sample_display_signals
[SIG_LOOP_CHANGED
], start
, end
);
185 sample_display_set_selection (SampleDisplay
*s
,
189 g_return_if_fail(s
!= NULL
);
190 g_return_if_fail(IS_SAMPLE_DISPLAY(s
));
192 if(!s
->edit
|| !IS_INITIALIZED(s
))
195 g_return_if_fail(start
>= -1 && start
< s
->datalen
);
196 g_return_if_fail(end
>= 1 && end
<= s
->datalen
);
197 g_return_if_fail(end
> start
);
199 s
->sel_start
= start
;
202 sample_display_idle_draw(s
);
203 gtk_signal_emit(GTK_OBJECT(s
), sample_display_signals
[SIG_SELECTION_CHANGED
], start
, end
);
207 sample_display_set_mixer_position (SampleDisplay
*s
,
210 g_return_if_fail(s
!= NULL
);
211 g_return_if_fail(IS_SAMPLE_DISPLAY(s
));
213 if(!s
->edit
|| !IS_INITIALIZED(s
))
216 if(offset
!= s
->mixerpos
) {
217 s
->mixerpos
= offset
;
218 sample_display_idle_draw(s
);
223 sample_display_set_window (SampleDisplay
*s
,
227 g_return_if_fail(s
!= NULL
);
228 g_return_if_fail(IS_SAMPLE_DISPLAY(s
));
229 g_return_if_fail(start
>= 0 && start
< s
->datalen
);
230 g_return_if_fail(end
> 0 && end
<= s
->datalen
);
231 g_return_if_fail(end
> start
);
233 s
->win_start
= start
;
234 s
->win_length
= end
- start
;
235 gtk_signal_emit(GTK_OBJECT(s
), sample_display_signals
[SIG_WINDOW_CHANGED
], start
, end
);
237 gtk_widget_queue_draw(GTK_WIDGET(s
));
241 sample_display_init_display (SampleDisplay
*s
,
250 sample_display_size_allocate (GtkWidget
*widget
,
251 GtkAllocation
*allocation
)
255 g_return_if_fail (widget
!= NULL
);
256 g_return_if_fail (IS_SAMPLE_DISPLAY (widget
));
257 g_return_if_fail (allocation
!= NULL
);
259 widget
->allocation
= *allocation
;
260 if (GTK_WIDGET_REALIZED (widget
)) {
261 s
= SAMPLE_DISPLAY (widget
);
263 gdk_window_move_resize (widget
->window
,
264 allocation
->x
, allocation
->y
,
265 allocation
->width
, allocation
->height
);
267 sample_display_init_display(s
, allocation
->width
, allocation
->height
);
272 sample_display_realize (GtkWidget
*widget
)
274 GdkWindowAttr attributes
;
275 gint attributes_mask
;
278 g_return_if_fail (widget
!= NULL
);
279 g_return_if_fail (IS_SAMPLE_DISPLAY (widget
));
281 GTK_WIDGET_SET_FLAGS (widget
, GTK_REALIZED
);
282 s
= SAMPLE_DISPLAY(widget
);
284 attributes
.x
= widget
->allocation
.x
;
285 attributes
.y
= widget
->allocation
.y
;
286 attributes
.width
= widget
->allocation
.width
;
287 attributes
.height
= widget
->allocation
.height
;
288 attributes
.wclass
= GDK_INPUT_OUTPUT
;
289 attributes
.window_type
= GDK_WINDOW_CHILD
;
290 attributes
.event_mask
= gtk_widget_get_events (widget
)
291 | GDK_EXPOSURE_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
292 | GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK
;
294 attributes
.visual
= gtk_widget_get_visual (widget
);
295 attributes
.colormap
= gtk_widget_get_colormap (widget
);
297 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
;
298 widget
->window
= gdk_window_new (widget
->parent
->window
, &attributes
, attributes_mask
);
300 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
302 s
->bg_gc
= gdk_gc_new(widget
->window
);
303 s
->fg_gc
= gdk_gc_new(widget
->window
);
304 s
->zeroline_gc
= gdk_gc_new(widget
->window
);
305 gdk_gc_set_foreground(s
->bg_gc
, &SAMPLE_DISPLAY_CLASS(GTK_OBJECT_GET_CLASS(widget
))->colors
[SAMPLE_DISPLAYCOL_BG
]);
306 gdk_gc_set_foreground(s
->fg_gc
, &SAMPLE_DISPLAY_CLASS(GTK_OBJECT_GET_CLASS(widget
))->colors
[SAMPLE_DISPLAYCOL_FG
]);
307 gdk_gc_set_foreground(s
->zeroline_gc
, &SAMPLE_DISPLAY_CLASS(GTK_OBJECT_GET_CLASS(widget
))->colors
[SAMPLE_DISPLAYCOL_ZERO
]);
309 s
->loop_gc
= gdk_gc_new(widget
->window
);
310 s
->mixerpos_gc
= gdk_gc_new(widget
->window
);
311 gdk_gc_set_foreground(s
->loop_gc
, &SAMPLE_DISPLAY_CLASS(GTK_OBJECT_GET_CLASS(widget
))->colors
[SAMPLE_DISPLAYCOL_LOOP
]);
312 gdk_gc_set_foreground(s
->mixerpos_gc
, &SAMPLE_DISPLAY_CLASS(GTK_OBJECT_GET_CLASS(widget
))->colors
[SAMPLE_DISPLAYCOL_MIXERPOS
]);
315 sample_display_init_display(s
, attributes
.width
, attributes
.height
);
317 gdk_window_set_user_data (widget
->window
, widget
);
321 sample_display_size_request (GtkWidget
*widget
,
322 GtkRequisition
*requisition
)
324 requisition
->width
= 10;
325 requisition
->height
= 32;
329 sample_display_draw_data (GdkDrawable
*win
,
330 const SampleDisplay
*s
,
337 const int sh
= s
->height
;
342 g_return_if_fail(x
>= 0);
343 g_return_if_fail(x
+ width
<= s
->width
);
345 gdk_draw_rectangle(win
, color
? s
->fg_gc
: s
->bg_gc
,
346 TRUE
, x
, 0, width
, s
->height
);
348 if(s
->display_zero_line
) {
349 gdk_draw_line(win
, s
->zeroline_gc
, x
, s
->height
/ 2, x
+ width
- 1, s
->height
/ 2);
352 gc
= color
? s
->bg_gc
: s
->fg_gc
;
354 if(s
->datatype
== 16) {
355 c
= ((gint16
*)s
->data
)[OFFSET_RANGE(s
->datalen
, XPOS_TO_OFFSET(x
- 1))];
358 d
= ((gint16
*)s
->data
)[OFFSET_RANGE(s
->datalen
, XPOS_TO_OFFSET(x
))];
359 gdk_draw_line(win
, gc
,
360 x
- 1, ((32768 - c
) * sh
) >> 16,
361 x
, ((32768 - d
) * sh
) >> 16);
367 c
= ((gint8
*)s
->data
)[OFFSET_RANGE(s
->datalen
, XPOS_TO_OFFSET(x
- 1))];
370 d
= ((gint8
*)s
->data
)[OFFSET_RANGE(s
->datalen
, XPOS_TO_OFFSET(x
))];
371 gdk_draw_line(win
, gc
,
372 x
- 1, ((128 - c
) * sh
) >> 8,
373 x
, ((128 - d
) * sh
) >> 8);
382 sample_display_startoffset_to_xpos (SampleDisplay
*s
,
385 gint64 d
= offset
- s
->win_start
;
389 if(d
>= s
->win_length
)
392 return d
* s
->width
/ s
->win_length
;
396 sample_display_endoffset_to_xpos (SampleDisplay
*s
,
399 if(s
->win_length
< s
->width
) {
400 return sample_display_startoffset_to_xpos(s
, offset
);
402 gint64 d
= offset
- s
->win_start
;
403 int l
= (1 - s
->win_length
) / s
->width
;
405 /* you get these tests by setting the complete formula below equal to 0 or s->width, respectively,
406 and then resolving towards d. */
409 if(d
> s
->win_length
+ l
)
412 return (d
* s
->width
+ s
->win_length
- 1) / s
->win_length
;
417 sample_display_do_marker_line (GdkDrawable
*win
,
427 if(offset
>= s
->win_start
&& offset
<= s
->win_start
+ s
->win_length
) {
429 x
= sample_display_startoffset_to_xpos(s
, offset
);
431 x
= sample_display_endoffset_to_xpos(s
, offset
);
432 if(x
+3 >= x_min
&& x
-3 < x_max
) {
433 gdk_draw_line(win
, gc
,
436 gdk_draw_rectangle(win
, gc
, TRUE
,
438 gdk_draw_rectangle(win
, gc
, TRUE
,
439 x
- 3, s
->height
- 10, 7, 10);
445 sample_display_draw_main (GtkWidget
*widget
,
448 SampleDisplay
*s
= SAMPLE_DISPLAY(widget
);
451 g_return_if_fail(area
->x
>= 0);
456 if(area
->x
+ area
->width
> s
->width
)
459 if(!IS_INITIALIZED(s
)) {
460 gdk_draw_rectangle(widget
->window
,
462 TRUE
, area
->x
, area
->y
, area
->width
, area
->height
);
463 gdk_draw_line(widget
->window
,
465 area
->x
, s
->height
/ 2,
466 area
->x
+ area
->width
- 1, s
->height
/ 2);
468 const int x_min
= area
->x
;
469 const int x_max
= area
->x
+ area
->width
;
471 if(s
->sel_start
!= -1) {
472 /* draw the part to the left of the selection */
473 x
= sample_display_startoffset_to_xpos(s
, s
->sel_start
);
474 x
= MIN(x_max
, MAX(x_min
, x
));
475 sample_display_draw_data(widget
->window
, s
, 0, x_min
, x
- x_min
);
477 /* draw the selection */
478 x2
= sample_display_endoffset_to_xpos(s
, s
->sel_end
);
479 x2
= MIN(x_max
, MAX(x_min
, x2
));
480 sample_display_draw_data(widget
->window
, s
, 1, x
, x2
- x
);
482 /* we don't have a selection */
486 /* draw the part to the right of the selection */
487 sample_display_draw_data(widget
->window
, s
, 0, x2
, x_max
- x2
);
489 if(s
->loop_start
!= -1) {
490 sample_display_do_marker_line(widget
->window
, s
, 0, s
->loop_start
, x_min
, x_max
, s
->loop_gc
);
491 sample_display_do_marker_line(widget
->window
, s
, 1, s
->loop_end
, x_min
, x_max
, s
->loop_gc
);
494 if(s
->mixerpos
!= -1) {
495 sample_display_do_marker_line(widget
->window
, s
, 0, s
->mixerpos
, x_min
, x_max
, s
->mixerpos_gc
);
496 s
->old_mixerpos
= s
->mixerpos
;
502 sample_display_draw_update (GtkWidget
*widget
,
505 SampleDisplay
*s
= SAMPLE_DISPLAY(widget
);
506 GdkRectangle area2
= { 0, 0, 0, s
->height
};
508 const int x_min
= area
->x
;
509 const int x_max
= area
->x
+ area
->width
;
510 gboolean special_draw
= FALSE
;
512 if(s
->mixerpos
!= s
->old_mixerpos
) {
513 /* Redraw area of old position, redraw area of new position. */
514 for(i
= 0; i
< 2; i
++) {
515 if(s
->old_mixerpos
>= s
->win_start
&& s
->old_mixerpos
< s
->win_start
+ s
->win_length
) {
516 x
= sample_display_startoffset_to_xpos(s
, s
->old_mixerpos
);
517 area2
.x
= MIN(x_max
- 1, MAX(x_min
, x
- 3));
519 if(area2
.x
+ area2
.width
> x_max
) {
520 area2
.width
= x_max
- area2
.x
;
522 sample_display_draw_main(widget
, &area2
);
524 s
->old_mixerpos
= s
->mixerpos
;
529 if(s
->sel_start
!= s
->old_ss
|| s
->sel_end
!= s
->old_se
) {
530 if(s
->sel_start
== -1 || s
->old_ss
== -1) {
531 sample_display_draw_main(widget
, area
);
533 if(s
->sel_start
< s
->old_ss
) {
534 /* repaint left additional side */
535 x
= sample_display_startoffset_to_xpos(s
, s
->sel_start
);
536 area2
.x
= MIN(x_max
, MAX(x_min
, x
));
537 x
= sample_display_startoffset_to_xpos(s
, s
->old_ss
);
538 area2
.width
= MIN(x_max
, MAX(x_min
, x
)) - area2
.x
;
540 /* repaint left removed side */
541 x
= sample_display_startoffset_to_xpos(s
, s
->old_ss
);
542 area2
.x
= MIN(x_max
, MAX(x_min
, x
));
543 x
= sample_display_startoffset_to_xpos(s
, s
->sel_start
);
544 area2
.width
= MIN(x_max
, MAX(x_min
, x
)) - area2
.x
;
546 sample_display_draw_main(widget
, &area2
);
548 if(s
->sel_end
< s
->old_se
) {
549 /* repaint right removed side */
550 x
= sample_display_endoffset_to_xpos(s
, s
->sel_end
);
551 area2
.x
= MIN(x_max
, MAX(x_min
, x
));
552 x
= sample_display_endoffset_to_xpos(s
, s
->old_se
);
553 area2
.width
= MIN(x_max
, MAX(x_min
, x
)) - area2
.x
;
555 /* repaint right additional side */
556 x
= sample_display_endoffset_to_xpos(s
, s
->old_se
);
557 area2
.x
= MIN(x_max
, MAX(x_min
, x
));
558 x
= sample_display_endoffset_to_xpos(s
, s
->sel_end
);
559 area2
.width
= MIN(x_max
, MAX(x_min
, x
)) - area2
.x
;
561 sample_display_draw_main(widget
, &area2
);
564 s
->old_ss
= s
->sel_start
;
565 s
->old_se
= s
->sel_end
;
570 sample_display_draw_main(widget
, area
);
575 sample_display_expose (GtkWidget
*widget
,
576 GdkEventExpose
*event
)
578 sample_display_draw_main(widget
, &event
->area
);
583 sample_display_idle_draw_function (SampleDisplay
*s
)
585 GdkRectangle area
= { 0, 0, s
->width
, s
->height
};
587 if(GTK_WIDGET_MAPPED(GTK_WIDGET(s
))) {
588 sample_display_draw_update(GTK_WIDGET(s
), &area
);
591 gtk_idle_remove(s
->idle_handler
);
597 sample_display_handle_motion (SampleDisplay
*s
,
603 int ss
= s
->sel_start
, se
= s
->sel_end
;
604 int ls
= s
->loop_start
, le
= s
->loop_end
;
611 else if(x
>= s
->width
)
614 ol
= XPOS_TO_OFFSET(x
);
615 if(s
->win_length
< s
->width
) {
616 or = XPOS_TO_OFFSET(x
) + 1;
618 or = XPOS_TO_OFFSET(x
+ 1);
621 g_return_if_fail(ol
>= 0 && ol
< s
->datalen
);
622 g_return_if_fail(or > 0 && or <= s
->datalen
);
623 g_return_if_fail(ol
< or);
625 switch(s
->selecting
) {
626 case SELECTING_SELECTION_START
:
628 if(ss
!= -1 && ol
< se
) {
640 s
->selecting
= SELECTING_SELECTION_END
;
644 case SELECTING_SELECTION_END
:
646 if(ss
!= -1 && or > ss
) {
658 s
->selecting
= SELECTING_SELECTION_START
;
662 case SELECTING_LOOP_START
:
668 case SELECTING_LOOP_END
:
669 if(or > s
->loop_start
)
675 g_assert_not_reached();
679 if(s
->sel_start
!= ss
|| s
->sel_end
!= se
) {
682 sample_display_idle_draw(s
);
683 gtk_signal_emit(GTK_OBJECT(s
), sample_display_signals
[SIG_SELECTION_CHANGED
], ss
, se
);
686 if(s
->loop_start
!= ls
|| s
->loop_end
!= le
) {
689 sample_display_idle_draw(s
);
690 gtk_signal_emit(GTK_OBJECT(s
), sample_display_signals
[SIG_LOOP_CHANGED
], ls
, le
);
694 // Handle middle mousebutton display window panning
696 sample_display_handle_motion_2 (SampleDisplay
*s
,
700 int new_win_start
= s
->selecting_wins0
+ (s
->selecting_x0
- x
) * s
->win_length
/ s
->width
;
702 new_win_start
= CLAMP(new_win_start
, 0, s
->datalen
- s
->win_length
);
704 if(new_win_start
!= s
->win_start
) {
705 sample_display_set_window (s
,
707 new_win_start
+ s
->win_length
);
712 sample_display_button_press (GtkWidget
*widget
,
713 GdkEventButton
*event
)
717 GdkModifierType state
;
719 g_return_val_if_fail (widget
!= NULL
, FALSE
);
720 g_return_val_if_fail (IS_SAMPLE_DISPLAY (widget
), FALSE
);
721 g_return_val_if_fail (event
!= NULL
, FALSE
);
723 s
= SAMPLE_DISPLAY(widget
);
728 if(!IS_INITIALIZED(s
))
731 if(s
->selecting
&& event
->button
!= s
->button
) {
734 s
->button
= event
->button
;
735 gdk_window_get_pointer (event
->window
, &x
, &y
, &state
);
736 if(!(state
& GDK_SHIFT_MASK
)) {
738 s
->selecting
= SELECTING_SELECTION_START
;
739 } else if(s
->button
== 2) {
740 s
->selecting
= SELECTING_PAN_WINDOW
;
741 gdk_window_get_pointer (event
->window
, &s
->selecting_x0
, NULL
, NULL
);
742 s
->selecting_wins0
= s
->win_start
;
743 } else if(s
->button
== 3) {
744 s
->selecting
= SELECTING_SELECTION_END
;
747 if(s
->loop_start
!= -1) {
749 s
->selecting
= SELECTING_LOOP_START
;
750 } else if(s
->button
== 3) {
751 s
->selecting
= SELECTING_LOOP_END
;
757 if(s
->selecting
!= SELECTING_PAN_WINDOW
)
758 sample_display_handle_motion(s
, x
, y
, 1);
765 sample_display_button_release (GtkWidget
*widget
,
766 GdkEventButton
*event
)
770 g_return_val_if_fail (widget
!= NULL
, FALSE
);
771 g_return_val_if_fail (IS_SAMPLE_DISPLAY (widget
), FALSE
);
772 g_return_val_if_fail (event
!= NULL
, FALSE
);
774 s
= SAMPLE_DISPLAY(widget
);
779 if(s
->selecting
&& event
->button
== s
->button
) {
787 sample_display_motion_notify (GtkWidget
*widget
,
788 GdkEventMotion
*event
)
792 GdkModifierType state
;
794 s
= SAMPLE_DISPLAY(widget
);
799 if(!IS_INITIALIZED(s
) || !s
->selecting
)
802 if (event
->is_hint
) {
803 gdk_window_get_pointer (event
->window
, &x
, &y
, &state
);
807 state
= event
->state
;
810 if(((state
& GDK_BUTTON1_MASK
) && s
->button
== 1) || ((state
& GDK_BUTTON3_MASK
) && s
->button
== 3)) {
811 sample_display_handle_motion(SAMPLE_DISPLAY(widget
), x
, y
, 0);
812 } else if((state
& GDK_BUTTON2_MASK
) && s
->button
== 2) {
813 sample_display_handle_motion_2(SAMPLE_DISPLAY(widget
), x
, y
);
822 sample_display_class_init (SampleDisplayClass
*class)
824 GtkObjectClass
*object_class
;
825 GtkWidgetClass
*widget_class
;
830 object_class
= (GtkObjectClass
*) class;
831 widget_class
= (GtkWidgetClass
*) class;
833 widget_class
->realize
= sample_display_realize
;
834 widget_class
->size_allocate
= sample_display_size_allocate
;
835 widget_class
->expose_event
= sample_display_expose
;
836 //widget_class->draw = sample_display_draw;
837 widget_class
->size_request
= sample_display_size_request
;
838 widget_class
->button_press_event
= sample_display_button_press
;
839 widget_class
->button_release_event
= sample_display_button_release
;
840 widget_class
->motion_notify_event
= sample_display_motion_notify
;
842 sample_display_signals
[SIG_SELECTION_CHANGED
] = gtk_signal_new ("selection_changed",
844 GTK_CLASS_TYPE(object_class
),
845 GTK_SIGNAL_OFFSET(SampleDisplayClass
, selection_changed
),
846 gtk_marshal_NONE__INT_INT
,
850 sample_display_signals
[SIG_LOOP_CHANGED
] = gtk_signal_new ("loop_changed",
852 GTK_CLASS_TYPE(object_class
),
853 GTK_SIGNAL_OFFSET(SampleDisplayClass
, loop_changed
),
854 gtk_marshal_NONE__INT_INT
,
858 sample_display_signals
[SIG_WINDOW_CHANGED
] = gtk_signal_new ("window_changed",
860 GTK_CLASS_TYPE(object_class
),
861 GTK_SIGNAL_OFFSET(SampleDisplayClass
, window_changed
),
862 gtk_marshal_NONE__INT_INT
,
867 //gtk_object_class_add_signals(object_class, sample_display_signals, LAST_SIGNAL);
869 class->selection_changed
= NULL
;
870 class->loop_changed
= NULL
;
871 class->window_changed
= NULL
;
873 for(n
= 0, p
= default_colors
, c
= class->colors
; n
< SAMPLE_DISPLAYCOL_LAST
; n
++, c
++) {
874 c
->red
= *p
++ * 65535 / 255;
875 c
->green
= *p
++ * 65535 / 255;
876 c
->blue
= *p
++ * 65535 / 255;
877 c
->pixel
= (gulong
)((c
->red
& 0xff00)*256 + (c
->green
& 0xff00) + (c
->blue
& 0xff00)/256);
878 gdk_color_alloc(gdk_colormap_get_system(), c
);
883 sample_display_init (SampleDisplay
*s
)
889 sample_display_get_type (void)
891 static guint sample_display_type
= 0;
893 if (!sample_display_type
) {
894 GtkTypeInfo sample_display_info
=
897 sizeof(SampleDisplay
),
898 sizeof(SampleDisplayClass
),
899 (GtkClassInitFunc
) sample_display_class_init
,
900 (GtkObjectInitFunc
) sample_display_init
,
905 sample_display_type
= gtk_type_unique (gtk_widget_get_type (), &sample_display_info
);
908 return sample_display_type
;
912 sample_display_new (gboolean edit
)
914 SampleDisplay
*s
= SAMPLE_DISPLAY(gtk_type_new(sample_display_get_type()));
918 s
->display_zero_line
= 0;
919 return GTK_WIDGET(s
);