Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Trusted Contributor
Brennan12325
Posts: 204
Registered: ‎05-15-2012
My Device: None
Accepted Solution

Compare a labels color in QML

How can I compare the color of a label in QML to another Color. My code below does not work as I'd expect it to. Despite the "scoreLabel" having color "Color.DarkGray" the if statements returns true.

 

I also tried comparing it to the Color.create() color, but that does not work as expected either.

 

if(scoreLabel.textStyle.color != Color.DarkGray/*Color.create("#f89e52")*/){
	scoreLabel.textStyle.color = Color.DarkGray;

//Otherwise make it orange.
} else {
	scoreLabel.textStyle.color = Color.create("#f89e52")
}

 

----------------------
Check out my app, Alien Flow for reddit

And of course, like my post if you found it helpful or informative!
Please use plain text.
Trusted Contributor
Brennan12325
Posts: 204
Registered: ‎05-15-2012
My Device: None

Re: Compare a labels color in QML

They do seem to be of the same type, in any case. When I log them I get this:

 

console.log(scoreLabel.textStyle.color);
console.log(Color.DarkGray);

 outputs:

QVariant(bb::cascades::Color)
QVariant(bb::cascades::Color)

 

 

----------------------
Check out my app, Alien Flow for reddit

And of course, like my post if you found it helpful or informative!
Please use plain text.
Developer
Zmey
Posts: 1,512
Registered: ‎12-18-2012
My Device: PlayBook, Z10, DAC

Re: Compare a labels color in QML

[ Edited ]

Could you please try:
if (scoreLabel.textStyle.color.toString() != Color.DarkGray.toString())
But most likely this won't work.

 

I've checked Color class source code and there are operator== and operator!= defined. I don't think QML can use them though. It seems all instances are wrapped in QVariants which can't be directly compared.

 

And Color class doesn't seem to support a conversion to string, so comparing them as strings also won't work.

 

A possible solution is creating a C++ function and exporting it to QML:

Q_INVOKABLE bool colorsEqual(Color *color1, Color *color2)
{
  return *color1 == *color2;
}

UPD: Color is declared as meta-type in Cascades headers but pointer to it is not:

resources/color.h:Q_DECLARE_METATYPE(bb::cascades::Color).

 

If the above function won't work, try the following:

Q_INVOKABLE bool colorsEqual(const Color &color1, const Color &color2)
{
return color1 == color2;
}
...or...
Q_INVOKABLE bool colorsEqual(Color color1, Color color2)
...

Try experimenting with different forms, I'm not sure which one will work.

 


Andrey Fidrya, @zmeyc on twitter
Please use plain text.
Trusted Contributor
Brennan12325
Posts: 204
Registered: ‎05-15-2012
My Device: None

Re: Compare a labels color in QML

if(scoreLabel.textStyle.color.toString() == Color.DarkGray.toString())

 this seems to always return true, strangely. I will try the C++ solution and see how that works. I would imagine it will work, seems like a good solution.

----------------------
Check out my app, Alien Flow for reddit

And of course, like my post if you found it helpful or informative!
Please use plain text.
Developer
Zmey
Posts: 1,512
Registered: ‎12-18-2012
My Device: PlayBook, Z10, DAC

Re: Compare a labels color in QML

An easier solution might be adding a custom property to a label to track the state:

property int stateOne: 0
property int stateTwo: 1

Label
{
id: scoreLabel
property int state: stateOne
}

...
if (scoreLabel.state == stateOne)
scoreLabel.textStyle.color = ...
etc

Andrey Fidrya, @zmeyc on twitter
Please use plain text.
Trusted Contributor
Brennan12325
Posts: 204
Registered: ‎05-15-2012
My Device: None

Re: Compare a labels color in QML

[ Edited ]

I can't get any of the equals methods working.

 

Error: Unknown method parameter type: Color

 

for the second two and

 

Error: Unknown method parameter type: Color*

 

for the first one.

 

I'll have to look into propertys, I guess. There's no way to change a property at runtime, is there? I'm not sure I can do all my logic with just a single state.

 

For instance, if the label starts black and has state1 when an action is performed I need to switch it to color orange. Orange would be state2. Now If I need to reset that back to black I still have the state assigned to it indicating that the color is black, since I couldn't change the state to state2.

 

Any ideas?

 

I'm starting to think it might be quicker to rewrite the entire list in C++ -__- QML is nothing but trouble.

----------------------
Check out my app, Alien Flow for reddit

And of course, like my post if you found it helpful or informative!
Please use plain text.
Developer
Zmey
Posts: 1,512
Registered: ‎12-18-2012
My Device: PlayBook, Z10, DAC

Re: Compare a labels color in QML

[ Edited ]

I'll try to experiment with C++ function exporting too.

 

The following code seems to work:

 

// Navigation pane project template
import bb.cascades 1.0

Page {
    Container {
        Label {
            id: label
            textStyle { base: style1.style }
            text: "Label text"
        }
        Button {
            id: button
            text: "Click me"
            property variant activeStyle: style1
            onClicked: {
                if (activeStyle == style1) {
                    label.textStyle.base = style2.style
                    activeStyle = style2
                } else {
                    label.textStyle.base = style1.style
                    activeStyle = style1
                }
            }
        }
        attachedObjects: [
            TextStyleDefinition {
                id: style1
                color: Color.create("#ff0000")
            },
            TextStyleDefinition {
                id: style2
                color: Color.create("#00ff00")
            }
        ]
    }
}

Directly swapping the colors should also work. Properties can be reassigned at runtime.

 

 


 

Ok, the C++ method also works. But I think the one with states is better.

 

QML:

 

// Navigation pane project template
import bb.cascades 1.0

Page {
    Container {
        Label {
            id: label
            textStyle { color: Color.create("#ff0000") }
            text: "Label text"
        }
        Button {
            id: button
            text: "Click me"
            onClicked: {
                if (app.colorsEqual(label.textStyle.color, Color.create("#ff0000"))) {
                    label.textStyle.color = Color.create("#00ff00")
                } else {
                    label.textStyle.color = Color.create("#ff0000")
                }
            }
        }
    }
}

 

Test.hpp:

#include <bb/cascades/Color>

class Test : public QObject { Q_OBJECT public: Test(bb::cascades::Application *app); virtual ~Test() {} Q_INVOKABLE bool colorsEqual(bb::cascades::Color color1, bb::cascades::Color color2); };

 Test.cpp:

Test::Test(bb::cascades::Application *app)
: QObject(app)
{
  ...
    qml->setContextProperty("app", this); // <--------- ADDED
    AbstractPane *root = qml->createRootObject<AbstractPane>();
    app->setScene(root);

 ...

bool Test::colorsEqual(Color color1, Color color2)
{
	return color1 == color2;
}

 


Andrey Fidrya, @zmeyc on twitter
Please use plain text.
Trusted Contributor
Brennan12325
Posts: 204
Registered: ‎05-15-2012
My Device: None

Re: Compare a labels color in QML

I was able to solve my problem with a variant. The reason I thought they couldn't be assigned at run time was because when I tried to conditionally set the variant with an if statement, I got a syntax error. Of course, I might just not know the correct syntax to do it, but this won't work:

 

property variant activeStyle: if(ListItemData.num == 0) {style1} else {style2}

However, by assigning the variant in the onCreationCompleted method of the label, I was able to skirt around that problem.

 

Thanks for your help!

----------------------
Check out my app, Alien Flow for reddit

And of course, like my post if you found it helpful or informative!
Please use plain text.