Latest juce tip, my code gives "unresolved external symbol" for juce::Slider::? methods. Reverting juce library fixes it


#1

I wanted a colour selector that supported RGBA, so I copied JUCE's ColourSelector into my own class, and added the functionality, which has worked fine till today.

I got the lates juce code through Git, and now recompiling gives me the below:

1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::paint(class juce::Graphics &)" (?paint@Slider@juce@@MAEXAAVGraphics@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::resized(void)" (?resized@Slider@juce@@MAEXXZ)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::mouseDown(class juce::MouseEvent const &)" (?mouseDown@Slider@juce@@MAEXABVMouseEvent@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::mouseUp(class juce::MouseEvent const &)" (?mouseUp@Slider@juce@@MAEXABVMouseEvent@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::mouseDrag(class juce::MouseEvent const &)" (?mouseDrag@Slider@juce@@MAEXABVMouseEvent@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::mouseDoubleClick(class juce::MouseEvent const &)" (?mouseDoubleClick@Slider@juce@@MAEXABVMouseEvent@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::mouseWheelMove(class juce::MouseEvent const &,struct juce::MouseWheelDetails const &)" (?mouseWheelMove@Slider@juce@@MAEXABVMouseEvent@2@ABUMouseWheelDetails@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::modifierKeysChanged(class juce::ModifierKeys const &)" (?modifierKeysChanged@Slider@juce@@MAEXABVModifierKeys@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::lookAndFeelChanged(void)" (?lookAndFeelChanged@Slider@juce@@MAEXXZ)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::enablementChanged(void)" (?enablementChanged@Slider@juce@@MAEXXZ)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::focusOfChildComponentChanged(enum juce::Component::FocusChangeType)" (?focusOfChildComponentChanged@Slider@juce@@MAEXW4FocusChangeType@Component@2@@Z)
1>MediatorColourSelector.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall juce::Slider::colourChanged(void)" (?colourChanged@Slider@juce@@MAEXXZ)

...Which is weird, I don't know what could have caused it really!

Any ideas?

The class the above pertains to is at the end of this post, it contains few changes compared to the ColourSelector I copied to base it on. I checked the juce_ColourSelector equivalents against mine to see if there were any important differences, but I could only see my own changes, no singatures or other seemed to have been changed...

 

MediatorColourSelector.h



#ifndef MEDIATOR_COLOURSELECTOR_H_INCLUDED
#define MEDIATOR_COLOURSELECTOR_H_INCLUDED

#include "../../../../../JuceLibraryCode/JuceHeader.h"

//==============================================================================
/**
    A component that lets the user choose a colour.

    This shows RGB sliders and a colourspace that the user can pick colours from.

    This class is also a ChangeBroadcaster, so listeners can register to be told
    when the colour changes.
*/

class MediatorColourSelector : public Component,
                                public ChangeBroadcaster,
                                protected juce::Slider::Listener
{
public:

    //==============================================================================
    /** Options for the type of selector to show. These are passed into the constructor. */
    enum ColourSelectorOptions
    {
        showAlphaChannel    = 1 << 0,   /**< if set, the colour's alpha channel can be changed as well as its RGB. */

        showColourAtTop     = 1 << 1,   /**< if set, a swatch of the colour is shown at the top of the component. */
        showSliders         = 1 << 2,   /**< if set, RGB sliders are shown at the bottom of the component. */
        showColourspace     = 1 << 3    /**< if set, a big HSV selector is shown. */
    };

    //==============================================================================
    /** Creates a ColourSelector object.

        The flags are a combination of values from the ColourSelectorOptions enum, specifying
        which of the selector's features should be visible.

        The edgeGap value specifies the amount of space to leave around the edge.

        gapAroundColourSpaceComponent indicates how much of a gap to put around the
        colourspace and hue selector components.
    */
    MediatorColourSelector (int sectionsToShow = (showAlphaChannel | showColourAtTop | showSliders | showColourspace),
                    int edgeGap = 4,
                    int gapAroundColourSpaceComponent = 7);

    /** Destructor. */
    ~MediatorColourSelector();

    //==============================================================================
    /** Returns the colour that the user has currently selected.

        The ColourSelector class is also a ChangeBroadcaster, so listeners can
        register to be told when the colour changes.

        @see setCurrentColour
    */
    Colour getCurrentColour() const;

    /** Changes the colour that is currently being shown.
    */
    void setCurrentColour (Colour newColour);

    //==============================================================================
    /** Tells the selector how many preset colour swatches you want to have on the component.

        To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
        setSwatchColour(), to return the number of colours you want, and to set and retrieve
        their values.
    */
    virtual int getNumSwatches() const;

    /** Called by the selector to find out the colour of one of the swatches.

        Your subclass should return the colour of the swatch with the given index.

        To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
        setSwatchColour(), to return the number of colours you want, and to set and retrieve
        their values.
    */
    virtual Colour getSwatchColour (int index) const;

    /** Called by the selector when the user puts a new colour into one of the swatches.

        Your subclass should change the colour of the swatch with the given index.

        To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
        setSwatchColour(), to return the number of colours you want, and to set and retrieve
        their values.
    */
    virtual void setSwatchColour (int index, const Colour& newColour) const;

    //==============================================================================
    /** A set of colour IDs to use to change the colour of various aspects of the keyboard.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId              = 0x1007000,    /**< the colour used to fill the component's background. */
        labelTextColourId               = 0x1007001     /**< the colour used for the labels next to the sliders. */
    };

private:
    //==============================================================================
    class AlphaComp;
    
    

    class ColourSpaceView;
    class HueSelectorComp;
    class SwatchComponent;
    class ColourComponentSlider;
    class ColourSpaceMarker;
    class HueSelectorMarker;
    friend class ColourSpaceView;
    friend struct ContainerDeletePolicy<ColourSpaceView>;
    friend class HueSelectorComp;
    friend struct ContainerDeletePolicy<HueSelectorComp>;

    Colour colour;
    float h, s, v, a;
    ScopedPointer<Slider> sliders[4];
    ScopedPointer<ColourSpaceView> colourSpace;
    ScopedPointer<HueSelectorComp> hueSelector;

    ScopedPointer<AlphaComp> alphaSelector;

    OwnedArray <SwatchComponent> swatchComponents;
    const int flags;
    int edgeGap;
    Rectangle<int> previewArea;

    void setHue (float newH);
    void setSV (float newS, float newV);
    
    void setAlpha (float newAlpha);
    
    void updateHSV();
    void update();
    void sliderValueChanged (Slider*);
    void paint (Graphics&) override;
    void resized() override;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MediatorColourSelector)
};

#endif   // MEDIATOR_COLOURSELECTOR_H_INCLUDED

MediatorColourSelector.cpp

#include "MediatorColourSelector.h"

#include "../../../../../JuceLibraryCode/JuceHeader.h"

class MediatorColourSelector::ColourComponentSlider : public Slider
{
public:
    ColourComponentSlider(const String& name)
        : Slider(name)
    {
        setRange(0.0, 255.0, 1.0);
    }

    String getTextFromValue(double value)
    {
        return String::toHexString((int)value).toUpperCase().paddedLeft('0', 2);
    }

    double getValueFromText(const String& text)
    {
        return (double)text.getHexValue32();
    }

private:
    JUCE_DECLARE_NON_COPYABLE(ColourComponentSlider)
};

//==============================================================================
class MediatorColourSelector::ColourSpaceMarker  : public Component
{
public:
    ColourSpaceMarker()
    {
        setInterceptsMouseClicks (false, false);
    }

    void paint (Graphics& g) override
    {
        g.setColour (Colour::greyLevel (0.1f));
        g.drawEllipse (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 1.0f);
        g.setColour (Colour::greyLevel (0.9f));
        g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 1.0f);
    }

private:
    JUCE_DECLARE_NON_COPYABLE (ColourSpaceMarker)
};

