change stroke of Widgets after creation

Hi

is there any possibility to reference the stroke of a Widget?

As an example the ButtonWidget-object. I would like to adjust the stroke after its creation.

I already tried:

local softEdgeButton = widget.newButton({ left = 140, top = 350, }) softEdgeButton.stroke = {type="image", filename="stroke/brush1.png"} softEdgeButton.strokeWidth = 2 softEdgeButton:setStrokeColor(0,0,0)

I thought that this must be possible since i assumed that the button is basically a simple display.newRect ?

But what is the correct hierarchy in the object model of a widget to reference its display-object?

Actually i want to find a solution for the anti-aliasing issue like described here and combine the solution with my customized widgets. But unfortunately I almost think that I have to build my very own widgets instead of using the widget library by corona labs? I would really not like to do that, because I do not not know much about building classes in Lua / Corona.

Thanks in advance.

Okay i think i figured it out by looking through the open source widget library.

For all others that are also looking for this:

Referencing the display-Object of a Widget is done like the following:

local softEdgeButton = widget.newButton({ left = 140, top = 350, }) softEdgeButton.\_view.strokeWidth = 25 softEdgeButton.\_view.stroke = {type="image", filename="stroke/brush1.png"} softEdgeButton:setStrokeColor(0,0,0)

Ok next Problem…
 
how do i set the color for the default and over state?
 
The following does not bring the desired result:

customWidget.\_view.\_strokeColor.default = {1,0,0} customWidget.\_view.\_strokeColor.over = {1,0,0}

By this the color just changes to nothing/transparent?

And when i set the color by 

softEdgeButton:setStrokeColor(1,0,0)

Then it changes it for both states. Any aproaches ?

I’m going to answer your widget stroke question but completely ignore the other question because it is (as you stated) the next problem and thus unrelated - please post new questions in *new* threads.

No, you should not be trying to set the stroke of a widget. Widgets are generated by using image sheets. Any mucking about with strokes will just make them look really bizarre and break their basic functionality. It may even get forcibly overridden by the widget library.

Take a look at the documentation for the widgets and you’ll see quite an expansive list of image sheet images which you can use to apply the different interface effects. Anything outside of that list is probably going to need a different type of input altogether.

Thank you for your answer and your time thinking about that! :slight_smile:

The “next problem” was directly related to the first one since I may have found out how to adress/reference the stroke for the default state but actually I need to reference both states. Because with my current solution it works fine but when I click the button the stroke will stay at the color, that I defined, for instance the default color(?!).

And unfortunately I have to set the stroke that way. This is because I am setting up a collection of customized widgets for. I have come so far that you can set the Design of the widgets via newButton({layout = 11}) for example, and the Button will be fully styled in a pre defined way. I store this definition in ja json-File. Those widgets should be furthermore be customizable later on, therefore the json-File. So and this customization process has to be easy later on, otherwise no one in my team wants to use it :wink: And using the “shape”-Version of the ButtonWidget, makes it a lot easier to maintain compared to the image or imageSheet versions.

What I have done so far is perfectly working without any problems but I was just not very satisfied by the outcome of the widget.newButton() when you use the “shape” version. the Edges of roundedRects do not look very nicely.

See this example App:

The two Blue Buttons (without label) are both my Widgets with customized Features. the right one looks  as if it has smooth edges and the left one has some aliasing. You can see the difference on some of the objects above too (red ones without smoothing function, black with)

You see, why I try to do it that way? I do not want to code a whole new Button Widget because that would mean all those work around Focus and lose of Focus while touching and all those other things coronalabs thankfully already provided.

EDIT: I forgot to add the Buttons in pressed State.

Figure 1.

Figure 1:The one without my function (with aliasing but no different strokeColor when clicked)

Figure 2.

Figure 2: The one with my “Fake”-Anti-Aliasing function (nearly without alisasing but with another strokeColor when in pressed state). I have to admit that the stroke can just barely be seen, but the effect is actually there and a little more concise on Phone and Simulator than on JPG :wink:

