[SCM] calf/master: + Curve: added (quite primitive) cursor feedback, added object destructor + Keyboard: added callbacks for changing key colour and drawing overlays on keys

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:26 UTC 2013


The following commit has been merged in the master branch:
commit 6055b82305a9d406201c558d44f9a08394c4da08
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Thu Jul 31 20:36:09 2008 +0000

    + Curve: added (quite primitive) cursor feedback, added object destructor
    + Keyboard: added callbacks for changing key colour and drawing overlays on keys
    
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@242 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/ctl_curve.h b/src/calf/ctl_curve.h
index 5a31c19..0c53d4f 100644
--- a/src/calf/ctl_curve.h
+++ b/src/calf/ctl_curve.h
@@ -48,7 +48,7 @@ struct CalfCurve
         virtual void curve_changed(const point_vector &data) {}
     };
 
-    struct EventTester: public EventSink
+    struct EventTester: public EventAdapter
     {
         virtual void curve_changed(const point_vector &data) {
             for(size_t i = 0; i < data.size(); i++)
@@ -62,37 +62,11 @@ struct CalfCurve
     int cur_pt;
     bool hide_current;
     EventSink *sink;
-    
-    void log2phys(float &x, float &y) {
-        x = (x - x0) / (x1 - x0) * (parent.allocation.width - 2) + 1;
-        y = (y - y0) / (y1 - y0) * (parent.allocation.height - 2) + 1;
-    }
-    void phys2log(float &x, float &y) {
-        x = x0 + (x - 1) * (x1 - x0) / (parent.allocation.width - 2);
-        y = y0 + (y - 1) * (y1 - y0) / (parent.allocation.height - 2);
-    }
-    void clip(int pt, float &x, float &y, bool &hide)
-    {
-        float ymin = std::min(y0, y1), ymax = std::max(y0, y1);
-        float yamp = ymax - ymin;
-        hide = false;
-        if (pt != 0 && pt != (int)(points->size() - 1))
-        {
-            if (y < ymin - yamp || y > ymax + yamp)
-                hide = true;
-        }
-        if (x < x0) x = x0;
-        if (y < ymin) y = ymin;
-        if (x > x1) x = x1;
-        if (y > ymax) y = ymax;
-        if (pt == 0) x = 0;
-        if (pt == (int)(points->size() - 1))
-            x = (*points)[pt].first;
-        if (pt > 0 && x < (*points)[pt - 1].first)
-            x = (*points)[pt - 1].first;
-        if (pt < (int)(points->size() - 1) && x > (*points)[pt + 1].first)
-            x = (*points)[pt + 1].first;
-    }
+    GdkCursor *hand_cursor, *pencil_cursor;
+
+    void log2phys(float &x, float &y);
+    void phys2log(float &x, float &y);
+    void clip(int pt, float &x, float &y, bool &hide);
 };
 
 struct CalfCurveClass
@@ -101,8 +75,8 @@ struct CalfCurveClass
 };
 
 extern GtkWidget *calf_curve_new();
-
 extern GType calf_curve_get_type();
+extern void calf_curve_set_points(GtkWidget *widget, const CalfCurve::point_vector &src);
 
 G_END_DECLS
 
diff --git a/src/calf/ctl_keyboard.h b/src/calf/ctl_keyboard.h
index 7e47051..f94262e 100644
--- a/src/calf/ctl_keyboard.h
+++ b/src/calf/ctl_keyboard.h
@@ -35,20 +35,49 @@ G_BEGIN_DECLS
 
 struct CalfKeyboard
 {
+    struct KeyInfo
+    {
+        double x, y, width, height;
+        int note;
+        bool black;
+    };
+    
     struct EventSink
     {
+        virtual void set_instance(CalfKeyboard *kb)=0;
+        virtual bool pre_draw(cairo_t *c, KeyInfo &ki)=0;
+        virtual bool pre_draw_outline(cairo_t *c, KeyInfo &ki)=0;
+        virtual void post_draw(cairo_t *c, KeyInfo &ki)=0;
+        virtual void post_all(cairo_t *c)=0;
         virtual void note_on(int note, int vel) = 0;
         virtual void note_off(int note) = 0;
     };
 
     struct EventAdapter: public EventSink
     {
+        CalfKeyboard *kb;
+        virtual void set_instance(CalfKeyboard *_kb) { kb = _kb; }
+        virtual bool pre_draw(cairo_t *c, KeyInfo &ki) { return false; }
+        virtual bool pre_draw_outline(cairo_t *c, KeyInfo &ki) { return false; }
+        virtual void post_draw(cairo_t *c, KeyInfo &ki) {}
+        virtual void post_all(cairo_t *c) {}
         virtual void note_on(int note, int vel) {}
         virtual void note_off(int note) {}
     };
 
-    struct EventTester: public EventSink
+    struct EventTester: public EventAdapter
     {
+        virtual bool pre_draw(cairo_t *c, KeyInfo &ki) { if (ki.note == 60) cairo_set_source_rgb(c, 1.0, 1.0, 0.5); return false; }
+        virtual void post_draw(cairo_t *c, KeyInfo &ki) { 
+            if (ki.note % 12 != 0 && ki.note % 12 != 3 && ki.note % 12 != 7)
+                return;
+            cairo_rectangle(c, ki.x + ki.width / 2 - 2, ki.y + ki.height - 8, 4, 4);
+            if (ki.black)
+                cairo_set_source_rgb(c, 1.0, 1.0, 1.0);
+            else
+                cairo_set_source_rgb(c, 0.0, 0.0, 0.0);
+            cairo_fill(c); 
+        }
         virtual void note_on(int note, int vel) { g_message("note on %d %d", note, vel); }
         virtual void note_off(int note) { g_message("note off %d", note); }
     };
@@ -57,6 +86,7 @@ struct CalfKeyboard
     int nkeys;
     EventSink *sink;
     int last_key;
+    bool interactive;
 };
 
 struct CalfKeyboardClass