//==============================================================================
class MediatorColourSelector::ColourSpaceView  : public Component
{
public:
    ColourSpaceView (MediatorColourSelector& cs, float& hue, float& sat, float& val, const int edgeSize)
        : owner (cs), h (hue), s (sat), v (val), lastHue (0.0f), edge (edgeSize)
    {
        addAndMakeVisible (marker);
        setMouseCursor (MouseCursor::CrosshairCursor);
    }

    void paint (Graphics& g) override
    {
        if (colours.isNull())
        {
            const int width = getWidth() / 2;
            const int height = getHeight() / 2;
            colours = Image (Image::RGB, width, height, false);

            Image::BitmapData pixels (colours, Image::BitmapData::writeOnly);

            for (int y = 0; y < height; ++y)
            {
                const float val = 1.0f - y / (float) height;

                for (int x = 0; x < width; ++x)
                {
                    const float sat = x / (float) width;
                    pixels.setPixelColour (x, y, Colour (h, sat, val, 1.0f));
                }
            }
        }

        g.setOpacity (1.0f);
        g.drawImageTransformed (colours,
                                RectanglePlacement (RectanglePlacement::stretchToFit)
                                    .getTransformToFit (colours.getBounds().toFloat(),
                                                        getLocalBounds().reduced (edge).toFloat()),
                                false);
    }

