[SCM] calf/master: + LED: new custom control (ugly and displays a GTK critical warning, but you can't have everything)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:38:03 UTC 2013


The following commit has been merged in the master branch:
commit fe6152d6e6900c1392a5925ce01a1baa3573ef3e
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Fri Oct 31 21:55:14 2008 +0000

    + LED: new custom control (ugly and displays a GTK critical warning, but you can't have everything)

diff --git a/bigbull/mkskel.py b/bigbull/mkskel.py
new file mode 100755
index 0000000..24811c0
--- /dev/null
+++ b/bigbull/mkskel.py
@@ -0,0 +1,173 @@
+#!/usr/bin/python
+
+templ_h = """// Header
+#ifndef [PREF]_CTL_[TYPE]_H
+#define [PREF]_CTL_[TYPE]_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define [PREF]_TYPE_[TYPE]          ([pref]_[type]_get_type())
+#define [PREF]_[TYPE](obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), [PREF]_TYPE_[TYPE], [Pref][Type]))
+#define [PREF]_IS_[TYPE](obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), [PREF]_TYPE_[TYPE]))
+#define [PREF]_[TYPE]_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),  [PREF]_TYPE_[TYPE], [Pref][Type]Class))
+#define [PREF]_IS_[TYPE]_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass),  [PREF]_TYPE_[TYPE]))
+
+/// Instance object for [Pref][Type]
+struct [Pref][Type]
+{
+    GtkWidget parent;
+};
+
+/// Class object for [Pref][Type]
+struct [Pref][Type]Class
+{
+    GtkWidgetClass parent_class;
+};
+
+/// Create new [Pref][Type]
+extern GtkWidget *[pref]_[type]_new();
+
+/// Get GObject type
+extern GType [pref]_[type]_get_type();
+
+G_END_DECLS
+
+#endif
+"""
+
+templ_cpp = """// Source
+
+GtkWidget *
+[preftype]_new()
+{
+    GtkWidget *widget = GTK_WIDGET( g_object_new ([PREF]_TYPE_[TYPE], NULL ));
+    return widget;
+}
+
+static gboolean
+[preftype]_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+    g_assert([PREF]_IS_[TYPE](widget));
+    
+    [PrefType] *self = [PREFTYPE](widget);
+    GdkWindow *window = widget->window;
+    cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(window));
+    cairo_destroy(c);
+
+    return TRUE;
+}
+
+static void
+[preftype]_realize(GtkWidget *widget)
+{
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+
+    GdkWindowAttr attributes;
+    attributes.event_mask = GDK_EXPOSURE_MASK | GDK_BUTTON1_MOTION_MASK | 
+        GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | 
+        GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+
+    widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, GDK_WA_X | GDK_WA_Y);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void
+[preftype]_size_request (GtkWidget *widget,
+                           GtkRequisition *requisition)
+{
+    g_assert([PREF]_IS_[TYPE](widget));
+    
+    // width/height is hardwired at 40px now
+    requisition->width = ...;
+    requisition->height = ...;
+}
+
+static void
+[preftype]_size_allocate (GtkWidget *widget,
+                           GtkAllocation *allocation)
+{
+    g_assert([PREF]_IS_[TYPE](widget));
+    
+    widget->allocation = *allocation;
+    
+    if (GTK_WIDGET_REALIZED(widget))
+        gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height );
+}
+
+static void
+[preftype]_class_init ([PrefType]Class *klass)
+{
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+    widget_class->realize = [preftype]_realize;
+    widget_class->expose_event = [preftype]_expose;
+    widget_class->size_request = [preftype]_size_request;
+    widget_class->size_allocate = [preftype]_size_allocate;
+    // widget_class->button_press_event = [preftype]_button_press;
+    // widget_class->button_release_event = [preftype]_button_release;
+    // widget_class->motion_notify_event = [preftype]_pointer_motion;
+    // widget_class->key_press_event = [preftype]_key_press;
+    // widget_class->scroll_event = [preftype]_scroll;
+}
+
+static void
+[preftype]_init ([PrefType] *self)
+{
+    GtkWidget *widget = GTK_WIDGET(self);
+    GTK_WIDGET_SET_FLAGS (GTK_WIDGET(self), GTK_CAN_FOCUS);
+}
+
+GType
+[preftype]_get_type (void)
+{
+    static GType type = 0;
+    if (!type) {
+        
+        static const GTypeInfo type_info = {
+            sizeof([PrefType]Class),
+            NULL, /* base_init */
+            NULL, /* base_finalize */
+            (GClassInitFunc)[preftype]_class_init,
+            NULL, /* class_finalize */
+            NULL, /* class_data */
+            sizeof([PrefType]),
+            0,    /* n_preallocs */
+            (GInstanceInitFunc)[preftype]_init
+        };
+        
+        for (int i = 0; ; i++) {
+            char *name = g_strdup_printf("[PrefType]%u%d", 
+                ((unsigned int)(intptr_t)[preftype]_class_init) >> 16, i);
+            if (g_type_from_name(name)) {
+                free(name);
+                continue;
+            }
+            type = g_type_register_static(GTK_TYPE_WIDGET,
+                                          name,
+                                          &type_info,
+                                          (GTypeFlags)0);
+            free(name);
+            break;
+        }
+    }
+    return type;
+}
+"""
+
+def subst(text, pref, type):
+    text = text.replace("[pref]", pref.lower()).replace("[PREF]", pref.upper()).replace("[Pref]", pref)
+    text = text.replace("[type]", type.lower()).replace("[TYPE]", type.upper()).replace("[Type]", type)    
+    text = text.replace("[preftype]", pref.lower()+"_"+type.lower()).replace("[PrefType]", pref+type)
+    text = text.replace("[PREFTYPE]", pref.upper()+"_"+type.upper())
+    return text
+    
+print subst(templ_h, "Calf", "Led")
+print subst(templ_cpp, "Calf", "Led")
diff --git a/src/Makefile.am b/src/Makefile.am
index 08de89d..5a7051b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,7 +58,7 @@ calf_la_LDFLAGS = -rpath $(ladspadir) -avoid-version -module -lexpat -export-sym
 endif
 
 if USE_LV2_GUI
-calflv2gui_la_SOURCES = gui.cpp ctl_curve.cpp ctl_keyboard.cpp custom_ctl.cpp modules.cpp giface.cpp monosynth.cpp organ.cpp preset.cpp synth.cpp lv2gui.cpp main_win.cpp
+calflv2gui_la_SOURCES = gui.cpp ctl_curve.cpp ctl_keyboard.cpp ctl_led.cpp custom_ctl.cpp modules.cpp giface.cpp monosynth.cpp organ.cpp preset.cpp synth.cpp lv2gui.cpp main_win.cpp
 if USE_DEBUG
 calflv2gui_la_LDFLAGS = -rpath $(lv2dir) -avoid-version -module -lexpat $(GUI_DEPS_LIBS) 
 else
@@ -70,7 +70,7 @@ libcalfstatic_la_SOURCES = modules.cpp modules_small.cpp giface.cpp monosynth.cp
 libcalfstatic_la_LDFLAGS = -static -lexpat
 
 if USE_GUI
-libcalfgui_la_SOURCES = gui.cpp ctl_curve.cpp ctl_keyboard.cpp preset_gui.cpp custom_ctl.cpp osctl.cpp osctlnet.cpp main_win.cpp
+libcalfgui_la_SOURCES = gui.cpp ctl_curve.cpp ctl_keyboard.cpp ctl_led.cpp preset_gui.cpp custom_ctl.cpp osctl.cpp osctlnet.cpp main_win.cpp
 libcalfgui_la_LDFLAGS = -static
 endif
 
diff --git a/src/calf/Makefile.am b/src/calf/Makefile.am
index 2994a0a..d10c38a 100644
--- a/src/calf/Makefile.am
+++ b/src/calf/Makefile.am
@@ -1,7 +1,7 @@
 calfdir = $(includedir)/calf
 
 calf_HEADERS = audio_fx.h benchmark.h biquad.h buffer.h custom_ctl.h \
-    ctl_curve.h ctl_keyboard.h \
+    ctl_curve.h ctl_keyboard.h ctl_led.h \
     delay.h envelope.h fft.h fixed_point.h giface.h gui.h inertia.h jackhost.h \
     lv2_contexts.h lv2_event.h lv2_ui.h lv2_uri_map.h lv2-midiport.h lv2helpers.h lv2wrap.h \
     main_win.h modules.h modules_dev.h modules_small.h modules_synths.h modulelist.h \
diff --git a/src/calf/ctl_led.h b/src/calf/ctl_led.h
new file mode 100644
index 0000000..6a89d5e
--- /dev/null
+++ b/src/calf/ctl_led.h
@@ -0,0 +1,62 @@
+/* Calf DSP Library
+ * Light emitting diode-like control.
+ *
+ * Copyright (C) 2008 Krzysztof Foltman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CALF_CTL_LED_H
+#define CALF_CTL_LED_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define CALF_TYPE_LED          (calf_led_get_type())
+#define CALF_LED(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALF_TYPE_LED, CalfLed))
+#define CALF_IS_LED(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALF_TYPE_LED))
+#define CALF_LED_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),  CALF_TYPE_LED, CalfLedClass))
+#define CALF_IS_LED_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass),  CALF_TYPE_LED))
+
+/// Instance object for CalfLed
+struct CalfLed
+{
+    GtkWidget parent;
+    gboolean led_state;
+};
+
+/// Class object for CalfLed
+struct CalfLedClass
+{
+    GtkWidgetClass parent_class;
+};
+
+/// Create new CalfLed
+extern GtkWidget *calf_led_new();
+
+/// Get GObject type for the CalfLed
+extern GType calf_led_get_type();
+
+/// Set LED state (true - lit, false - unlit)
+extern void calf_led_set_state(CalfLed *led, gboolean state);
+
+/// Get LED state (true - lit, false - unlit)
+extern gboolean calf_led_get_state(CalfLed *led);
+
+G_END_DECLS
+
+#endif
diff --git a/src/calf/giface.h b/src/calf/giface.h
index f66e3ed..77b3dff 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -75,6 +75,7 @@ enum parameter_flags
   PF_CTL_RADIO =   0x0500, ///< radio button
   PF_CTL_BUTTON =  0x0600, ///< push button
   PF_CTL_METER  =  0x0700, ///< volume meter
+  PF_CTL_LED    =  0x0800, ///< light emitting diode
   
   PF_CTLOPTIONS     = 0x00F000,
   PF_CTLO_HORIZ     = 0x001000, ///< horizontal version of the control
diff --git a/src/calf/gui.h b/src/calf/gui.h
index e605267..aa7c64e 100644
--- a/src/calf/gui.h
+++ b/src/calf/gui.h
@@ -27,8 +27,9 @@
 #include <gtk/gtk.h>
 #include "custom_ctl.h"
 
-struct CalfKeyboard;
 struct CalfCurve;
+struct CalfKeyboard;
+struct CalfLed;
 
 namespace synth {
 
@@ -156,6 +157,16 @@ struct vumeter_param_control: public param_control
     virtual void set();
 };
 
+/// Display-only control: LED
+struct led_param_control: public param_control
+{
+    CalfLed *meter;
+    
+    virtual GtkWidget *create(plugin_gui *_gui, int _param_no);
+    virtual void get() {}
+    virtual void set();
+};
+
 struct hscale_param_control: public param_control
 {
     GtkHScale *scale;
diff --git a/src/ctl_led.cpp b/src/ctl_led.cpp
new file mode 100644
index 0000000..1d8d311
--- /dev/null
+++ b/src/ctl_led.cpp
@@ -0,0 +1,180 @@
+/* Calf DSP Library
+ * Light emitting diode-like control.
+ *
+ * Copyright (C) 2008 Krzysztof Foltman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <calf/ctl_led.h>
+#include <math.h>
+#include <stdint.h>
+#include <malloc.h>
+
+GtkWidget *
+calf_led_new()
+{
+    GtkWidget *widget = GTK_WIDGET( g_object_new (CALF_TYPE_LED, NULL ));
+    return widget;
+}
+
+static gboolean
+calf_led_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+    g_assert(CALF_IS_LED(widget));
+    
+    CalfLed *self = CALF_LED(widget);
+    GdkWindow *window = widget->window;
+    cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(window));
+
+    gdk_cairo_set_source_color(c, &widget->style->bg[0]);
+    cairo_rectangle(c, 0, 0, widget->allocation.width, widget->allocation.height);
+    cairo_fill(c);
+
+    
+    int diameter = (widget->allocation.width < widget->allocation.height ? widget->allocation.width : widget->allocation.height) - 2;
+    cairo_arc(c, widget->allocation.width / 2, widget->allocation.height / 2, diameter / 2 - 1, 0, 2 * M_PI);
+    cairo_set_line_join(c, CAIRO_LINE_JOIN_BEVEL);
+    cairo_set_source_rgba (c, self->led_state ? 1 : 0.0, 0, 0, 0.8);
+    cairo_fill(c);
+    
+    cairo_arc(c, widget->allocation.width / 2, widget->allocation.height / 2, diameter / 2, 0, 2 * M_PI);
+    cairo_set_line_width(c, 2);
+    cairo_stroke(c);
+    cairo_set_source_rgba (c, self->led_state ? 0.8 : 0.3, 0, 0, 1.0);
+    
+    cairo_destroy(c);
+
+    return TRUE;
+}
+
+static void
+calf_led_realize(GtkWidget *widget)
+{
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+
+    GdkWindowAttr attributes;
+    attributes.event_mask = GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+
+    widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, GDK_WA_X | GDK_WA_Y);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void
+calf_led_size_request (GtkWidget *widget,
+                           GtkRequisition *requisition)
+{
+    g_assert(CALF_IS_LED(widget));
+    
+    requisition->width = 12;
+    requisition->height = 12;
+}
+
+static void
+calf_led_size_allocate (GtkWidget *widget,
+                           GtkAllocation *allocation)
+{
+    g_assert(CALF_IS_LED(widget));
+    
+    widget->allocation = *allocation;
+    
+    if (GTK_WIDGET_REALIZED(widget))
+        gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height );
+}
+
+static gboolean
+calf_led_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+    return TRUE;
+}
+
+static void
+calf_led_class_init (CalfLedClass *klass)
+{
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+    widget_class->realize = calf_led_realize;
+    widget_class->expose_event = calf_led_expose;
+    widget_class->size_request = calf_led_size_request;
+    widget_class->size_allocate = calf_led_size_allocate;
+    widget_class->button_press_event = calf_led_button_press;
+}
+
+static void
+calf_led_init (CalfLed *self)
+{
+    GtkWidget *widget = GTK_WIDGET(self);
+    // GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+    self->led_state = FALSE;
+}
+
+void calf_led_set_state(CalfLed *led, gboolean state)
+{
+    if (state != led->led_state)
+    {
+        led->led_state = state;
+        GtkWidget *widget = GTK_WIDGET (led);
+        if (GTK_WIDGET_REALIZED(widget))
+            gtk_widget_queue_draw (widget);
+    }
+}
+
+gboolean calf_led_get_state(CalfLed *led)
+{
+    return led->led_state;
+}
+
+GType
+calf_led_get_type (void)
+{
+    static GType type = 0;
+    if (!type) {
+        
+        static const GTypeInfo type_info = {
+            sizeof(CalfLedClass),
+            NULL, /* base_init */
+            NULL, /* base_finalize */
+            (GClassInitFunc)calf_led_class_init,
+            NULL, /* class_finalize */
+            NULL, /* class_data */
+            sizeof(CalfLed),
+            0,    /* n_preallocs */
+            (GInstanceInitFunc)calf_led_init
+        };
+        
+        for (int i = 0; ; i++) {
+            char *name = g_strdup_printf("CalfLed%u%d", 
+                ((unsigned int)(intptr_t)calf_led_class_init) >> 16, i);
+            if (g_type_from_name(name)) {
+                free(name);
+                continue;
+            }
+            type = g_type_register_static(GTK_TYPE_WIDGET,
+                                          name,
+                                          &type_info,
+                                          (GTypeFlags)0);
+            free(name);
+            break;
+        }
+    }
+    return type;
+}
+
diff --git a/src/gui.cpp b/src/gui.cpp
index fd393b7..e36ebd3 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -22,6 +22,7 @@
 #include <assert.h>
 #include <calf/ctl_curve.h>
 #include <calf/ctl_keyboard.h>