diff --git a/src/ctl_curve.cpp b/src/ctl_curve.cpp
index 21a4afd..5c554b3 100644
--- a/src/ctl_curve.cpp
+++ b/src/ctl_curve.cpp
@@ -24,6 +24,8 @@
 #include <stdint.h>
 #include <math.h>
 
+static gpointer parent_class = NULL;
+
 GtkWidget *
 calf_curve_new()
 {
@@ -83,7 +85,8 @@ calf_curve_realize(GtkWidget *widget)
     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;
+        GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | 
+        GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
     attributes.x = widget->allocation.x;
     attributes.y = widget->allocation.y;
     attributes.width = widget->allocation.width;
@@ -119,27 +122,34 @@ calf_curve_size_allocate (GtkWidget *widget,
         gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height );
 }
 
-static gboolean
-calf_curve_button_press (GtkWidget *widget, GdkEventButton *event)
+static int 
+find_nearest(CalfCurve *self, int ex, int ey, int &insert_pt)
 {
-    g_assert(CALF_IS_CURVE(widget));
-    CalfCurve *self = CALF_CURVE(widget);
     float dist = 5;
-    int found_pt = -1, insert_pt = -1;
-    int i;
-    for (i = 0; i < (int)self->points->size(); i++)
+    int found_pt = -1;
+    for (int i = 0; i < (int)self->points->size(); i++)
     {
         float x = (*self->points)[i].first, y = (*self->points)[i].second;
         self->log2phys(x, y);
-        float thisdist = std::max(fabs(event->x - x), fabs(event->y - y));
+        float thisdist = std::max(fabs(ex - x), fabs(ey - y));
         if (thisdist < dist)
         {
             dist = thisdist;
             found_pt = i;
         }
-        if (event->x > x)
+        if (ex > x)
             insert_pt = i + 1;
     }
+    return found_pt;
+}
+
+static gboolean
+calf_curve_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+    g_assert(CALF_IS_CURVE(widget));
+    CalfCurve *self = CALF_CURVE(widget);
+    int found_pt, insert_pt = -1;
+    found_pt = find_nearest(self, event->x, event->y, insert_pt);
     if (found_pt == -1 && insert_pt != -1)
     {
         float x = event->x, y = event->y;
@@ -161,6 +171,7 @@ calf_curve_button_press (GtkWidget *widget, GdkEventButton *event)
     gtk_widget_queue_draw(widget);
     if (self->sink)
         self->sink->curve_changed(*self->points);
+    gdk_window_set_cursor(widget->window, self->hand_cursor);
     return TRUE;
 }
 
@@ -176,6 +187,7 @@ calf_curve_button_release (GtkWidget *widget, GdkEventButton *event)
     if (self->sink)
         self->sink->curve_changed(*self->points);
     gtk_widget_queue_draw(widget);
+    gdk_window_set_cursor(widget->window, self->pencil_cursor);
     return FALSE;
 }
 
@@ -183,6 +195,8 @@ static gboolean
 calf_curve_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
 {
     g_assert(CALF_IS_CURVE(widget));
+    if (event->is_hint)
+        gdk_event_request_motions(event);
     CalfCurve *self = CALF_CURVE(widget);
     if (self->cur_pt != -1)
     {
@@ -194,12 +208,34 @@ calf_curve_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
             self->sink->curve_changed(*self->points);
         gtk_widget_queue_draw(widget);        
     }
+    else
+    {
+        int insert_pt = -1;
+        if (find_nearest(self, event->x, event->y, insert_pt) == -1)
+            gdk_window_set_cursor(widget->window, self->pencil_cursor);
+        else
+            gdk_window_set_cursor(widget->window, self->hand_cursor);
+    }
     return FALSE;
 }
 
 static void