    void mouseDown (const MouseEvent& e) override
    {
        mouseDrag (e);
    }

    void mouseDrag (const MouseEvent& e) override
    {
        const float sat = (e.x - edge) / (float) (getWidth() - edge * 2);
        const float val = 1.0f - (e.y - edge) / (float) (getHeight() - edge * 2);

        owner.setSV (sat, val);
    }

    void updateIfNeeded()
    {
        if (lastHue != h)
        {
            lastHue = h;
            colours = Image::null;
            repaint();
        }

        updateMarker();
    }

    void resized() override
    {
        colours = Image::null;
        updateMarker();
    }

private:
    MediatorColourSelector& owner;
    float& h;
    float& s;
    float& v;
    float lastHue;
    ColourSpaceMarker marker;
    const int edge;
    Image colours;

    void updateMarker()
    {
        marker.setBounds (roundToInt ((getWidth() - edge * 2) * s),
                          roundToInt ((getHeight() - edge * 2) * (1.0f - v)),
                          edge * 2, edge * 2);
    }

    JUCE_DECLARE_NON_COPYABLE (ColourSpaceView)
};

//==============================================================================
class MediatorColourSelector::HueSelectorMarker  : public Component
{
public:
    HueSelectorMarker()
    {
        setInterceptsMouseClicks (false, false);
    }

    void paint (Graphics& g) override
    {
        const float cw = (float) getWidth();
        const float ch = (float) getHeight();

        Path p;
        p.addTriangle (1.0f, 1.0f,
                       cw * 0.3f, ch * 0.5f,
                       1.0f, ch - 1.0f);

        p.addTriangle (cw - 1.0f, 1.0f,
                       cw * 0.7f, ch * 0.5f,
                       cw - 1.0f, ch - 1.0f);

        g.setColour (Colours::white.withAlpha (0.75f));
        g.fillPath (p);

        g.setColour (Colours::black.withAlpha (0.75f));
        g.strokePath (p, PathStrokeType (1.2f));
    }

private:
    JUCE_DECLARE_NON_COPYABLE (HueSelectorMarker)
};

//// ILIAS

class MediatorColourSelector::AlphaComp  : public Component
{
public:
    AlphaComp (MediatorColourSelector& cs, float& alpha, const int edgeSize)
        : owner (cs), a (alpha), edge (edgeSize) {
        addAndMakeVisible (marker);
    }

    void paint (Graphics& g) override {
        ColourGradient cg;
        cg.isRadial = false;
        cg.point1.setXY (0.0f, (float) edge);
        cg.point2.setXY (0.0f, (float) (getHeight() - edge));

        cg.addColour (0, Colours::black);
        cg.addColour (1, Colours::white);
        
        g.setGradientFill (cg);
        g.fillRect (getLocalBounds().reduced (edge));
    }

    void resized() override {
        float height = getHeight() - edge * 2;
        marker.setBounds (0, roundToInt(height-height * a), getWidth(), edge * 2);
    }

    void mouseDown (const MouseEvent& e) override {
        mouseDrag (e);
    }

    void mouseDrag (const MouseEvent& e) override {
        float height = getHeight() - edge * 2;

        owner.setAlpha ((height-(e.y - edge)) / height);
    }

    void updateIfNeeded() {
        resized();
    }

private:
    MediatorColourSelector& owner;
    float& a;
    HueSelectorMarker marker;
    const int edge;

    JUCE_DECLARE_NON_COPYABLE (AlphaComp)
};

////////////

//==============================================================================
class MediatorColourSelector::HueSelectorComp  : public Component
{
public:
    HueSelectorComp (MediatorColourSelector& cs, float& hue, const int edgeSize)
        : owner (cs), h (hue), edge (edgeSize)
    {
        addAndMakeVisible (marker);
    }

