Coding questions... can you help?


#1

Hi there,

all the coding gods. can you help ?

How can I do (something like) this:

stepButtons[0].onClick = [this] {toggleClicked(variable); };

The (pre) complier claims that this cannot be done inside the lamda as the variable is not known yet. Is there another way? I read some goole, but I did not grasp it tbh…

2nd Question:

Creating my own class:

class StepSequencerPatternEditor : public Component
{
public:
GroupComponent firstQuarter;
ToggleButton onOff;
TextButton stepButtons[4];
int currentPattern[4] = { -1,-1,-1,-1 };
int myPatternPos = 0;

StepSequencerPatternEditor()
{
	addAndMakeVisible(firstQuarter);
	for (int i = 0; i <= 3; ++i)
	{
		addAndMakeVisible(stepButtons[i]);
		stepButtons[i].setButtonText(String(currentPattern[i]));
	}

	stepButtons[0].onClick = [this] {toggleClicked(0); };
	stepButtons[1].onClick = [this] {toggleClicked(1); };
	stepButtons[2].onClick = [this] {toggleClicked(2); };
	stepButtons[3].onClick = [this] {toggleClicked(3); };
}

~StepSequencerPatternEditor() {

}

void paint(Graphics& g)
{
	g.fillAll(Colours::darkgrey);
}

void resized()
{
	firstQuarter.setBounds(getLocalBounds());
	Rectangle<int> buttonBounds = firstQuarter.getBounds().removeFromBottom(50);
	Rectangle<int> stepBounds;

	for (int i = 0; i <= 3; ++i)
	{
		stepBounds= buttonBounds.removeFromLeft(firstQuarter.getWidth() / 4);
		stepBounds.reduce(5, 5);
		stepButtons[i].setBounds(stepBounds);
	}
}

void  toggleClicked(int stepNote)
{
	currentPattern[stepNote] = currentPattern[stepNote] * -1;
	stepButtons[stepNote].setButtonText(String(currentPattern[stepNote]));
	
}

void setName(String name) 
{
	firstQuarter.setText(name);
}
private:
 
};

It works nicely, but I would like to pass it values on Construction:

StepSequencerPatternEditor myEditor ("Name");

I get the error “trying to access a deleted function”

I also would like to access the processor, but I can not, how do I refer to it? Maybe I just derive from something else?

Thanks in advance,

Jens


#2

If “variable” is not a member variable of the class in scope it can’t be used inside the lambda that way. (“this” just captures the object instance of the current class.) You need to capture it separately into the lambda. [this,variable] as the capture may work if “variable” is a local variable in the code where you declare the lambda.


#3

Thanks for the fast answer!

It actually IS a local variable, but it does not work. It has something to do with the value not being known at compile time, so I need kind of an “eval” statement…


#4

Code like this should work, but of course since you didn’t provide any additional details, I can’t know what is wrong for you :

int variable = 0;
stepButtons[0].onClick = [this,variable] () {toggleClicked(variable); };

(That would assume toggleClicked has a signature like void toggleClicked(int whichbutton))


#5

Hey very nice,

that worked, I just missed the () after [this,variable]

Thanks so much for the instant help :wink:


#6

In some compilers it works even without the (), but that may be a C++17 or later addition into the language…


#7

Its just Visual Studio 2017 here…


#8

Same here, but I have the “latest draft standard” option enabled in the language settings…


#9

You do not have by chance an idea on my other problems?

Do not want to seem greedy, but you seem to know your way round :wink:


#10

For your class problem, you need to add a constructor that can take in the parameters you need. Your current implementation has only the default constructor.

Default constructor :

StepSequencerPatternEditor()
{ 
  ...
}

An example of a constructor with parameters :

StepSequencerPatternEditor(String name, MyAudioProcessor& proc) 
: m_name(name), m_processor(proc) 
{
  ...
}

But the exact way you would write it, depends on your class(es) involved.


#11

Funny,

it stops working as soon as I derive from a Juce class. If I just define a class it works fine and dandy…

class MyClass 
{
public:
   MyClass(String gaga);
   ~MyClass();
   String m_gaga="test";

private:

};

This code is in the .cpp not in the header:

MyClass::MyClass(String gaga) : m_gaga(gaga)
{
}

MyClass::~MyClass()
{
}

So the above is working, the following is not:

class MyClass : public Component

All the rest of the code is completely the same… I can pass a string and see it no problem…

This on brings the error seen here, which translated to english means no suitable constructor found. So what do I have to derive from to be able to to it?

I kind of lost the plot here, do not see anything wrond …


#12

This works just fine (It doesn’t matter this is a header only implementation.) :

class MyComponent : public Component
{
public:
    MyComponent(String gaga) : m_gaga(gaga)
    {}
private:
    String m_gaga;
};

Of course the object has to be instantiated correctly elsewhere. Since there’s no default constructor, it can’t be used without giving the constructor arguments.


#13

Did you actually try to instatiate? Because as long as you don’t it does not complain :wink:


#14

Yes, I put it into another class as a member like this :

MyComponent m_gagacomp{"foo name"};

However, I am not sure how AudioProcessorEditor plays into all this…(Which the compiler is complaining about.)


#15

I found it. I was not using

MyClass myClass {"foo name"}

but

MyClass myCLass ("foo name");

interestingly enough it worked as long as it was not derived from Component…

Thank you for all the help and the time !


#16

When you’re deriving from juce::Component, it has its own constructor with the signature:

juce::Component::Component(const juce::String&)

That constructor is used to initialize a component with a given name. I believe your error was because the MyClass constructor takes a string as well, but does not call any constructor of the class it derived from. You could give this a try:

class MyClass : public juce::Component
{
public:
    // This could either initialize m_gaga or set the juce::Component name, depending on what
    // you really need
    MyClass(const juce::String &s) : juce::Component(), m_gaga(s) {}
    juce::String m_gaga;
};

From my understanding, the bracket syntax {} would initialize the member without actually calling a class constructor, which is why you’re not getting the error now.


#17

It does call the constructor as expected. (Tested with a breakpoint inside the constructor body.)

But yeah, having a component subclass with a constructor that only takes in a String can be a bit confusing because the Juce Component class also has the constructor taking in a String. (A const String&, though…)


#18

Guys,

I learned so much today ! Thanks a lot !

It works fine now !

Jens


#19

Ah you’re right :slight_smile: I haven’t used that much myself in C++ so I was thinking of it incorrectly