So, i’ve scoured the forum for info about this class. You can use it to see if a value changes, which works well. But how are we supposed to query what this new value is?
Example: Value v; v.setValue(false); //now it's a boolean
Somewhere else, we have a listener who is responding to changes to v;
void MyClass::valueChanged(juce::Value &value) {
if( value == v ) {...}
}
but now what? how do we take the next step and if( value == true ) { } else { }
?
the closest thing i’ve found is: if( value.getValue().equals( juce::var(false) ) ) { }
class Channels : public Component, public Value::Listener {
public:
...
Channels();
void ValueChanged( Value& value ) override;
private:
...
const std::vector<unique_ptr<MidiChannel>> channelSections;
};
Channels::Channels() {
...
//make 16 midiChannel objects
for( auto i = 0; i < 16; i++ ) { channelSections.push_back(...); }
...
for( auto i = 0; i < channelSections.size(); i++ ) {
//add listeners to the isSelected member in the ActivityIndicator
channelSections[i]->getIsSelected().addListener(this);
}
}
Here’s the valueChanged callback:
void Channels::valueChanged(juce::Value &value) {
//how can we tell which value was used?
for(uint i = 0; i < channelSections.size(); ++i ) {
if( value == channelSections[i]->getIsSelected() ) {
DBG( "value changed: " + value.toString() + " channel: " + String(i) );
if( value == true ) { //if a channel was selected, deselect all other channels
for( uint j = 0; j < channelSections.size(); ++j ) {
if( j != i ) {
channelSections[j]->setIsSelected(false);
//DBG( "setting channel off: " + String(j) );
}
}
}
break;
}
}
}
If l click on Channel 8 to begin with, When I click on a channel LOWER than 8, it toggles correctly (channel 8 turns off, the other channel turns on). if I click on a channel HIGHER than 8, 8 doesn’t turn off, and the other channel doesn’t turn on either. The DBG( “value changed:” ) line prints out value changed: 1 channel: 8 value changed: 0 channel: 0
I have no idea what is causing that either. it’s driving me nuts!!
Anyone have any insight for determining the underlying type and being able to cast/store it that way for comparison?
I’m trying to determine if a juce::Value is between some values and it is not cooperating. Do i need to cast, or what?
i saw the Value::getValue() method, which returns the juce::var object, and from there, there is an operator overload method for int(), but I’m not sure how to use it.
Value bVal;
bVal.setValue (true);
if (bVal.getValue().isBool())
{
DBG ("It's a Bool");
}
if (bVal.getValue().isDouble())
{
DBG ("It's a Double");
}
double makeMineADouble = double (bVal.getValue()); // See Jules' next post, use a static_cast<double> (v)
// or implicit conversion
DBG ("bVal = " + bVal.getValue().toString());
DBG ("makeMineADouble = " + String (makeMineADouble, 3));
Value value;
auto v = value.getValue();
bool isBool = v.isBool();
bool isDouble = v.isDouble();
double asDouble = v;
C-style casts are a really bad idea when using non-primitive types, so never write double (bVal.getValue()). Instead just allow it to be implicitly converted (e.g. when you pass it as a function arg or if you assign it like in my example here), or do a static_cast<double> (v)
A proper tutorial showing how to use juce::Value in a class that has two different Value objects (each a different type like int and Array), and how to use valueChanged() in that class would be awesome!!
Ok, what about ++'ing or += 1’ing a juce::Value that is holding an int? I’m getting nothing but "Invalid operands to binary expression (‘juce::Value’ and ‘int’) for the line:
The Value class can contain strings, objects or arrays, so it’d make no sense to give it an operator like “+”. You’d need to actually get an integer before you try to add 1 to it, e.g.
in fact, the compiler should tell you when you have to use a cast. One reason might be, that there exist different types that provide implicit conversions from that object, like float or double.