    void paint (Graphics& g) override
    {
        ColourGradient cg;
        cg.isRadial = false;
        cg.point1.setXY (0.0f, (float) edge);
        cg.point2.setXY (0.0f, (float) (getHeight() - edge));

        for (float i = 0.0f; i <= 1.0f; i += 0.02f)
            cg.addColour (i, Colour (i, 1.0f, 1.0f, 1.0f));

        g.setGradientFill (cg);
        g.fillRect (getLocalBounds().reduced (edge));
    }

    void resized() override
    {
        marker.setBounds (0, roundToInt ((getHeight() - edge * 2) * h), getWidth(), edge * 2);
    }

    void mouseDown (const MouseEvent& e) override
    {
        mouseDrag (e);
    }

    void mouseDrag (const MouseEvent& e) override
    {
        owner.setHue ((e.y - edge) / (float) (getHeight() - edge * 2));
    }

    void updateIfNeeded()
    {
        resized();
    }

private:
    MediatorColourSelector& owner;
    float& h;
    HueSelectorMarker marker;
    const int edge;

    JUCE_DECLARE_NON_COPYABLE (HueSelectorComp)
};

//==============================================================================
class MediatorColourSelector::SwatchComponent   : public Component
{
public:
    SwatchComponent (MediatorColourSelector& cs, int itemIndex)
        : owner (cs), index (itemIndex)
    {
    }

    void paint (Graphics& g) override
    {
        const Colour c (owner.getSwatchColour (index));

        g.fillCheckerBoard (getLocalBounds(), 6, 6,
                            Colour (0xffdddddd).overlaidWith (c),
                            Colour (0xffffffff).overlaidWith (c));
    }

    void mouseDown (const MouseEvent&) override
    {
        PopupMenu m;
        m.addItem (1, TRANS("Use this swatch as the current colour"));
        m.addSeparator();
        m.addItem (2, TRANS("Set this swatch to the current colour"));

        m.showMenuAsync (PopupMenu::Options().withTargetComponent (this),
                         ModalCallbackFunction::forComponent (menuStaticCallback, this));
    }

private:
    MediatorColourSelector& owner;
    const int index;

    static void menuStaticCallback (int result, SwatchComponent* comp)
    {
        if (comp != nullptr)
        {
            if (result == 1)
                comp->setColourFromSwatch();
            else if (result == 2)
                comp->setSwatchFromColour();
        }
    }

    void setColourFromSwatch()
    {
        owner.setCurrentColour (owner.getSwatchColour (index));
    }

    void setSwatchFromColour()
    {
        if (owner.getSwatchColour (index) != owner.getCurrentColour())
        {
            owner.setSwatchColour (index, owner.getCurrentColour());
            repaint();
        }
    }

    JUCE_DECLARE_NON_COPYABLE (SwatchComponent)
};

//==============================================================================
MediatorColourSelector::MediatorColourSelector (const int sectionsToShow, const int edge, const int gapAroundColourSpaceComponent)
    : colour (Colour::fromFloatRGBA(1.0f,1.0f,1.0f,1.0f)),
      flags (sectionsToShow),
      edgeGap (edge)
{
    // not much point having a selector with no components in it!
    jassert ((flags & (showColourAtTop | showSliders | showColourspace)) != 0);

    updateHSV();

    if ((flags & showSliders) != 0)
    {
        addAndMakeVisible (sliders[0] = new ColourComponentSlider (TRANS ("red")));
        addAndMakeVisible (sliders[1] = new ColourComponentSlider (TRANS ("green")));
        addAndMakeVisible (sliders[2] = new ColourComponentSlider (TRANS ("blue")));
        addChildComponent (sliders[3] = new ColourComponentSlider (TRANS ("alpha")));

        sliders[3]->setVisible ((flags & showAlphaChannel) != 0);

        for (int i = 4; --i >= 0;)
            sliders[i]->addListener (this);
    }

    if ((flags & showColourspace) != 0)
    {
        addAndMakeVisible (colourSpace = new ColourSpaceView (*this, h, s, v, gapAroundColourSpaceComponent));
        addAndMakeVisible (hueSelector = new HueSelectorComp (*this, h,  gapAroundColourSpaceComponent));

        if ((flags & showAlphaChannel) != 0)
        {
            addAndMakeVisible (alphaSelector = new AlphaComp (*this, a,  gapAroundColourSpaceComponent));
        }
    }

    update();
}

