--- gigedit/trunk/src/gigedit/regionchooser.cpp 2008/01/30 02:20:48 1654 +++ gigedit/trunk/src/gigedit/regionchooser.cpp 2008/02/03 00:19:55 1660 @@ -27,6 +27,9 @@ #include "global.h" +#define REGION_BLOCK_HEIGHT 20 +#define KEYBOARD_HEIGHT 40 + void SortedRegions::update(gig::Instrument* instrument) { // Usually, the regions in a gig file are ordered after their key // range, but there are files where they are not. The @@ -74,7 +77,7 @@ resize.active = false; move.active = false; cursor_is_resize = false; - h1 = 20; + h1 = REGION_BLOCK_HEIGHT; actionGroup = Gtk::ActionGroup::create(); actionGroup->add(Gtk::Action::create("Properties", @@ -122,6 +125,12 @@ sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed) ) ); + keyboard_key_hit_signal.connect( + sigc::mem_fun(*this, &RegionChooser::on_note_on_event) + ); + keyboard_key_released_signal.connect( + sigc::mem_fun(*this, &RegionChooser::on_note_off_event) + ); } RegionChooser::~RegionChooser() @@ -154,16 +163,13 @@ { Glib::RefPtr window = get_window(); window->clear(); - const int h = 40; + const int h = KEYBOARD_HEIGHT; const int w = get_width() - 1; const int bh = int(h * 0.55); Glib::RefPtr black = get_style()->get_black_gc(); Glib::RefPtr white = get_style()->get_white_gc(); - Glib::RefPtr context = get_pango_context(); - Glib::RefPtr layout = Pango::Layout::create(context); - window->draw_rectangle(black, false, 0, h1, w, h - 1); gc->set_foreground(grey1); int x1 = int(w * 20.5 / 128.0 + 0.5); @@ -173,7 +179,6 @@ window->draw_rectangle(white, true, x1 + 1, h1 + 1, x2 - x1 - 1, h - 2); window->draw_rectangle(gc, true, x2 + 1, h1 + 1, w - x2 - 1, h - 2); - int octave = -1; for (int i = 0 ; i < 128 ; i++) { int note = (i + 3) % 12; int x = int(w * i / 128.0 + 0.5); @@ -187,18 +192,7 @@ } else if (note == 3 || note == 8) { window->draw_line(black, x, h1 + 1, x, h1 + h); } - if (note == 3) { - char buf[30]; - sprintf(buf, "%d", octave); - layout->set_markup(buf); - Pango::Rectangle rectangle = layout->get_logical_extents(); - double text_w = double(rectangle.get_width()) / Pango::SCALE; - double text_h = double(rectangle.get_height()) / Pango::SCALE; - double x2 = w * (i + 0.75) / 128.0; - window->draw_layout(black, int(x2 - text_w / 2 + 1), - int(h1 + h - text_h + 0.5), layout); - octave++; - } + if (note == 3) draw_digit(i); } if (instrument) { @@ -239,7 +233,7 @@ void RegionChooser::on_size_request(GtkRequisition* requisition) { *requisition = GtkRequisition(); - requisition->height = 40 + 20; + requisition->height = KEYBOARD_HEIGHT + REGION_BLOCK_HEIGHT; requisition->width = 500; } @@ -248,10 +242,25 @@ return note == 1 || note == 4 || note == 6 || note == 9 || note == 11; } +void RegionChooser::draw_digit(int key) { + const int h = KEYBOARD_HEIGHT; + const int w = get_width() - 1; + Glib::RefPtr layout = Pango::Layout::create(get_pango_context()); + char buf[30]; + sprintf(buf, "%d", key / 12 - 1); + layout->set_markup(buf); + Pango::Rectangle rectangle = layout->get_logical_extents(); + double text_w = double(rectangle.get_width()) / Pango::SCALE; + double text_h = double(rectangle.get_height()) / Pango::SCALE; + double x = w * (key + 0.75) / 128.0; + get_window()->draw_layout(get_style()->get_black_gc(), int(x - text_w / 2 + 1), + int(h1 + h - text_h + 0.5), layout); +} + void RegionChooser::draw_region(int from, int to, const Gdk::Color& color) { - const int h = 40; - const int w = get_width(); + const int h = KEYBOARD_HEIGHT; + const int w = get_width() - 1; const int bh = int(h * 0.55); Glib::RefPtr window = get_window(); @@ -262,23 +271,24 @@ int x = int(w * i / 128.0 + 0.5) + 1; int x2 = int(w * (i + 1.5) / 128.0 + 0.5); int x3 = int(w * (i + 1) / 128.0 + 0.5); - int x4 = int(w * (i - 0.5) / 128 + 0.5) + 1; + int x4 = int(w * (i - 0.5) / 128.0 + 0.5); int w1 = x3 - x; switch (note) { case 0: case 5: case 10: - window->draw_rectangle(gc, true, x - 1, h1 + 1, w1, bh); - window->draw_rectangle(gc, true, x4, h1 + bh + 1, x2 - x4 - 1, h - bh - 2); + window->draw_rectangle(gc, true, x, h1 + 1, w1, bh); + window->draw_rectangle(gc, true, x4 + 1, h1 + bh + 1, x2 - x4 - 1, h - bh - 2); break; case 2: case 7: window->draw_rectangle(gc, true, x, h1 + 1, w1, bh); - window->draw_rectangle(gc, true, x4 - 1, h1 + bh + 1, x3 - x4 + 1, h - bh - 2); + window->draw_rectangle(gc, true, x4 + 1, h1 + bh + 1, x3 - x4 - 1, h - bh - 2); break; case 3: case 8: window->draw_rectangle(gc, true, x, h1 + 1, w1, bh); window->draw_rectangle(gc, true, x, h1 + bh + 1, x2 - x, h - bh - 2); + if (note == 3) draw_digit(i); break; default: - window->draw_rectangle(gc, true, x, h1 + 1, w1 - 1, bh - 1); + window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1); break; } } @@ -295,6 +305,16 @@ bool RegionChooser::on_button_release_event(GdkEventButton* event) { + const int k = int(event->x / (get_width() - 1) * 128.0); + + if (event->type == GDK_BUTTON_RELEASE) { + if (event->y >= REGION_BLOCK_HEIGHT) { + int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 : + int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1; + keyboard_key_released_signal.emit(k, velocity); + } + } + if (resize.active) { get_window()->pointer_ungrab(event->time); resize.active = false; @@ -354,8 +374,17 @@ { if (!instrument) return true; - int k = int(event->x / (get_width() - 1) * 128.0); + const int k = int(event->x / (get_width() - 1) * 128.0); + + if (event->type == GDK_BUTTON_PRESS) { + if (event->y >= REGION_BLOCK_HEIGHT) { + int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 : + int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1; + keyboard_key_hit_signal.emit(k, velocity); + } + } + if (event->y >= REGION_BLOCK_HEIGHT) return true; if (event->type == GDK_BUTTON_PRESS && event->button == 3) { gig::Region* r = get_region(k); if (r) { @@ -750,3 +779,11 @@ sigc::signal& RegionChooser::signal_region_changed_signal() { return region_changed_signal; } + +sigc::signal& RegionChooser::signal_keyboard_key_hit() { + return keyboard_key_hit_signal; +} + +sigc::signal& RegionChooser::signal_keyboard_key_released() { + return keyboard_key_released_signal; +}