diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/gui/rulers/ControlRuler.cpp | |
download | rosegarden-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.cpp | 539 |
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" |