MediatorColourSelector::~MediatorColourSelector()
{
    dispatchPendingMessages();
    swatchComponents.clear();
}

//==============================================================================
Colour MediatorColourSelector::getCurrentColour() const
{
    return colour;
}

void MediatorColourSelector::setCurrentColour (Colour c)
{
    if (c != colour)
    {
        colour = c;
        updateHSV();
        update();
    }
}

void MediatorColourSelector::setHue (float newH)
{
    newH = jlimit (0.0f, 1.0f, newH);

    if (h != newH)
    {
        h = newH;
        colour = Colour (h, s, v, a);
        update();
    }
}

///// ILIAS

void MediatorColourSelector::setAlpha (float newAlpha) {
    newAlpha = jlimit (0.0f, 1.0f, newAlpha);

    if (a != newAlpha) {
        a = newAlpha;
        colour = Colour (h, s, v, a);
        update();
    }
}

///////////

void MediatorColourSelector::setSV (float newS, float newV)
{
    newS = jlimit (0.0f, 1.0f, newS);
    newV = jlimit (0.0f, 1.0f, newV);

    if (s != newS || v != newV)
    {
        s = newS;
        v = newV;
        colour = Colour (h, s, v, a);
        update();
    }
}

//==============================================================================
void MediatorColourSelector::updateHSV()
{
    colour.getHSB (h, s, v);

    if ((flags & showAlphaChannel) != 0)
    {
        a = colour.getFloatAlpha();
    }
}

void MediatorColourSelector::update()
{
    if (sliders[0] != nullptr)
    {
        sliders[0]->setValue ((int) colour.getRed());
        sliders[1]->setValue ((int) colour.getGreen());
        sliders[2]->setValue ((int) colour.getBlue());
        sliders[3]->setValue ((int) colour.getAlpha());
    }

    if (colourSpace != nullptr)
    {
        colourSpace->updateIfNeeded();
        hueSelector->updateIfNeeded();

        if ((flags & showAlphaChannel) != 0)
        {
            alphaSelector->updateIfNeeded();
        }
    }

    if ((flags & showColourAtTop) != 0)
        repaint (previewArea);

    sendChangeMessage();
}

//==============================================================================
void MediatorColourSelector::paint (Graphics& g)
{
    g.fillAll (findColour (backgroundColourId));

    if ((flags & showColourAtTop) != 0)
    {
        const Colour currentColour (getCurrentColour());

        g.fillCheckerBoard (previewArea, 10, 10,
                            Colour (0xffdddddd).overlaidWith (currentColour),
                            Colour (0xffffffff).overlaidWith (currentColour));

        g.setColour (Colours::white.overlaidWith (currentColour).contrasting());
        g.setFont (Font (14.0f, Font::bold));
        g.drawText (currentColour.toDisplayString ((flags & showAlphaChannel) != 0),
                    previewArea, Justification::centred, false);
    }

    if ((flags & showSliders) != 0)
    {
        g.setColour (findColour (labelTextColourId));
        g.setFont (11.0f);

        for (int i = 4; --i >= 0;)
        {
            if (sliders[i]->isVisible())
                g.drawText (sliders[i]->getName() + ":",
                            0, sliders[i]->getY(),
                            sliders[i]->getX() - 8, sliders[i]->getHeight(),
                            Justification::centredRight, false);
        }
    }
}

