SequencerComponent::~SequencerComponent()
{
	for (int i = 0; i < sequencer->getTotalRows(); i++) {
		for (int j = 0; j < sequencer->getTotalCols(); j++) {
			CellComponent* cell = getCellAt (i, j);
			cell->removeMouseListener (this);
		}
	}
	
	deleteAllChildren();
}
void SequencerComponent::resized()
{
	float cellWidth = (float)getWidth() / sequencer->getTotalCols();
	float cellHeight = (float)getHeight() / sequencer->getTotalRows();
	
	for (int i = 0; i < sequencer->getTotalRows(); i++) {
		for (int j = 0; j < sequencer->getTotalCols(); j++) {
			CellComponent* cell = getCellAt (i, j);
			cell->setBounds (j * cellWidth, i * cellHeight, cellWidth, cellHeight);
		}
	}
}
Beispiel #3
0
void Board::save(std::ostream& st) const
{
	for (int i = 0; i < getWidth(); ++i) {
		st << "|";
		for (int j = 0; j < getHeight(); ++j) {
			getCellAt(i, j)->save(st);
			st	<< "|";
		}
		if (i != getWidth()-1)
			st << std::endl;
	}
}
Beispiel #4
0
//prey.cc
void Prey::moveFrom(Coordinate from, Coordinate to) {
  Cell *toCell;
  --timeToReproduce;
  if (to != from) {
    toCell = getCellAt(to);
    delete toCell;
    setOffset(to);
    assignCellAt(to, this);
    if (timeToReproduce <= 0) {
      timeToReproduce = TimeToReproduce;
      assignCellAt(from, reproduce(from));
    }
    else
      assignCellAt(from, new Cell(from));
  }
}
QVariant PlotDataExtendedTableModel::data(const QModelIndex &index, int role) const {
    if (! data_)
        return QVariant();

    if (!index.isValid())
        return QVariant();

    if (index.row() >= rowCount(index) || index.row() < 0)
        return QVariant();

    if (index.row() == addLines_-1 && role == Qt::DisplayRole && addLines_ > 0 && showColumnType_) {
        int columntype = static_cast<int>(data_->getColumnType(index.column()));
        std::string ausgabe;
        switch (columntype) {
            case 1 : ausgabe = "STRING"; break;
            case 2 : ausgabe = "NUMBER"; break;
            default: ausgabe = "EMPTY"; break;
        }
        return QVariant(QString::fromStdString(ausgabe));
    }
    if (index.row() == 0 && role == Qt::DisplayRole && (type_ == FunctionLibrary::SELECT || type_ == FunctionLibrary::GROUPBY)) {
        for (size_t i = 0; i < stringVector_.size(); ++i) {
            if (stringVector_.at(i).first == index.column()) {
                return QVariant(QString::fromStdString(stringVector_.at(i).second));
                break;
            }
        }
        return QVariant("");
    }

    if (role == Qt::TextAlignmentRole && index.row() < addLines_) {
        return QVariant(Qt::AlignRight | Qt::AlignVCenter);
    }

    if (index.row() < addLines_ && (role == Qt::DisplayRole || role == Qt::BackgroundColorRole))
        return QVariant();

    if ((index.row() >=  addLines_) && (role == Qt::DisplayRole))
        return getCellAt(index.row(), index.column());

    return PlotDataSimpleTableModel::data(index,role);
}
// Timer methods
void SequencerComponent::timerCallback()
{
	lastPlayheadCol = sequencer->getPlayheadCol();
	repaint();
	
	if (lastPanelIndex != pluginAudioProcessor->getPanelIndex() 
		|| lastTabIndex != pluginAudioProcessor->getTabIndex()) {
		lastPanelIndex = pluginAudioProcessor->getPanelIndex();
		lastTabIndex = pluginAudioProcessor->getTabIndex();
		
		for (int i = 0; i < sequencer->getTotalRows(); i++) {
			for (int j = 0; j < sequencer->getTotalCols(); j++) {
				CellComponent* cellComponent = getCellAt (i, j);
				Cell* cell = sequencer->getCellAt (lastPanelIndex, lastTabIndex, 
												   i, j);
				cellComponent->setCell (cell);
			}
		}		
	}
}
QVariant PlotDataSimpleTableModel::data(const QModelIndex &index, int role) const {
    if (! pData_)
        return QVariant();


    if (!index.isValid())
        return QVariant();

    if (index.row() >= rowCount(index) || index.row() < 0)
        return QVariant();

    if (role == Qt::TextAlignmentRole) {
        if (pData_->getColumnType(index.column()) == PlotBase::NUMBER)
            return QVariant(Qt::AlignRight | Qt::AlignVCenter);
        if (pData_->getColumnType(index.column()) == PlotBase::STRING)
            return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
        return QVariant(Qt::AlignCenter);
    }

    if (role == Qt::DisplayRole)
        return getCellAt(index.row(), index.column());

    if (role == Qt::BackgroundColorRole && getPlotCellAt(index.row(),index.column()).isHighlighted()) {
        return highlightedColor_;
    }
    else if (role == Qt::BackgroundColorRole && selectedColumn_ == index.column()) {
        return selectColumnColor_;
    }
    else if (role == Qt::BackgroundColorRole && pData_->getKeyColumnCount() > index.column()) {
        return keyColumnColor_;
    }
    else if (role == Qt::BackgroundColorRole && pData_->getKeyColumnCount() <= index.column()) {
        return dataColumnColor_;
    }

    return QVariant();
}
void Sequencer::processBlock (AudioSampleBuffer& buffer,
                              MidiBuffer& midiMessages)
{
	AudioPlayHead::CurrentPositionInfo pos (pluginAudioProcessor->lastPosInfo);	
	
	// If we aren't playing...
	if (! pos.isPlaying) {
		if (noteOffs.size() > 0) {
			// Send any upcoming note-off events
			Array<NoteOff*> notesToRemove; 
			for (int i = 0; i < noteOffs.size(); i++) {
				int noteNumber = noteOffs[i]->noteNumber;
				MidiMessage m2 = MidiMessage::noteOff (1, noteNumber);
				midiMessages.addEvent (m2, 0);			
				playingNotes.set (noteNumber, false);

				notesToRemove.add (noteOffs[i]);
			}
			for (int i = 0; i < notesToRemove.size(); i++) {
				// Remove the event from the note-off event list
				// (We do this in two steps so that the noteOffs array isn't modified inside a loop)
				noteOffs.removeObject (notesToRemove[i], true);
			}			
		}
		return;
	}
	
	double ppq = pos.ppqPosition;
	double timeInSeconds = pos.timeInSeconds;
	double bpm = pos.bpm;
	//if (primary) {
		SharedState::getInstance()->setPpqPosition (ppq);
		SharedState::getInstance()->setTimeInSeconds (timeInSeconds);
		SharedState::getInstance()->setBpm (bpm);
	//}
	
	/*
	 int numerator = pos.timeSigNumerator;
	 int denominator = pos.timeSigDenominator;
	 
	 const int ppqPerBar = (numerator * 4 / denominator); // e.g. 4 if 4/4
	 const double beats = (fmod (ppq, ppqPerBar) / ppqPerBar) * numerator;
	 
	 const int bar = ((int) ppq) / ppqPerBar + 1;
	 const int beat = ((int) beats) + 1;
	 const int ticks = ((int) (fmod (beats, 1.0) * 960.0));	
	 */
	
	double tickCountPrecise = fmod (ppq * speed * ticksPerCol, getTotalCols() * ticksPerCol);
	tickCount = (int)tickCountPrecise;
	
	lastPlayheadColPrecise = tickCountPrecise / ticksPerCol;
	jassert (lastPlayheadColPrecise >= 0.0)
	jassert (lastPlayheadColPrecise <= 16.0)
	//if (primary) {
		SharedState::getInstance()->setPlayheadColPrecise (lastPlayheadColPrecise);
	//}		
	
	if (tickCount != lastTickCount) {
		lastTickCount = tickCount;
		
		// Check if we should be degrading...
		int panelIndex = pluginAudioProcessor->getPanelIndex();
      int state = SharedState::getInstance()->getState(panelIndex);
      if (state == Panel::DEGRADING_SLOW ||
          state == Panel::DEGRADING_FAST) {
         // degrade at most once per tempo sweep, in column 0
         if (getPlayheadCol() == 0) {
            if (!columnZeroDegradeUpdate) {
               SharedState::getInstance()->degradeStep(panelIndex);
               columnZeroDegradeUpdate = true;
            }
         } else {
            columnZeroDegradeUpdate = false;
         }
      } else {
         columnZeroDegradeUpdate = false;
         if (state == Panel::ACTIVE) {
            if (SharedState::kDegradeAfterInactiveSec > 0 &&
                (SharedState::getInstance()->getLastTouchElapsedMs(panelIndex) >= 
                 SharedState::kDegradeAfterInactiveSec * 1000)) {
               DBG(String(Time::currentTimeMillis()) + " "
                   + "Start degrading panel " + String(panelIndex));
               SharedState::getInstance()->startDegrade(panelIndex);
            }
         }
      }
		
		// Update starfield if necessary
		if (SharedState::getInstance()->getStarFieldActive()) {
         // bug:67 - for production running, we could assert that the following is true:
         //    SharedState::getInstance()->allAttracting()
         // but that won't work if someone turns on the star field by hand via the sequencer GUI
			if (pluginAudioProcessor->getPanelIndex() == 0) {
				SharedState::getInstance()->updateStarField();
			}
		}
		
		bool playCol = false;  // play the current column of notes?
		float velocity = 0.9f;		
		
		// Swing...
		// If we're on an odd column
		if (getPlayheadCol() % 2 != 0) {
			// If we've waited for enough ticks for the swing
			if (tickCount == (getPlayheadCol() * ticksPerCol) + swingTicks) {
				playCol = true;
			}
		} else {
			// Else we're on an even column
			// If we're on the first tick of the column...
			if (tickCount % ticksPerCol == 0) {
				playCol = true;
			}
		}
		
		// Calculate the latency
		double beatsPerSec = bpm * speed * ticksPerCol / 60.0;
		double secPerBeat = 1.0 / beatsPerSec;	
		
		double tickOffset = tickCountPrecise - tickCount;
		int tickOffsetSamples = tickOffset * secPerBeat * sampleRate;
		tickOffsetSamples = jmax (buffer.getNumSamples() - tickOffsetSamples - 1, 0);
		
		// Send any upcoming note-off events
		Array<NoteOff*> notesToRemove; 
		for (int i = 0; i < noteOffs.size(); i++) {
			if (noteOffs[i]->tick == tickCount) {
				int noteNumber = noteOffs[i]->noteNumber;
				MidiMessage m2 = MidiMessage::noteOff (1, noteNumber);
				midiMessages.addEvent (m2, tickOffsetSamples);			
				playingNotes.set (noteNumber, false);

				notesToRemove.add (noteOffs[i]);
			}
		}
		for (int i = 0; i < notesToRemove.size(); i++) {
			// Remove the event from the note-off event list
			// (We do this in two steps so that the noteOffs array isn't modified inside a loop)
			noteOffs.removeObject (notesToRemove[i], true);
		}		
		
		// If we should play the current column of notes
		if (playCol) {
			int panelIndex = pluginAudioProcessor->getPanelIndex();
			int tabIndex = pluginAudioProcessor->getTabIndex();

			for (int i = 0; i < getTotalRows(); i++) {
				Cell* cell = getCellAt (panelIndex, tabIndex, i, getPlayheadCol());
            if (cell->isOn()) {
               int noteNumber = cell->getNoteNumber();
					// If this note is currently playing
					if (playingNotes[noteNumber] == true) {
						Array<NoteOff*> notesToRemove;
						// Remove any pending note-offs
						for (int j = 0; j < noteOffs.size(); j++) {
							if (noteOffs[j]->noteNumber == noteNumber) {
								notesToRemove.add (noteOffs[j]);
							}
						}
						for (int j = 0; j < notesToRemove.size(); j++) {
							noteOffs.removeObject (notesToRemove[j], true);
						}
						// Send a note-off before retriggering
						MidiMessage m = MidiMessage::noteOff (1, noteNumber);
						midiMessages.addEvent (m, tickOffsetSamples);
						playingNotes.set (noteNumber, false);

					}
					// Play this note
					MidiMessage m = MidiMessage::noteOn (1, noteNumber, velocity);
					midiMessages.addEvent (m, tickOffsetSamples);
					playingNotes.set (noteNumber, true);
					
					// Add an upcoming note-off event
					NoteOff* no;
					noteOffs.add (no = new NoteOff());
					no->tick = (tickCount + noteLength) % (ticksPerCol * getTotalCols());
					no->noteNumber = noteNumber;
				}
			}
		}
	}
}
Beispiel #9
0
bool GUITable::OnEvent(const SEvent &event)
{
	if (!isEnabled())
		return IGUIElement::OnEvent(event);

	if (event.EventType == EET_KEY_INPUT_EVENT) {
		if (event.KeyInput.PressedDown && (
				event.KeyInput.Key == KEY_DOWN ||
				event.KeyInput.Key == KEY_UP   ||
				event.KeyInput.Key == KEY_HOME ||
				event.KeyInput.Key == KEY_END  ||
				event.KeyInput.Key == KEY_NEXT ||
				event.KeyInput.Key == KEY_PRIOR)) {
			s32 offset = 0;
			switch (event.KeyInput.Key) {
				case KEY_DOWN:
					offset = 1;
					break;
				case KEY_UP:
					offset = -1;
					break;
				case KEY_HOME:
					offset = - (s32) m_visible_rows.size();
					break;
				case KEY_END:
					offset = m_visible_rows.size();
					break;
				case KEY_NEXT:
					offset = AbsoluteRect.getHeight() / m_rowheight;
					break;
				case KEY_PRIOR:
					offset = - (s32) (AbsoluteRect.getHeight() / m_rowheight);
					break;
				default:
					break;
			}
			s32 old_selected = m_selected;
			s32 rowcount = m_visible_rows.size();
			if (rowcount != 0) {
				m_selected = rangelim(m_selected + offset, 0, rowcount-1);
				autoScroll();
			}

			if (m_selected != old_selected)
				sendTableEvent(0, false);

			return true;
		}
		else if (event.KeyInput.PressedDown && (
				event.KeyInput.Key == KEY_LEFT ||
				event.KeyInput.Key == KEY_RIGHT)) {
			// Open/close subtree via keyboard
			if (m_selected >= 0) {
				int dir = event.KeyInput.Key == KEY_LEFT ? -1 : 1;
				toggleVisibleTree(m_selected, dir, true);
			}
			return true;
		}
		else if (!event.KeyInput.PressedDown && (
				event.KeyInput.Key == KEY_RETURN ||
				event.KeyInput.Key == KEY_SPACE)) {
			sendTableEvent(0, true);
			return true;
		}
		else if (event.KeyInput.Key == KEY_ESCAPE ||
				event.KeyInput.Key == KEY_SPACE) {
			// pass to parent
		}
		else if (event.KeyInput.PressedDown && event.KeyInput.Char) {
			// change selection based on text as it is typed
			s32 now = getTimeMs();
			if (now - m_keynav_time >= 500)
				m_keynav_buffer = L"";
			m_keynav_time = now;

			// add to key buffer if not a key repeat
			if (!(m_keynav_buffer.size() == 1 &&
					m_keynav_buffer[0] == event.KeyInput.Char)) {
				m_keynav_buffer.append(event.KeyInput.Char);
			}

			// find the selected item, starting at the current selection
			// don't change selection if the key buffer matches the current item
			s32 old_selected = m_selected;
			s32 start = MYMAX(m_selected, 0);
			s32 rowcount = m_visible_rows.size();
			for (s32 k = 1; k < rowcount; ++k) {
				s32 current = start + k;
				if (current >= rowcount)
					current -= rowcount;
				if (doesRowStartWith(getRow(current), m_keynav_buffer)) {
					m_selected = current;
					break;
				}
			}
			autoScroll();
			if (m_selected != old_selected)
				sendTableEvent(0, false);

			return true;
		}
	}
	if (event.EventType == EET_MOUSE_INPUT_EVENT) {
		core::position2d<s32> p(event.MouseInput.X, event.MouseInput.Y);

		if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
			m_scrollbar->setPos(m_scrollbar->getPos() +
					(event.MouseInput.Wheel < 0 ? -3 : 3) *
					- (s32) m_rowheight / 2);
			return true;
		}

		// Find hovered row and cell
		bool really_hovering = false;
		s32 row_i = getRowAt(p.Y, really_hovering);
		const Cell *cell = NULL;
		if (really_hovering) {
			s32 cell_j = getCellAt(p.X, row_i);
			if (cell_j >= 0)
				cell = &(getRow(row_i)->cells[cell_j]);
		}

		// Update tooltip
		setToolTipText(cell ? m_strings[cell->tooltip_index].c_str() : L"");

		// Fix for #1567/#1806:
		// IGUIScrollBar passes double click events to its parent,
		// which we don't want. Detect this case and discard the event
		if (event.MouseInput.Event != EMIE_MOUSE_MOVED &&
				m_scrollbar->isVisible() &&
				m_scrollbar->isPointInside(p))
			return true;

		if (event.MouseInput.isLeftPressed() &&
				(isPointInside(p) ||
				 event.MouseInput.Event == EMIE_MOUSE_MOVED)) {
			s32 sel_column = 0;
			bool sel_doubleclick = (event.MouseInput.Event
					== EMIE_LMOUSE_DOUBLE_CLICK);
			bool plusminus_clicked = false;

			// For certain events (left click), report column
			// Also open/close subtrees when the +/- is clicked
			if (cell && (
					event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN ||
					event.MouseInput.Event == EMIE_LMOUSE_DOUBLE_CLICK ||
					event.MouseInput.Event == EMIE_LMOUSE_TRIPLE_CLICK)) {
				sel_column = cell->reported_column;
				if (cell->content_type == COLUMN_TYPE_TREE)
					plusminus_clicked = true;
			}

			if (plusminus_clicked) {
				if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
					toggleVisibleTree(row_i, 0, false);
				}
			}
			else {
				// Normal selection
				s32 old_selected = m_selected;
				m_selected = row_i;
				autoScroll();

				if (m_selected != old_selected ||
						sel_column >= 1 ||
						sel_doubleclick) {
					sendTableEvent(sel_column, sel_doubleclick);
				}

				// Treeview: double click opens/closes trees
				if (m_has_tree_column && sel_doubleclick) {
					toggleVisibleTree(m_selected, 0, false);
				}
			}
		}
		return true;
	}
	if (event.EventType == EET_GUI_EVENT &&
			event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED &&
			event.GUIEvent.Caller == m_scrollbar) {
		// Don't pass events from our scrollbar to the parent
		return true;
	}

	return IGUIElement::OnEvent(event);
}