X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fgtkmm2ext%2Fscroomer.cc;h=69944b4bc7ad17f4cfe4bd5ad5a405432afd6400;hb=e7a154b9dd8ed43a77424f8624ce61db0fa390d9;hp=6572c8b51c39609fbdde045c5f617f1eea8a3a3a;hpb=449aab3c465bbbf66d221fac3d7ea559f1720357;p=ardour.git diff --git a/libs/gtkmm2ext/scroomer.cc b/libs/gtkmm2ext/scroomer.cc index 6572c8b51c..69944b4bc7 100644 --- a/libs/gtkmm2ext/scroomer.cc +++ b/libs/gtkmm2ext/scroomer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2008 Paul Davis + Copyright (C) 2008 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 @@ -18,7 +18,9 @@ */ #include -#include + +#include "gtkmm2ext/scroomer.h" +#include "gtkmm2ext/keyboard.h" using namespace Gtkmm2ext; using namespace Gtk; @@ -28,8 +30,8 @@ using namespace std; Scroomer::Scroomer(Gtk::Adjustment& adjustment) : adj(adjustment) , handle_size(0) - , grab_comp(None) { - + , grab_comp(None) +{ position[TopBase] = 0; position[Handle1] = 0; position[Slider] = 0; @@ -46,11 +48,13 @@ Scroomer::Scroomer(Gtk::Adjustment& adjustment) //adjustment.signal_changed().connect (mem_fun (*this, &Scroomer::adjustment_changed)); } -Scroomer::~Scroomer() { +Scroomer::~Scroomer() +{ } bool -Scroomer::on_motion_notify_event (GdkEventMotion* ev) { +Scroomer::on_motion_notify_event (GdkEventMotion* ev) +{ double range = adj.get_upper() - adj.get_lower(); double pixel2val = range / get_height(); double val_at_pointer = ((get_height() - ev->y) * pixel2val) + adj.get_lower(); @@ -60,7 +64,7 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { double scale, temp, zoom; double val, page; - if(grab_comp == None || grab_comp == Total) { + if (grab_comp == None || grab_comp == Total) { return true; } @@ -70,10 +74,14 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { return true; } + if (ev->y < 0 || ev->y > get_height ()) { + return true; + } + grab_y = ev->y; - 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; @@ -86,7 +94,7 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { fract = max (-1.0, fract); fract = -fract; - switch(grab_comp) { + switch (grab_comp) { case TopBase: case BottomBase: unzoomed_val += scale * fract * range; @@ -99,9 +107,18 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { unzoomed_val = max(unzoomed_val, adj.get_lower()); break; case Handle1: + unzoomed_page += scale * fract * range; unzoomed_page = min(unzoomed_page, adj.get_upper() - unzoomed_val); unzoomed_page = max(unzoomed_page, min_page_size); + + if (pinch){ + temp = unzoomed_val + unzoomed_page; + unzoomed_val -= scale * fract * range * 0.5; + unzoomed_val = min(unzoomed_val, temp - min_page_size); + unzoomed_val = max(unzoomed_val, adj.get_lower()); + } + break; case Handle2: temp = unzoomed_val + unzoomed_page; @@ -110,21 +127,28 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { unzoomed_val = max(unzoomed_val, adj.get_lower()); unzoomed_page = temp - unzoomed_val; + + if (pinch){ + + unzoomed_page -= scale * fract * range; + } + + unzoomed_page = min(unzoomed_page, adj.get_upper() - unzoomed_val); unzoomed_page = max(unzoomed_page, min_page_size); break; default: break; } - /* - * Then we handle zoom, which is dragging horizontally. We zoom around the area that is + /* Then we handle zoom, which is dragging horizontally. We zoom around the area that is * the current y pointer value, not from the area that was the start of the drag. - * the point of zoom must have the same + * We don't start doing zoom until we are at least one scroomer width outside the scroomer's + * area. */ - - if(ev->x > get_width()) { + + if (ev->x > (get_width() * 2)) { zoom = ev->x - get_width(); - + double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; double lower = val_at_pointer - (unzoomed_val + half_min_page); @@ -136,21 +160,19 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { page = max(page, min_page_size); - if(lower < 0) { + if (lower < 0) { val = max(val, val_at_pointer - half_min_page); - } - else if(lower > 0) { + } else if (lower > 0) { val = min(val, val_at_pointer - half_min_page); } val = min(val, adj.get_upper() - min_page_size); page = min(page, adj.get_upper() - val); - } - else if (ev->x < 0) { + } else if (ev->x < 0) { /* on zoom out increase the page size as well as moving the range towards the mouse pos*/ - zoom = abs(ev->x); + /*zoom = abs(ev->x); - /*double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; + double higher = unzoomed_val + unzoomed_page - half_min_page - val_at_pointer; double lower = val_at_pointer - (unzoomed_val + half_min_page); higher *= zoom / 128; @@ -161,10 +183,10 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { page = max(page, min_page_size); - if(lower < 0) { + if (lower < 0) { val = max(val, val_at_pointer - half_min_page); } - else if(lower > 0) { + else if (lower > 0) { val = min(val, val_at_pointer - half_min_page); } @@ -173,36 +195,43 @@ Scroomer::on_motion_notify_event (GdkEventMotion* ev) { val = unzoomed_val; page = unzoomed_page; - } - else { + } else { val = unzoomed_val; page = unzoomed_page; } - adj.set_page_size(page); - - if(val == adj.get_value()) { - adj.value_changed(); - } - if(val < adj.get_lower()) { - adj.value_changed(); - } - else if(val > adj.get_upper()) { - adj.value_changed(); - } - else { - adj.set_value(val); + /* Round these values to stop the scroomer handlers quivering about during drags */ + adj.set_page_size (rint (page)); + adj.set_value (rint (val)); + adj.value_changed(); + + return true; +} + +bool +Scroomer::on_scroll_event (GdkEventScroll* ev) +{ + switch (ev->direction) { + case GDK_SCROLL_UP: + adj.set_value (min (adj.get_value() + adj.get_page_size() / 10.0, adj.get_upper() - adj.get_page_size())); + break; + case GDK_SCROLL_DOWN: + adj.set_value (adj.get_value() - adj.get_page_size() / 10.0); + break; + default: + return false; } return true; } bool -Scroomer::on_button_press_event (GdkEventButton* ev) { - if(ev->button == 1) { +Scroomer::on_button_press_event (GdkEventButton* ev) +{ + if (ev->button == 1 || ev->button == 3) { Component comp = point_in(ev->y); - if(comp == Total || comp == None) { + if (comp == Total || comp == None) { return false; } @@ -212,13 +241,27 @@ Scroomer::on_button_press_event (GdkEventButton* ev) { unzoomed_val = adj.get_value(); unzoomed_page = adj.get_page_size(); grab_window = ev->window; + + if (ev->button == 3){ + pinch = true; + } else { + pinch = false; + } + + DragStarting (); /* EMIT SIGNAL */ + } + + if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) { + DoubleClicked(); } - return false; + + return true; } bool -Scroomer::on_button_release_event (GdkEventButton* ev) { - if(grab_comp == None || grab_comp == Total) { +Scroomer::on_button_release_event (GdkEventButton* ev) +{ + if (grab_comp == None || grab_comp == Total) { return true; } @@ -228,11 +271,11 @@ Scroomer::on_button_release_event (GdkEventButton* ev) { return true; } - if (ev->button != 1) { + if (ev->button != 1 && ev->button != 3) { return true; } - switch(grab_comp) { + switch (grab_comp) { case TopBase: break; case Handle1: @@ -246,20 +289,17 @@ Scroomer::on_button_release_event (GdkEventButton* ev) { default: break; } - + grab_comp = None; remove_modal_grab(); - return true; -} - -bool -Scroomer::on_scroll_event (GdkEventScroll*) { + DragFinishing (); /* EMIT SIGNAL */ return true; } void -Scroomer::on_size_allocate (Allocation& a) { +Scroomer::on_size_allocate (Allocation& a) +{ Gtk::DrawingArea::on_size_allocate(a); position[Total] = a.get_height(); @@ -267,14 +307,14 @@ Scroomer::on_size_allocate (Allocation& a) { update(); } -/* - * assumes that x and width are correct, and they will not be altered +/** Assumes that x and width are correct, and they will not be altered. */ void -Scroomer::set_comp_rect(GdkRectangle& r, Component c) const { +Scroomer::set_comp_rect(GdkRectangle& r, Component c) const +{ int index = (int) c; - switch(c) { + switch (c) { case None: return; case Total: @@ -289,9 +329,10 @@ Scroomer::set_comp_rect(GdkRectangle& r, Component c) const { } Scroomer::Component -Scroomer::point_in(double point) const { - for(int i = 0; i < Total; ++i) { - if(position[i+1] >= point) { +Scroomer::point_in(double point) const +{ + for (int i = 0; i < Total; ++i) { + if (position[i+1] >= point) { return (Component) i; } } @@ -300,7 +341,8 @@ Scroomer::point_in(double point) const { } void -Scroomer::set_min_page_size(double ps) { +Scroomer::set_min_page_size(double ps) +{ double coeff = ((double)position[Total]) / (adj.get_upper() - adj.get_lower()); min_page_size = ps; @@ -308,14 +350,15 @@ Scroomer::set_min_page_size(double ps) { } void -Scroomer::update() { +Scroomer::update() +{ double range = adj.get_upper() - adj.get_lower(); //double value = adj.get_value() - adj.get_lower(); int height = position[Total]; double coeff = ((double) height) / range; /* save the old positions to calculate update regions later*/ - for(int i = Handle1; i < Total; ++i) { + for (int i = Handle1; i < Total; ++i) { old_pos[i] = position[i]; } @@ -327,63 +370,39 @@ Scroomer::update() { } void -Scroomer::adjustment_changed() { +Scroomer::adjustment_changed() +{ //cerr << floor(adj.get_value()) << " " << floor(adj.get_value() + adj.get_page_size()) << endl; Gdk::Rectangle rect; Glib::RefPtr win = get_window(); update(); - if(!win) { + if (!win) { return; } rect.set_x(0); rect.set_width(get_width()); - if(position[Handle1] < old_pos[Handle1]) { + if (position[Handle1] < old_pos[Handle1]) { rect.set_y(position[Handle1]); rect.set_height(old_pos[Slider] - position[Handle1]); win->invalidate_rect(rect, false); - } - else if(position[Handle1] > old_pos[Handle1]) { + } else if (position[Handle1] > old_pos[Handle1]) { rect.set_y(old_pos[Handle1]); rect.set_height(position[Slider] - old_pos[Handle1]); win->invalidate_rect(rect, false); } - if(position[Handle2] < old_pos[Handle2]) { + if (position[Handle2] < old_pos[Handle2]) { rect.set_y(position[Handle2]); rect.set_height(old_pos[BottomBase] - position[Handle2]); win->invalidate_rect(rect, false); - } - else if(position[Handle2] > old_pos[Handle2]) { + } else if (position[Handle2] > old_pos[Handle2]) { rect.set_y(old_pos[Handle2]); rect.set_height(position[BottomBase] - old_pos[Handle2]); win->invalidate_rect(rect, false); } - - win->process_updates(false); } -std::string -Scroomer::get_comp_name(Component c) { - switch(c) { - case TopBase: - return "TopBase"; - case Handle1: - return "Handle1"; - case Slider: - return "Slider"; - case Handle2: - return "Handle2"; - case BottomBase: - return "BottomBase"; - case Total: - return "Total"; - case None: - return "None"; - default: - return "ERROR"; - } -}