void MediatorColourSelector::resized()
{
    const int swatchesPerRow = 8;
    const int swatchHeight = 22;

    const int numSliders = ((flags & showAlphaChannel) != 0) ? 4 : 3;
    const int numSwatches = getNumSwatches();

    const int swatchSpace = numSwatches > 0 ? edgeGap + swatchHeight * ((numSwatches + 7) / swatchesPerRow) : 0;
    const int sliderSpace = ((flags & showSliders) != 0)  ? jmin (22 * numSliders + edgeGap, proportionOfHeight (0.3f)) : 0;
    const int topSpace = ((flags & showColourAtTop) != 0) ? jmin (30 + edgeGap * 2, proportionOfHeight (0.2f)) : edgeGap;

    previewArea.setBounds (edgeGap, edgeGap, getWidth() - edgeGap * 2, topSpace - edgeGap * 2);

    int y = topSpace;

    if ((flags & showColourspace) != 0)
    {
        const int hueWidth = jmin (50, proportionOfWidth (0.15f));

        if ((flags & showAlphaChannel) != 0){
            colourSpace->setBounds (edgeGap, y,
                                    getWidth() - 2*hueWidth - edgeGap - 4,
                                    getHeight() - topSpace - sliderSpace - swatchSpace - edgeGap);

            hueSelector->setBounds (colourSpace->getRight() + 4, y,
                                    getWidth() - edgeGap - hueWidth - (colourSpace->getRight() + 4),
                                    colourSpace->getHeight());

            alphaSelector->setBounds (hueSelector->getRight() + 4, y,
                                    getWidth() - edgeGap - hueWidth - (colourSpace->getRight() + 4),
                                    colourSpace->getHeight());
            
            y = getHeight() - sliderSpace - swatchSpace - edgeGap;
        }
        else {
            const int hueWidth = jmin (50, proportionOfWidth (0.15f));

            colourSpace->setBounds (edgeGap, y,
                                    getWidth() - hueWidth - edgeGap - 4,
                                    getHeight() - topSpace - sliderSpace - swatchSpace - edgeGap);

            hueSelector->setBounds (colourSpace->getRight() + 4, y,
                                    getWidth() - edgeGap - (colourSpace->getRight() + 4),
                                    colourSpace->getHeight());

            y = getHeight() - sliderSpace - swatchSpace - edgeGap;
        }

        
    }

    if ((flags & showSliders) != 0)
    {
        const int sliderHeight = jmax (4, sliderSpace / numSliders);

        for (int i = 0; i < numSliders; ++i)
        {
            sliders[i]->setBounds (proportionOfWidth (0.2f), y,
                                   proportionOfWidth (0.72f), sliderHeight - 2);

            y += sliderHeight;
        }
    }

    if (numSwatches > 0)
    {
        const int startX = 8;
        const int xGap = 4;
        const int yGap = 4;
        const int swatchWidth = (getWidth() - startX * 2) / swatchesPerRow;
        y += edgeGap;

        if (swatchComponents.size() != numSwatches)
        {
            swatchComponents.clear();

            for (int i = 0; i < numSwatches; ++i)
            {
                SwatchComponent* const sc = new SwatchComponent (*this, i);
                swatchComponents.add (sc);
                addAndMakeVisible (sc);
            }
        }

        int x = startX;

        for (int i = 0; i < swatchComponents.size(); ++i)
        {
            SwatchComponent* const sc = swatchComponents.getUnchecked(i);

            sc->setBounds (x + xGap / 2,
                           y + yGap / 2,
                           swatchWidth - xGap,
                           swatchHeight - yGap);

            if (((i + 1) % swatchesPerRow) == 0)
            {
                x = startX;
                y += swatchHeight;
            }
            else
            {
                x += swatchWidth;
            }
        }
    }
}

void MediatorColourSelector::sliderValueChanged (Slider*)
{
    if (sliders[0] != nullptr)
        setCurrentColour (Colour ((uint8) sliders[0]->getValue(),
                                  (uint8) sliders[1]->getValue(),
                                  (uint8) sliders[2]->getValue(),
                                  (uint8) sliders[3]->getValue()));
}

//==============================================================================
int MediatorColourSelector::getNumSwatches() const
{
    return 0;
}

Colour MediatorColourSelector::getSwatchColour (const int) const
{
    jassertfalse; // if you've overridden getNumSwatches(), you also need to implement this method
    return Colours::black;
}

void MediatorColourSelector::setSwatchColour (const int, const Colour&) const
{
    jassertfalse; // if you've overridden getNumSwatches(), you also need to implement this method
}

 


#2

I found a hack that resolves it temporarily:

In juce_Slider.h in the latest tip, "protected:" had been removed from just above void paint(...) etc.

Putting it back resolved my issue. ...But I can't keep doing that whenever I get the new JUCE tip... How could I fix this issue properly?

Thanks!


#3

When you have such issue after an update, I strongly suggest to first try a clean build.(rebuild all)


#4

And make sure you're not mis-matching headers and cpp files which come from different versions of the library.


#5

Hi!

That was it!

I had done a clean rebuild before of course, that didn't fix it. But making a new introjuicer project from a fresh clone off the git repo did.

I don't know how or when it happened, somehow along the way of updating JUCE from GIT and updating the project, with copying the modules to my project, it broke...

Thank you!