Fix midi region split, trim and move operations.
[ardour.git] / libs / gtkmm2ext / pixscroller.cc
index 95861fd9300c89322d4626de18e4a7886435c574..55bbef8c80a357a3ed576b94a4d7499d306f8c5a 100644 (file)
@@ -1,6 +1,6 @@
 /*
     Copyright (C) 2005 Paul Davis
+
     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
 
 #include <gtkmm.h>
 
-#include <gtkmm2ext/pixscroller.h>
+#include "gtkmm2ext/pixscroller.h"
+#include "gtkmm2ext/keyboard.h"
 
 using namespace std;
 using namespace Gtk;
 using namespace Gtkmm2ext;
 
-PixScroller::PixScroller (Adjustment& a, Pix& p)
+PixScroller::PixScroller (Adjustment& a,
+                         Glib::RefPtr<Gdk::Pixbuf> s,
+                         Glib::RefPtr<Gdk::Pixbuf> r)
        : adj (a),
-         pix (p)
+         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);
 
        adj.signal_value_changed().connect (mem_fun (*this, &PixScroller::adjustment_changed));
        default_value = adj.get_value();
 
-}
-
-void
-PixScroller::on_realize ()
-{
-       DrawingArea::on_realize ();
-
-       Glib::RefPtr<Gdk::Drawable> drawable = Glib::RefPtr<Gdk::Window>::cast_dynamic (get_window());
-
-       pix.generate (drawable);
-
-       rail = *(pix.pixmap (0));
-       rail_mask = *(pix.shape_mask (0));
-       slider = *(pix.pixmap (1));
-       slider_mask = *(pix.shape_mask (1));
-
-       int w, h;
-
-       slider->get_size (w, h);
-       sliderrect.set_width(w);
-       sliderrect.set_height(h);
-       rail->get_size (w, h);
-       railrect.set_width(w);
-       railrect.set_height(h);
+       sliderrect.set_width(slider->get_width());
+       sliderrect.set_height(slider->get_height());
+       railrect.set_width(rail->get_width());
+       railrect.set_height(rail->get_height());
 
        railrect.set_y(sliderrect.get_height() / 2);
        sliderrect.set_x(0);
@@ -72,7 +58,25 @@ PixScroller::on_realize ()
        sliderrect.set_y((int) rint ((overall_height - sliderrect.get_height()) * (adj.get_upper() - adj.get_value())));
        railrect.set_x((sliderrect.get_width() / 2) - 2);
 
-       set_size_request (sliderrect.get_width(), overall_height);
+        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
@@ -87,43 +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_drawable (gc, rail, 
-                                intersect.x - railrect.get_x(),
-                                intersect.y - railrect.get_y(),
-                                intersect.x, 
-                                intersect.y, 
-                                intersect.width,
-                                intersect.height);
+
+                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_drawable (gc, slider, 
-                                intersect.x - sliderrect.get_x(),
-                                intersect.y - sliderrect.get_y(),
-                                intersect.x, 
-                                intersect.y, 
-                                intersect.width,
-                                intersect.height);
-               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;
 }
@@ -133,7 +125,7 @@ PixScroller::on_button_press_event (GdkEventButton* ev)
 {
        switch (ev->button) {
        case 1:
-               if (!(ev->state & Gdk::SHIFT_MASK)) {
+               if (!(ev->state & Keyboard::TertiaryModifier)) {
                        add_modal_grab();
                        grab_y = ev->y;
                        grab_start = ev->y;
@@ -143,8 +135,8 @@ PixScroller::on_button_press_event (GdkEventButton* ev)
                break;
        default:
                break;
-       } 
-                              
+       }
+
 
        return false;
 }
@@ -153,9 +145,9 @@ bool
 PixScroller::on_button_release_event (GdkEventButton* ev)
 {
        double scale;
-       
-       if (ev->state & GDK_CONTROL_MASK) {
-               if (ev->state & GDK_MOD1_MASK) {
+
+       if (ev->state & Keyboard::PrimaryModifier) {
+               if (ev->state & Keyboard::SecondaryModifier) {
                        scale = 0.05;
                } else {
                        scale = 0.1;
@@ -187,17 +179,40 @@ PixScroller::on_button_release_event (GdkEventButton* ev)
                                adj.set_value (scale * fract * (adj.get_upper() - adj.get_lower()));
                        }
                } else {
-                       if (ev->state & Gdk::SHIFT_MASK) {
+                       if (ev->state & Keyboard::TertiaryModifier) {
                                adj.set_value (default_value);
                                cerr << "default value = " << default_value << endl;
                        }
                }
                break;
-       case 4:
+       default:
+               break;
+       }
+       return false;
+}
+
+bool
+PixScroller::on_scroll_event (GdkEventScroll* ev)
+{
+       double scale;
+
+       if (ev->state & Keyboard::PrimaryModifier) {
+               if (ev->state & Keyboard::SecondaryModifier) {
+                       scale = 0.05;
+               } else {
+                       scale = 0.1;
+               }
+       } else {
+               scale = 0.5;
+       }
+
+       switch (ev->direction) {
+
+       case GDK_SCROLL_UP:
                /* wheel up */
                adj.set_value (adj.get_value() + (adj.get_page_increment() * scale));
                break;
-       case 5:
+       case GDK_SCROLL_DOWN:
                /* wheel down */
                adj.set_value (adj.get_value() - (adj.get_page_increment() * scale));
                break;
@@ -220,9 +235,9 @@ PixScroller::on_motion_notify_event (GdkEventMotion* ev)
                        grab_window = ev->window;
                        return true;
                }
-               
-               if (ev->state & GDK_CONTROL_MASK) {
-                       if (ev->state & GDK_MOD1_MASK) {
+
+               if (ev->state & Keyboard::PrimaryModifier) {
+                       if (ev->state & Keyboard::SecondaryModifier) {
                                scale = 0.05;
                        } else {
                                scale = 0.1;
@@ -238,7 +253,7 @@ PixScroller::on_motion_notify_event (GdkEventMotion* ev)
 
                fract = min (1.0, fract);
                fract = max (-1.0, fract);
-               
+
                fract = -fract;
 
                adj.set_value (adj.get_value() + scale * fract * (adj.get_upper() - adj.get_lower()));