--- gigedit/trunk/src/gigedit/regionchooser.cpp 2017/04/27 17:28:01 3131 +++ gigedit/trunk/src/gigedit/regionchooser.cpp 2018/01/23 16:30:56 3409 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2015 Andreas Persson + * Copyright (C) 2006-2017 Andreas Persson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,18 +17,26 @@ * 02110-1301 USA. */ +#include "compat.h" +#include "global.h" #include "regionchooser.h" #include +#include #include #include +#if HAS_GDKMM_SEAT +# include +#endif #include +#if HAS_GTKMM_STOCK +# include +#endif #include #include #include -#include "global.h" #include "Settings.h" #include "gfx/builtinpix.h" @@ -38,9 +46,10 @@ struct RegionFeatures { int sampleRefs; int loops; + int validDimRegs; RegionFeatures() { - sampleRefs = loops = 0; + sampleRefs = loops = validDimRegs = 0; } }; @@ -48,6 +57,9 @@ RegionFeatures f; for (int i = 0; i < rgn->DimensionRegions; ++i) { gig::DimensionRegion* dr = rgn->pDimensionRegions[i]; + DimensionCase c = dimensionCaseOf(dr); + if (!isUsedCase(c, rgn)) continue; + f.validDimRegs++; if (dr->pSample) f.sampleRefs++; // the user doesn't care about loop if there is no valid sample reference if (dr->pSample && dr->SampleLoops) f.loops++; @@ -89,12 +101,51 @@ white("white"), black("black"), m_VirtKeybModeChoice(_("Virtual Keyboard Mode")), - currentActiveKey(-1) + currentActiveKey(-1), + modifyallregions(false) { set_size_request(500, KEYBOARD_HEIGHT + REGION_BLOCK_HEIGHT); loadBuiltInPix(); + // create blue hatched pattern + { + const int width = blueHatchedPattern->get_width(); + const int height = blueHatchedPattern->get_height(); + const int stride = blueHatchedPattern->get_rowstride(); + + // manually convert from RGBA to ARGB + this->blueHatchedPatternARGB = blueHatchedPattern->copy(); + const int pixelSize = stride / width; + const int totalPixels = width * height; + assert(pixelSize == 4); + unsigned char* ptr = this->blueHatchedPatternARGB->get_pixels(); + for (int iPixel = 0; iPixel < totalPixels; ++iPixel, ptr += pixelSize) { + const unsigned char r = ptr[0]; + const unsigned char g = ptr[1]; + const unsigned char b = ptr[2]; + const unsigned char a = ptr[3]; + ptr[0] = b; + ptr[1] = g; + ptr[2] = r; + ptr[3] = a; + } + + Cairo::RefPtr imageSurface = Cairo::ImageSurface::create( +#if HAS_CAIROMM_CPP11_ENUMS + this->blueHatchedPatternARGB->get_pixels(), Cairo::Surface::Format::ARGB32, width, height, stride +#else + this->blueHatchedPatternARGB->get_pixels(), Cairo::FORMAT_ARGB32, width, height, stride +#endif + ); + this->blueHatchedSurfacePattern = Cairo::SurfacePattern::create(imageSurface); +#if HAS_CAIROMM_CPP11_ENUMS + this->blueHatchedSurfacePattern->set_extend(Cairo::Pattern::Extend::REPEAT); +#else + this->blueHatchedSurfacePattern->set_extend(Cairo::EXTEND_REPEAT); +#endif + } + instrument = 0; region = 0; resize.active = false; @@ -126,17 +177,76 @@ m_VirtKeybPropsBox.show(); for (int i = 0 ; i < 128 ; i++) key_pressed[i] = false; - actionGroup = Gtk::ActionGroup::create(); - actionGroup->add(Gtk::Action::create("Properties", _("_Properties")), + actionGroup = ActionGroup::create(); +#if USE_GLIB_ACTION + actionGroup->add_action( + "Properties", sigc::mem_fun(*this, &RegionChooser::show_region_properties) + ); + actionGroup->add_action( + "Remove", sigc::mem_fun(*this, &RegionChooser::delete_region) + ); + actionGroup->add_action( + "Add", sigc::mem_fun(*this, &RegionChooser::add_region) + ); + actionGroup->add_action( + "Dimensions", sigc::mem_fun(*this, &RegionChooser::manage_dimensions) + ); + insert_action_group("PopupMenuInsideRegion", actionGroup); +#else + actionGroup->add(Gtk::Action::create("Properties", + Gtk::Stock::PROPERTIES), sigc::mem_fun(*this, &RegionChooser::show_region_properties)); - actionGroup->add(Gtk::Action::create("Remove", _("_Remove")), + actionGroup->add(Gtk::Action::create("Remove", Gtk::Stock::REMOVE), sigc::mem_fun(*this, &RegionChooser::delete_region)); - actionGroup->add(Gtk::Action::create("Add", _("_Add")), + actionGroup->add(Gtk::Action::create("Add", Gtk::Stock::ADD), sigc::mem_fun(*this, &RegionChooser::add_region)); actionGroup->add(Gtk::Action::create("Dimensions", _("Dimensions...")), sigc::mem_fun(*this, &RegionChooser::manage_dimensions)); +#endif +#if USE_GTKMM_BUILDER + uiManager = Gtk::Builder::create(); + Glib::ustring ui_info = + "" + " " + "
" + " " + " Properties" + " PopupMenuInsideRegion.Properties" + " " + " " + " Dimensions" + " PopupMenuInsideRegion.Dimensions" + " " + " " + " Remove" + " PopupMenuInsideRegion.Remove" + " " + "
" + "
" + " " + "
" + " " + " Add" + " PopupMenuInsideRegion.Add" + " " + "
" + "
" + "
"; + uiManager->add_from_string(ui_info); + + popup_menu_inside_region = new Gtk::Menu( + Glib::RefPtr::cast_dynamic( + uiManager->get_object("menu-PopupMenuInsideRegion") + ) + ); + popup_menu_outside_region = new Gtk::Menu( + Glib::RefPtr::cast_dynamic( + uiManager->get_object("menu-PopupMenuOutsideRegion") + ) + ); +#else uiManager = Gtk::UIManager::create(); uiManager->insert_action_group(actionGroup); Glib::ustring ui_info = @@ -157,8 +267,15 @@ popup_menu_outside_region = dynamic_cast( uiManager->get_widget("/PopupMenuOutsideRegion")); +#endif // USE_GTKMM_BUILDER + +#if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION > 22) +# warning GTKMM4 event registration code missing for regionchooser! + //add_events(Gdk::EventMask::BUTTON_PRESS_MASK); +#else add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK); +#endif dimensionManager.region_to_be_changed_signal.connect( region_to_be_changed_signal.make_slot() @@ -178,12 +295,30 @@ sigc::mem_fun(*this, &RegionChooser::on_note_off_event) ); set_tooltip_text(_("Right click here for adding new region. Use mouse pointer for moving (dragging) or resizing existing regions (by pointing at region's boundary). Right click on an existing region for more actions.")); + + Settings::singleton()->showTooltips.get_proxy().signal_changed().connect( + sigc::mem_fun(*this, &RegionChooser::on_show_tooltips_changed) + ); + + on_show_tooltips_changed(); } RegionChooser::~RegionChooser() { } +void RegionChooser::on_show_tooltips_changed() { + const bool b = Settings::singleton()->showTooltips; + + set_has_tooltip(b); +} + +void RegionChooser::setModifyAllRegions(bool b) { + modifyallregions = b; + // redraw required parts + queue_draw(); +} + void RegionChooser::invalidate_key(int key) { const int h = KEYBOARD_HEIGHT; const int w = get_width() - 1; @@ -231,7 +366,13 @@ #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 const Gdk::Color bg = get_style()->get_bg(Gtk::STATE_NORMAL); #else +#if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION > 22) + GdkRGBA gdkBgRGBA; + gtk_style_context_get_background_color(get_style_context()->gobj(), &gdkBgRGBA); + const Gdk::RGBA bg = Glib::wrap(&gdkBgRGBA, true); +# else const Gdk::RGBA bg = get_style_context()->get_background_color(); +# endif #endif Gdk::Cairo::set_source_rgba(cr, bg); cr->paint(); @@ -334,7 +475,13 @@ cr->line_to(x3, h1 - 0.5); cr->stroke(); - Gdk::Cairo::set_source_rgba(cr, region == r ? blue : white); + if (region == r) + Gdk::Cairo::set_source_rgba(cr, blue); + else if (modifyallregions) + cr->set_source(blueHatchedSurfacePattern); + else + Gdk::Cairo::set_source_rgba(cr, white); + cr->rectangle(x3 + 1, 1, x2 - x3 - 1, h1 - 2); cr->fill(); Gdk::Cairo::set_source_rgba(cr, black); @@ -350,7 +497,7 @@ RegionFeatures features = regionFeatures(r); const bool bShowLoopSymbol = features.loops > 0; - const bool bShowSampleRefSymbol = features.sampleRefs < r->DimensionRegions; + const bool bShowSampleRefSymbol = features.sampleRefs < features.validDimRegs; if (bShowLoopSymbol || bShowSampleRefSymbol) { const int margin = 2; const int wRgn = x2 - x; @@ -374,7 +521,7 @@ const int wPic = 12; const int hPic = 14; Gdk::Cairo::set_source_pixbuf( - cr, (features.loops == r->DimensionRegions) ? blackLoop : grayLoop, + cr, (features.loops == features.validDimRegs) ? blackLoop : grayLoop, x + (wRgn-wPic)/2.f, (bShowSampleRefSymbol) ? h1 - hPic - margin : (h1-hPic)/2.f ); @@ -524,7 +671,11 @@ #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 get_window()->pointer_ungrab(event->time); #else +# if GTKMM_MAJOR_VERSION < 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 20) Glib::wrap(event->device, true)->ungrab(event->time); +# else + gdk_device_ungrab(Glib::wrap(event->device, true)->gobj(), event->time); +# endif #endif resize.active = false; @@ -536,7 +687,11 @@ #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 get_window()->pointer_ungrab(event->time); #else +# if GTKMM_MAJOR_VERSION < 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 20) Glib::wrap(event->device, true)->ungrab(event->time); +# else + gdk_device_ungrab(Glib::wrap(event->device, true)->gobj(), event->time); +# endif #endif move.active = false; @@ -544,7 +699,16 @@ #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW)); #else - get_window()->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW)); + get_window()->set_cursor( +# if GTKMM_MAJOR_VERSION < 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 20) + Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW) +# else + Gdk::Cursor::create( + Glib::wrap(event->device, true)->get_seat()->get_display(), + Gdk::SB_H_DOUBLE_ARROW + ) +# endif + ); #endif cursor_is_resize = true; } @@ -640,6 +804,7 @@ Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW), event->time); #else +# if GTKMM_MAJOR_VERSION < 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 20) Glib::wrap(event->device, true)->grab(get_window(), Gdk::OWNERSHIP_NONE, false, @@ -648,6 +813,21 @@ Gdk::POINTER_MOTION_HINT_MASK, Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW), event->time); +# else + gdk_device_grab( + Glib::wrap(event->device, true)->gobj(), + get_window()->gobj(), + GDK_OWNERSHIP_NONE, + false, + GdkEventMask(GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK), + Gdk::Cursor::create( + Glib::wrap(event->device, true)->get_seat()->get_display(), + Gdk::SB_H_DOUBLE_ARROW + )->gobj(), + event->time + ); +# endif #endif resize.active = true; } else { @@ -666,14 +846,30 @@ Gdk::Cursor(Gdk::FLEUR), event->time); #else - Glib::wrap(event->device, true)->grab(get_window(), - Gdk::OWNERSHIP_NONE, - false, - Gdk::BUTTON_RELEASE_MASK | - Gdk::POINTER_MOTION_MASK | - Gdk::POINTER_MOTION_HINT_MASK, - Gdk::Cursor::create(Gdk::FLEUR), - event->time); +# if GTKMM_MAJOR_VERSION < 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 20) + Glib::wrap(event->device, true)->grab(get_window(), + Gdk::OWNERSHIP_NONE, + false, + Gdk::BUTTON_RELEASE_MASK | + Gdk::POINTER_MOTION_MASK | + Gdk::POINTER_MOTION_HINT_MASK, + Gdk::Cursor::create(Gdk::FLEUR), + event->time); +# else + gdk_device_grab( + Glib::wrap(event->device, true)->gobj(), + get_window()->gobj(), + GDK_OWNERSHIP_NONE, + false, + GdkEventMask(GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK), + Gdk::Cursor::create( + Glib::wrap(event->device, true)->get_seat()->get_display(), + Gdk::FLEUR + )->gobj(), + event->time + ); +# endif #endif move.active = true; move.offset = event->x - key_to_x(region->KeyRange.low, w); @@ -891,8 +1087,14 @@ { Glib::RefPtr window = get_window(); int x, y; +#if HAS_GDKMM_SEAT + x = event->x; + y = event->y; + Gdk::ModifierType state = Gdk::ModifierType(event->state); +#else Gdk::ModifierType state = Gdk::ModifierType(0); window->get_pointer(x, y, state); +#endif // handle virtual MIDI keyboard if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD && @@ -923,7 +1125,16 @@ #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW)); #else - window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW)); + window->set_cursor( +# if GTKMM_MAJOR_VERSION < 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 20) + Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW) +# else + Gdk::Cursor::create( + Glib::wrap(event->device, true)->get_seat()->get_display(), + Gdk::SB_H_DOUBLE_ARROW + ) +# endif + ); #endif cursor_is_resize = true; } @@ -1003,7 +1214,11 @@ // add "Keygroup" checkbox Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)")); checkBoxKeygroup.set_active(region->KeyGroup); +#if USE_GTKMM_BOX + dialog.get_content_area()->pack_start(checkBoxKeygroup); +#else dialog.get_vbox()->pack_start(checkBoxKeygroup); +#endif checkBoxKeygroup.show(); // add "Keygroup" spinbox #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 @@ -1013,12 +1228,24 @@ Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999)); #endif if (region->KeyGroup) spinBox.set_value(region->KeyGroup); +#if USE_GTKMM_BOX + dialog.get_content_area()->pack_start(spinBox); +#else dialog.get_vbox()->pack_start(spinBox); +#endif spinBox.show(); // add OK and CANCEL buttons to the dialog +#if HAS_GTKMM_STOCK + dialog.add_button(Gtk::Stock::OK, 0); + dialog.add_button(Gtk::Stock::CANCEL, 1); +#else dialog.add_button(_("_OK"), 0); dialog.add_button(_("_Cancel"), 1); +#endif + dialog.set_position(Gtk::WIN_POS_MOUSE); +#if HAS_GTKMM_SHOW_ALL_CHILDREN dialog.show_all_children(); +#endif if (!dialog.run()) { // OK selected ... region->KeyGroup = (checkBoxKeygroup.get_active()) ? spinBox.get_value_as_int() : 0;