+#include <calf/ctl_led.h>
 #include <calf/giface.h>
 #include <calf/gui.h>
 #include <calf/preset.h>
@@ -232,7 +233,7 @@ void value_param_control::set()
     gtk_label_set_text (GTK_LABEL (widget), props.to_string(gui->plugin->get_param_value(param_no)).c_str());    
 }
 
-// value
+// VU meter
 
 GtkWidget *vumeter_param_control::create(plugin_gui *_gui, int _param_no)
 {
@@ -251,6 +252,25 @@ void vumeter_param_control::set()
         update_label();
 }
 
+// LED
+
+GtkWidget *led_param_control::create(plugin_gui *_gui, int _param_no)
+{
+    gui = _gui, param_no = _param_no;
+    // parameter_properties &props = get_props();
+    widget = calf_led_new ();
+    return widget;
+}
+
+void led_param_control::set()
+{
+    _GUARD_CHANGE_
+    parameter_properties &props = get_props();
+    calf_led_set_state (CALF_LED (widget), gui->plugin->get_param_value(param_no) > 0);
+    if (label)
+        update_label();
+}
+
 // check box
 
 GtkWidget *toggle_param_control::create(plugin_gui *_gui, int _param_no)
@@ -540,6 +560,13 @@ GtkWidget *plugin_gui::create(plugin_ctl_iface *_plugin)
             widget = params[i]->create(this, i);
             gtk_table_attach (GTK_TABLE (container), widget, 0, 3, trow, trow + 1, GTK_EXPAND, GTK_SHRINK, 0, 0);
         }