Just a suggestion… Our widget.newButton is designed to be for general use where we pass various parameters and create a generic button. If you can’t style it using the styling features we provide by passing parameters, I would not spend time monkeying under the hood with them. While you can take the open source library and alter it, I would argue it would be faster to use a pair of display.newRect() or display.newImageRect()'s drawn on top of each other (one for the up state and one for the down state), apply a touch handler to them and change visibility on them to show which ever one should show. You have direct access to the objects to style them as you see fit, all in about the same amount of code as it takes to create a widget.newButton in the first place providing the parameters to style the button.

Rob

Ah right that seems like a good idea.

  • build a function that builds two Rect-display objects
  • both same location and same width/height
  • respectively with the given filling color for default and over state
  • give the upper one (default state) a touch listener that sets the visibility to false and ‘object.isHitTestable=true’

Is this more or less what you meant with your suggestion? Because I do not really understand why you would add a touch handler to both of them and change the visibility of each?

Basically if you hide the top image to show the bottom one, you loose hitTestability on the top one, so you would want the touch listener active on the bottom one.  Setting .isHitTestable = true solves the issue and you would only need one handler.

But let me through out another reason too. The touch handler gets an event.target that you may want to manipulate in the touch handler. If you only have one touch handler and go the .isHitTestable route, event.target will refer to the invisible button.

Rob

Hi @pascal456,

To be perfectly clear, certain vector-related API calls are, in fact, applicable to “widget.newButton()”, but ONLY if that button is a shape-constructed button:

https://docs.coronalabs.com/api/library/widget/newButton.html#shape-construction

In this case, you can freely make the following calls on the button anytime after it’s created:

object:setFillColor()

object:setStrokeColor()

As for setting the width of the stroke, that can only be done when you declare the widget, not afterward. Just set the “strokeWidth” parameter as outlined in the documentation.

Hope this helps,

Brent

That is a very good advice, thanks.

Yes, I think I can do something with this. And actually for my functions I assumed, or better say I explicitly defined the Button to be shape-generated. But this also means to have the display-Objects that have aliasing on its round edges. I think I was just too stubbornly fastidious to get the perfect edges on the buttons :smiley:

So I will just remark this in my documentation that, if someone does not like the color of the buttons when they are pressed, he or she has to use object.setStrokeColor() in the listener method.

Okay i think i figured it out by looking through the open source widget library.

For all others that are also looking for this:

Referencing the display-Object of a Widget is done like the following:

local softEdgeButton = widget.newButton({ left = 140, top = 350, }) softEdgeButton.\_view.strokeWidth = 25 softEdgeButton.\_view.stroke = {type="image", filename="stroke/brush1.png"} softEdgeButton:setStrokeColor(0,0,0)

Ok next Problem…
 
how do i set the color for the default and over state?
 
The following does not bring the desired result:

customWidget.\_view.\_strokeColor.default = {1,0,0} customWidget.\_view.\_strokeColor.over = {1,0,0}

By this the color just changes to nothing/transparent?

And when i set the color by 

softEdgeButton:setStrokeColor(1,0,0)

Then it changes it for both states. Any aproaches ?

I’m going to answer your widget stroke question but completely ignore the other question because it is (as you stated) the next problem and thus unrelated - please post new questions in *new* threads.

No, you should not be trying to set the stroke of a widget. Widgets are generated by using image sheets. Any mucking about with strokes will just make them look really bizarre and break their basic functionality. It may even get forcibly overridden by the widget library.

Take a look at the documentation for the widgets and you’ll see quite an expansive list of image sheet images which you can use to apply the different interface effects. Anything outside of that list is probably going to need a different type of input altogether.

Thank you for your answer and your time thinking about that! :slight_smile:

The “next problem” was directly related to the first one since I may have found out how to adress/reference the stroke for the default state but actually I need to reference both states. Because with my current solution it works fine but when I click the button the stroke will stay at the color, that I defined, for instance the default color(?!).

