void PropertyControlRuler::updateSelection(std::vector <ViewElement*> *elementList) { // Use base class fcn to set each item as not selected, clear the m_selectedItems lsit // and create a new m_eventSelection member clearSelectedItems(); // For now, simply clear the selected items list and build it afresh PropertyControlItem *item = 0; // for (ControlItemList::iterator it = m_selectedItems.begin(); it != m_selectedItems.end(); ++it) { // item = dynamic_cast <PropertyControlItem *> (*it); // if (item) item->setSelected(false); // } // // m_selectedItems.clear(); for (std::vector<ViewElement*>::iterator elit = elementList->begin(); elit != elementList->end();++elit) { for (ControlItemMap::iterator it = m_controlItemMap.begin(); it != m_controlItemMap.end(); ++it) { item = dynamic_cast<PropertyControlItem*>(it->second); if (item) { if (item->getElement() == (*elit)) { break; } else { item = 0; } } } if (!item) continue; item->setSelected(true); m_selectedItems.push_back(item); m_eventSelection->addEvent(item->getEvent()); } update(); }
ControlItem* ControllerEventsRuler::addControlItem(float x, float y) { // Adds a ControlItem in the absence of an event (used by ControlPainter) clearSelectedItems(); EventControlItem *item = new EventControlItem(this, new ControllerEventAdapter(0), QPolygonF()); item->reconfigure(x,y); item->setSelected(true); // m_selectedItems.push_back(item); // if (isVisible(item)) { // m_visibleItems.push_back(item); // } ControlRuler::addControlItem(item); return item; }
void FileTreeComponent::setSelectedFile (const File& target) { for (int i = getNumSelectedItems(); --i >= 0;) { FileListTreeItem* t = dynamic_cast <FileListTreeItem*> (getSelectedItem (i)); if (t != nullptr && t->file == target) { t->setSelected (true, true); return; } } clearSelectedItems(); }
void FileTreeComponent::deselectAllFiles() { clearSelectedItems(); }
void ControllerEventsRuler::addControlLine(float x1, float y1, float x2, float y2, bool eraseExistingControllers) { std::cout << "ControllerEventsRuler::addControlLine()"; clearSelectedItems(); // get a timeT for one end point of our line timeT originTime = m_rulerScale->getTimeForX(x1); // get a timeT for the other end point of our line timeT destinationTime = m_rulerScale->getTimeForX(x2); // get a value for one end point of our line long originValue = yToValue(y1); // get a value for the other end point long destinationValue = yToValue(y2); if (originTime == destinationTime || originValue == destinationValue) return; // If the "anchor point" was to the right of the newly clicked destination // point, we're drawing a line from right to left. We simply swap origin // for destination and calculate all lines as drawn from left to right, for // convenience and sanity. if (originTime > destinationTime) { timeT swapTime = originTime; originTime = destinationTime; destinationTime = swapTime; long swapValue = originValue; originValue = destinationValue; destinationValue = swapValue; } // save a list of existing events that occur within the span of the new line // for later deletion, if desired std::vector<Event*> eventsToClear; if (eraseExistingControllers) { for (Segment::iterator si = m_segment->begin(); si != m_segment->end(); ++si) { timeT t = (*si)->getNotationAbsoluteTime(); if (t >= originTime && t <= destinationTime) { eventsToClear.push_back(*si); } } } // rise and run long rise = destinationValue - originValue; timeT run = destinationTime - originTime; std::cout << "Drawing a line from origin time: " << originTime << " to " << destinationTime << " rising from: " << originValue << " to " << destinationValue << " with a rise of: " << rise << " and run of: " << run << std::endl; // avoid divide by 0 potential, rise is always at least 1 if (rise == 0) rise = 1; // are we rising or falling? bool rising = (rise > 0); // always calculate step on a positive value for rise, and make sure it's at // least 1 float step = run / (float)(rising ? rise : rise * -1); // Trying this with pitch bend with a rise approaching the maximum over a // span of around four bars generated over 15,000 pitch bend events! That's // super duper fine resolution, but it's too much for anything to handle. // Let's try to do some sensible thinning without getting too complicated... // bool isPitchBend = (m_controller->getType() == Rosegarden::PitchBend::EventType); int thinningHackCounter = 1; long intermediateValue = originValue; long controllerNumber = 0; if (m_controller) { controllerNumber = m_controller->getControllerValue(); } else { std::cout << "No controller number set. Time to panic! Line drawing aborted." << std::endl; return; } MacroCommand *macro = new MacroCommand(tr("Insert Line of Controllers")); bool failsafe = false; // if we're clearing existing events, add that to the macro command for (std::vector<Event*>::iterator ei = eventsToClear.begin(); ei != eventsToClear.end(); ++ei) { // if the event was a controller or pitch bend, and it is on this ruler, // add it to the list if (((*ei)->isa(Controller::EventType) || (*ei)->isa(PitchBend::EventType)) && isOnThisRuler(*ei)) { bool collapseRests = true; macro->addCommand(new EraseEventCommand(*m_segment, *ei, collapseRests)); } } if (macro->haveCommands()) { CommandHistory::getInstance()->addCommand(macro); macro = new MacroCommand(tr("Insert Line of Controllers")); } for (float i = originTime; i <= destinationTime; i += step) { if (failsafe) continue; if (rising) intermediateValue++; else intermediateValue--; if (rising && intermediateValue > destinationValue) failsafe = true; else if (!rising && intermediateValue < destinationValue) failsafe = true; // std::cout << "creating event at time: " << i << " of value: " << intermediateValue << std::endl; // continue; Event *controllerEvent = new Event(m_controller->getType(), (timeT) i); if (m_controller->getType() == Rosegarden::Controller::EventType) { controllerEvent->set<Rosegarden::Int>(Rosegarden::Controller::VALUE, intermediateValue); controllerEvent->set<Rosegarden::Int>(Rosegarden::Controller::NUMBER, controllerNumber); } else if (m_controller->getType() == Rosegarden::PitchBend::EventType) { // always set the first and last events, then only set every 25th, // 50th, and 75th event for pitch bend if (thinningHackCounter++ > 100) thinningHackCounter = 1; if (thinningHackCounter != 25 && thinningHackCounter != 50 && thinningHackCounter != 75 && i != originTime && i != destinationTime) continue; std::cout << "intermediate value: " << intermediateValue << std::endl; // Convert to PitchBend MSB/LSB int lsb = intermediateValue & 0x7f; int msb = (intermediateValue >> 7) & 0x7f; controllerEvent->set<Rosegarden::Int>(Rosegarden::PitchBend::MSB, msb); controllerEvent->set<Rosegarden::Int>(Rosegarden::PitchBend::LSB, lsb); } if (failsafe) std::cout << "intermediate value: " << intermediateValue << " exceeded target: " << destinationValue << std::endl; macro->addCommand(new EventInsertionCommand (*m_segment, controllerEvent)); } m_moddingSegment = true; CommandHistory::getInstance()->addCommand(macro); m_moddingSegment = false; // How else to re-initialize and bring things into view? I'm missing // something, but this works... init(); }