summaryrefslogtreecommitdiffstats
path: root/src/gui/rulers/ControlRuler.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
commit145364a8af6a1fec06556221e66d4b724a62fc9a (patch)
tree53bd71a544008c518034f208d64c932dc2883f50 /src/gui/rulers/ControlRuler.cpp
downloadrosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz
rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/gui/rulers/ControlRuler.cpp')
-rw-r--r--src/gui/rulers/ControlRuler.cpp539
1 files changed, 539 insertions, 0 deletions
diff --git a/src/gui/rulers/ControlRuler.cpp b/src/gui/rulers/ControlRuler.cpp
new file mode 100644
index 0000000..12064f5
--- /dev/null
+++ b/src/gui/rulers/ControlRuler.cpp
@@ -0,0 +1,539 @@
+/* -*- 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 "ControlRuler.h"
+
+#include "base/Event.h"
+#include "misc/Debug.h"
+#include "base/RulerScale.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "ControlChangeCommand.h"
+#include "ControlItem.h"
+#include "ControlSelector.h"
+#include "ControlTool.h"
+#include "DefaultVelocityColour.h"
+#include "ElementAdapter.h"
+#include "gui/general/EditView.h"
+#include "gui/general/RosegardenCanvasView.h"
+#include "gui/widgets/TextFloat.h"
+#include <kmainwindow.h>
+#include <qcanvas.h>
+#include <qcolor.h>
+#include <qcursor.h>
+#include <qpoint.h>
+#include <qpopupmenu.h>
+#include <qscrollbar.h>
+#include <qscrollview.h>
+#include <qstring.h>
+#include <qwidget.h>
+#include <algorithm>
+
+
+namespace Rosegarden
+{
+
+const int ControlRuler::DefaultRulerHeight = 75;
+const int ControlRuler::MinItemHeight = 5;
+const int ControlRuler::MaxItemHeight = 64 + 5;
+const int ControlRuler::ItemHeightRange = 64;
+
+ControlRuler::ControlRuler(Segment *segment,
+ RulerScale* rulerScale,
+ EditViewBase* parentView,
+ QCanvas* c, QWidget* parent,
+ const char* name, WFlags f) :
+ RosegardenCanvasView(c, parent, name, f),
+ m_parentEditView(parentView),
+ m_mainHorizontalScrollBar(0),
+ m_rulerScale(rulerScale),
+ m_eventSelection(new EventSelection(*segment)),
+ m_segment(segment),
+ m_currentItem(0),
+ m_tool(0),
+ m_maxItemValue(127),
+ m_staffOffset(0),
+ m_currentX(0.0),
+ m_itemMoved(false),
+ m_selecting(false),
+ m_selector(new ControlSelector(this)),
+ m_selectionRect(new QCanvasRectangle(canvas())),
+ m_menu(0)
+{
+ setHScrollBarMode(QScrollView::AlwaysOff);
+
+ m_selectionRect->setPen(Qt::red);
+
+ setFixedHeight(sizeHint().height());
+
+ connect(this, SIGNAL(stateChange(const QString&, bool)),
+ m_parentEditView, SLOT(slotStateChanged(const QString&, bool)));
+
+ m_numberFloat = new TextFloat(this);
+ m_numberFloat->hide();
+
+ m_segment->addObserver(this);
+
+ emit stateChange("have_controller_item_selected", false);
+}
+
+ControlRuler::~ControlRuler()
+{
+ if (m_segment) {
+ m_segment->removeObserver(this);
+ }
+}
+
+void ControlRuler::slotUpdate()
+{
+ RG_DEBUG << "ControlRuler::slotUpdate()\n";
+
+ canvas()->setAllChanged(); // TODO: be a bit more subtle, call setChanged(<time area>)
+
+ canvas()->update();
+ repaint();
+}
+
+void ControlRuler::slotUpdateElementsHPos()
+{
+ computeStaffOffset();
+
+ QCanvasItemList list = canvas()->allItems();
+
+ QCanvasItemList::Iterator it = list.begin();
+ for (; it != list.end(); ++it) {
+ ControlItem* item = dynamic_cast<ControlItem*>(*it);
+ if (!item)
+ continue;
+ layoutItem(item);
+ }
+
+ canvas()->update();
+}
+
+void ControlRuler::layoutItem(ControlItem* item)
+{
+ timeT itemTime = item->getElementAdapter()->getTime();
+
+ double x = m_rulerScale->getXForTime(itemTime);
+
+ item->setX(x + m_staffOffset);
+ int itemElementDuration = item->getElementAdapter()->getDuration();
+
+ int width = int(m_rulerScale->getXForTime(itemTime + itemElementDuration) - x);
+
+ item->setWidth(width);
+
+ // RG_DEBUG << "ControlRuler::layoutItem ControlItem x = " << x << " - width = " << width << endl;
+}
+
+void ControlRuler::setControlTool(ControlTool* tool)
+{
+ if (m_tool)
+ delete m_tool;
+ m_tool = tool;
+}
+
+void
+ControlRuler::segmentDeleted(const Segment *)
+{
+ m_segment = 0;
+}
+
+void ControlRuler::contentsMousePressEvent(QMouseEvent* e)
+{
+ if (e->button() != Qt::LeftButton) {
+ m_numberFloat->hide();
+ m_selecting = false;
+ return ;
+ }
+
+ RG_DEBUG << "ControlRuler::contentsMousePressEvent()\n";
+
+ QPoint p = inverseMapPoint(e->pos());
+
+ QCanvasItemList l = canvas()->collisions(p);
+
+ if (l.count() == 0) { // de-select current item
+ clearSelectedItems();
+ m_selecting = true;
+ m_selector->handleMouseButtonPress(e);
+ RG_DEBUG << "ControlRuler::contentsMousePressEvent : entering selection mode\n";
+ return ;
+ }
+
+ // clear selection unless control was pressed, in which case
+ // add the event to the current selection
+ if (!(e->state() && QMouseEvent::ControlButton)) {
+ clearSelectedItems();
+ }
+
+ ControlItem *topItem = 0;
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+
+ if (ControlItem *item = dynamic_cast<ControlItem*>(*it)) {
+
+ if (topItem == 0)
+ topItem = item;
+
+ if (item->isSelected()) { // if the item which was clicked
+ // on is part of a selection,
+ // propagate mousepress on all
+ // selected items
+
+ item->handleMouseButtonPress(e);
+
+ for (QCanvasItemList::Iterator it = m_selectedItems.begin();
+ it != m_selectedItems.end(); ++it) {
+ if (ControlItem *selectedItem =
+ dynamic_cast<ControlItem*>(*it)) {
+ selectedItem->handleMouseButtonPress(e);
+ }
+ }
+
+
+ } else { // select it
+
+ if (!(e->state() && QMouseEvent::ControlButton)) {
+ if (item->z() > topItem->z())
+ topItem = item;
+
+ } else {
+ m_selectedItems << item;
+ item->setSelected(true);
+ item->handleMouseButtonPress(e);
+ ElementAdapter* adapter = item->getElementAdapter();
+ m_eventSelection->addEvent(adapter->getEvent());
+ }
+ }
+ }
+ }
+
+ if (topItem && !m_selectedItems.contains(topItem)) { // select the top item
+ m_selectedItems << topItem;
+ topItem->setSelected(true);
+ topItem->handleMouseButtonPress(e);
+ ElementAdapter* adapter = topItem->getElementAdapter();
+ m_eventSelection->addEvent(adapter->getEvent());
+ }
+
+ m_itemMoved = false;
+ m_lastEventPos = p;
+}
+
+void ControlRuler::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ if (e->button() != Qt::LeftButton) {
+ m_numberFloat->hide();
+ m_selecting = false;
+ return ;
+ }
+
+ if (m_selecting) {
+ updateSelection();
+ m_selector->handleMouseButtonRelease(e);
+ RG_DEBUG << "ControlRuler::contentsMouseReleaseEvent : leaving selection mode\n";
+ m_selecting = false;
+ return ;
+ }
+
+ for (QCanvasItemList::Iterator it = m_selectedItems.begin(); it != m_selectedItems.end(); ++it) {
+ if (ControlItem *item = dynamic_cast<ControlItem*>(*it)) {
+
+ ElementAdapter * adapter = item->getElementAdapter();
+ m_eventSelection->addEvent(adapter->getEvent());
+ item->handleMouseButtonRelease(e);
+ }
+ }
+
+ emit stateChange("have_controller_item_selected", true);
+
+ if (m_itemMoved) {
+
+ m_lastEventPos = inverseMapPoint(e->pos());
+
+ // Add command to history
+ ControlChangeCommand* command = new ControlChangeCommand(m_selectedItems,
+ *m_segment,
+ m_eventSelection->getStartTime(),
+ m_eventSelection->getEndTime());
+
+ RG_DEBUG << "ControlRuler::contentsMouseReleaseEvent : adding command\n";
+ m_parentEditView->addCommandToHistory(command);
+
+ m_itemMoved = false;
+ }
+
+ m_numberFloat->hide();
+}
+
+void ControlRuler::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ QPoint p = inverseMapPoint(e->pos());
+
+ int deltaX = p.x() - m_lastEventPos.x(),
+ deltaY = p.y() - m_lastEventPos.y();
+ m_lastEventPos = p;
+
+ if (m_selecting) {
+ updateSelection();
+ m_selector->handleMouseMove(e, deltaX, deltaY);
+ slotScrollHorizSmallSteps(p.x());
+ return ;
+ }
+
+ m_itemMoved = true;
+
+ // Borrowed from Rotary - compute total position within window
+ //
+ QPoint totalPos = mapTo(topLevelWidget(), QPoint(0, 0));
+
+ int scrollX = dynamic_cast<EditView*>(m_parentEditView)->getRawCanvasView()->
+ horizontalScrollBar()->value();
+
+ /*
+ RG_DEBUG << "ControlRuler::contentsMouseMoveEvent - total pos = " << totalPos.x()
+ << ",e pos = " << e->pos().x()
+ << ", scroll bar = " << scrollX
+ << endl;
+ */
+
+ // Allow for scrollbar
+ //
+ m_numberFloat->move(totalPos.x() + e->pos().x() - scrollX + 20,
+ totalPos.y() + e->pos().y() - 10);
+
+ int value = 0;
+
+ for (QCanvasItemList::Iterator it = m_selectedItems.begin(); it != m_selectedItems.end(); ++it) {
+ if (ControlItem *item = dynamic_cast<ControlItem*>(*it)) {
+ item->handleMouseMove(e, deltaX, deltaY);
+ // ElementAdapter* adapter = item->getElementAdapter();
+
+ // set value to highest in selection
+ if (item->getValue() >= value) {
+ value = item->getValue();
+ m_numberFloat->setText(QString("%1").arg(value));
+ }
+ }
+ }
+ canvas()->update();
+
+ m_numberFloat->show();
+
+}
+
+void
+ControlRuler::contentsWheelEvent(QWheelEvent *e)
+{
+ // not sure what to do yet
+ QCanvasView::contentsWheelEvent(e);
+}
+
+void ControlRuler::updateSelection()
+{
+ clearSelectedItems();
+
+ bool haveSelectedItems = false;
+
+ QCanvasItemList l = getSelectionRectangle()->collisions(true);
+
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+
+ if (ControlItem *item = dynamic_cast<ControlItem*>(*it)) {
+ item->setSelected(true);
+ m_selectedItems << item;
+ haveSelectedItems = true;
+
+ ElementAdapter* adapter = item->getElementAdapter();
+ m_eventSelection->addEvent(adapter->getEvent());
+ }
+ }
+
+ emit stateChange("have_controller_item_selected", haveSelectedItems);
+}
+
+void ControlRuler::contentsContextMenuEvent(QContextMenuEvent* e)
+{
+ if (!m_menu && !m_menuName.isEmpty())
+ createMenu();
+
+ if (m_menu) {
+ RG_DEBUG << "ControlRuler::showMenu() - show menu with" << m_menu->count() << " items\n";
+ m_lastEventPos = inverseMapPoint(e->pos());
+ m_menu->exec(QCursor::pos());
+ } else
+ RG_DEBUG << "ControlRuler::showMenu() : no menu to show\n";
+
+}
+
+void ControlRuler::createMenu()
+{
+ RG_DEBUG << "ControlRuler::createMenu()\n";
+
+ KMainWindow* parentMainWindow = dynamic_cast<KMainWindow*>(topLevelWidget());
+
+ if (parentMainWindow && parentMainWindow->factory()) {
+ m_menu = static_cast<QPopupMenu*>(parentMainWindow->factory()->container(m_menuName, parentMainWindow));
+
+ if (!m_menu) {
+ RG_DEBUG << "ControlRuler::createMenu() failed\n";
+ }
+ } else {
+ RG_DEBUG << "ControlRuler::createMenu() failed: no parent factory\n";
+ }
+}
+
+void
+ControlRuler::clearSelectedItems()
+{
+ for (QCanvasItemList::Iterator it = m_selectedItems.begin(); it != m_selectedItems.end(); ++it) {
+ (*it)->setSelected(false);
+ }
+ m_selectedItems.clear();
+
+ delete m_eventSelection;
+ m_eventSelection = new EventSelection(*m_segment);
+}
+
+void ControlRuler::clear()
+{
+ QCanvasItemList allItems = canvas()->allItems();
+
+ for (QCanvasItemList::Iterator it = allItems.begin(); it != allItems.end(); ++it) {
+ if (ControlItem *item = dynamic_cast<ControlItem*>(*it)) {
+ delete item;
+ }
+ }
+}
+
+int ControlRuler::valueToHeight(long val)
+{
+ long scaleVal = val * (ItemHeightRange);
+
+ int res = -(int(scaleVal / getMaxItemValue()) + MinItemHeight);
+
+ //RG_DEBUG << "ControlRuler::valueToHeight : val = " << val << " - height = " << res
+ //<< " - scaleVal = " << scaleVal << endl;
+
+ return res;
+}
+
+long ControlRuler::heightToValue(int h)
+{
+ long val = -h;
+ val -= MinItemHeight;
+ val *= getMaxItemValue();
+ val /= (ItemHeightRange);
+ val = std::min(val, long(getMaxItemValue()));
+ return val;
+}
+
+QColor ControlRuler::valueToColour(int max, int val)
+{
+ int maxDefault = DefaultVelocityColour::getInstance()->getMaxValue();
+
+ int value = val;
+
+ // Scale value accordingly
+ //
+ if (maxDefault != max)
+ value = int(double(maxDefault) * double(val) / double(max));
+
+ return DefaultVelocityColour::getInstance()->getColour(value);
+}
+
+int ControlRuler::applyTool(double x, int val)
+{
+ if (m_tool)
+ return (*m_tool)(x, val);
+ return val;
+}
+
+void ControlRuler::flipForwards()
+{
+ std::pair<int, int> minMax = getZMinMax();
+
+ QCanvasItemList l = canvas()->allItems();
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+
+ // skip all but rectangles
+ if ((*it)->rtti() != QCanvasItem::Rtti_Rectangle)
+ continue;
+
+ // match min
+ if ((*it)->z() == minMax.second)
+ (*it)->setZ(minMax.first);
+ else
+ (*it)->setZ((*it)->z() + 1);
+ }
+
+ canvas()->update();
+}
+
+void ControlRuler::flipBackwards()
+{
+ std::pair<int, int> minMax = getZMinMax();
+
+ QCanvasItemList l = canvas()->allItems();
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+
+ // skip all but rectangles
+ if ((*it)->rtti() != QCanvasItem::Rtti_Rectangle)
+ continue;
+
+ // match min
+ if ((*it)->z() == minMax.first)
+ (*it)->setZ(minMax.second);
+ else
+ (*it)->setZ((*it)->z() - 1);
+ }
+
+ canvas()->update();
+}
+
+std::pair<int, int> ControlRuler::getZMinMax()
+{
+ QCanvasItemList l = canvas()->allItems();
+ std::vector<int> zList;
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+
+ // skip all but rectangles
+ if ((*it)->rtti() != QCanvasItem::Rtti_Rectangle) continue;
+ zList.push_back(int((*it)->z()));
+ }
+
+ std::sort(zList.begin(), zList.end());
+
+ return std::pair<int, int>(zList[0], zList[zList.size() - 1]);
+}
+
+QScrollBar* ControlRuler::getMainHorizontalScrollBar()
+{
+ return m_mainHorizontalScrollBar ? m_mainHorizontalScrollBar : horizontalScrollBar();
+}
+
+}
+#include "ControlRuler.moc"