summaryrefslogtreecommitdiffstats
path: root/src/gui/editors/matrix/MatrixStaff.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/editors/matrix/MatrixStaff.cpp')
-rw-r--r--src/gui/editors/matrix/MatrixStaff.cpp232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/gui/editors/matrix/MatrixStaff.cpp b/src/gui/editors/matrix/MatrixStaff.cpp
new file mode 100644
index 0000000..b6be79f
--- /dev/null
+++ b/src/gui/editors/matrix/MatrixStaff.cpp
@@ -0,0 +1,232 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Rosegarden
+ A MIDI and audio sequencer and musical notation editor.
+
+ This program is Copyright 2000-2008
+ Guillaume Laurent <[email protected]>,
+ Chris Cannam <[email protected]>,
+ Richard Bown <[email protected]>
+
+ The moral rights of Guillaume Laurent, Chris Cannam, and Richard
+ Bown to claim authorship of this work have been asserted.
+
+ Other copyrights also apply to some parts of this work. Please
+ see the AUTHORS file and individual file headers for details.
+
+ 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 the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+
+#include "MatrixStaff.h"
+#include "misc/Debug.h"
+
+#include "base/BaseProperties.h"
+#include "base/Composition.h"
+#include "base/Event.h"
+#include "base/Instrument.h"
+#include "base/MidiProgram.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "base/SnapGrid.h"
+#include "base/Staff.h"
+#include "base/Track.h"
+#include "base/ViewElement.h"
+#include "base/SegmentMatrixHelper.h"
+#include "document/RosegardenGUIDoc.h"
+#include "gui/general/GUIPalette.h"
+#include "gui/general/LinedStaff.h"
+#include "gui/rulers/DefaultVelocityColour.h"
+#include "MatrixElement.h"
+#include "MatrixView.h"
+#include "MatrixVLayout.h"
+#include <qcanvas.h>
+
+
+namespace Rosegarden
+{
+
+MatrixStaff::MatrixStaff(QCanvas *canvas,
+ Segment *segment,
+ SnapGrid *snapGrid,
+ int id,
+ int vResolution,
+ MatrixView *view) :
+ LinedStaff(canvas, segment, snapGrid, id, vResolution, 1),
+ m_scaleFactor(2.0 /
+ Note(Note::Shortest).getDuration()),
+ m_view(view)
+{}
+
+MatrixStaff::~MatrixStaff()
+{
+ // nothing
+}
+
+int MatrixStaff::getLineCount() const
+{
+ // MATRIX_DEBUG << "MatrixStaff::getLineCount: isDrumMode " << m_view->isDrumMode() << ", key mapping " << (getKeyMapping() ? getKeyMapping()->getName() : "<none>") << endl;
+
+ if (m_view->isDrumMode()) {
+ const MidiKeyMapping *km = getKeyMapping();
+ if (km)
+ return km->getPitchExtent() + 1;
+ }
+ return MatrixVLayout::maxMIDIPitch + 2;
+}
+
+int MatrixStaff::getLegerLineCount() const
+{
+ return 0;
+}
+
+int MatrixStaff::getBottomLineHeight() const
+{
+ if (m_view->isDrumMode()) {
+ const MidiKeyMapping *km = getKeyMapping();
+ if (km)
+ return km->getPitchForOffset(0);
+ }
+ return 0;
+}
+
+int MatrixStaff::getHeightPerLine() const
+{
+ return 1;
+}
+
+bool MatrixStaff::elementsInSpaces() const
+{
+ return true;
+}
+
+bool MatrixStaff::showBeatLines() const
+{
+ return true;
+}
+
+bool MatrixStaff::wrapEvent(Event* e)
+{
+ // Changed from "Note or Time signature" to just "Note" because
+ // there should be no time signature events in any ordinary
+ // segments, they're only in the composition's ref segment
+
+ return e->isa(Note::EventType) &&
+ Staff::wrapEvent(e);
+}
+
+void
+MatrixStaff::positionElements(timeT from, timeT to)
+{
+ MatrixElementList *mel = getViewElementList();
+
+ MatrixElementList::iterator beginAt = mel->findTime(from);
+ if (beginAt != mel->begin())
+ --beginAt;
+
+ MatrixElementList::iterator endAt = mel->findTime(to);
+
+ for (MatrixElementList::iterator i = beginAt; i != endAt; ++i) {
+ positionElement(*i);
+ }
+}
+
+void MatrixStaff::positionElement(ViewElement* vel)
+{
+ MatrixElement* el = dynamic_cast<MatrixElement*>(vel);
+
+ // Memorize initial rectangle position. May be some overlap rectangles
+ // belonging to other notes are here and should be refreshed after
+ // current element is moved.
+ QRect initialRect;
+ bool rectWasVisible;
+ if (! m_view->isDrumMode())
+ rectWasVisible = el->getVisibleRectangle(initialRect);
+
+ LinedStaffCoords coords = getCanvasCoordsForLayoutCoords
+ (el->getLayoutX(), int(el->getLayoutY()));
+
+ // Get velocity for colouring
+ //
+ using BaseProperties::VELOCITY;
+ long velocity = 127;
+ if (el->event()->has(VELOCITY))
+ el->event()->get
+ <Int>(VELOCITY, velocity);
+
+ el->setCanvas(m_canvas);
+
+ // Is the event currently selected? Colour accordingly.
+ //
+ EventSelection *selection = m_view->getCurrentSelection();
+
+ if (selection && selection->contains(el->event()))
+ el->setColour(GUIPalette::getColour(GUIPalette::SelectedElement));
+ else if (el->event()->has(BaseProperties::TRIGGER_SEGMENT_ID))
+ el->setColour(Qt::gray);
+ else
+ el->setColour(DefaultVelocityColour::getInstance()->getColour(velocity));
+
+ el->setCanvasX(coords.first);
+ el->setCanvasY((double)coords.second);
+
+ // Display overlaps
+ if (m_view->isDrumMode()) {
+ SegmentMatrixHelper helper(m_segment);
+ if (helper.isDrumColliding(el->event()))
+ el->setColour(GUIPalette::getColour(GUIPalette::MatrixOverlapBlock));
+ } else {
+ el->drawOverlapRectangles();
+
+ // Refresh other overlap rectangles
+ if (rectWasVisible) el->redrawOverlaps(initialRect);
+ }
+
+}
+
+MatrixElement*
+MatrixStaff::getElement(Event *event)
+{
+ ViewElementList::iterator i = findEvent(event);
+ if (i == m_viewElementList->end())
+ return 0;
+ return dynamic_cast<MatrixElement*>(*i);
+}
+
+void
+MatrixStaff::eventRemoved(const Segment *segment,
+ Event *event)
+{
+ LinedStaff::eventRemoved(segment, event);
+ m_view->handleEventRemoved(event);
+}
+
+ViewElement*
+MatrixStaff::makeViewElement(Event* e)
+{
+ return new MatrixElement(e, m_view->isDrumMode());
+}
+
+const MidiKeyMapping*
+MatrixStaff::getKeyMapping() const
+{
+ Composition *comp = getSegment().getComposition();
+ if (!comp)
+ return 0;
+ TrackId trackId = getSegment().getTrack();
+ Track *track = comp->getTrackById(trackId);
+ Instrument *instr = m_view->getDocument()->getStudio().
+ getInstrumentById(track->getInstrument());
+ if (!instr)
+ return 0;
+ return m_view->getKeyMapping();
+}
+
+
+}