コード例 #1
0
ファイル: wfxListCtrl.cpp プロジェクト: wxtnote/wfc
void ListCtrl::calcVirtualSize( Size& sz )
{
	setVirtualSizeCached();
	sz.empty();
	int nTotalRow = getTotalRows();
	for (int i = 0; i < nTotalRow; i++)
	{
		sz.cy += getRowHeight(i);
	}
	int nTotalCol = getTotalColumns();
	for (int i = 0; i < nTotalCol; i++)
	{
		sz.cx += getColumnWidth(i);
	}
}
コード例 #2
0
ファイル: wfxListCtrl.cpp プロジェクト: wxtnote/wfc
void ListCtrl::calcCellRect()
{
	WFX_CONDITION(m_nStartRow != -1);
	WFX_CONDITION(m_nEndRow != -1);
	WFX_CONDITION(m_nStartCol != -1);
	WFX_CONDITION(m_nEndCol != -1);
	WFX_CONDITION(m_nEndRow >= m_nStartRow);
	WFX_CONDITION(m_nEndCol >= m_nEndCol);
	m_rgRectFast.clear();
	m_rgRect.clear();
	m_rgRowNumRect.clear();
	ULONG nTotalRow = getTotalRows();
	ULONG nTotalCol = getTotalColumns();
	ULONG nSeqBarWidth = getRowNumBarWidth();
	ULONG nHeadHeight = getHeadHeight();
	Rect rcWid = getClientRect();
	Rect rcCell = rcWid;
	Rect rcRowNum = rcWid;
	ULONG nWidth = 0;
	ULONG nHeight = 0;
	rcRowNum.right = rcRowNum.left + nSeqBarWidth;
	rcCell.left += nSeqBarWidth + 1;
	rcCell.top += nHeadHeight + 1;
	m_rgRectFast.resize(m_nEndRow - m_nStartRow + 1);
	for (LONG nRow = m_nStartRow; nRow <= m_nEndRow; nRow++)
	{
		nHeight = getRowHeight(nRow);
		rcCell.bottom = rcCell.top + nHeight;
		rcRowNum.top = rcCell.top;
		rcRowNum.bottom = rcCell.bottom;
		m_rgRowNumRect.push_back(rcRowNum);
		if (rcCell.bottom > rcWid.bottom)
			rcCell.bottom = rcWid.bottom;
		m_rgRectFast[nRow - m_nStartRow].resize(m_nEndCol - m_nStartCol + 1);
		for (LONG nCol = m_nStartCol; nCol <= m_nEndCol; nCol++)
		{
			nWidth = getColumnWidth(nCol);
			rcCell.right = rcCell.left + nWidth;
			m_rgRect.insert(std::make_pair(CellID(nRow, nCol), rcCell));
			m_rgRectFast[nRow - m_nStartRow][nCol - m_nStartCol] = rcCell;
			rcCell.left += rcCell.right - rcCell.left;
		}
		rcCell.left = rcWid.left + nSeqBarWidth + 1;
		rcCell.top += rcCell.bottom - rcCell.top;
	}
}
コード例 #3
0
ファイル: wfxListCtrl.cpp プロジェクト: wxtnote/wfc
BOOL ListCtrl::calcRow()
{
	ULONG nOldStartRow = m_nStartRow;
	ULONG nOldEndRow = m_nEndRow;
	m_nStartRow = m_nEndRow = -1;
	Rect rcDraw = getClientRect();
	LONG nOffset = getVOffset();
	//TRACE(L"nOffset = %d", nOffset);
	ULONG nTotalRow = getTotalRows();
	LONG nSumHeight = 0;
	for (ULONG nRow = 0; nRow < nTotalRow; nRow++)
	{
		nSumHeight += getRowHeight(nRow);
		if (nSumHeight >= nOffset)
		{
			m_nStartRow = nRow;
			break;
		}
	}
	nSumHeight = 0;
	LONG nViewHeight = rcDraw.bottom - rcDraw.top;
	for (ULONG nRow = m_nStartRow; nRow < nTotalRow; nRow++)
	{
		nSumHeight += getRowHeight(nRow);
		if (nSumHeight > nViewHeight)
		{
			m_nEndRow = nRow;
			break;
		}
	}

	if (nSumHeight <= nViewHeight)
	{
		m_nEndRow = nTotalRow - 1;
	}
	//TRACE(L"m_nStartRow = %d", m_nStartRow);
	//TRACE(L"m_nEndRow = %d", m_nEndRow);
	return (m_nStartRow != nOldStartRow || m_nEndRow != nOldEndRow);
}
コード例 #4
0
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;
				}
			}
		}
	}
}
コード例 #5
0
ファイル: wfxListCtrl.cpp プロジェクト: wxtnote/wfc
void ListCtrl::onDraw( HDC hdc, const Rect& rcPaint )
{
	Rect rc = getRect();
	if (!verify())
	{
		WfxRender::drawFrame(hdc, rc, WBTN_BKGND_MOUSE, getDispatcher());
		return;
	}
	LCDrawItemInfo* pDrawItemInfo = getDrawItemInfo();
	pDrawItemInfo->clear();
	pDrawItemInfo->m_hDC = hdc;
	Rect rcCell;
	DWORD dwState = WCS_NORMAL;
	ULONG nLayer = 0;
	BOOL bRowexpanded = FALSE;
	COLORREF clrText = 0;
	LONG nLayerOffset = 0;
	LONG nTotalRow = getTotalRows();
	LONG nTotalCol = getTotalColumns();
	ULONG nSeqBarWidth = getRowNumBarWidth();
	ObjectAdapterBase* pOjbect = NULL;
	for (LONG nRow = m_nStartRow, nRowNum = 0; nRow <= m_nEndRow; nRow++, nRowNum++)
	{
		pDrawItemInfo->m_nRow = nRow;
		WFX_CONDITION(m_rgRowNumRect.size() > nRowNum);
		pDrawItemInfo->m_prcItem = &m_rgRowNumRect[nRowNum];
		pDrawItemInfo->m_dwState = 0;
		onDrawSeqBar(pDrawItemInfo);
		nLayer = getLayer(nRow);
		nLayerOffset = (nLayer - 1) * 30;
		clrText = getColor(nLayer);
		if (m_bHasSubItem)
		{
			bRowexpanded = isExpanded(nRow);
		}
		pOjbect = m_pArrayAdapter->getAt(nRow);
		WFX_CONDITION(pOjbect != NULL);

		for (LONG nCol = m_nStartCol; nCol <= m_nEndCol; nCol++)
		{
			WFX_CONDITION(nCol < pOjbect->getCount());
			AttributeBase* pAttribute = pOjbect->getAt(nCol);
			WFX_CONDITION(pAttribute != NULL);

			CellID cellID(nRow, nCol);
			dwState = WCS_NORMAL;
			if (m_bHasSubItem && nCol == 0)
			{
				if (bRowexpanded)
				{
					dwState |= WCS_EXPAND;
				}
				else
				{
					dwState |= WCS_CLOSE;
				}
			}
			if (m_cellSelected == cellID)
			{
				dwState |= WCS_SELECTED;
			}
			if (m_cellMouseMove == cellID)
			{
				dwState |= WCS_MOUSEMOVE;
			}
			rcCell = getCellRect(nRow, nCol);
			rcCell.left += nLayerOffset;
			pDrawItemInfo->m_nCol = nCol;
			pDrawItemInfo->m_prcItem = &rcCell;
			pDrawItemInfo->m_dwState = dwState;
			pDrawItemInfo->m_pszText = pAttribute->getText().c_str();
			pDrawItemInfo->m_dwFormat = pAttribute->getFormat();
			onDrawItem(pDrawItemInfo);
		}
	}
	WfxRender::drawFrame(hdc, rc, WBTN_BKGND_MOUSE, getDispatcher());
}
コード例 #6
0
ファイル: wfxListCtrl.cpp プロジェクト: wxtnote/wfc
BOOL ListCtrl::verify() const
{
	ULONG nTotalRow = getTotalRows();
	ULONG nTotalCol = getTotalColumns();
	return nTotalRow > 0 && nTotalCol > 0;
}