+        else if ((props.flags & PF_TYPEMASK) == PF_BOOL && 
+                 (props.flags & PF_CTLMASK) == PF_CTL_LED)
+        {
+            params[i] = new led_param_control();
+            widget = params[i]->create(this, i);
+            gtk_table_attach (GTK_TABLE (container), widget, 1, 3, trow, trow + 1, GTK_SHRINK, GTK_SHRINK, 10, 0);
+        }
         else if ((props.flags & PF_CTLMASK) == PF_CTL_METER)
         {
             params[i] = new vumeter_param_control();
diff --git a/src/main_win.cpp b/src/main_win.cpp
index 82e2853..3e3c70b 100644
--- a/src/main_win.cpp
+++ b/src/main_win.cpp
@@ -20,6 +20,7 @@
  
 #include <assert.h>
 #include <config.h>
+#include <calf/ctl_led.h>
 #include <calf/giface.h>
 #include <calf/gui.h>
 #include <calf/preset.h>
@@ -197,7 +198,10 @@ main_window::plugin_strip *main_window::create_strip(plugin_ctl_iface *plugin)
         (plugin_ctl_iface *)strip);
     gtk_widget_show(strip->name);
     
-    label = gtk_label_new(plugin->get_midi() ? "?" : "");
+    if (plugin->get_midi())
+        label = calf_led_new();
+    else
+        label = gtk_label_new("");
     gtk_table_attach(GTK_TABLE(strips_table), label, 1, 2, row, row + 2, GTK_FILL, GTK_SHRINK, 0, 0);
     strip->midi_in = label;
     gtk_widget_show(strip->midi_in);
@@ -396,7 +400,7 @@ gboolean main_window::on_idle(void *data)
                 calf_vumeter_set_value(CALF_VUMETER(strip->audio_out[1]), LVL(plugin->get_level(idx++)));
             }
             if (plugin->get_midi()) {
-                gtk_label_set_text(GTK_LABEL(strip->midi_in), (plugin->get_level(idx++) > 0.f) ? "*" : "");
+                calf_led_set_state (CALF_LED (strip->midi_in), plugin->get_level(idx++) > 0.f);
             }
         }
     }

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list