And unfortunately I have to set the stroke that way. This is because I am setting up a collection of customized widgets for. I have come so far that you can set the Design of the widgets via newButton({layout = 11}) for example, and the Button will be fully styled in a pre defined way. I store this definition in ja json-File. Those widgets should be furthermore be customizable later on, therefore the json-File. So and this customization process has to be easy later on, otherwise no one in my team wants to use it :wink: And using the “shape”-Version of the ButtonWidget, makes it a lot easier to maintain compared to the image or imageSheet versions.

What I have done so far is perfectly working without any problems but I was just not very satisfied by the outcome of the widget.newButton() when you use the “shape” version. the Edges of roundedRects do not look very nicely.

See this example App:

The two Blue Buttons (without label) are both my Widgets with customized Features. the right one looks  as if it has smooth edges and the left one has some aliasing. You can see the difference on some of the objects above too (red ones without smoothing function, black with)

You see, why I try to do it that way? I do not want to code a whole new Button Widget because that would mean all those work around Focus and lose of Focus while touching and all those other things coronalabs thankfully already provided.

EDIT: I forgot to add the Buttons in pressed State.

Figure 1.

Figure 1:The one without my function (with aliasing but no different strokeColor when clicked)

Figure 2.

Figure 2: The one with my “Fake”-Anti-Aliasing function (nearly without alisasing but with another strokeColor when in pressed state). I have to admit that the stroke can just barely be seen, but the effect is actually there and a little more concise on Phone and Simulator than on JPG :wink:

Just a suggestion… Our widget.newButton is designed to be for general use where we pass various parameters and create a generic button. If you can’t style it using the styling features we provide by passing parameters, I would not spend time monkeying under the hood with them. While you can take the open source library and alter it, I would argue it would be faster to use a pair of display.newRect() or display.newImageRect()'s drawn on top of each other (one for the up state and one for the down state), apply a touch handler to them and change visibility on them to show which ever one should show. You have direct access to the objects to style them as you see fit, all in about the same amount of code as it takes to create a widget.newButton in the first place providing the parameters to style the button.

Rob

Ah right that seems like a good idea.

  • build a function that builds two Rect-display objects
  • both same location and same width/height
  • respectively with the given filling color for default and over state
  • give the upper one (default state) a touch listener that sets the visibility to false and ‘object.isHitTestable=true’

Is this more or less what you meant with your suggestion? Because I do not really understand why you would add a touch handler to both of them and change the visibility of each?

Basically if you hide the top image to show the bottom one, you loose hitTestability on the top one, so you would want the touch listener active on the bottom one.  Setting .isHitTestable = true solves the issue and you would only need one handler.

But let me through out another reason too. The touch handler gets an event.target that you may want to manipulate in the touch handler. If you only have one touch handler and go the .isHitTestable route, event.target will refer to the invisible button.

Rob

Hi @pascal456,

To be perfectly clear, certain vector-related API calls are, in fact, applicable to “widget.newButton()”, but ONLY if that button is a shape-constructed button:

https://docs.coronalabs.com/api/library/widget/newButton.html#shape-construction

In this case, you can freely make the following calls on the button anytime after it’s created:

object:setFillColor()

object:setStrokeColor()

As for setting the width of the stroke, that can only be done when you declare the widget, not afterward. Just set the “strokeWidth” parameter as outlined in the documentation.

Hope this helps,

Brent

That is a very good advice, thanks.

Yes, I think I can do something with this. And actually for my functions I assumed, or better say I explicitly defined the Button to be shape-generated. But this also means to have the display-Objects that have aliasing on its round edges. I think I was just too stubbornly fastidious to get the perfect edges on the buttons :smiley:

So I will just remark this in my documentation that, if someone does not like the color of the buttons when they are pressed, he or she has to use object.setStrokeColor() in the listener method.