Exemplo n.º 1
0
void AmNode::CopyContentsTo(AmNode* copy) const
{
	assert( copy );
	if( !copy || !mEvent ) return;
	AmNode*		node = copy;
	node->SetEvent( mEvent->Copy() );
}
Exemplo n.º 2
0
void SeqPhraseMatrixView::DrawTrack(BRect clip,
                                    BView* view,
                                    const AmTrack* track,
                                    AmPhraseRendererI* renderer)
{
    /* Find the first phrase left of the window.
     */
    const AmPhrase&	phrases = track->Phrases();
    AmTime		start = mMtc.PixelToTick(clip.left);
    AmTime		end = mMtc.PixelToTick(clip.right);
    AmNode*		n = phrases.FindNode(start, BACKWARDS_SEARCH);
    if (!n) n = phrases.FindNode(start);
    if (!n) return;

    while (n && (n->Event()->StartTime() <= end) ) {
        if( n->Event()->Type() == n->Event()->PHRASE_TYPE ) {
            AmPhraseEvent*	pe = dynamic_cast<AmPhraseEvent*>( n->Event() );
            if (pe) DrawTopLevelPhrase(clip, view, track, pe, end, pe, renderer);
            /* Events need to know if they are in a link or not, so they
             * are required to be bundled up in a phrase.
             */
        } else {
            debugger("Error condition");
//		} else if( n->Event()->Type() == n->Event()->NOTEON_TYPE ) {
//			DrawEvent( clip, view, dynamic_cast<AmNoteOn*>( n->Event() ) );
        }
        n = n->next;
    }
}
Exemplo n.º 3
0
AmNode* AmNode::Copy() const
{
	const AmNode* pos = this;
	
	AmNode* head = NULL;
	AmNode* tail = NULL;
	
	while (pos) {
		AmNode*	copy = new AmNode(0);
		if (!copy) {
			if (head) {
				head->DeleteListContents();
				delete head;
			}
			return NULL;
		}
		
		pos->CopyContentsTo( copy );
		if (!tail) {
			head = tail = copy;
		} else {
			tail->InsertNext(copy);
			tail = copy;
		}
		
		pos = pos->next;
	}
	
	return head;
}
Exemplo n.º 4
0
void AmTrackDataView::DrawPhrase(	BRect clip,
									BView* view,
									track_id trackId,
									const AmPhraseEvent& topPhrase,
									AmPhraseEvent* pe,
									AmTime start,
									AmTime end,
									int32 properties,
									AmSelectionsI* selections)
{
	ArpASSERT(pe && pe->Phrase());
	AmNode*		n = pe->Phrase()->HeadNode();
	if (!n) return;
	AmRange		eventRange = topPhrase.EventRange( n->Event() );
	while (n && eventRange.start <= end) {
		if (eventRange.end >= start) {
			if (mTarget->IsInteresting( n->Event() )) {
				if (selections && selections->IncludesEvent(trackId, &topPhrase, n->Event() ) )
					DrawEvent(view, topPhrase, n->Event(), eventRange, ARPEVENT_SELECTED);
				else
					DrawEvent(view, topPhrase, n->Event(), eventRange, properties);
			} else if (n->Event()->Type() == n->Event()->PHRASE_TYPE) {
				AmPhraseEvent*	pe2 = dynamic_cast<AmPhraseEvent*>( n->Event() );
				if (pe2) DrawPhrase(clip, view, trackId, topPhrase, pe2, start, end, properties, selections);
			}
		}
		n = n->next;
		if (n) eventRange = topPhrase.EventRange( n->Event() );
	}
}
Exemplo n.º 5
0
AmNode* AmNode::NodeBefore(AmTime time)
{
	if( StartTime() >= time ) return 0;
	
	AmNode* pos = this;
	while (pos && pos->next && pos->StartTime() < time) pos = pos->next;
	return pos;
}
Exemplo n.º 6
0
void AmNode::DeleteListContents()
{
	AmNode* pos = this;
	
	while (pos) {
		if( pos->mEvent ) {
			pos->pDeleteContents();
			pos->mEvent = 0;
		}
		pos = pos->next;
	}
}
Exemplo n.º 7
0
const AmSignature* AmTimeView::GetSignatureBefore(const AmPhrase& signatures, int32 measure)
{
	AmNode*			node = signatures.HeadNode();
	if( !node ) return 0;
	
	while ( (node != 0) && (node->next != 0) ) {
		const AmSignature*	sig = dynamic_cast<const AmSignature*>( ((AmNode*)node->next)->Event() );
		if ( (sig != 0) && (sig->Measure() > measure) ) return sig;
		node = (AmNode*)node->next;
	}
	return dynamic_cast<const AmSignature*>( node->Event() );
}
Exemplo n.º 8
0
/* This method finds the first event that STARTS after my left edge.
 * events that are overhanging into my left border are ignored.  This
 * is an arbitrary decision, but basically it makes sense to me to do
 * it this way because this method is used to select the first visible
 * event, if there isn't already one.  And if I did it the other way,
 * then that overhanging note might actually be measures away, so as users
 * clicked the right arrow the actual events being selected would be far
 * away.
 */
