// return the center of the key over the point p.
//
Vec2 TouchTracker::getKeyCenterAtPoint(const Vec2 p) 
{
	float x = p.x();
	float y = p.y();
	int ix, iy;
	float fx, fy;
	switch (mKeyboardType)
	{
		case(rectangularA):
		default:
			MLRange xRange(3.5f, 59.5f);
			xRange.convertTo(MLRange(1.f, 29.f));
			float kx = xRange(x);
			kx = clamp(kx, 0.f, 30.f);
			ix = kx;
			
			MLRange yRange(1.25, 5.75);  // Soundplane A as measured
			yRange.convertTo(MLRange(1.f, 4.f));
			float ky = yRange(y);
			ky = clamp(ky, 0.f, 5.f);
			iy = ky;
			
			MLRange xRangeInv(1.f, 29.f);
			xRangeInv.convertTo(MLRange(3.5f, 59.5f));
			fx = xRangeInv(ix + 0.5f);
			
			MLRange yRangeInv(1.f, 4.f);
			yRangeInv.convertTo(MLRange(1.25, 5.75));
			fy = yRangeInv(iy + 0.5f);

			break;
	}
	return Vec2(fx, fy);
}
// return the index of the key over the point p.
//
int TouchTracker::getKeyIndexAtPoint(const Vec2 p) 
{
	int k = -1;
	float x = p.x();
	float y = p.y();
	int ix, iy;
	switch (mKeyboardType)
	{
		case(rectangularA):
		default:
			MLRange xRange(3.5f, 59.5f);
			xRange.convertTo(MLRange(1.f, 29.f));
			float kx = xRange(x);
			kx = clamp(kx, 0.f, 29.f);
			ix = kx;
			
			MLRange yRange(1.25, 5.75);  // Soundplane A as measured
			yRange.convertTo(MLRange(1.f, 4.f));
			float ky = yRange(y);
			ky = clamp(ky, 0.f, 4.f);
			iy = ky;

			k = iy*30 + ix;
			break;
	}
	return k;
}
Beispiel #3
0
void MLGraph::resized()
{
	MLLookAndFeel* myLookAndFeel = MLLookAndFeel::getInstance();
	int m = myLookAndFeel->getSmallMargin();
	int w = getWidth();
	int h = getHeight();

	// default ctor for MLRange sets [0, 1]
	//
	mResolution = w/4;	
	mViewDomain.convertTo(MLRange(m + 0.5, w - m + 0.5));
	mViewRange.convertTo(MLRange(h - m + 0.5, m + 0.5));
}
Vec2 TouchTracker::getKeyCenterByIndex(int idx) 
{
	// for Soundplane A only
	int iy = idx/30;
	int ix = idx - iy*30;
	
	MLRange xRangeInv(1.f, 29.f);
	xRangeInv.convertTo(MLRange(3.5f, 59.5f));
	float fx = xRangeInv(ix + 0.5f);

	MLRange yRangeInv(1.f, 4.f);
	yRangeInv.convertTo(MLRange(1.25, 5.75));
	float fy = yRangeInv(iy + 0.5f);

	return Vec2(fx, fy);
}
Beispiel #5
0
void MLMultiSlider::paint (Graphics& g)
{
	MLLookAndFeel* myLookAndFeel = (&(getRootViewResources(this).mLookAndFeel));
	if (isOpaque()) myLookAndFeel->drawBackground(g, this);	
	float outlineThickness = myLookAndFeel->getGridUnitSize() / 64.f;
	MLRect r = mPos.getLocalOutline();
	const Colour outlineColor (findColour(MLLookAndFeel::outlineColor).withAlpha (isEnabled() ? 1.f : 0.5f));
	
	// draw fills
	// vertical only
	Path full, empty;
	Colour fullColor, emptyColor;
	MLRect fullRect, emptyRect;
	float dialY;
	
	MLRange drawRange(mRange);
	drawRange.convertTo(MLRange(r.height(), 0.));
	
	for (int i=0; i<mNumSliders; ++i)
	{
		MLRect sr = (mPos.getElementBounds(i));

		dialY = drawRange(getFloatProperty(ml::textUtils::addFinalNumber(ml::Symbol("value"), i)));
		fullRect = sr;
		emptyRect = sr;		
		fullRect.setTop(dialY);
	
		fullColor = findColour(trackFullDarkColor);
		emptyColor = findColour(trackEmptyDarkColor);
		
		// groups of 4 
		if (!(i&4))
		{
			emptyColor = emptyColor.brighter(0.10f);
			fullColor = fullColor.brighter(0.20f);
		}
		
		empty.clear();
		empty.addRectangle(MLToJuceRect(emptyRect));
		g.setColour(emptyColor);
		g.fillPath(empty);	
		
		full.clear();
		full.addRectangle(MLToJuceRect(fullRect));
		g.setColour(fullColor);
		g.fillPath(full);	
				
		g.setColour(outlineColor);
		g.strokePath(empty, PathStrokeType (outlineThickness));
	}
}
void SoundplaneTouchGraphView::renderTouchBarGraphs()
{
	if (!mpModel) return;
	if (!isShowing()) return;
    
    int viewW = getBackingLayerWidth();
    int viewH = getBackingLayerHeight();
	
	const MLSignal& currentTouch = mpModel->getTouchFrame();
	const MLSignal& touchHistory = mpModel->getTouchHistory();
	const int frames = mpModel->getFloatProperty("max_touches");
	if (!frames) return;
		
	const Colour c = findColour(MLLookAndFeel::backgroundColor);
	float p = c.getBrightness();
		
	int margin = viewH / 30;
	int numSize = margin*2;
	int left = margin*2 + numSize;
	
	int right = viewW - margin;
	int top = margin;
	int bottom = viewH - margin;
	
	int frameWidth = right - left;
	int frameOffset = (bottom - top)/frames;
	int frameHeight = frameOffset - margin;
	MLRect frameSize(0, 0, frameWidth, frameHeight);		

    MLGL::orthoView(viewW, viewH);
	for(int j=0; j<frames; ++j)
	{
		// draw frames
		p = 0.9f;
		glColor4f(p, p, p, 1.0f);
		MLRect fr = frameSize.translated(Vec2(left, margin + j*frameOffset));
		MLGL::fillRect(fr);	
		p = 0.6f;
		glColor4f(p, p, p, 1.0f);
        MLGL::strokeRect(fr);
		
		// draw touch activity indicators at left
		glColor4fv(MLGL::getIndicatorColor(j));
		MLRect r(0, 0, numSize, numSize);		
		MLRect tr = r.translated(Vec2(margin, margin + j*frameOffset + (frameHeight - numSize)/2));				
		int age = currentTouch(4, j);		
		if (age > 0)
			MLGL::fillRect(tr);	
		else
			MLGL::strokeRect(tr);
			
		// draw history	
		MLRange frameXRange(fr.left(), fr.right());
		frameXRange.convertTo(MLRange(0, (float)kSoundplaneHistorySize));		
		MLRange frameYRange(0, 1);
		frameYRange.convertTo(MLRange(fr.bottom(), fr.top()));
		
		glBegin(GL_LINES);
		for(int i=fr.left() + 1; i<fr.right()-1; ++i)
		{
			int time = frameXRange(i);			
			float force = touchHistory(2, j, time);
	//		float d = touchHistory(3, j, time);
	//		int age = touchHistory(4, j, time);
			float y = frameYRange.convert(force);
	//		float drawY = (age > 0) ? y : 0.;	
	//		y = frameYRange.convert(d);
			
			// draw line
			glVertex2f(i, fr.bottom());	
			glVertex2f(i, y);	
		}
		glEnd();
	}
}
Beispiel #7
0
void MLEnvelope::paint (Graphics& g)
{	
	float mDelay = getFloatProperty("delay");
	float mAttack = getFloatProperty("attack");
	float mSustain = getFloatProperty("sustain");
	float mDecay = getFloatProperty("decay");
	float mRelease = getFloatProperty("release");
	float r = getFloatProperty("repeat");
	float mRepeat = (r > 0.f) ? (1.f / (r + 0.0001f)) : 0.f;

	MLLookAndFeel* myLookAndFeel = (&(getRootViewResources(this).mLookAndFeel));
	if (isOpaque()) 
		myLookAndFeel->drawBackground(g, this);	
	
	float margin = myLookAndFeel->getSmallMargin() * myLookAndFeel->getGridUnitSize();
	int w = getWidth()-1;
	int h = getHeight()-1;
	
	float totalTime;
	float startX, delX, attX, decX, susX, relX, repX, endX;
	float attTime, decTime, relTime, susTime;
	float leadIn = 0.01;
	float leadOut = 0.01;
	float susHeight;
	float epsilon = 0.0005;
	float susLevel = mDARMode ? 1.0f : mSustain;
	attTime = mAttack + kMinAttack;
	decTime = mDecay * (1.f - susLevel) + kMinDecay;
	relTime = mRelease * susLevel + kMinDecay;
			
	// get times
	if (mDARMode)
	{
		susTime = (mSustain > 0.5) ? 1.f : 0.f; // is hold on?
		decTime = 0.;
		totalTime = leadIn + mDelay + attTime + susTime + relTime + leadIn + leadOut;
	}
	else
	{
		susTime = 1.f;
		totalTime = leadIn + attTime + decTime + susTime + relTime + leadIn + leadOut;
	}
	
	if (mRepeat > epsilon)
	{
		totalTime = ml::max(totalTime, (float)(leadIn + mDelay + mRepeat + leadOut));
	}
	
	totalTime = ml::max(totalTime, 0.01f);
	
	// get dims
	MLRange vRange(UnityRange);
	MLRange wRange(0.f, totalTime);
	vRange.convertTo(MLRange(h - margin, margin));
	wRange.convertTo(MLRange(margin, w - margin*2));
	float t = 0.;
	startX = wRange(0.);

	delX = wRange(t += mDelay);
	attX = wRange(t += attTime);
	decX = wRange(t += decTime);
	susX = wRange(t += susTime);
	relX = wRange(t += relTime);
	endX = wRange(totalTime);
	repX = wRange(leadIn + mDelay + mRepeat);
	susHeight = vRange(susLevel);
		
	// draw env shape
	Path envPath;
	envPath.startNewSubPath(startX,  floor(h - margin) + 0.5);
	envPath.lineTo(delX,  floor(h - margin) + 0.5);
	envPath.quadraticTo(delX,  floor(margin) + 0.5, attX, floor(margin) + 0.5); // up
	envPath.quadraticTo(attX,  floor(susHeight) + 0.5, decX,  floor(susHeight) + 0.5);  // down
	envPath.quadraticTo(decX,  floor(susHeight) + 0.5, susX,  floor(susHeight) + 0.5); // across
	envPath.quadraticTo(susX,  floor(h - margin) + 0.5, relX,  floor(h - margin) + 0.5); // down
	envPath.quadraticTo(relX,  floor(h - margin) + 0.5, endX,  floor(h - margin) + 0.5); // across
	g.setColour(findColour(MLLookAndFeel::outlineColor));
	g.strokePath(envPath, PathStrokeType (mOutlineThickness));	
	g.setColour(findColour(MLLookAndFeel::outlineColor).withAlpha(0.125f));
	g.fillPath(envPath);
	// lines down
	envPath.clear();
	envPath.startNewSubPath(attX,  floor(margin) + 0.5);
	envPath.lineTo(attX,  floor(h - margin) + 0.5);
	envPath.startNewSubPath(decX,  floor(susHeight) + 0.5);
	envPath.lineTo(decX,  floor(h - margin) + 0.5);
	envPath.startNewSubPath(susX,  floor(susHeight) + 0.5);
	envPath.lineTo(susX,   floor(h - margin) + 0.5);
	g.setColour(findColour(MLLookAndFeel::outlineColor));
	g.strokePath(envPath, PathStrokeType (mOutlineThickness / 2));	

	// draw repeat bracket
	if (mRepeat > epsilon)
	{		
		float thick = margin / 2;
		float high = margin * 1.5;
		envPath.clear();
		envPath.startNewSubPath(floor(delX - thick/2) , floor(h - margin - high));
		envPath.lineTo(floor(delX - thick/2) , floor(h - margin));
		envPath.lineTo(floor( repX + thick/2) , floor(h - margin));
		envPath.lineTo(floor( repX + thick/2) , floor(h - margin - high));
		g.strokePath(envPath, PathStrokeType (mOutlineThickness * 4));	

	}

//debug() << "DEL " << mDelay << " ATT " << attTime << " DEC " << decTime << " SUS " << susTime << " REL " << relTime << " REP " << mRepeat << "\n";
//debug() << "repeatX: " << repX << " delayX: " << delX << "\n";

	/*
	// TEST
	Path tbounds;
	const Rectangle<int> & boundsRect ( getLocalBounds());	
	tbounds.addRectangle(boundsRect);
	g.setColour(Colours::red);	
	g.strokePath(tbounds, PathStrokeType(0.5f));
	*/
}