From cc074c66fabd3fb28f8387b64f58e6d49206f122 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 8 Feb 2011 19:19:55 +0000 Subject: [PATCH] cairo-ify expose handlers for PixFader and PixScroller (latter is not used); tweak UI RC file in response; move rgb macros to gtkmm2ext for easier use there as we go cairo over time git-svn-id: svn://localhost/ardour2/branches/3.0@8775 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour3_ui_dark.rc.in | 10 +- gtk2_ardour/gain_meter.cc | 5 +- gtk2_ardour/rgb_macros.h | 28 +++ gtk2_ardour/utils.cc | 30 +-- libs/gtkmm2ext/gtkmm2ext/pixfader.h | 18 +- libs/gtkmm2ext/gtkmm2ext/pixscroller.h | 5 + libs/gtkmm2ext/gtkmm2ext/rgb_macros.h | 291 +++++++++++++++++++++++++ libs/gtkmm2ext/pixfader.cc | 123 ++++++++--- libs/gtkmm2ext/pixscroller.cc | 74 ++++--- 9 files changed, 494 insertions(+), 90 deletions(-) create mode 100644 gtk2_ardour/rgb_macros.h create mode 100644 libs/gtkmm2ext/gtkmm2ext/rgb_macros.h diff --git a/gtk2_ardour/ardour3_ui_dark.rc.in b/gtk2_ardour/ardour3_ui_dark.rc.in index 6763d78bad..3cba4e5fe8 100644 --- a/gtk2_ardour/ardour3_ui_dark.rc.in +++ b/gtk2_ardour/ardour3_ui_dark.rc.in @@ -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 diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index 82b106c9a1..77cdbfe82e 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -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 index 0000000000..ceda85738d --- /dev/null +++ b/gtk2_ardour/rgb_macros.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2000 EMC Capital Management, Inc. + + Developed by Jon Trowbridge and + Havoc Pennington . + + 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__ */ diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 621cdb0dd9..fe0235f6d5 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -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; diff --git a/libs/gtkmm2ext/gtkmm2ext/pixfader.h b/libs/gtkmm2ext/gtkmm2ext/pixfader.h index 36989a25a6..00a42769be 100644 --- a/libs/gtkmm2ext/gtkmm2ext/pixfader.h +++ b/libs/gtkmm2ext/gtkmm2ext/pixfader.h @@ -21,10 +21,11 @@ #define __gtkmm2ext_pixfader_h__ #include +#include #include #include -#include +#include 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 pixbuf; + private: + Cairo::RefPtr belt_context; + Cairo::RefPtr belt_surface; + Glib::RefPtr 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; diff --git a/libs/gtkmm2ext/gtkmm2ext/pixscroller.h b/libs/gtkmm2ext/gtkmm2ext/pixscroller.h index ea33359a25..c87d1f130c 100644 --- a/libs/gtkmm2ext/gtkmm2ext/pixscroller.h +++ b/libs/gtkmm2ext/gtkmm2ext/pixscroller.h @@ -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 rail; + Cairo::RefPtr< Cairo::Context > slider_context; + Cairo::RefPtr< Cairo::ImageSurface > slider_surface; Glib::RefPtr 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 index 0000000000..a3909d9a08 --- /dev/null +++ b/libs/gtkmm2ext/gtkmm2ext/rgb_macros.h @@ -0,0 +1,291 @@ +/* + Copyright (C) 2000 EMC Capital Management, Inc. + + Developed by Jon Trowbridge and + Havoc Pennington . + + 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_jbuf_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_jbuf_rowstride; \ + } \ +} + +#endif /* __gtkmm2ext_rgb_macros_h__ */ diff --git a/libs/gtkmm2ext/pixfader.cc b/libs/gtkmm2ext/pixfader.cc index 9a0d2f66d6..f24e5da389 100644 --- a/libs/gtkmm2ext/pixfader.cc +++ b/libs/gtkmm2ext/pixfader.cc @@ -22,22 +22,23 @@ #include #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 belt, Gtk::Adjustment& adj, int orientation, int fader_length) +PixFader::PixFader (Glib::RefPtr 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 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 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 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 diff --git a/libs/gtkmm2ext/pixscroller.cc b/libs/gtkmm2ext/pixscroller.cc index f20e11c9ca..22db1892d1 100644 --- a/libs/gtkmm2ext/pixscroller.cc +++ b/libs/gtkmm2ext/pixscroller.cc @@ -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,46 +91,32 @@ PixScroller::on_expose_event (GdkEventExpose* ev) { GdkRectangle intersect; Glib::RefPtr 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 context = get_window()->create_cairo_context(); + if (gdk_rectangle_intersect (railrect.gobj(), &ev->area, &intersect)) { - Glib::RefPtr 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 gc(get_style()->get_fg_gc(get_state())); - // Glib::RefPtr 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; }