AmEvent* AmTrackDataView::FirstEvent(const AmTrack* track, AmPhraseEvent** answer) const
{
	ArpASSERT(mTarget);
	const AmPhrase&		phrase = track->Phrases();
	AmTime				time = mTarget->TimeConverter().PixelToTick( Bounds().left );
	AmNode*				phraseNode = phrase.FindNode( time, BACKWARDS_SEARCH );
	if( !phraseNode ) return 0;
	AmPhraseEvent*		pe;
	while (phraseNode != 0) {
		if( (phraseNode->Event()->Type() == phraseNode->Event()->PHRASE_TYPE)
				&& (pe = dynamic_cast<AmPhraseEvent*>( phraseNode->Event() ))
				&& pe->Phrase() ) {
			AmNode*		eventNode = pe->Phrase()->FindNode( time, FORWARDS_SEARCH );
			while( eventNode ) {
				if( mTarget->IsInteresting( eventNode->Event() ) ) {
					*answer = pe;
					return eventNode->Event();
				}
				eventNode = eventNode->next;
			}
		}
		phraseNode = phraseNode->next;
	}
	return 0;
}
Exemplo n.º 9
0
status_t AmTimeView::ConstructSignatureFromTime(const AmPhrase& signatures)
{
	debugger("This code doesn't work at all -- if anyone actually uses it, it needs to be rewritten");
	AmNode*			node = signatures.FindNode( DisplayTime(), BACKWARDS_SEARCH );
	if( !node ) return B_ERROR;
	AmSignature*	sig = dynamic_cast<AmSignature*>( node->Event() );
	if( !sig ) return B_ERROR;
	
	AmTime			start = sig->StartTime();
	AmTime			ticks = sig->TicksPerBeat();
	AmTime			displayTime = DisplayTime();
	int32			measure = sig->Measure();
	while ( (start + ticks) <= displayTime ) {
		start += ticks;
		measure++;
	}
	mSignature->Set( start, measure, sig->Beats(), sig->BeatValue() );
	return B_OK;
}
Exemplo n.º 10
0
status_t AmTrackDataView::NextRightEvent(	const AmTrack* track,
											AmEvent* event, AmPhraseEvent* container,
											AmEvent** eventAnswer, AmPhraseEvent** containerAnswer) const
{
#if 0
	ArpASSERT( mTarget );
	ArpASSERT( event && container && container->Phrase() );
	AmNode*		n = container->Phrase()->FindNode(event);
//	AmEvent*	nextEvent = 0;
	/* Simple case, there's an event after the current one.
	 */
	if( n ) n = n->next;
	while( n ) {
		if( mTarget->IsInteresting( n->Event() ) ) {
			*eventAnswer = n->Event();
			*containerAnswer = container;
			return B_OK;
		}
		n = n->next;
	}
#endif
	return B_ERROR;
}
Exemplo n.º 11
0
AmTimeView::AmTimeView(	const AmPhrase& signatures)
		: inherited(BRect(0, 0, 0, 0),
					"midi_time",
					B_FOLLOW_TOP | B_FOLLOW_LEFT,
					B_WILL_DRAW),
		  AmSongObserver( AmSongRef() ),
		  mSignature(new AmSignature), mTime(0),
		  mMeasureCtrl(0), mBeatCtrl(0), mClockCtrl(0)
{
	AmNode*		n = signatures.HeadNode();
	while( n ) {
		if( n->Event()->Type() == n->Event()->SIGNATURE_TYPE ) {
			AmSignature*	event = dynamic_cast<AmSignature*>( n->Event() );
			AmSignature*	sig;
			if( event && (sig = new AmSignature( *event )) ) {
				mSignatures.Add( sig );
			}
		}
		n = n->next;
	}

	AddViews();
}
Exemplo n.º 12
0
AmEvent* _AmControlTarget::InterestingEventAt(	const AmTrack* track,
												const AmPhraseEvent& topPhrase,
												const AmPhrase& phrase,
												AmTime time,
												float y,
												int32* extraData) const
{
	AmNode*		n = phrase.ChainHeadNode(time);
	if (!n) return NULL;
	/* Since control changes are single pixels, it can be a bit tricky
	 * for users to hit exactly the right pixel.  Compensate for this
	 * by finding the closest control change within a given fudge factor.
	 */
	AmTime		fudge = EventAtFudge();
	AmEvent*	closest = NULL;
	/* As soon as I've hit events that are within range of where I'm
	 * looking, I set this flag.  This lets me know to end the search
	 * as soon as I'm out of range.
	 */
	bool		beenInRange = false;
	while (n) {
		AmRange		eventRange = topPhrase.EventRange( n->Event() );
		if( (eventRange.start >= time - fudge) && (eventRange.start <= time + fudge) ) {
			beenInRange = true;
			if( IsInteresting( n->Event() ) ) {
				if (!closest)
					closest = n->Event();
				else if ( abs(time - eventRange.start) < abs(time - topPhrase.EventRange(closest).start) )
					closest = n->Event();
			}
		} else {
			if (beenInRange) return closest;
		}
		n = n->next;
	}
	return closest;
}
Exemplo n.º 13
0
static void _control_report(const AmPhrase* phrase, uint8* active)
{
	if (!phrase) return;
	AmNode*		node = phrase->HeadNode();
	while (node) {
		if (node->Event() ) {
			if (node->Event()->Type() == node->Event()->PHRASE_TYPE) {
				AmPhraseEvent*	pe = dynamic_cast<AmPhraseEvent*>(node->Event() );
				if (pe) _control_report(pe->Phrase(), active);
			} else if (node->Event()->Type() == node->Event()->CONTROLCHANGE_TYPE) {
				AmControlChange*	cc = dynamic_cast<AmControlChange*>(node->Event() );
				if (cc) active[cc->ControlNumber()] = 1;
			}
		}
		node = node->next;
	}
}
Exemplo n.º 14
0
static void program_report(const AmPhrase* phrase, _AmProgramEntry& entry)
{
	if (!phrase) return;
	AmNode*		node = phrase->HeadNode();
	while (node) {
		if ( node->Event() ) {
			if (node->Event()->Type() == node->Event()->PHRASE_TYPE) {
				AmPhraseEvent*	pe = dynamic_cast<AmPhraseEvent*>( node->Event() );
				if (pe) program_report(pe->Phrase(), entry);
			} else if (node->Event()->Type() == node->Event()->PROGRAMCHANGE_TYPE) {
				AmProgramChange*	pc = dynamic_cast<AmProgramChange*>( node->Event() );
				if (pc) entry.AddProgram( pc->ProgramNumber() );
			}
		}
		node = node->next;
	}
}
Exemplo n.º 15
0
static void control_report(const AmPhrase* phrase, _AmControlEntry& entry)
{
	if (!phrase) return;
	AmNode*		node = phrase->HeadNode();
	while (node) {
		if (node->Event() ) {
			if (node->Event()->Type() == node->Event()->PHRASE_TYPE) {
				AmPhraseEvent*	pe = dynamic_cast<AmPhraseEvent*>(node->Event() );
				if (pe) control_report(pe->Phrase(), entry);
			} else if (node->Event()->Type() == node->Event()->CONTROLCHANGE_TYPE) {
				AmControlChange*	cc = dynamic_cast<AmControlChange*>(node->Event() );
				if (cc) entry.AddControl(cc->ControlNumber() );
			}
		}
		node = node->next;
	}
}
Exemplo n.º 16
0
void AmTrackDataView::DrawTrack(const AmTrack* track,
								BRect clip,
								BView* view,
								int32 properties,
								AmSelectionsI* selections)
{
	AmTime		start = mMtc.PixelToTick(clip.left - 2);
	AmTime		end = mMtc.PixelToTick(clip.right + 2);
	AmNode*		n = track->Phrases().HeadNode();
	while (n && n->Event() && n->StartTime() <= end) {
		if (n->EndTime() >= start) {
			if (n->Event()->Type() == n->Event()->PHRASE_TYPE) {
				AmPhraseEvent*	pe = dynamic_cast<AmPhraseEvent*>( n->Event() );
				if (pe && pe->Phrase() ) {
					mEventColor = pe->Phrase()->Color(AmPhrase::FOREGROUND_C);
					mix_in(mEventColor, AmPrefs().Color(AM_DATA_BG_C), 0.75, mLowEventColor);
					DrawPhrase(clip, view, track->Id(), *pe, pe, start, end, properties, selections);
				}
			}
		}
		n = n->next;
	}
}
Exemplo n.º 17
0
void SeqMeasureControl::LockedDrawRightOn(	const AmPhrase& signatures, BRect rBounds, BView* view,
											AmTime songEndTime)
{
	AmTime				centerRightTime = mMtc.PixelToTick( rBounds.left - 1 - mLeftIndent + mScrollX );
	if (centerRightTime < 0) return;
	AmTime				timeWidth = songEndTime - centerRightTime;
	if( timeWidth < 0 ) return;
	AmTimeConverter		mtc( mRightIndent / ((float)timeWidth / (float)PPQN) );
	if( mtc.BeatLength() >= mMtc.BeatLength() ) return;

	AmNode*				node = signatures.HeadNode();
	if (node == 0) return;
	AmSignature*		sig = dynamic_cast<AmSignature*>( node->Event() );
	if (sig == 0) return;
	AmSignature			currentSig(*sig);
	AmTime				sigLength = currentSig.Duration();
	AmSignature*		nextSig = 0;
	AmNode*				nextNode = node->next;
	if (nextNode != 0) nextSig = dynamic_cast<AmSignature*>( nextNode->Event() );
	char				buf[16];
	float				lastRight = -1;

	/* Find the first signature right of the center view.
	 */
	while (currentSig.EndTime() < centerRightTime) {
		currentSig.Set( currentSig.StartTime() + sigLength,
						currentSig.Measure() + 1,
						currentSig.Beats(),
						currentSig.BeatValue() );

		if ( nextSig && ( currentSig.StartTime() == nextSig->StartTime() ) ) {
			int32	measure = currentSig.Measure();
			currentSig.Set( *nextSig );
			currentSig.SetMeasure( measure );
			sigLength = currentSig.Duration();
			node = nextNode;
			nextNode = (AmNode*)nextNode->next;
			if (nextNode != 0) nextSig = dynamic_cast<AmSignature*>( nextNode->Event() );
			else nextSig = 0;
		}
	}
	DrawRightBgOn(rBounds, view, songEndTime);	
	/* Draw the center dividing line.
	 */
	float				fh = view_font_height(view);
	rBounds.top = rBounds.bottom - fh;
	view->SetHighColor( Prefs().Color( AM_MEASURE_FG_C ) );
	view->StrokeLine( BPoint(rBounds.left, rBounds.top-1), BPoint(rBounds.right, rBounds.top-1) );
	view->SetHighColor( Prefs().Color( AM_MEASURE_HIGHLIGHT_C ) );
	view->StrokeLine( BPoint(rBounds.left, rBounds.top), BPoint(rBounds.right, rBounds.top) );
	
	/* Now draw til the end.
	 */
	view->SetHighColor( Prefs().Color( AM_MEASURE_FG_C ) );
	view->SetDrawingMode(B_OP_ALPHA);
	view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
	
	while (currentSig.EndTime() < songEndTime) {

		float		pixel = mtc.TickToPixel( currentSig.StartTime() - centerRightTime );
		if( pixel > lastRight ) {
			view->StrokeLine( BPoint(pixel + rBounds.left, rBounds.top), BPoint(pixel + rBounds.left, rBounds.bottom) );
			sprintf( buf, "%ld", currentSig.Measure() );
			float	width = view->StringWidth( buf );
			view->DrawString( buf, BPoint( pixel + rBounds.left + 2, rBounds.bottom - 2 ) );
			lastRight = pixel + 2 + width + 2;
		}
		currentSig.Set( currentSig.StartTime() + sigLength,
						currentSig.Measure() + 1,
						currentSig.Beats(),
						currentSig.BeatValue() );

		if ( nextSig && ( currentSig.StartTime() == nextSig->StartTime() ) ) {
			int32	measure = currentSig.Measure();
			currentSig.Set( *nextSig );
			currentSig.SetMeasure( measure );
			sigLength = currentSig.Duration();
			node = nextNode;
			nextNode = (AmNode*)nextNode->next;
			if (nextNode != 0) nextSig = dynamic_cast<AmSignature*>( nextNode->Event() );
			else nextSig = 0;
		}
	}
	
	view->SetDrawingMode(B_OP_COPY);
}
Exemplo n.º 18
0
void SeqMeasureControl::LockedDrawLeftOn(const AmPhrase& signatures, BRect lBounds, BView* view)
{
	AmTime				rightTick = mMtc.PixelToTick(mScrollX);
	AmTimeConverter		mtc( mLeftIndent / ((float)rightTick / (float)PPQN) );
	AmNode*				node = signatures.HeadNode();
	if (node == 0) return;
	AmSignature*		sig = dynamic_cast<AmSignature*>( node->Event() );
	if (sig == 0) return;
	AmSignature			currentSig(*sig);
	AmTime				sigLength = currentSig.Duration();
	AmSignature*		nextSig = 0;
	AmNode*				nextNode = node->next;
	if (nextNode != 0) nextSig = dynamic_cast<AmSignature*>( nextNode->Event() );
	char				buf[16];
	float				lastRight = -1;

	/* Draw the center dividing line.
	 */
	float				fh = view_font_height(view);
	lBounds.top = lBounds.bottom - fh;
	view->SetHighColor( Prefs().Color( AM_MEASURE_FG_C ) );
	view->StrokeLine( BPoint(lBounds.left, lBounds.top-1), BPoint(lBounds.right, lBounds.top-1) );
	view->SetHighColor( Prefs().Color( AM_MEASURE_HIGHLIGHT_C ) );
	view->StrokeLine( BPoint(lBounds.left, lBounds.top), BPoint(lBounds.right, lBounds.top) );

	view->SetHighColor( Prefs().Color( AM_MEASURE_FG_C ) );
	view->SetDrawingMode(B_OP_ALPHA);
	view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
	
	while (currentSig.EndTime() < rightTick) {

		float		pixel = mtc.TickToPixel( currentSig.StartTime() );
		if( pixel > lastRight ) {
			view->StrokeLine( BPoint(pixel, lBounds.top), BPoint(pixel, lBounds.bottom) );
			sprintf( buf, "%ld", currentSig.Measure() );
			float	width = view->StringWidth( buf );
			if( pixel + 2 + width > mLeftIndent ) {
				lastRight = pixel + 2;
			} else {
				view->DrawString( buf, BPoint( pixel + 2, lBounds.bottom - 2 ) );
				lastRight = pixel + 2 + width + 2;
			}
		}
		currentSig.Set( currentSig.StartTime() + sigLength,
						currentSig.Measure() + 1,
						currentSig.Beats(),
						currentSig.BeatValue() );

		if ( nextSig && ( currentSig.StartTime() == nextSig->StartTime() ) ) {
			int32	measure = currentSig.Measure();
			currentSig.Set( *nextSig );
			currentSig.SetMeasure( measure );
			sigLength = currentSig.Duration();
			node = nextNode;
			nextNode = (AmNode*)nextNode->next;
			if (nextNode != 0) nextSig = dynamic_cast<AmSignature*>( nextNode->Event() );
			else nextSig = 0;
		}
	}
	
	view->SetDrawingMode(B_OP_COPY);
}
Exemplo n.º 19
0
status_t AmNode::AddNode(AmNode* node)
{
	assert( node );

	AmNode* destPos = this;
	
	#if NOISY
	ArpD(cdb << ADH << "Merging " << node << " into " << destPos << endl);
	#endif
	
	const AmTime nodeTime = node->StartTime();
	#if NOISY
	ArpD(cdb << ADH << "Node time is " << nodeTime << endl);
	#endif
	AmNode* tmp=NULL;
	bool searched = false;
	
	// If node time is after current position time, look forward for
	// the place to insert it.
	while( nodeTime >= destPos->StartTime() ) {
		#if NOISY
		ArpD(cdb << ADH << "Dest time is " << destPos->StartTime()
				<< ", going forward." << endl);
		#endif
		tmp = destPos->next;
		if( !tmp ) {
			// Whoops, ran to end of list -- place source at end.
			#if NOISY
			ArpD(cdb << ADH << "This is the last event; appending src.\n");
			#endif
			destPos->InsertNext(node);
			return B_OK;
		}
		destPos = tmp;
		searched = true;
	}
	
	if( searched ) {
		// We moved forward at least one event in the dest list, so
		// we know this is where to put it.
		#if NOISY
		ArpD(cdb << ADH << "Found dest time " << destPos->Time()
						<< ", inserting here." << endl);
		#endif
		destPos->InsertPrev(node);
		return B_OK;
	}
	
	// That didn't work -- node time is before current position, so look
	// back in the list for where this goes.
	while( nodeTime < destPos->StartTime() ) {
		#if NOISY
		ArpD(cdb << ADH << "Dest time is " << destPos->StartTime()
						<< ", going backward." << endl);
		#endif
		tmp = destPos->prev;
		if( !tmp ) {
			// Whoops, ran to end of list -- place source at front.
			#if NOISY
			ArpD(cdb << ADH << "This is the first event; inserting src.\n");
			#endif
			destPos->InsertPrev(node);
			return B_OK;
		}
		destPos = tmp;
	}
	
	// Okay, we absolutely positive know that this is the place to
	// put it.
	#if NOISY
	ArpD(cdb << ADH << "Found dest time " << destPos->StartTime()
					<< ", appending here." << endl);
	#endif
	destPos->InsertNext(node);
	return B_OK;
}