void Table::modifyHandlePos (float j) { //This function changes the x position of each envelope handle //after a zoom in or out. j will either be 2 or 0.5. for (int i=0; i<handles.size(); i++) { CabbageEnvelopeHandleComponent* handle = handles.getUnchecked (i); handle->setBounds (handle->getX() * j, handle->getY(), HANDLESIZE, HANDLESIZE); } }
CabbageEnvelopeHandleComponent* Table::addHandle(int x, int y) { int i; for (i=0; i<handles.size(); i++) { CabbageEnvelopeHandleComponent* handle = handles.getUnchecked (i); if (handle->getX() > x) break; } CabbageEnvelopeHandleComponent* handle = new CabbageEnvelopeHandleComponent(); handle->setBounds (x, y, HANDLESIZE, HANDLESIZE); addAndMakeVisible (handle); handles.insert (i, handle); repaint(); return handle; }
void CabbageEnvelopeHandleComponent::mouseDrag (const MouseEvent& e) { CabbageEnvelopeHandleComponent* previousHandle = getPreviousHandle(); CabbageEnvelopeHandleComponent* nextHandle = getNextHandle(); bool fixed = this->getProperties().getWithDefault("fixedPos", false); int leftLimit = previousHandle == 0 ? 0 : previousHandle->getX()+1; int rightLimit = nextHandle == 0 ? getParentWidth()-previousHandle->getHeight() : nextHandle->getX()-1; int topLimit = previousHandle == 0 ? 0 : previousHandle->getX()+1; int bottomLimit = nextHandle == 0 ? getParentWidth()-previousHandle->getHeight() : nextHandle->getX()-1; int dragX = x+e.getDistanceFromDragStartX(); int dragY = y+e.getDistanceFromDragStartY(); //dragger.dragComponent(this, e, &resizeLimits); if(dragX < leftLimit) dragX = leftLimit; if(dragX > rightLimit) dragX = rightLimit; if(dragY< 0) dragY = 0; if(dragY > height-5) dragY = height-5; if(fixed) dragX = x; this->setTopLeftPosition(dragX, dragY); getParentComponent()->repaint(); }
CabbageEnvelopeHandleComponent* Table::addHandle(int x, int y, bool fixedPos, int width, Colour col) { int i; for (i=0; i<handles.size(); i++) { CabbageEnvelopeHandleComponent* handle = handles.getUnchecked (i); if (handle->getX() > x) break; } CabbageEnvelopeHandleComponent* handle = new CabbageEnvelopeHandleComponent(handles.size(), col, fixedEnvelope); handle->addChangeListener(this); handle->getProperties().set("fixedPos", fixedPos); handle->height = getHeight(); handle->width = getWidth(); //if(this->toggleMaxMin) //handle->setBounds (x, y, width, 3); //else handle->setBounds (x, y, width, HANDLESIZE); addAndMakeVisible (handle); handles.insert (i, handle); repaint(); return handle; }
void Table::paint (Graphics& g) { //Image bg = ImageCache::getFromHashCode(15); //g.drawImage (bg, viewX, 0, origWidth, getHeight(), // 0, 0, bg.getWidth(), bg.getHeight(), false); if (isCurrentlyOnTop) currColour = activeColour.withMultipliedSaturation(3); else currColour = activeColour; int startIndx, endIndx; // If using overview... if (useOverview == true) { startIndx = (viewX/getWidth()) * overview.maxY.size(); endIndx = startIndx + viewWidth; float bottomYPixelValue, topYPixelValue; bottomYPixelValue = topYPixelValue = 0; // For loop which will draw a vertical line between the min and max value //for each x pixel int xPixelValue = 0; for (int i=startIndx; i<endIndx; i++) { //We need to make sure that the current min value is not greater than the //next max value. Otherwise there would be a gap in the wave form... if (overview.minY[i] < overview.maxY[i+1]) bottomYPixelValue = overview.maxY[i+1]; else bottomYPixelValue = overview.minY[i]; if (overview.maxY[i] > overview.minY[i+1]) topYPixelValue = overview.minY[i+1]; else topYPixelValue = overview.maxY[i]; float minGap = 0.4; float diff = bottomYPixelValue - topYPixelValue; if (diff < minGap) { bottomYPixelValue += (minGap-diff)/2; topYPixelValue -= (minGap-diff)/2; } if (CabbageUtils::isNumber(topYPixelValue) && CabbageUtils::isNumber(bottomYPixelValue)) { g.setColour(currColour); topYPixelValue -= minWaveHeight/2; bottomYPixelValue += minWaveHeight/2; g.drawVerticalLine (xPixelValue+viewX, topYPixelValue, bottomYPixelValue); xPixelValue += 1; // Fill if (tblSize <= 4096) { g.setColour(currColour.withAlpha(0.1f)); if (bottomYPixelValue < zeroAmpPosition) g.drawVerticalLine (xPixelValue+viewX, bottomYPixelValue, zeroAmpPosition); else if (bottomYPixelValue > zeroAmpPosition) g.drawVerticalLine (xPixelValue+viewX, zeroAmpPosition, bottomYPixelValue); if (isCurrentlyOnTop) currColour = activeColour.withMultipliedSaturation(3); else currColour = activeColour; } } } } //Else if using original array values for painting... else if (useOverview == false) { g.setColour(currColour); startIndx = ((viewX/getWidth()) * tableData.amps.size()) + 0.5; //0.5 for rounding endIndx = (startIndx + (viewWidth/numPixelsPerIndex)) + 0.5; float prevX = viewX; float prevY = convertAmpToPixel (tableData.amps[startIndx]); float currY; for (int i=startIndx+1; i<=endIndx; i++) { currY = convertAmpToPixel (tableData.amps[i]); g.drawLine (prevX, prevY, prevX+numPixelsPerIndex, currY, minWaveHeight); // For drawing index markers if (numPixelsPerIndex > 4) g.drawVerticalLine (prevX+numPixelsPerIndex, currY-3, currY+3); prevX = prevX + numPixelsPerIndex; prevY = currY; } } // g.setColour(Colours::lightblue); // envPath.scaleToFit (0, tableTop, getWidth(), tableHeight, false); // g.strokePath (envPath, PathStrokeType(2.0f)); //----- For handles.... Path path; for(int i = 0; i < handles.size(); i++) { CabbageEnvelopeHandleComponent* handle = handles.getUnchecked(i); if(handle->getProperties().getWithDefault(String("shape"), String("")).equals("linear")) { //for linear envelopes if(i==0) { path.startNewSubPath((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); } else { path.lineTo((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); } } else { //for bezier envelopes if(i==0){ path.startNewSubPath((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); } else { int curX = handle->getX(); int curY = handle->getY(); int prevX = path.getCurrentPosition().getX(); int prevY = path.getCurrentPosition().getY(); if(curY>prevY) path.quadraticTo(prevX, curY, (curX + handle->getRight()) / 2, (curY + handle->getBottom()) / 2); else if(curY<prevY){ path.quadraticTo(curX, prevY, (curX + handle->getRight()) / 2, (curY + handle->getBottom()) / 2); } } } //String coordinate; //coordinate = String(handle->getX()) + String(", ") + String(handle->getY()); //g.setColour(Colours::lime); //g.drawFittedText(coordinate, handle->getX(), handle->getY(), 50, 20, Justification::centred, 1); g.setColour(Colours::lightblue); g.strokePath (path, PathStrokeType(2.0f)); } //draw the crubber if needed if(scrubberPosition>0){ g.setColour(currColour); scrubberPosition = scrubberPosition*getWidth(); g.drawLine(scrubberPosition, 0, scrubberPosition, getHeight(), 2); } }
//==================================================== void Table::paint (Graphics& g) { //Image bg = ImageCache::getFromHashCode(15); //g.drawImage (bg, viewX, 0, origWidth, getHeight(), // 0, 0, bg.getWidth(), bg.getHeight(), false); if (isCurrentlyOnTop) currColour = activeColour.withMultipliedSaturation(3); else currColour = activeColour; int startIndx, endIndx; // If using overview... if (useOverview && drawOriginalTableData) { startIndx = (viewX/getWidth()) * overview.maxY.size(); endIndx = startIndx + viewWidth; float bottomYPixelValue, topYPixelValue; bottomYPixelValue = topYPixelValue = 0; // For loop which will draw a vertical line between the min and max value //for each x pixel int xPixelValue = 0; for (int i=startIndx; i<endIndx; i++) { //We need to make sure that the current min value is not greater than the //next max value. Otherwise there would be a gap in the wave form... if (overview.minY[i] < overview.maxY[i+1]) bottomYPixelValue = overview.maxY[i+1]; else bottomYPixelValue = overview.minY[i]; if (overview.maxY[i] > overview.minY[i+1]) topYPixelValue = overview.minY[i+1]; else topYPixelValue = overview.maxY[i]; float minGap = 0.4; float diff = bottomYPixelValue - topYPixelValue; if (diff < minGap) { bottomYPixelValue += (minGap-diff)/2; topYPixelValue -= (minGap-diff)/2; } if (CabbageUtils::isNumber(topYPixelValue) && CabbageUtils::isNumber(bottomYPixelValue)) { g.setColour(currColour); topYPixelValue -= minWaveHeight/2; bottomYPixelValue += minWaveHeight/2; g.drawVerticalLine (xPixelValue+viewX, topYPixelValue, bottomYPixelValue); xPixelValue += 1; // Fill if (tableSize <= 4096) { g.setColour(currColour.withAlpha(0.1f)); if (bottomYPixelValue < zeroAmpPosition) g.drawVerticalLine (xPixelValue+viewX, bottomYPixelValue, zeroAmpPosition); else if (bottomYPixelValue > zeroAmpPosition) g.drawVerticalLine (xPixelValue+viewX, zeroAmpPosition, bottomYPixelValue); if (isCurrentlyOnTop) currColour = activeColour.withMultipliedSaturation(3); else currColour = activeColour; } } } } //Else if using original array values for painting... else if (!useOverview && drawOriginalTableData) { g.setColour(currColour); startIndx = ((viewX/getWidth()) * tableData.amps.size()) + 0.5; //0.5 for rounding endIndx = (startIndx + (viewWidth/numPixelsPerIndex))+0.5; float prevX = viewX; float prevY = convertAmpToPixel (tableData.amps[startIndx]); float currY; for (int i=startIndx+1; i<=endIndx; i++) { currY = convertAmpToPixel (tableData.amps[i]); if(drawHorizontalSegments==true) { g.setColour(currColour); g.drawLine(prevX, prevY, prevX+numPixelsPerIndex, prevY, minWaveHeight); g.setColour(currColour.darker(.7)); if(drawFill==true) g.fillRect(prevX, (prevY>convertAmpToPixel(0) ? prevY-minWaveHeight : prevY+minWaveHeight), numPixelsPerIndex, convertAmpToPixel(0)-prevY); } else { g.drawLine(prevX, prevY, prevX+numPixelsPerIndex, currY, minWaveHeight); // For drawing index markers if (numPixelsPerIndex > 4) g.drawVerticalLine (prevX+numPixelsPerIndex, currY-3, currY+3); } prevX = prevX + numPixelsPerIndex; prevY = currY; } } // g.setColour(Colours::lightblue); // envPath.letoleToFit (0, tableTop, getWidth(), tableHeight, false); // g.strokePath (envPath, PathStrokeType(2.0f)); //----- For handles.... else if(!drawOriginalTableData) { envPath.clear(); for(int i = 0; i < handles.size(); i++) { CabbageEnvelopeHandleComponent* handle = handles.getUnchecked(i); int prevX, prevY; if((int)handle->getProperties().getWithDefault("curveType", 1)==0) { //for linear envelopes if(i==0) { envPath.startNewSubPath((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); if(toggleMaxMin) g.setColour(currColour); else g.setColour(currColour.darker(.9f)); if(drawHorizontalSegments==true && fixedEnvelope == true) if(drawFill==true && !toggleMaxMin) g.fillRect(0, jmax(handle->getY(), 0), jmax(handle->getWidth(), 0), jmax(0, getHeight()-1)); else if(drawFill==true && toggleMaxMin) { //g.setColour(Colours::red); g.fillRect(0, jmax(handle->getY(), 0), jmax(handle->getWidth(), 0), jmax(0, getHeight()-1)); //g.drawRect(0, jmax(handle->getY(), 0), jmax(handle->getWidth(), 0), jmax(0, getHeight()-1), 2); g.setColour(currColour); } prevX = handle->getX(); prevY = handle->getY(); } else { if(drawFill==true) g.fillRect(jmax(handle->getX(), 0), jmax(handle->getY(), 0), jmax(handle->getWidth()-1, 0), jmax(0, getHeight()-1)); if(toggleMaxMin) g.setColour(currColour); else g.setColour(currColour.darker(.9f)); if(toggleMaxMin) { g.drawRect(jmax(handle->getX(), 0), jmax(handle->getY(), 0), jmax(handle->getWidth()-1, 0), jmax(0, getHeight()-1), 2); g.setColour(currColour); } if(drawHorizontalSegments==true && fixedEnvelope == false) { envPath.lineTo((handle->getX() + handle->getRight()) / 2, (prevY+(handle->getHeight()/2))); envPath.lineTo((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); } else if(drawHorizontalSegments==true && fixedEnvelope==true) { envPath.lineTo((handle->getX()+1), (prevY+(handle->getHeight()/2))); envPath.lineTo((handle->getX()+1), (handle->getY() + handle->getBottom()) / 2); } else { envPath.lineTo((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); } prevY = handle->getY(); prevX = handle->getX(); } } else { //for bezier envelopes if(i==0) { envPath.startNewSubPath((handle->getX() + handle->getRight()) / 2, (handle->getY() + handle->getBottom()) / 2); } else { int curX = handle->getX(); int curY = handle->getY(); int prevX = envPath.getCurrentPosition().getX(); int prevY = envPath.getCurrentPosition().getY(); //int controlPoint1 if(curY>prevY) { if((int)handle->getProperties().getWithDefault("curveType", 0)==CONVEX) envPath.quadraticTo(prevX+(curX/3), curY, (curX + handle->getRight()) / 2, (curY + handle->getBottom()) / 2); else if((int)handle->getProperties().getWithDefault("curveType", 0)==CONCAVE) envPath.quadraticTo(curX-(curX/3), prevY, (curX + handle->getRight()) / 2, (curY + handle->getBottom()) / 2); } else if(curY<prevY) if((int)handle->getProperties().getWithDefault("curveType", 0)==CONVEX) envPath.quadraticTo(curX-(curX/3.f), prevY, (curX + handle->getRight()) / 2, (curY + handle->getBottom()) / 2); else if((int)handle->getProperties().getWithDefault("curveType", 0)==CONCAVE) envPath.quadraticTo(prevX+(prevX/3.f), curY, (curX + handle->getRight()) / 2, (curY + handle->getBottom()) / 2); } } //String coordinate; //coordinate = String(handle->getX()) + String(", ") + String(handle->getY()); //g.setColour(Colours::lime); //g.drawFittedText(coordinate, handle->getX(), handle->getY(), 50, 20, Justification::centred, 1); //envPath.lineTo(getWidth(), getHeight()); //envPath.lineTo(0, getHeight()); //envPath.closeSubPath(); //g.setColour(currColour.darker(.7f)); //if(toggleMaxMin) // int test; //else if((drawHorizontalSegments==true && fixedEnvelope == false)) //g.fillPath(envPath); //else if(!drawFill) g.strokePath (envPath, PathStrokeType(2.0f)); } } //if current table is on top, place text on widget to indicate so.. /* if(onTop){ String text = "ftable:"+String(tableNumber); g.setColour(currColour); g.setFont(CabbageUtils::getComponentFont()); int length = CabbageUtils::getComponentFont().getStringWidth(text)+10; g.drawText(text, getWidth()-length, 2, length, 12, Justification::centred, 1); }*/ //draw the crubber if needed if(scrubberPosition>0) { g.setColour(currColour); scrubberPosition = scrubberPosition*getWidth(); g.drawLine(scrubberPosition, 0, scrubberPosition, getHeight(), 2); } }