+calf_curve_finalize (GObject *obj)
+{
+    g_assert(CALF_IS_CURVE(obj));
+    CalfCurve *self = CALF_CURVE(obj);
+    
+    delete self->points;
+    self->points = NULL;
+    
+    G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+
+static void
 calf_curve_class_init (CalfCurveClass *klass)
 {
+    parent_class = g_type_class_peek_parent (klass);
+    
     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
     widget_class->realize = calf_curve_realize;
     widget_class->expose_event = calf_curve_expose;
@@ -210,17 +246,18 @@ calf_curve_class_init (CalfCurveClass *klass)
     widget_class->motion_notify_event = calf_curve_pointer_motion;
     // widget_class->key_press_event = calf_curve_key_press;
     // widget_class->scroll_event = calf_curve_scroll;
+    
+    G_OBJECT_CLASS(klass)->finalize = calf_curve_finalize;
 }
 
 static void
 calf_curve_init (CalfCurve *self)
 {
     GtkWidget *widget = GTK_WIDGET(self);
-    GTK_WIDGET_SET_FLAGS (GTK_WIDGET(self), GTK_CAN_FOCUS);
+    GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
     self->points = new CalfCurve::point_vector;
     // XXXKF: destructor
-    self->points->push_back(CalfCurve::point(0.f, 0.f));
-    self->points->push_back(CalfCurve::point(0.5f, 0.25f));
+    self->points->push_back(CalfCurve::point(0.f, 1.f));
     self->points->push_back(CalfCurve::point(1.f, 1.f));
     self->x0 = 0.f;
     self->x1 = 1.f;
@@ -228,6 +265,52 @@ calf_curve_init (CalfCurve *self)
     self->y1 = 0.f;
     self->cur_pt = -1;
     self->hide_current = false;
+    self->pencil_cursor = gdk_cursor_new(GDK_PENCIL);
+    self->hand_cursor = gdk_cursor_new(GDK_FLEUR);
+}
+
+void CalfCurve::log2phys(float &x, float &y) {
+    x = (x - x0) / (x1 - x0) * (parent.allocation.width - 2) + 1;
+    y = (y - y0) / (y1 - y0) * (parent.allocation.height - 2) + 1;
+}
+
+void CalfCurve::phys2log(float &x, float &y) {
+    x = x0 + (x - 1) * (x1 - x0) / (parent.allocation.width - 2);
+    y = y0 + (y - 1) * (y1 - y0) / (parent.allocation.height - 2);
+}
+
+void CalfCurve::clip(int pt, float &x, float &y, bool &hide)
+{
+    float ymin = std::min(y0, y1), ymax = std::max(y0, y1);
+    float yamp = ymax - ymin;
+    hide = false;
+    if (pt != 0 && pt != (int)(points->size() - 1))
+    {
+        if (y < ymin - yamp || y > ymax + yamp)
+            hide = true;
+    }
+    if (x < x0) x = x0;
+    if (y < ymin) y = ymin;
+    if (x > x1) x = x1;
+    if (y > ymax) y = ymax;
+    if (pt == 0) x = 0;
+    if (pt == (int)(points->size() - 1))
+        x = (*points)[pt].first;
+    if (pt > 0 && x < (*points)[pt - 1].first)
+        x = (*points)[pt - 1].first;
+    if (pt < (int)(points->size() - 1) && x > (*points)[pt + 1].first)
+        x = (*points)[pt + 1].first;
+}
+
+void calf_curve_set_points(GtkWidget *widget, const CalfCurve::point_vector &src)
+{
+    g_assert(CALF_IS_CURVE(widget));
+    CalfCurve *self = CALF_CURVE(widget);
+    if (self->points->size() != src.size())
+        self->cur_pt = -1;
+    *self->points = src;
+    
+    gtk_widget_queue_draw(widget);
 }
 
 GType
diff --git a/src/ctl_keyboard.cpp b/src/ctl_keyboard.cpp
index 3edd427..3eb8808 100644
--- a/src/ctl_keyboard.cpp
+++ b/src/ctl_keyboard.cpp
@@ -24,6 +24,10 @@
 #include <stdint.h>
 #include <malloc.h>
 
+static const int semitones_b[] = { 1, 3, -1, 6, 8, 10, -1 };
+static const int semitones_w[] = { 0, 2, 4, 5, 7, 9, 11 };
+
+
 GtkWidget *
 calf_keyboard_new()
 {
@@ -48,23 +52,40 @@ calf_keyboard_expose (GtkWidget *widget, GdkEventExpose *event)
     
     for (int i = 0; i < self->nkeys; i++)
     {
-        cairo_rectangle(c, 0.5 + 12 * i, 0.5, 12, sy);
+        CalfKeyboard::KeyInfo ki = { 0.5 + 12 * i, 0.5, 12, sy, 12 * (i / 7) + semitones_w[i % 7], false };
+        cairo_new_path(c);
         gdk_cairo_set_source_color(c, &scWhiteKey);
-        cairo_fill_preserve(c);
-        gdk_cairo_set_source_color(c, &scOutline);
-        cairo_stroke(c);
+        if (!self->sink->pre_draw(c, ki))
+        {
+            cairo_rectangle(c, ki.x, ki.y, ki.width, ki.height);
+            cairo_fill_preserve(c);
+            gdk_cairo_set_source_color(c, &scOutline);
+            if (!self->sink->pre_draw_outline(c, ki))
+                cairo_stroke(c);
+            else
+                cairo_new_path(c);
+            self->sink->post_draw(c, ki);
+        }
     }
 
     for (int i = 0; i < self->nkeys - 1; i++)
     {
         if ((1 << (i % 7)) & 59)
         {
-            cairo_rectangle(c, 8 + 12 * i, 0, 8, sy * 3 / 5);
+            CalfKeyboard::KeyInfo ki = { 8.5 + 12 * i, 0.5, 8, sy * 3 / 5, 12 * (i / 7) + semitones_b[i % 7], true };
+            cairo_new_path(c);
+            cairo_rectangle(c, ki.x, ki.y, ki.width, ki.height);
             gdk_cairo_set_source_color(c, &scBlackKey);
-            cairo_fill(c);
+            if (!self->sink->pre_draw(c, ki))
+            {
+                cairo_fill(c);
+                self->sink->post_draw(c, ki);
+            }
         }
     }
     
+    self->sink->post_all(c);
+    
     cairo_destroy(c);
 
     return TRUE;
@@ -128,7 +149,7 @@ calf_keyboard_key_press (GtkWidget *widget, GdkEventKey *event)
     return FALSE;
 }
 
-static int
+int
 calf_keyboard_pos_to_note (CalfKeyboard *kb, int x, int y, int *vel = NULL)
 {
     // first try black keys
@@ -137,15 +158,13 @@ calf_keyboard_pos_to_note (CalfKeyboard *kb, int x, int y, int *vel = NULL)
         int blackkey = (x - 8) / 12;
         if (blackkey < kb->nkeys && (59 & (1 << (blackkey % 7))))
         {
-            static const int semitones[] = { 1, 3, -1, 6, 8, 10, -1 };
-            return semitones[blackkey % 7] + 12 * (blackkey / 7);
+            return semitones_b[blackkey % 7] + 12 * (blackkey / 7);
         }
     }
     // if not a black key, then which white one?
-    static const int semitones[] = { 0, 2, 4, 5, 7, 9, 11 };
     int whitekey = x / 12;
     // semitones within octave + 12 semitones per octave
-    return semitones[whitekey % 7] + 12 * (whitekey / 7);
+    return semitones_w[whitekey % 7] + 12 * (whitekey / 7);
 }
 
 static gboolean
