cairo-ify expose handlers for PixFader and PixScroller (latter is not used); tweak...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 8 Feb 2011 19:19:55 +0000 (19:19 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 8 Feb 2011 19:19:55 +0000 (19:19 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8775 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/ardour3_ui_dark.rc.in
gtk2_ardour/gain_meter.cc
gtk2_ardour/rgb_macros.h [new file with mode: 0644]
gtk2_ardour/utils.cc
libs/gtkmm2ext/gtkmm2ext/pixfader.h
libs/gtkmm2ext/gtkmm2ext/pixscroller.h
libs/gtkmm2ext/gtkmm2ext/rgb_macros.h [new file with mode: 0644]
libs/gtkmm2ext/pixfader.cc
libs/gtkmm2ext/pixscroller.cc

index 6763d78bad9d6dae91ca8bee03f4f4abf7f3c7f6..3cba4e5fe8212065606aa0f86779c7bd1d141a90 100644 (file)
@@ -357,12 +357,10 @@ style "small_red_active_and_selected_button" = "small_button"
 
 style "gain_fader"
 {
-       bg[NORMAL] =   { 0.269, 0.269, 0.300}
-       bg[ACTIVE] =   { 0.152, 0.152, 0.168 }
+        bg[NORMAL] = shade (0.7, @A_lightest)
+       bg[ACTIVE] = shade (0.72, @A_lightest)
 }
 
-
-
 #MSR and related buttons
 
 style "track_rec_enable_button" = "small_button"
@@ -1286,9 +1284,9 @@ style "processor_fader"
 }
 
 # Fader processor's frame
-style "processor_fader_frame"
+style "processor_fader_frame" 
 {
-       bg[NORMAL] = @A_processor_fader_frame
+bg[NORMAL] = @A_processor_fader_frame
 }
 
 # Pre-fader processor's background
index 82b106c9a187e1533be3d0692f6ca2449397f082..77cdbfe82e2ffd69db18c04413f4e5a64096bf84 100644 (file)
@@ -449,7 +449,10 @@ GainMeterBase::set_meter_strip_name (const char * name)
 void
 GainMeterBase::set_fader_name (const char * name)
 {
-       gain_slider->set_name (name);
+        uint32_t rgb_active = rgba_from_style (name, 0xff, 0, 0xff, 0, "bg", STATE_ACTIVE, false);
+        uint32_t rgb_normal = rgba_from_style (name, 0xff, 0xff, 0, 0, "bg", STATE_NORMAL, false);
+
+       gain_slider->set_border_colors (rgb_normal, rgb_active);
 }
 
 void
diff --git a/gtk2_ardour/rgb_macros.h b/gtk2_ardour/rgb_macros.h
new file mode 100644 (file)
index 0000000..ceda857
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+    Copyright (C) 2000 EMC Capital Management, Inc.
+
+    Developed by Jon Trowbridge <trow@gnu.org> and
+    Havoc Pennington <hp@pobox.com>.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __gtk_ardour_rgb_macros_h__
+#define __gtk_ardour_rgb_macros_h__
+
+#include "gtkmm2ext/rgb_macros.h"
+
+#endif /* __gtk_ardour_rgb_macros_h__ */
index 621cdb0dd9a9e90827aa801178b2e252a6cd9abf..fe0235f6d5ac86d18a97bf2208e89fb716e7611a 100644 (file)
@@ -351,31 +351,31 @@ rgba_from_style (string style, uint32_t r, uint32_t g, uint32_t b, uint32_t a, s
        foo.set_name (style);
        foo.ensure_style ();
 
-       GtkRcStyle* waverc = foo.get_style()->gobj()->rc_style;
+       GtkRcStyle* rc = foo.get_style()->gobj()->rc_style;
 
-       if (waverc) {
+       if (rc) {
                if (attr == "fg") {
-                       r = waverc->fg[state].red / 257;
-                       g = waverc->fg[state].green / 257;
-                       b = waverc->fg[state].blue / 257;
+                       r = rc->fg[state].red / 257;
+                       g = rc->fg[state].green / 257;
+                       b = rc->fg[state].blue / 257;
 
                        /* what a hack ... "a" is for "active" */
                        if (state == Gtk::STATE_NORMAL && rgba) {
-                               a = waverc->fg[GTK_STATE_ACTIVE].red / 257;
+                               a = rc->fg[GTK_STATE_ACTIVE].red / 257;
                        }
                } else if (attr == "bg") {
                        r = g = b = 0;
-                       r = waverc->bg[state].red / 257;
-                       g = waverc->bg[state].green / 257;
-                       b = waverc->bg[state].blue / 257;
+                       r = rc->bg[state].red / 257;
+                       g = rc->bg[state].green / 257;
+                       b = rc->bg[state].blue / 257;
                } else if (attr == "base") {
-                       r = waverc->base[state].red / 257;
-                       g = waverc->base[state].green / 257;
-                       b = waverc->base[state].blue / 257;
+                       r = rc->base[state].red / 257;
+                       g = rc->base[state].green / 257;
+                       b = rc->base[state].blue / 257;
                } else if (attr == "text") {
-                       r = waverc->text[state].red / 257;
-                       g = waverc->text[state].green / 257;
-                       b = waverc->text[state].blue / 257;
+                       r = rc->text[state].red / 257;
+                       g = rc->text[state].green / 257;
+                       b = rc->text[state].blue / 257;
                }
        } else {
                warning << string_compose (_("missing RGBA style for \"%1\""), style) << endl;
index 36989a25a6924d20177f592cab7e5baa4714ee50..00a42769beeab7f1d65359f5dce9e94b55edd60b 100644 (file)
 #define __gtkmm2ext_pixfader_h__
 
 #include <cmath>
+#include <stdint.h>
 
 #include <gtkmm/drawingarea.h>
 #include <gtkmm/adjustment.h>
-#include <gdkmm/pixbuf.h>
+#include <gdkmm.h>
 
 namespace Gtkmm2ext {
 
@@ -35,7 +36,8 @@ class PixFader : public Gtk::DrawingArea
        virtual ~PixFader ();
 
        void set_fader_length (int);
-       
+        void set_border_colors (uint32_t rgba_left, uint32_t rgba_right);
+
   protected:
        Gtk::Adjustment& adjustment;
 
@@ -54,10 +56,18 @@ class PixFader : public Gtk::DrawingArea
                HORIZ=2,
        };
 
-  private:
-       Glib::RefPtr<Gdk::Pixbuf> pixbuf;
+  private:     
+        Cairo::RefPtr<Cairo::Context> belt_context;
+        Cairo::RefPtr<Cairo::ImageSurface> belt_surface;
+        Glib::RefPtr<Gdk::Pixbuf> pixbuf;
        int span, girth;
        int _orien;
+        float left_r;
+        float left_g;
+        float left_b;
+        float right_r;
+        float right_g;
+        float right_b;
 
        GdkRectangle view;
 
index ea33359a2527b7e6f5a41998e377290bf085e103..c87d1f130c46c92c4b7b8c5cb92e70b24fc143ed 100644 (file)
@@ -44,7 +44,12 @@ class PixScroller : public Gtk::DrawingArea
        Gtk::Adjustment& adj;
 
   private:
+
+        Cairo::RefPtr< Cairo::Context > rail_context;
+        Cairo::RefPtr< Cairo::ImageSurface > rail_surface;
        Glib::RefPtr<Gdk::Pixbuf> rail;
+        Cairo::RefPtr< Cairo::Context > slider_context;
+        Cairo::RefPtr< Cairo::ImageSurface > slider_surface;
        Glib::RefPtr<Gdk::Pixbuf> slider;
        Gdk::Rectangle sliderrect;
        Gdk::Rectangle railrect;
diff --git a/libs/gtkmm2ext/gtkmm2ext/rgb_macros.h b/libs/gtkmm2ext/gtkmm2ext/rgb_macros.h
new file mode 100644 (file)
index 0000000..a3909d9
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+    Copyright (C) 2000 EMC Capital Management, Inc.
+
+    Developed by Jon Trowbridge <trow@gnu.org> and
+    Havoc Pennington <hp@pobox.com>.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __gtkmm2ext_rgb_macros_h__
+#define __gtkmm2ext_rgb_macros_h__
+
+/*
+  Some convenient macros for drawing into an RGB buffer.
+  Beware of side effects, code-bloat, and all of the other classic
+  cpp-perils...
+*/
+
+#define RGB_TO_UINT(r,g,b) ((((guint)(r))<<16)|(((guint)(g))<<8)|((guint)(b)))
+#define RGB_TO_RGBA(x,a) (((x) << 8) | ((((guint)a) & 0xff)))
+#define RGBA_TO_UINT(r,g,b,a) RGB_TO_RGBA(RGB_TO_UINT(r,g,b), a)
+#define RGB_WHITE  RGB_TO_UINT(0xff, 0xff, 0xff)
+#define RGB_BLACK  RGB_TO_UINT(0x00, 0x00, 0x00)
+#define RGB_RED    RGB_TO_UINT(0xff, 0x00, 0x00)
+#define RGB_GREEN  RGB_TO_UINT(0x00, 0xff, 0x00)
+#define RGB_BLUE   RGB_TO_UINT(0x00, 0x00, 0xff)
+#define RGB_YELLOW RGB_TO_UINT(0xff, 0xff, 0x00)
+#define RGB_VIOLET RGB_TO_UINT(0xff, 0x00, 0xff)
+#define RGB_CYAN   RGB_TO_UINT(0x00, 0xff, 0xff)
+#define RGBA_WHITE  RGB_TO_RGBA(RGB_WHITE, 0xff)
+#define RGBA_BLACK  RGB_TO_RGBA(RGB_BLACK, 0xff)
+#define RGBA_RED    RGB_TO_RGBA(RGB_RED, 0xff)
+#define RGBA_GREEN  RGB_TO_RGBA(RGB_GREEN, 0xff)
+#define RGBA_BLUE   RGB_TO_RGBA(RGB_BLUE, 0xff)
+#define RGBA_YELLOW RGB_TO_RGBA(RGB_YELLOW, 0xff)
+#define RGBA_VIOLET RGB_TO_RGBA(RGB_VIOLET, 0xff)
+#define RGBA_CYAN   RGB_TO_RGBA(RGB_CYAN, 0xff)
+#define RGB_GREY(x) RGB_TO_UINT(x,x,x)
+#define RGBA_GREY(x) RGB_TO_RGBA(RGB_GREY(x), 0xff)
+#define UINT_RGBA_R(x) (((guint)(x))>>24)
+#define UINT_RGBA_G(x) ((((guint)(x))>>16)&0xff)
+#define UINT_RGBA_B(x) ((((guint)(x))>>8)&0xff)
+#define UINT_RGBA_A(x) (((guint)(x))&0xff)
+#define UINT_RGBA_R_FLT(x) ((((guint)(x))>>24)/255.0)
+#define UINT_RGBA_G_FLT(x) (((((guint)(x))>>16)&0xff)/255.0)
+#define UINT_RGBA_B_FLT(x) (((((guint)(x))>>8)&0xff)/255.0)
+#define UINT_RGBA_A_FLT(x) ((((guint)(x))&0xff)/255.0)
+#define UINT_RGBA_CHANGE_R(x, r) (((x)&(~(0xff<<24)))|(((r)&0xff)<<24))
+#define UINT_RGBA_CHANGE_G(x, g) (((x)&(~(0xff<<16)))|(((g)&0xff)<<16))
+#define UINT_RGBA_CHANGE_B(x, b) (((x)&(~(0xff<<8)))|(((b)&0xff)<<8))
+#define UINT_RGBA_CHANGE_A(x, a) (((x)&(~0xff))|((a)&0xff))
+#define UINT_TO_RGB(u,r,g,b) \
+{ (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
+#define UINT_TO_RGBA(u,r,g,b,a) \
+{ UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
+#define MONO_INTERPOLATE(v1, v2, t) ((gint)rint((v2)*(t)+(v1)*(1-(t))))
+#define UINT_INTERPOLATE(c1, c2, t) \
+  RGBA_TO_UINT( MONO_INTERPOLATE(UINT_RGBA_R(c1), UINT_RGBA_R(c2), t), \
+               MONO_INTERPOLATE(UINT_RGBA_G(c1), UINT_RGBA_G(c2), t), \
+               MONO_INTERPOLATE(UINT_RGBA_B(c1), UINT_RGBA_B(c2), t), \
+               MONO_INTERPOLATE(UINT_RGBA_A(c1), UINT_RGBA_A(c2), t) )
+#define PIXEL_RGB(p, r, g, b) \
+{((guchar*)(p))[0]=(r); ((guchar*)(p))[1]=(g); ((guchar*)(p))[2]=(b);}
+#define PIXEL_RGBA(p, r, g, b, a) \
+{ if ((a)>=0xff) { PIXEL_RGB(p,r,g,b) } \
+  else if ((a)>0) { \
+    guint pixel_tmp; \
+    pixel_tmp = ((guchar*)(p))[0]; \
+    ((guchar*)(p))[0] = pixel_tmp + ((((r)-pixel_tmp)*(a)+0x80) >> 8); \
+    pixel_tmp = ((guchar*)(p))[1]; \
+    ((guchar*)(p))[1] = pixel_tmp + ((((g)-pixel_tmp)*(a)+0x80) >> 8); \
+    pixel_tmp = ((guchar*)(p))[2]; \
+    ((guchar*)(p))[2] = pixel_tmp + ((((b)-pixel_tmp)*(a)+0x80) >> 8); }}
+#define PIXEL_RGB_UINT(p, i) \
+UINT_TO_RGB((i), ((guchar*)p), ((guchar*)p)+1, ((guchar*)p)+2)
+#define PIXEL_RGBA_UINT(p, i) \
+  PIXEL_RGBA((p), ((i)>>24)&0xff, ((i)>>16)&0xff, ((i)>>8)&0xff, (i)&0xff)
+#define PIXEL_BLACK(p) PIXEL_RGB(p,0,0,0)
+#define PIXEL_WHITE(p) PIXEL_RGB(p,0xff,0xff,0xff)
+#define PIXEL_GREY(p,g) PIXEL_RGB(p,g,g,g)
+#define PIXEL_GREYA(p,g,a) PIXEL_RGBA(p,g,g,g,a)
+#define BUF_PTR(inbuf, ptx, pty) \
+ ((inbuf)->buf + 3*((ptx)-(inbuf)->rect.x0) + (inbuf)->buf_rowstride*((pty)-(inbuf)->rect.y0))
+#define BUF_INBOUNDS_X(inbuf, ptx) \
+((inbuf)->rect.x0 <= (ptx) && (ptx) < (inbuf)->rect.x1)
+#define BUF_INBOUNDS_Y(inbuf, pty) \
+((inbuf)->rect.y0 <= (pty) && (pty) < (inbuf)->rect.y1)
+#define PAINT_DOT(inbuf, colr, colg, colb,ptx, pty) \
+{ \
+  guchar* pd_p; \
+  if (BUF_INBOUNDS_X(inbuf, ptx) && BUF_INBOUNDS_Y(inbuf, pty)) { \
+    pd_p = BUF_PTR(inbuf, ptx, pty); \
+    PIXEL_RGB(pd_p, (colr), (colg), (colb)); \
+  } \
+}
+#define FAST_PAINT_DOT(inbuf, colr, colg, colb,ptx, pty) \
+{ \
+  guchar* pd_p; \
+  pd_p = BUF_PTR(inbuf, ptx, pty); \
+  PIXEL_RGB(pd_p, (colr), (colg), (colb)); \
+}
+#define PAINT_DOTA(inbuf, colr, colg, colb, cola, ptx, pty) \
+{ \
+  guchar* pd_p; \
+  if (BUF_INBOUNDS_X(inbuf, ptx) && BUF_INBOUNDS_Y(inbuf, pty)) { \
+    pd_p = BUF_PTR(inbuf, ptx, pty); \
+    PIXEL_RGBA(pd_p, (colr), (colg), (colb), (cola)); \
+  } \
+}
+#define FAST_PAINT_DOTA(inbuf, colr, colg, colb, cola, ptx, pty) \
+{ \
+  guchar* pd_p; \
+  pd_p = BUF_PTR(inbuf, ptx, pty); \
+  PIXEL_RGBA(pd_p, (colr), (colg), (colb), (cola)); \
+}
+#define PAINT_HORIZ(inbuf, colr, colg, colb, ptx0, ptx1, pty) \
+{ \
+  GnomeCanvasBuf* ph_buf = (inbuf); \
+  guchar* ph_p; \
+  gint ph_a0, ph_a1; \
+  gint ph_colr=(colr), ph_colg=(colg), ph_colb=(colb); \
+\
+  ph_a0 = MAX(ph_buf->rect.x0, (gint)(ptx0)); \
+  ph_a1 = MIN(ph_buf->rect.x1, (gint)(ptx1)); \
+\
+  if (ph_a0 < ph_a1 && BUF_INBOUNDS_Y(ph_buf, (gint)(pty))) { \
+    ph_p = BUF_PTR(ph_buf, ph_a0, pty); \
+    while (ph_a0 < ph_a1) { \
+      PIXEL_RGB(ph_p, ph_colr, ph_colg, ph_colb); \
+      ++ph_a0; \
+      ph_p += 3; \
+    } \
+  } \
+}
+#define FAST_PAINT_HORIZ(inbuf, colr, colg, colb, ptx0, ptx1, pty) \
+{ \
+  GnomeCanvasBuf* ph_buf = (inbuf); \
+  guchar* ph_p; \
+  gint ph_a0, ph_a1; \
+  gint ph_colr=(colr), ph_colg=(colg), ph_colb=(colb); \
+\
+  ph_a0 = MAX(ph_buf->rect.x0, (gint)(ptx0)); \
+  ph_a1 = MIN(ph_buf->rect.x1, (gint)(ptx1)); \
+\
+  if (ph_a0 < ph_a1 && BUF_INBOUNDS_Y(ph_buf, (gint)(pty))) { \
+    ph_p = BUF_PTR(ph_buf, ph_a0, pty); \
+    while (ph_a0 < ph_a1) { \
+      PIXEL_RGB(ph_p, ph_colr, ph_colg, ph_colb); \
+      ++ph_a0; \
+      ph_p += 3; \
+    } \
+  } \
+}
+#define PAINT_HORIZA(inbuf, colr, colg, colb, cola, ptx0, ptx1, pty) \
+{ \
+  GnomeCanvasBuf* ph_buf = (inbuf); \
+  guchar* ph_p; \
+  gint ph_a0, ph_a1; \
+  gint ph_colr=(colr), ph_colg=(colg), ph_colb=(colb), ph_cola=(cola); \
+\
+  ph_a0 = MAX(ph_buf->rect.x0, (gint)(ptx0)); \
+  ph_a1 = MIN(ph_buf->rect.x1, (gint)(ptx1)); \
+\
+  if (ph_a0 < ph_a1 && BUF_INBOUNDS_Y(ph_buf, (gint)(pty))) { \
+    ph_p = BUF_PTR(ph_buf, ph_a0, pty); \
+    while (ph_a0 < ph_a1) { \
+      PIXEL_RGBA(ph_p, ph_colr, ph_colg, ph_colb, ph_cola); \
+      ++ph_a0; \
+      ph_p += 3; \
+    } \
+  } \
+}
+#define PAINT_VERT(inbuf, colr, colg, colb, ptx, pty0, pty1) \
+{ \
+  GnomeCanvasBuf* pv_buf = (inbuf); \
+  guchar* pv_p; \
+  gint pv_b0, pv_b1; \
+  gint pv_colr=(colr), pv_colg=(colg), pv_colb=(colb);\
+\
+  pv_b0 = MAX(pv_buf->rect.y0, (gint)(pty0)); \
+  pv_b1 = MIN(pv_buf->rect.y1, (gint)(pty1)); \
+\
+ if (pv_b0 < pv_b1 && BUF_INBOUNDS_X(pv_buf, (gint)(ptx))) { \
+    pv_p = BUF_PTR(pv_buf, ptx, pv_b0); \
+    while (pv_b0 < pv_b1) { \
+      PIXEL_RGB(pv_p, pv_colr, pv_colg, pv_colb); \
+      ++pv_b0; \
+      pv_p += pv_buf->buf_rowstride; \
+    } \
+  } \
+}
+#define FAST_PAINT_VERT(inbuf, colr, colg, colb, ptx, pty0, pty1) \
+{ \
+  GnomeCanvasBuf* fpv_buf = (inbuf); \
+  guchar* fpv_p; \
+  gint fpv_b0, fpv_b1; \
+\
+  fpv_b0 = MAX(fpv_buf->rect.y0, (gint)(pty0)); \
+  fpv_b1 = MIN(fpv_buf->rect.y1, (gint)(pty1)); \
+\
+  fpv_p = BUF_PTR(fpv_buf, ptx, fpv_b0); \
+\
+  while (fpv_b0 < fpv_b1) { \
+      PIXEL_RGB(fpv_p, colr, colg, colb); \
+      ++fpv_b0; \
+      fpv_p += fpv_buf->buf_rowstride; \
+  } \
+}
+#define PAINT_VERTA(inbuf, colr, colg, colb, cola, ptx, pty0, pty1) \
+{ \
+  GnomeCanvasBuf* pv_buf = (inbuf); \
+  guchar* pv_p; \
+  gint pv_b0, pv_b1; \
+  gint pv_colr=(colr), pv_colg=(colg), pv_colb=(colb), pv_cola=(cola);\
+\
+  pv_b0 = MAX(pv_buf->rect.y0, (pty0)); \
+  pv_b1 = MIN(pv_buf->rect.y1, (pty1)); \
+\
+ if (pv_b0 < pv_b1 && BUF_INBOUNDS_X(pv_buf, ptx)) { \
+    pv_p = BUF_PTR(pv_buf, ptx, pv_b0); \
+    while (pv_b0 < pv_b1) { \
+      PIXEL_RGBA(pv_p, pv_colr, pv_colg, pv_colb, pv_cola); \
+      ++pv_b0; \
+      pv_p += pv_buf->buf_rowstride; \
+    } \
+  } \
+}
+
+/* Paint a solid-colored box into a GnomeCanvasBuf (clipping as necessary).
+   The box contains (ptx0,pty0), but not (ptx1, pty1).
+   Each macro arg should appear exactly once in the body of the code. */
+#define PAINT_BOX(inbuf, colr, colg, colb, cola, ptx0, pty0, ptx1, pty1) \
+{ \
+  GnomeCanvasBuf* pb_buf = (inbuf); \
+  guchar* pb_p; \
+  guchar* pb_pp; \
+  gint pb_a0, pb_a1, pb_b0, pb_b1, pb_i, pb_j; \
+  gint pb_colr=(colr), pb_colg=(colg), pb_colb=(colb), pb_cola=(cola); \
+\
+  pb_a0 = MAX(pb_buf->rect.x0, (ptx0)); \
+  pb_a1 = MIN(pb_buf->rect.x1, (ptx1)); \
+  pb_b0 = MAX(pb_buf->rect.y0, (pty0)); \
+  pb_b1 = MIN(pb_buf->rect.y1, (pty1)); \
+\
+  if (pb_a0 < pb_a1 && pb_b0 < pb_b1) { \
+    pb_p = BUF_PTR(pb_buf, pb_a0, pb_b0); \
+    for (pb_j=pb_b0; pb_j<pb_b1; ++pb_j) { \
+      pb_pp = pb_p; \
+      for (pb_i=pb_a0; pb_i<pb_a1; ++pb_i) { \
+        PIXEL_RGBA(pb_pp, pb_colr, pb_colg, pb_colb, pb_cola); \
+        pb_pp += 3; \
+      } \
+      pb_p += pb_buf->buf_rowstride; \
+    } \
+  } \
+}
+
+/* No bounds checking in this version */
+
+#define FAST_PAINT_BOX(inbuf, colr, colg, colb, cola, ptx0, pty0, ptx1, pty1) \
+{ \
+  GnomeCanvasBuf* pb_buf = (inbuf); \
+  guchar* pb_p; \
+  guchar* pb_pp; \
+  gint pb_i, pb_j; \
+\
+  pb_p = BUF_PTR(pb_buf, ptx0, pty0); \
+  for (pb_j=pty0; pb_j<pty1; ++pb_j) { \
+      pb_pp = pb_p; \
+      for (pb_i=ptx0; pb_i<ptx1; ++pb_i) { \
+        PIXEL_RGBA(pb_pp, colr, colg, colb, cola); \
+        pb_pp += 3; \
+      } \
+      pb_p += pb_buf->buf_rowstride; \
+    } \
+}
+
+#endif /* __gtkmm2ext_rgb_macros_h__ */
index 9a0d2f66d681aa6e562c5e8d46a5a1bcfc688352..f24e5da389b18e2b68bdccd078a139723eceb763 100644 (file)
 #include <iostream>
 #include "gtkmm2ext/pixfader.h"
 #include "gtkmm2ext/keyboard.h"
+#include "gtkmm2ext/rgb_macros.h"
 
 using namespace Gtkmm2ext;
 using namespace Gtk;
-using namespace Gdk;
 using namespace std;
 
-
 int PixFader::fine_scale_modifier = Keyboard::PrimaryModifier;
 int PixFader::extra_fine_scale_modifier = Keyboard::SecondaryModifier;
 
-PixFader::PixFader (Glib::RefPtr<Pixbuf> belt, Gtk::Adjustment& adj, int orientation, int fader_length)
+PixFader::PixFader (Glib::RefPtr<Gdk::Pixbuf> belt, Gtk::Adjustment& adj, int orientation, int fader_length)
 
        : adjustment (adj),
          pixbuf (belt),
          _orien(orientation)
 {
+        Cairo::Format format;
+
        dragging = false;
        default_value = adjustment.get_value();
        last_drawn = -1;
@@ -57,20 +58,50 @@ PixFader::PixFader (Glib::RefPtr<Pixbuf> belt, Gtk::Adjustment& adj, int orienta
 
        adjustment.signal_value_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
        adjustment.signal_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
+
+        if (pixbuf->get_has_alpha()) {
+                format = Cairo::FORMAT_ARGB32;
+        } else {
+                format = Cairo::FORMAT_RGB24;
+        }
+        belt_surface = Cairo::ImageSurface::create  (format, pixbuf->get_width(), pixbuf->get_height());
+        belt_context = Cairo::Context::create (belt_surface);
+        Gdk::Cairo::set_source_pixbuf (belt_context, pixbuf, 0.0, 0.0);
+        belt_context->paint();        
+
+        left_r = 0;
+        left_g = 0;
+        left_b = 0;
+
+        right_r = 0;
+        right_g = 0;
+        right_b = 0;
 }
 
 PixFader::~PixFader ()
 {
 }
 
+void
+PixFader::set_border_colors (uint32_t left, uint32_t right)
+{
+        int r, g, b;
+        UINT_TO_RGB(left, &r, &g, &b);
+        left_r = r/255.0;
+        left_g = g/255.0;
+        left_b = b/255.0;
+        UINT_TO_RGB(right, &r, &g, &b);
+        right_r = r/255.0;
+        right_g = g/255.0;
+        right_b = b/255.0;
+}
+
 bool
 PixFader::on_expose_event (GdkEventExpose* ev)
 {
-       GdkRectangle intersection;
+        Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
        int srcx, srcy;
-
        int const ds = display_span ();
-
        int offset_into_pixbuf = (int) floor (span / ((float) span / ds));
 
        /* account for fader lengths that are shorter than the fader pixbuf */
@@ -79,36 +110,66 @@ PixFader::on_expose_event (GdkEventExpose* ev)
        } else {
                offset_into_pixbuf += pixbuf->get_width() / 2 - view.width;
        }
+
+        context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+        context->clip ();
        
-       Glib::RefPtr<Gdk::GC> fg_gc (get_style()->get_fg_gc(get_state()));
+        if (_orien == VERT) {
+                srcx = 0;
+                srcy = offset_into_pixbuf;
+        } else {
+                srcx = offset_into_pixbuf;
+                srcy = 0;
+        }
+
+        /* fader */
+
+        context->save();
+        context->set_source (belt_surface, -srcx, -srcy);
+        context->rectangle (0, 0, get_width(), get_height());
+        context->clip();
+        context->paint();
+        context->restore();
+
+        /* bounding box lines (2 colors for nicer visuals) */
+        
+        /* top and left side */
+
+        context->set_line_width (1);
+        context->set_source_rgb (left_r, left_g, left_b);
+        context->move_to (view.width - 1, 0); /* upper right */
+        context->line_to (0, 0);              /* upper left */
+        context->line_to (0, view.height - 1);/* lower left */
+        context->stroke ();
+
+        /* bottom & right side */
+
+        context->set_line_width (1);
+        context->set_source_rgb (right_r, right_g, right_b);
+        context->move_to (0, view.height - 1 + 0.5); /* lower left */
+        context->line_to (view.width - 1, view.height - 1 + 0.5); /* lower right */
+        context->line_to (view.width - 1 + 0.5, 0); /* upper right */
+        context->stroke ();
+
+       /* always draw the unity-position line */
 
-       if (gdk_rectangle_intersect (&view, &ev->area, &intersection)) {
-               if (_orien == VERT) {
-                       srcx = intersection.x;
-                       srcy = offset_into_pixbuf + intersection.y;
-               } else {
-                       srcx = offset_into_pixbuf + intersection.x;
-                       srcy = intersection.y;
-               }
-               get_window()->draw_pixbuf (fg_gc, pixbuf, 
-                                          srcx, srcy,
-                                          intersection.x, intersection.y,
-                                          intersection.width, intersection.height,
-                                          Gdk::RGB_DITHER_NONE, 0, 0);
-               
-               get_window()->draw_line (get_style()->get_bg_gc(STATE_ACTIVE), 0, 0, view.width - 1, 0); /* top */
-               get_window()->draw_line (get_style()->get_bg_gc(STATE_ACTIVE), 0, 0, 0, view.height - 1); /* left */
-               get_window()->draw_line (get_style()->get_bg_gc(STATE_NORMAL), view.width - 1, 0, view.width - 1, view.height - 1); /* right */
-               get_window()->draw_line (get_style()->get_bg_gc(STATE_NORMAL), 0, view.height - 1, view.width - 1, view.height - 1); /* bottom */
-       }
 
-       /* always draw the line */
        if (_orien == VERT) {
-               get_window()->draw_line (fg_gc, 1, unity_loc, girth - 2, unity_loc);
+                context->set_line_width (1); 
+                context->set_source_rgb (0.0, 1.0, 0.0);
+                context->move_to (1, unity_loc);
+                context->line_to (girth - 2, unity_loc);
+                context->stroke ();
        } else {
-               get_window()->draw_line (fg_gc, unity_loc, 1, unity_loc, girth - 2);
+                context->set_line_width (1); 
+                context->set_source_rgb (0.0, 1.0, 0.0);
+                context->move_to (unity_loc, 1.5);
+                context->line_to (unity_loc, girth - 1.5);
+                context->stroke ();
        }
+
        last_drawn = ds;
+
        return true;
 }
 
@@ -299,8 +360,8 @@ PixFader::adjustment_changed ()
 int
 PixFader::display_span ()
 {
-       float fract = (adjustment.get_upper() - adjustment.get_value ()) / ((adjustment.get_upper() - adjustment.get_lower()));
-       return (_orien == VERT) ? (int)floor (span * (1.0 - fract)) : (int)floor (span * fract);
+       float fract = (adjustment.get_value () - adjustment.get_lower()) / ((adjustment.get_upper() - adjustment.get_lower()));
+       return (_orien != VERT) ? (int)floor (span * (1.0 - fract)) : (int)floor (span * fract);
 }
 
 void
index f20e11c9ca7d55e34904e04f3d98c6a4b03c9101..22db1892d1fb8c9c45b9fa6257c9293741f8fb7b 100644 (file)
@@ -37,6 +37,8 @@ PixScroller::PixScroller (Adjustment& a,
          rail (r),
          slider (s)
 {
+        Cairo::Format format;
+
        dragging = false;
        add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
 
@@ -55,6 +57,26 @@ PixScroller::PixScroller (Adjustment& a,
 
        sliderrect.set_y((int) rint ((overall_height - sliderrect.get_height()) * (adj.get_upper() - adj.get_value())));
        railrect.set_x((sliderrect.get_width() / 2) - 2);
+
+        if (rail->get_has_alpha()) {
+                format = Cairo::FORMAT_ARGB32;
+        } else {
+                format = Cairo::FORMAT_RGB24;
+        }
+        rail_surface = Cairo::ImageSurface::create  (format, rail->get_width(), rail->get_height());
+        rail_context = Cairo::Context::create (rail_surface);
+        Gdk::Cairo::set_source_pixbuf (rail_context, rail, 0.0, 0.0);
+        rail_context->paint();        
+
+        if (slider->get_has_alpha()) {
+                format = Cairo::FORMAT_ARGB32;
+        } else {
+                format = Cairo::FORMAT_RGB24;
+        }
+        slider_surface = Cairo::ImageSurface::create  (format, slider->get_width(), slider->get_height());
+        slider_context = Cairo::Context::create (slider_surface);
+        Gdk::Cairo::set_source_pixbuf (slider_context, slider, 0.0, 0.0);
+        slider_context->paint();        
 }
 
 void
@@ -69,45 +91,31 @@ PixScroller::on_expose_event (GdkEventExpose* ev)
 {
        GdkRectangle intersect;
        Glib::RefPtr<Gdk::Window> win (get_window());
-
-       win->draw_rectangle (get_style()->get_bg_gc(get_state()), TRUE, 
-                           ev->area.x,
-                           ev->area.y,
-                           ev->area.width,
-                           ev->area.height);
-
+        Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
+        
        if (gdk_rectangle_intersect (railrect.gobj(), &ev->area, &intersect)) {
-               Glib::RefPtr<Gdk::GC> gc(get_style()->get_bg_gc(get_state()));
-               win->draw_pixbuf (gc, rail, 
-                                 intersect.x - railrect.get_x(),
-                                 intersect.y - railrect.get_y(),
-                                 intersect.x, 
-                                 intersect.y, 
-                                 intersect.width,
-                                 intersect.height,
-                                 Gdk::RGB_DITHER_NONE, 0, 0);
+
+                context->save();
+                context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
+                context->clip();
+                context->set_source (rail_surface, intersect.x - railrect.get_x(), intersect.y - railrect.get_y());
+                context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
+                context->clip();
+                context->paint();
+                context->restore();
        }
        
        if (gdk_rectangle_intersect (sliderrect.gobj(), &ev->area, &intersect)) {
-               Glib::RefPtr<Gdk::GC> gc(get_style()->get_fg_gc(get_state()));
-               // Glib::RefPtr<Gdk::Bitmap> mask (slider_mask);
-
-               GdkGCValues values;
-               gdk_gc_get_values(gc->gobj(), &values);
-               gc->set_clip_origin (sliderrect.get_x(), sliderrect.get_y());
-               // gc->set_clip_mask (mask);
-               win->draw_pixbuf (gc, slider, 
-                                 intersect.x - sliderrect.get_x(),
-                                 intersect.y - sliderrect.get_y(),
-                                 intersect.x, 
-                                 intersect.y, 
-                                 intersect.width,
-                                 intersect.height,
-                                 Gdk::RGB_DITHER_NONE, 0, 0);
-               gc->set_clip_origin (values.clip_x_origin, values.clip_y_origin);
-               // gdk_gc_set_clip_mask (gc->gobj(), values.clip_mask);
-       }
 
+                context->save();
+                context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
+                context->clip();
+                context->set_source (rail_surface, intersect.x - sliderrect.get_x(), intersect.y - sliderrect.get_y());
+                context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
+                context->clip();
+                context->paint();
+                context->restore();
+       }
 
        return true;
 }