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

111
nknob.c
View File

@ -6,6 +6,10 @@
* over a GtkRange (i.e. it can be used exactly like a
* 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:
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999
* Tony Garnock-Jones, with modifications by Sean Bolton,
@ -84,11 +88,38 @@ static void n_knob_get_property (GObject *object,
GError *gerror;
/* 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) {
GtkObjectClass *object_class;
@ -99,6 +130,8 @@ static void n_knob_class_init (NKnobClass *klass) {
widget_class = GTK_WIDGET_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->get_property = n_knob_get_property;
@ -172,8 +205,8 @@ GtkWidget *n_knob_new(GtkAdjustment *adjustment) {
* Returns: a newly created #NKnob
*
*/
GtkWidget* n_knob_new_with_range (double value, double lower,
double upper, double step) {
GtkWidget* n_knob_new_with_range (gdouble value, gdouble lower,
gdouble upper, gdouble step) {
GtkAdjustment* adj;
adj = (GtkAdjustment*) gtk_adjustment_new (value, lower, upper, step, step, 0);
return n_knob_new (adj);
@ -186,23 +219,10 @@ static void n_knob_destroy(GtkObject *object) {
g_return_if_fail(N_IS_KNOB(object));
knob = N_KNOB(object);
knob->pixbuf = NULL;
if (knob->mask) {
gdk_bitmap_unref(knob->mask);
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);
if (GTK_OBJECT_CLASS(parent_class)->destroy)
(*GTK_OBJECT_CLASS(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(N_IS_KNOB(widget));
if (GTK_WIDGET_CLASS(n_knob_parent_class)->realize)
(*GTK_WIDGET_CLASS(n_knob_parent_class)->realize)(widget);
if (GTK_WIDGET_CLASS(parent_class)->realize)
(*GTK_WIDGET_CLASS(parent_class)->realize)(widget);
knob = N_KNOB(widget);
@ -297,7 +317,7 @@ static gint n_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
case STATE_IDLE:
switch (event->button) {
case 1:
case 2:
case 3:
gtk_grab_add(widget);
knob->state = STATE_PRESSED;
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) {
NKnob *knob;
GtkRange *range;
GtkAdjustment *adj;
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(N_IS_KNOB(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
knob = N_KNOB(widget);
range = GTK_RANGE(knob);
adj = gtk_range_get_adjustment(range);
switch (event->button) {
case 1:
case 3:
switch (knob->state) {
case STATE_PRESSED:
gtk_grab_remove(widget);
knob->state = STATE_IDLE;
case STATE_DRAGGING:
gtk_grab_remove(widget);
knob->state = STATE_IDLE;
switch (knob->state) {
case STATE_PRESSED:
gtk_grab_remove(widget);
knob->state = STATE_IDLE;
switch (event->button) {
case 1:
gtk_range_set_value(range,
gtk_range_get_value(range)+
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;
default:
break;
}
break;
case STATE_DRAGGING:
gtk_grab_remove(widget);
knob->state = STATE_IDLE;
break;
default:
break;
case 2: {
gtk_range_set_value(GTK_RANGE(knob),0.0);
}
}
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__
#define __NKNOB_H__
#include <gdk/gdk.h>
#include <gtk/gtkrange.h>
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_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_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;
@ -56,16 +61,13 @@ struct _NKnob {
/* Pixmap for knob */
GdkPixbuf *pixbuf;
GdkBitmap *mask;
GdkGC *mask_gc;
GdkGC *red_gc;
};
struct _NKnobClass {
GtkRangeClass parent_class;
};
GType n_knob_get_type ( );
GType n_knob_get_type ( ) G_GNUC_CONST;
GtkWidget* n_knob_new (GtkAdjustment* adjustment);