Moved note height/range/etc stuff from MidiRegionView to MidiStreamView, since it's all shared anyway.

Fixed positioning of percussion hits.
Note row separator lines (ie a "piano roll".. if it counts as a piano roll without an actual piano on the side of it, anyway).


git-svn-id: svn://localhost/ardour2/trunk@2237 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-08-04 04:18:34 +00:00
parent 93dbcbd606
commit 604a0079ce
6 changed files with 93 additions and 43 deletions

View File

@ -115,16 +115,16 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
drag_delta_x += dx;
// Snap to note rows
if (abs(dy) < _region.note_height()) {
if (abs(dy) < _region.midi_stream_view()->note_height()) {
dy = 0.0;
} else {
int8_t this_delta_note;
if (dy > 0)
this_delta_note = (int8_t)ceil(dy / _region.note_height());
this_delta_note = (int8_t)ceil(dy / _region.midi_stream_view()->note_height());
else
this_delta_note = (int8_t)floor(dy / _region.note_height());
this_delta_note = (int8_t)floor(dy / _region.midi_stream_view()->note_height());
drag_delta_note -= this_delta_note;
dy = _region.note_height() * this_delta_note;
dy = _region.midi_stream_view()->note_height() * this_delta_note;
last_y = last_y + dy;
}

View File

@ -193,9 +193,9 @@ MidiRegionView::canvas_event(GdkEvent* ev)
drag_rect = new ArdourCanvas::SimpleRect(*group);
drag_rect->property_x1() = event_x;
drag_rect->property_y1() = note_to_y(y_to_note(event_y));
drag_rect->property_y1() = midi_stream_view()->note_to_y(midi_stream_view()->y_to_note(event_y));
drag_rect->property_x2() = event_x;
drag_rect->property_y2() = drag_rect->property_y1() + note_height();
drag_rect->property_y2() = drag_rect->property_y1() + floor(midi_stream_view()->note_height());
drag_rect->property_outline_what() = 0xFF;
drag_rect->property_outline_color_rgba() = 0xFFFFFF99;
drag_rect->property_fill_color_rgba() = 0xFFFFFF66;
@ -279,7 +279,7 @@ MidiRegionView::create_note_at(double x, double y, double dur)
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
MidiStreamView* const view = mtv->midi_view();
double note = y_to_note(y) - 1;
double note = midi_stream_view()->y_to_note(y);
assert(note >= 0.0);
assert(note <= 127.0);
@ -461,7 +461,7 @@ MidiRegionView::add_event (const MidiEvent& ev)
if (midi_view()->note_mode() == Sustained) {
if ((ev.buffer()[0] & 0xF0) == MIDI_CMD_NOTE_ON) {
const Byte& note = ev.buffer()[1];
const double y1 = note_to_y(note);
const double y1 = midi_stream_view()->note_to_y(note);
CanvasNote* ev_rect = new CanvasNote(*this, *group);
ev_rect->property_x1() = trackview.editor.frame_to_pixel (
@ -469,7 +469,7 @@ MidiRegionView::add_event (const MidiEvent& ev)
ev_rect->property_y1() = y1;
ev_rect->property_x2() = trackview.editor.frame_to_pixel (
_region->length());
ev_rect->property_y2() = y1 + note_height();
ev_rect->property_y2() = y1 + floor(midi_stream_view()->note_height());
ev_rect->property_outline_color_rgba() = 0xFFFFFFAA;
/* outline all but right edge */
ev_rect->property_outline_what() = (guint32) (0x1 & 0x4 & 0x8);
@ -492,9 +492,9 @@ MidiRegionView::add_event (const MidiEvent& ev)
} else if (midi_view()->note_mode() == Percussive) {
const Byte& note = ev.buffer()[1];
const double diamond_size = std::min(note_height(), 5.0);
const double diamond_size = midi_stream_view()->note_height() / 2.0;
const double x = trackview.editor.frame_to_pixel((nframes_t)ev.time());
const double y = note_to_y(note) + (diamond_size / 2.0);
const double y = midi_stream_view()->note_to_y(note) + (diamond_size / 2.0);
CanvasHit* ev_diamond = new CanvasHit(*this, *group, diamond_size);
ev_diamond->move(x, y);
@ -543,13 +543,13 @@ MidiRegionView::add_note (const MidiModel::Note& note)
//printf("Event, time = %f, note = %d\n", note.time(), note.note());
if (midi_view()->note_mode() == Sustained) {
const double y1 = note_to_y(note.note());
const double y1 = midi_stream_view()->note_to_y(note.note());
ArdourCanvas::SimpleRect * ev_rect = new CanvasNote(*this, *group, &note);
ev_rect->property_x1() = trackview.editor.frame_to_pixel((nframes_t)note.time());
ev_rect->property_y1() = y1;
ev_rect->property_x2() = trackview.editor.frame_to_pixel((nframes_t)(note.end_time()));
ev_rect->property_y2() = y1 + note_height();
ev_rect->property_y2() = y1 + floor(midi_stream_view()->note_height());
ev_rect->property_fill_color_rgba() = fill;
ev_rect->property_outline_color_rgba() = outline;
@ -559,10 +559,11 @@ MidiRegionView::add_note (const MidiModel::Note& note)
_events.push_back(ev_rect);
} else if (midi_view()->note_mode() == Percussive) {
const double diamond_size = midi_stream_view()->note_height() / 2.0;
const double x = trackview.editor.frame_to_pixel((nframes_t)note.time());
const double y = note_to_y(note.note());
const double y = midi_stream_view()->note_to_y(note.note()) + (diamond_size / 2.0) - 2;
CanvasHit* ev_diamond = new CanvasHit(*this, *group, note_height(), &note);
CanvasHit* ev_diamond = new CanvasHit(*this, *group, diamond_size);
ev_diamond->move(x, y);
ev_diamond->show();
ev_diamond->property_fill_color_rgba() = fill;

View File

@ -67,28 +67,6 @@ class MidiRegionView : public RegionView
inline MidiStreamView* midi_stream_view() const
{ return midi_view()->midi_view(); }
inline uint8_t contents_note_range() const
{ return midi_stream_view()->highest_note() - midi_stream_view()->lowest_note() + 1; }
inline double footer_height() const
{ return name_highlight->property_y2() - name_highlight->property_y1(); }
inline double contents_height() const
{ return (trackview.height - footer_height() - 2); }
inline double note_height() const
{ return contents_height() / (double)contents_note_range(); }
inline double note_to_y(uint8_t note) const
{ return contents_height()
- (note + 1 - midi_stream_view()->lowest_note()) * note_height(); }
inline uint8_t y_to_note(double y) const
{ return (uint8_t)floor((contents_height() - y)
/ contents_height() * (double)contents_note_range())
+ midi_stream_view()->lowest_note(); }
void set_y_position_and_height (double, double);
void show_region_editor ();

View File

@ -46,6 +46,7 @@
#include "gui_thread.h"
#include "utils.h"
#include "simplerect.h"
#include "simpleline.h"
using namespace std;
using namespace ARDOUR;
@ -56,7 +57,7 @@ MidiStreamView::MidiStreamView (MidiTimeAxisView& tv)
: StreamView (tv)
, _range(ContentsRange)
, _lowest_note(60)
, _highest_note(60)
, _highest_note(71)
{
if (tv.is_track())
stream_base_color = ARDOUR_UI::config()->canvasvar_MidiTrackBase.get();
@ -67,6 +68,14 @@ MidiStreamView::MidiStreamView (MidiTimeAxisView& tv)
canvas_rect->property_outline_color_rgba() = RGBA_BLACK;
use_rec_regions = tv.editor.show_waveforms_recording ();
_note_line_group = new ArdourCanvas::Group (*canvas_group);
for (uint8_t i=0; i < 127; ++i) {
_note_lines[i] = new ArdourCanvas::SimpleLine(*_note_line_group,
0, note_to_y(i), 10, note_to_y(i));
_note_lines[i]->property_color_rgba() = 0xEEEEEE55;
}
}
MidiStreamView::~MidiStreamView ()
@ -149,6 +158,13 @@ MidiStreamView::display_region(MidiRegionView* region_view, bool load_model)
region_view->display_model(source->model());
}
void
MidiStreamView::display_diskstream (boost::shared_ptr<Diskstream> ds)
{
StreamView::display_diskstream(ds);
draw_note_separators();
}
// FIXME: code duplication with AudioStreamView
void
MidiStreamView::redisplay_diskstream ()
@ -188,13 +204,41 @@ MidiStreamView::redisplay_diskstream ()
i = tmp;
}
/* now fix layering */
for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
region_layered (*i);
}
draw_note_separators();
}
void
MidiStreamView::update_contents_y_position_and_height ()
{
StreamView::update_contents_y_position_and_height();
draw_note_separators();
}
void
MidiStreamView::draw_note_separators()
{
for (uint8_t i=0; i < 127; ++i) {
if (i >= _lowest_note-1 && i <= _highest_note) {
_note_lines[i]->property_x1() = 0;
_note_lines[i]->property_x2() = canvas_rect->property_x2() - 2;
_note_lines[i]->property_y1() = note_to_y(i);
_note_lines[i]->property_y2() = note_to_y(i);
_note_lines[i]->show();
_note_lines[i]->raise_to_top();
} else {
_note_lines[i]->hide();
}
}
}
void
MidiStreamView::update_bounds(uint8_t note_num)

View File

@ -26,6 +26,8 @@
#include "enums.h"
#include "simplerect.h"
#include "streamview.h"
#include "time_axis_view_item.h"
#include "route_time_axis.h"
namespace Gdk {
class Color;
@ -72,6 +74,24 @@ class MidiStreamView : public StreamView
void update_bounds(uint8_t note_num);
void redisplay_diskstream ();
inline double contents_height() const
{ return (_trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
inline double note_to_y(uint8_t note) const
{ return contents_height()
- (note + 1 - _lowest_note) * note_height() + 1; }
inline uint8_t y_to_note(double y) const
{ return (uint8_t)((contents_height() - y - 1)
/ contents_height() * (double)contents_note_range())
+ _lowest_note; }
inline double note_height() const
{ return contents_height() / (double)contents_note_range(); }
inline uint8_t contents_note_range() const
{ return _highest_note - _lowest_note + 1; }
private:
void setup_rec_box ();
@ -80,12 +100,18 @@ class MidiStreamView : public StreamView
RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
void display_region(MidiRegionView* region_view, bool load_model);
void display_diskstream (boost::shared_ptr<ARDOUR::Diskstream> ds);
void update_contents_y_position_and_height ();
void draw_note_separators();
void color_handler ();
VisibleNoteRange _range;
uint8_t _lowest_note;
uint8_t _highest_note;
VisibleNoteRange _range;
uint8_t _lowest_note;
uint8_t _highest_note;
ArdourCanvas::Group* _note_line_group;
ArdourCanvas::SimpleLine* _note_lines[127];
};
#endif /* __ardour_midi_streamview_h__ */

View File

@ -59,7 +59,8 @@ class StreamView : public sigc::trackable
public:
virtual ~StreamView ();
RouteTimeAxisView& trackview() { return _trackview; }
RouteTimeAxisView& trackview() { return _trackview; }
const RouteTimeAxisView& trackview() const { return _trackview; }
void attach ();