Learning To Draw In Juce


#1

Hi guy's

 

I was just wondering if anyone can point me to some resources that might help me learn the basic concepts behing drawing components in JUCE usinc paths and paint routines etc. 

 

I could do with a bit more of an understanding of vector graphics and particularly how to translate this into code. 

 

If anyone has any example code or resources they could point me to it would be greatly appreciated. I have taken a peruse through the look and feel classes and functions like the drawrotaryslider (); but could do with more of an understanding on how to construct basic shapes (for things like rotary knobs) and how to place them correctly within parent components. 

 

Thanks


#2

Personally, if I've got anything non-trivial to do, I: 

  • Draw it in photoshop and make a mental note of the steps.
  • Have a resized() function which calcuates all the Paths, Rectangles and posistions I need to do a paint job. 
  • Have a paint(Graphics & g)  function which calls other paint() functions for the major steps, e.g. paintKnob(g) paintLine(g) paintShadow(g).
  • Make heavy use of the Rectangle functions. 
  • Do everything in ratios of pixels so it'll scale well. 

Then the paint functions end up nice and easy to follow: 

    void paintHighlight(Graphics & g) {

        g.beginTransparencyLayer(0.75f);

        g.setGradientFill(highlightFill);

        g.fillPath(highlightPath);

        g.endTransparencyLayer();

    }

    void paintShadow(Graphics & g) {

        ColourGradient gf(Colours::black.withAlpha(0.1f), cx, cy,

                          Colours::black.withAlpha(0.01f), w, h, false);

        g.setGradientFill(gf);


        g.fillPath(shadowPath);

    }

    void paintKnob(Graphics & g) {

        if (k->settings.grip) {

            g.setColour(knobColour.withMultipliedBrightness(0.2f));

            g.fillPath(gripPath);

        }

        g.setColour(knobColour);

        g.fillEllipse(knobArea);

        if (!k->settings.grip) {

            g.setColour(knobColour.withMultipliedBrightness(0.2f));

            g.drawEllipse(knobArea.reduced(koutlinewidth / 2.0), koutlinewidth);

        }

    }

 

See also SVG Path Helper in the GUI which should let you take stuff from a drawing program and turn it into JUCE paths. 

You'd better have a good experiment though I reckon...

 

Here's some path calcuations for a knob that I'm calling from resize(): 

    void calculateHighlightPath() {

        /* Highlight path. The lighting effect on the top edge of the knob. */

        Point<float> startPoint(centre.getPointOnCircumference(r - koutlinewidth, 1.25 * 3.141));

        Rectangle<float>area = knobArea.reduced(koutlinewidth);

        Point<float> midPoint(centre.getPointOnCircumference(r - koutlinewidth, 1.75 * 3.141));

        

        highlightFill = ColourGradient(Colours::white, midPoint.getX(), midPoint.getY(),

                                       Colours::transparentWhite, 0.0, 0.0, true);

        

        Path p;

        

        p.startNewSubPath(startPoint);

        float shift = unit * 0.25f;

        p.addArc(area.getX(), area.getY(),

                 area.getWidth(), area.getHeight(),

                 1.25 * 3.141, 2.25 * 3.141);

        p.addArc(area.getX()+shift, area.getY()+shift,

                 area.getWidth()+shift, area.getHeight()+shift,

                 2.25 * 3.141, 1.25 * 3.141);

        p.closeSubPath();

        highlightPath = p;

        

    }

#3

Thanks alot for the reply bazrush, 

 

You've set me down the right track and I've had a little bit of luck subclassing look and feel and modifying the drawRotarySlider function. 

 

I've attempted to use the SVG parser with paths from an Illustrator file I used but am constantly fighting linker errors when trying to use the code that the Parser generates. "Undefined Symbols" etc. 

 

For me the main learning curve is trying to work out the actual calculations for the likes of the following:


Point<float> startPoint(centre.getPointOnCircumference(r - koutlinewidth, 1.25 * 3.141));

 

Working out the correct dimensions to use for arguments in p.addarc fucntions etc. 

 

Are their any texts anyone is aware of that might help me learn/understand some of these principles ? Its the basic path and geometric shape building that I am struggling with and how to translate these into code. 


#4

PS. Important, if you've not spotted it:  Angles are all in radians. Clockwise from the top.  There are 2π radians in a circle.  

(So 1.25 * 3.141 refers to a point 5/8ths of the way around the circle.)