@@ -153,7 +172,7 @@ calf_keyboard_button_press (GtkWidget *widget, GdkEventButton *event)
 {
     g_assert(CALF_IS_KEYBOARD(widget));
     CalfKeyboard *self = CALF_KEYBOARD(widget);
-    if (!self->sink)
+    if (!self->interactive)
         return FALSE;
     gtk_widget_grab_focus(widget);
     int vel = 127;
@@ -168,7 +187,7 @@ calf_keyboard_button_release (GtkWidget *widget, GdkEventButton *event)
 {
     g_assert(CALF_IS_KEYBOARD(widget));
     CalfKeyboard *self = CALF_KEYBOARD(widget);
-    if (!self->sink)
+    if (!self->interactive)
         return FALSE;
     if (self->last_key != -1)
         self->sink->note_off(self->last_key);
@@ -180,7 +199,7 @@ calf_keyboard_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
 {
     g_assert(CALF_IS_KEYBOARD(widget));
     CalfKeyboard *self = CALF_KEYBOARD(widget);
-    if (!self->sink)
+    if (!self->interactive)
         return FALSE;
     int vel = 127;
     int key = calf_keyboard_pos_to_note(self, event->x, event->y, &vel);
@@ -213,11 +232,12 @@ calf_keyboard_class_init (CalfKeyboardClass *klass)
 static void
 calf_keyboard_init (CalfKeyboard *self)
 {
+    static CalfKeyboard::EventAdapter default_sink;
     GtkWidget *widget = GTK_WIDGET(self);
     g_assert(CALF_IS_KEYBOARD(widget));
     GTK_WIDGET_SET_FLAGS (GTK_WIDGET(self), GTK_CAN_FOCUS);
     self->nkeys = 7 * 3 + 1;
-    self->sink = NULL;
+    self->sink = &default_sink;
     self->last_key = -1;
 }
 

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list