Don't use G_DEFINE_TYPE anymore, to be pre-gtk+2.24 compatible. Middle click resets knob to 0.0.

This commit is contained in:
Nick Lanham 2012-02-23 12:09:34 +01:00
parent e4de7f2924
commit 9b90186994
2 changed files with 66 additions and 61 deletions

113
nknob.c
View File

@ -6,6 +6,10 @@
* over a GtkRange (i.e. it can be used exactly like a * over a GtkRange (i.e. it can be used exactly like a
* GtkRange from the outside) * GtkRange from the outside)
* *
* In addition, this knob makes the drmr_ui.so module memory resident
* so it can avoid attempting to re-load itself when shown/hidden in
* a ui.
*
* From PhatKnob code: * From PhatKnob code:
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999 * Most of this code comes from gAlan 0.2.0, copyright (C) 1999
* Tony Garnock-Jones, with modifications by Sean Bolton, * Tony Garnock-Jones, with modifications by Sean Bolton,
@ -84,11 +88,38 @@ static void n_knob_get_property (GObject *object,
GError *gerror; GError *gerror;
/* global pixbufs for less mem usage */ /* global pixbufs for less mem usage */
GdkPixbuf **pixbuf = NULL; static GdkPixbuf **pixbuf = NULL;
/* Local data */ // Can't use G_DEFINE_TYPE because ardour is at gtk 2.22
static NKnobClass *parent_class;
GType
n_knob_get_type (void) {
static GType nknob_type;
if (!nknob_type) {
// We need to make ourselves memory resident so our type won't get unloaded
// when the window is shown/hiddent
GModule *module_self = g_module_open (INSTALL_DIR"/drmr.lv2/drmr_ui.so", 0);
if (!module_self)
g_print ("error (segfault eminent): %s\n", g_module_error ());
else
g_module_make_resident(module_self);
G_DEFINE_TYPE (NKnob, n_knob, GTK_TYPE_RANGE); static const GTypeInfo object_info = {
sizeof (NKnobClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) n_knob_class_init,
(GClassFinalizeFunc) NULL,
NULL, // class data
sizeof (NKnob),
0, // preallocs
(GInstanceInitFunc) n_knob_init,
NULL // value table
};
nknob_type = g_type_register_static(GTK_TYPE_RANGE,"NKnob",&object_info,0);
}
return nknob_type;
}
static void n_knob_class_init (NKnobClass *klass) { static void n_knob_class_init (NKnobClass *klass) {
GtkObjectClass *object_class; GtkObjectClass *object_class;
@ -98,6 +129,8 @@ static void n_knob_class_init (NKnobClass *klass) {
object_class = GTK_OBJECT_CLASS(klass); object_class = GTK_OBJECT_CLASS(klass);
widget_class = GTK_WIDGET_CLASS(klass); widget_class = GTK_WIDGET_CLASS(klass);
g_object_class = G_OBJECT_CLASS(klass); g_object_class = G_OBJECT_CLASS(klass);
parent_class = g_type_class_peek_parent (klass);
g_object_class->set_property = n_knob_set_property; g_object_class->set_property = n_knob_set_property;
g_object_class->get_property = n_knob_get_property; g_object_class->get_property = n_knob_get_property;
@ -172,8 +205,8 @@ GtkWidget *n_knob_new(GtkAdjustment *adjustment) {
* Returns: a newly created #NKnob * Returns: a newly created #NKnob
* *
*/ */
GtkWidget* n_knob_new_with_range (double value, double lower, GtkWidget* n_knob_new_with_range (gdouble value, gdouble lower,
double upper, double step) { gdouble upper, gdouble step) {
GtkAdjustment* adj; GtkAdjustment* adj;
adj = (GtkAdjustment*) gtk_adjustment_new (value, lower, upper, step, step, 0); adj = (GtkAdjustment*) gtk_adjustment_new (value, lower, upper, step, step, 0);
return n_knob_new (adj); return n_knob_new (adj);
@ -181,28 +214,15 @@ GtkWidget* n_knob_new_with_range (double value, double lower,
static void n_knob_destroy(GtkObject *object) { static void n_knob_destroy(GtkObject *object) {
NKnob *knob; NKnob *knob;
g_return_if_fail(object != NULL); g_return_if_fail(object != NULL);
g_return_if_fail(N_IS_KNOB(object)); g_return_if_fail(N_IS_KNOB(object));
knob = N_KNOB(object); knob = N_KNOB(object);
knob->pixbuf = NULL;
if (knob->mask) { if (GTK_OBJECT_CLASS(parent_class)->destroy)
gdk_bitmap_unref(knob->mask); (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
knob->mask = NULL;
}
if (knob->mask_gc) {
gdk_gc_unref(knob->mask_gc);
knob->mask_gc = NULL;
}
if (knob->red_gc) {
gdk_gc_unref(knob->red_gc);
knob->red_gc = NULL;
}
if (GTK_OBJECT_CLASS(n_knob_parent_class)->destroy)
(*GTK_OBJECT_CLASS(n_knob_parent_class)->destroy)(object);
} }
@ -214,8 +234,8 @@ static void n_knob_realize(GtkWidget *widget) {
g_return_if_fail(widget != NULL); g_return_if_fail(widget != NULL);
g_return_if_fail(N_IS_KNOB(widget)); g_return_if_fail(N_IS_KNOB(widget));
if (GTK_WIDGET_CLASS(n_knob_parent_class)->realize) if (GTK_WIDGET_CLASS(parent_class)->realize)
(*GTK_WIDGET_CLASS(n_knob_parent_class)->realize)(widget); (*GTK_WIDGET_CLASS(parent_class)->realize)(widget);
knob = N_KNOB(widget); knob = N_KNOB(widget);
@ -297,7 +317,7 @@ static gint n_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
case STATE_IDLE: case STATE_IDLE:
switch (event->button) { switch (event->button) {
case 1: case 1:
case 2: case 3:
gtk_grab_add(widget); gtk_grab_add(widget);
knob->state = STATE_PRESSED; knob->state = STATE_PRESSED;
knob->saved_x = event->x; knob->saved_x = event->x;
@ -317,49 +337,32 @@ static gint n_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
static gint n_knob_button_release(GtkWidget *widget, GdkEventButton *event) { static gint n_knob_button_release(GtkWidget *widget, GdkEventButton *event) {
NKnob *knob; NKnob *knob;
GtkRange *range;
GtkAdjustment *adj;
g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(N_IS_KNOB(widget), FALSE); g_return_val_if_fail(N_IS_KNOB(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE); g_return_val_if_fail(event != NULL, FALSE);
knob = N_KNOB(widget); knob = N_KNOB(widget);
range = GTK_RANGE(knob);
adj = gtk_range_get_adjustment(range);
switch (event->button) {
switch (knob->state) { case 1:
case STATE_PRESSED: case 3:
gtk_grab_remove(widget); switch (knob->state) {
knob->state = STATE_IDLE; case STATE_PRESSED:
gtk_grab_remove(widget);
switch (event->button) { knob->state = STATE_IDLE;
case 1: case STATE_DRAGGING:
gtk_range_set_value(range, gtk_grab_remove(widget);
gtk_range_get_value(range)+ knob->state = STATE_IDLE;
gtk_adjustment_get_page_increment(adj));
break;
case 3:
gtk_range_set_value(range,
gtk_range_get_value(range)-
gtk_adjustment_get_page_increment(adj));
break; break;
default: default:
break; break;
} }
break; break;
case 2: {
case STATE_DRAGGING: gtk_range_set_value(GTK_RANGE(knob),0.0);
gtk_grab_remove(widget); }
knob->state = STATE_IDLE;
break;
default:
break;
} }
return FALSE; return FALSE;

14
nknob.h
View File

@ -27,18 +27,23 @@
*/ */
#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#ifndef __NKNOB_H__ #ifndef __NKNOB_H__
#define __NKNOB_H__ #define __NKNOB_H__
#include <gdk/gdk.h>
#include <gtk/gtkrange.h> #include <gtk/gtkrange.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define N_TYPE_KNOB (n_knob_get_type ( ))
#define N_KNOB(obj) GTK_CHECK_CAST(obj, n_knob_get_type(), NKnob) #define N_KNOB(obj) GTK_CHECK_CAST(obj, n_knob_get_type(), NKnob)
#define N_KNOB_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, n_knob_get_type(), NKnobClass) #define N_KNOB_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, n_knob_get_type(), NKnobClass)
#define N_IS_KNOB(obj) GTK_CHECK_TYPE(obj, n_knob_get_type()) #define N_IS_KNOB(obj) GTK_CHECK_TYPE(obj, n_knob_get_type())
#define N_TYPE_KNOB (n_knob_get_type ( )) #define N_IS_KNOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), N_TYPE_KNOB))
#define N_KNOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), N_TYPE_KNOB, NKnobClass))
typedef struct _NKnob NKnob; typedef struct _NKnob NKnob;
@ -56,16 +61,13 @@ struct _NKnob {
/* Pixmap for knob */ /* Pixmap for knob */
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
GdkBitmap *mask;
GdkGC *mask_gc;
GdkGC *red_gc;
}; };
struct _NKnobClass { struct _NKnobClass {
GtkRangeClass parent_class; GtkRangeClass parent_class;
}; };
GType n_knob_get_type ( ); GType n_knob_get_type ( ) G_GNUC_CONST;
GtkWidget* n_knob_new (GtkAdjustment* adjustment); GtkWidget* n_knob_new (GtkAdjustment* adjustment);