X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fgtkmm2ext%2Fbarcontroller.cc;h=693151aaed120042eff57b1c1bbd6307b6f30170;hb=e97b7bb924bd4ae6a7ca2f3c1e19dafd5294718f;hp=f59d192ff1402a78575d74a060f8a64128277699;hpb=532f6aad4ac79ca15d69deccd18fca90e444c437;p=ardour.git diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc index f59d192ff1..693151aaed 100644 --- a/libs/gtkmm2ext/barcontroller.cc +++ b/libs/gtkmm2ext/barcontroller.cc @@ -18,16 +18,19 @@ */ #include +#include #include #include #include #include #include +#include -#include -#include -#include +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/keyboard.h" +#include "gtkmm2ext/barcontroller.h" #include "i18n.h" @@ -36,12 +39,10 @@ using namespace Gtk; using namespace Gtkmm2ext; BarController::BarController (Gtk::Adjustment& adj, - PBD::Controllable& mc, - sigc::slot lc) + boost::shared_ptr mc) : adjustment (adj), binding_proxy (mc), - label_callback (lc), spinner (adjustment) { @@ -49,8 +50,8 @@ BarController::BarController (Gtk::Adjustment& adj, grabbed = false; switching = false; switch_on_release = false; - with_text = true; use_parent = false; + logarithmic = false; layout = darea.create_pango_layout(""); @@ -76,12 +77,22 @@ BarController::BarController (Gtk::Adjustment& adj, spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated)); spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out)); - spinner.set_digits (3); - + spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input)); + spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output)); + spinner.set_digits (9); + spinner.set_numeric (true); + add (darea); + show_all (); } +BarController::~BarController () +{ +// delete pattern; +// delete shine_pattern; +} + void BarController::drop_grab () { @@ -144,14 +155,14 @@ BarController::button_release (GdkEventButton* ev) return true; } - if ((ev->state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == GDK_SHIFT_MASK) { + if ((ev->state & (Keyboard::TertiaryModifier|Keyboard::PrimaryModifier)) == Keyboard::TertiaryModifier) { adjustment.set_value (initial_value); } else { double scale; - if (ev->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { + if ((ev->state & (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) == (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) { scale = 0.01; - } else if (ev->state & GDK_CONTROL_MASK) { + } else if (ev->state & Keyboard::PrimaryModifier) { scale = 0.1; } else { scale = 1.0; @@ -179,9 +190,9 @@ BarController::scroll (GdkEventScroll* ev) { double scale; - if (ev->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { + if ((ev->state & (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) == (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) { scale = 0.01; - } else if (ev->state & GDK_CONTROL_MASK) { + } else if (ev->state & Keyboard::PrimaryModifier) { scale = 0.1; } else { scale = 1.0; @@ -211,13 +222,13 @@ BarController::motion (GdkEventMotion* ev) return true; } - if ((ev->state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == GDK_SHIFT_MASK) { + if ((ev->state & (Keyboard::TertiaryModifier|Keyboard::PrimaryModifier)) == Keyboard::TertiaryModifier) { return TRUE; } - if (ev->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { + if ((ev->state & (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) == (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) { scale = 0.01; - } else if (ev->state & GDK_CONTROL_MASK) { + } else if (ev->state & Keyboard::PrimaryModifier) { scale = 0.1; } else { scale = 1.0; @@ -240,16 +251,17 @@ BarController::mouse_control (double x, GdkWindow* window, double scaling) delta = x - grab_x; grab_x = x; - + switch (_style) { case Line: + case Blob: case LeftToRight: + case CenterOut: fract = scaling * (delta / (darea.get_width() - 2)); fract = min (1.0, fract); fract = max (-1.0, fract); adjustment.set_value (adjustment.get_value() + fract * (adjustment.get_upper() - adjustment.get_lower())); break; - default: fract = 0.0; } @@ -258,79 +270,194 @@ BarController::mouse_control (double x, GdkWindow* window, double scaling) return TRUE; } +void +BarController::create_patterns () +{ + Glib::RefPtr win (darea.get_window()); + Cairo::RefPtr context = win->create_cairo_context(); + + Gdk::Color c = get_style()->get_fg (get_state()); + float r, g, b; + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + + float rheight = darea.get_height()-2; + + cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, rheight); + cairo_pattern_add_color_stop_rgba (pat, 0, r*0.8,g*0.8,b*0.8, 1.0); + cairo_pattern_add_color_stop_rgba (pat, 1, r*0.6,g*0.6,b*0.6, 1.0); + Cairo::RefPtr p (new Cairo::Pattern (pat, false)); + pattern = p; + cairo_pattern_destroy(pat); + + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, rheight); + cairo_pattern_add_color_stop_rgba (pat, 0, 1,1,1,0.0); + cairo_pattern_add_color_stop_rgba (pat, 0.2, 1,1,1,0.3); + cairo_pattern_add_color_stop_rgba (pat, 0.5, 1,1,1,0.0); + cairo_pattern_add_color_stop_rgba (pat, 1, 1,1,1,0.0); + Cairo::RefPtr p2 (new Cairo::Pattern (pat, false)); + shine_pattern = p2; + cairo_pattern_destroy(pat); + +} + bool -BarController::expose (GdkEventExpose* event) +BarController::expose (GdkEventExpose* /*event*/) { Glib::RefPtr win (darea.get_window()); + Cairo::RefPtr context = win->create_cairo_context(); + + if( !pattern ) + create_patterns(); + + Gdk::Color c; Widget* parent; - gint x1=0, x2=0, y1=0, y2=0; + gint x1=0, x2=0, y2=0; gint w, h; - double fract; - - w = darea.get_width() - 2; - h = darea.get_height() - 2; + double fract, radius; + float r, g, b; fract = ((adjustment.get_value() - adjustment.get_lower()) / (adjustment.get_upper() - adjustment.get_lower())); switch (_style) { case Line: + w = darea.get_width() - 1; h = darea.get_height(); x1 = (gint) floor (w * fract); x2 = x1; - y1 = 0; y2 = h - 1; + if (use_parent) { + parent = get_parent(); + + if (parent) { + c = parent->get_style()->get_fg (parent->get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->rectangle (0, 0, darea.get_width(), darea.get_height()); + context->fill (); + } + + } else { + + c = get_style()->get_bg (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->rectangle (0, 0, darea.get_width() - ((darea.get_width()+1) % 2), darea.get_height()); + context->fill (); + } + + c = get_style()->get_fg (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->move_to (x1, 0); + context->line_to (x1, h); + context->stroke (); + break; + + case Blob: + w = darea.get_width() - 1; + h = darea.get_height(); + x1 = (gint) floor (w * fract); + x2 = min (w-2,h-2); + if (use_parent) { parent = get_parent(); if (parent) { - win->draw_rectangle (parent->get_style()->get_fg_gc (parent->get_state()), - true, - 0, 0, darea.get_width(), darea.get_height()); + c = parent->get_style()->get_fg (parent->get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->rectangle (0, 0, darea.get_width(), darea.get_height()); + context->fill (); } } else { - win->draw_rectangle (get_style()->get_bg_gc (get_state()), - true, - 0, 0, darea.get_width() - ((darea.get_width()+1) % 2), darea.get_height()); + c = get_style()->get_bg (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->rectangle (0, 0, darea.get_width() - ((darea.get_width()+1) % 2), darea.get_height()); + context->fill (); } - win->draw_line (get_style()->get_fg_gc (get_state()), x1, 0, x1, h); + c = get_style()->get_fg (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->arc (x1, ((h-2)/2)-1, x2, 0, 2*M_PI); break; case CenterOut: + w = darea.get_width(); + h = darea.get_height()-2; + if (use_parent) { + parent = get_parent(); + if (parent) { + c = parent->get_style()->get_fg (parent->get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->rectangle (0, 0, darea.get_width(), darea.get_height()); + context->fill (); + } + } else { + c = get_style()->get_bg (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->rectangle (0, 0, darea.get_width(), darea.get_height()); + context->fill (); + } + c = get_style()->get_fg (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + x1 = (w/2) - ((w*fract)/2); // center, back up half the bar width + context->set_source_rgb (r, g, b); + context->rectangle (x1, 1, w*fract, h); + context->fill (); break; case LeftToRight: - x1 = 0; + + w = darea.get_width() - 2; + h = darea.get_height() - 2; + x2 = (gint) floor (w * fract); - y1 = 0; - y2 = h - 1; + y2 = h; + radius = 4; + if (x2 < 8) x2 = 8; - win->draw_rectangle (get_style()->get_bg_gc (get_state()), - false, - 0, 0, darea.get_width() - 1, darea.get_height() - 1); + /* border */ - /* draw active box */ + context->set_source_rgb (0,0,0); + cairo_rectangle (context->cobj(), 0, 0, darea.get_width(), darea.get_height()); + context->fill (); - win->draw_rectangle (get_style()->get_fg_gc (get_state()), - true, - 1 + x1, - 1 + y1, - x2, - 1 + y2); - - /* draw inactive box */ + /* draw active box */ - win->draw_rectangle (get_style()->get_fg_gc (STATE_INSENSITIVE), - true, - 1 + x2, - 1 + y1, - w - x2, - 1 + y2); + context->set_source (pattern); + rounded_rectangle (context, 1, 1, x2, y2, radius-1.5); + context->fill (); +// context->set_source (shine_pattern); +// rounded_rectangle (context, 2, 3, x2-2, y2-8, radius-2); +// context->fill (); break; case RightToLeft: @@ -341,47 +468,45 @@ BarController::expose (GdkEventExpose* event) break; } - if (with_text) { - /* draw label */ - - char buf[64]; - buf[0] = '\0'; - - label_callback (buf, 64); - - if (buf[0] != '\0') { + if (!darea.get_sensitive()) { + rounded_rectangle (context, 0, 0, darea.get_width(), darea.get_height(), 3); + context->set_source_rgba (0.505, 0.517, 0.525, 0.6); + context->fill (); + } - layout->set_text (buf); + /* draw label */ - int width, height; - layout->get_pixel_size (width, height); + double xpos = -1; + std::string const label = get_label (xpos); - int xpos; + if (!label.empty()) { + + layout->set_text (label); + + int width, height, x; + layout->get_pixel_size (width, height); - xpos = max (3, 1 + (x2 - (width/2))); - xpos = min (darea.get_width() - width - 3, xpos); - - win->draw_layout (get_style()->get_text_gc (get_state()), - xpos, - (darea.get_height()/2) - (height/2), - layout); - } + if (xpos == -1) { + x = max (3, 1 + (x2 - (width/2))); + x = min (darea.get_width() - width - 3, (int) lrint (xpos)); + } else { + x = lrint (darea.get_width() * xpos); + } + + c = get_style()->get_text (get_state()); + r = c.get_red_p (); + g = c.get_green_p (); + b = c.get_blue_p (); + context->set_source_rgb (r, g, b); + context->move_to (x, (darea.get_height()/2) - (height/2)); + layout->show_in_cairo_context (context); } - + return true; } void -BarController::set_with_text (bool yn) -{ - if (with_text != yn) { - with_text = yn; - queue_draw (); - } -} - -void -BarController::set_style (Style s) +BarController::set_style (barStyle s) { _style = s; darea.queue_draw (); @@ -405,6 +530,9 @@ BarController::switch_to_bar () darea.show (); switching = false; + + SpinnerActive (false); /* EMIT SIGNAL */ + return FALSE; } @@ -428,24 +556,20 @@ BarController::switch_to_spinner () spinner.grab_focus (); switching = false; + + SpinnerActive (true); /* EMIT SIGNAL */ + return FALSE; } void BarController::entry_activated () { - string text = spinner.get_text (); - float val; - - if (sscanf (text.c_str(), "%f", &val) == 1) { - adjustment.set_value (val); - } - switch_to_bar (); } bool -BarController::entry_focus_out (GdkEventFocus* ev) +BarController::entry_focus_out (GdkEventFocus* /*ev*/) { entry_activated (); return true; @@ -464,3 +588,82 @@ BarController::set_sensitive (bool yn) Frame::set_sensitive (yn); darea.set_sensitive (yn); } + +/* + This is called when we need to update the adjustment with the value + from the spinner's text entry. + + We need to use Gtk::Entry::get_text to avoid recursive nastiness :) + + If we're not in logarithmic mode we can return false to use the + default conversion. + + In theory we should check for conversion errors but set numeric + mode to true on the spinner prevents invalid input. +*/ +int +BarController::entry_input (double* new_value) +{ + if (!logarithmic) { + return false; + } + + // extract a double from the string and take its log + Entry *entry = dynamic_cast(&spinner); + double value; + + { + // Switch to user's preferred locale so that + // if they use different LC_NUMERIC conventions, + // we will honor them. + + PBD::LocaleGuard lg (""); + sscanf (entry->get_text().c_str(), "%lf", &value); + } + + *new_value = log(value); + + return true; +} + +/* + This is called when we need to update the spinner's text entry + with the value of the adjustment. + + We need to use Gtk::Entry::set_text to avoid recursive nastiness :) + + If we're not in logarithmic mode we can return false to use the + default conversion. +*/ +bool +BarController::entry_output () +{ + if (!logarithmic) { + return false; + } + + // generate the exponential and turn it into a string + // convert to correct locale. + + stringstream stream; + string str; + + char buf[128]; + + { + // Switch to user's preferred locale so that + // if they use different LC_NUMERIC conventions, + // we will honor them. + + PBD::LocaleGuard lg (""); + snprintf (buf, sizeof (buf), "%g", exp (spinner.get_adjustment()->get_value())); + } + + Entry *entry = dynamic_cast(&spinner); + entry->set_text(buf); + + return true; +} + + +