newSwitch strange behaviour

Ok, oh great and powerful wizards.

Would either of you like a quick contract to build that imageSheet for me (since I keep spinning my wheels)?  I’ve built the radio buttons and checkbox (as well as slider and buttons), but this one has got me.  Let me know how much and where to send (paypal or CC in advance is fine), and I’ll email you what I’ve done, which will give you the colors and general idea.

Thanks

Dave

@Davida6,

Are your assets arranged as discrete images?  I’m asking because I’d like to see them as discrete images before saying whether I can help on this.  i.e. I’d like to experiment with them first before committing.

Regardless, if I decide I can help, this would probably be a level-1 hit: https://forums.coronalabs.com/topic/69420-hire-a-hitman-problem-solver-is-back/

If you do have the images as discrete graphics, you can send them to me at the address on the post linked above.

Graphics sent.

Thanks

Dave

  1. Can you make a small sample, zip it up, and share it with us so we can see what you’re doing?  This is the easiest way to get a fix/help.

(Use the full editor when posting and you’ll have the option to attach a zip file.)

2.  Your post is a bit hard to read.  I’m seeing what looks like at least two questions in there.  You might want to consider bullet lists and clear numbered questions in the future.  (Lazy folk like myself give up when the post starts to wander or look like a run-on.)

A great format for posts like this is:

  • What I did.
  • What I saw.
  • What I expected to see.
  • Why I think it is wrong.
  • What I did to debug it.

( Tip: Provide links; Don’t assume we know what features you’re talking about)

  1. My interpretation of your post:
  • What you did - You made toggle and radio buttons using image sheets and the widget.* newSwitch() function (always provide links so we can be sure we understand what you mean and are referring to).
    • You then tried to pre-toggle the state using the setState() function. 
  • What you saw - The state toggled when you called setState(), but when you later clicked the button… something went wrong.  This is where I’m unclear.
  • … 

attached is the sample.

it has 2 toggles.  1 std, 1 with image sheet.

both have initialSwitchState set to false.

starting app - std shows false (off) state, imageSheet shows true (on)

after 5 secs, timer calls a routine to change state to true in both.

both switch state  (from code, both go from false to true - but std goes to visual true, imageSheet goes from visual true to false.

isOn on both read as true

tapping std, changes state back to false, and control transitions properly.

tapping imageSheet changes state back to false, control does not transition.  now imageSheet shows visual false, and isOn is false.

tapping imageSheet again changes state to true and control transitions to visual true.  control is now in sync.

Simulator look ok.  You need to run this on a device.

Thanks.

Dave

I will look after I finish eating

Note: That last note about needing to run on device is suspect to me.  It should behave exactly the same on device or in the simulator.

Usually, when I see variances between simulator and device (regarding touch based code) there is a coding issue.

I’m still looking at this, but I’m pretty sure you’re checking the state of the button too soon.  

One thing I’m seeing is that sometimes the switch made with your custom art sometimes becomes hard to tap/touch after you force-set the state.

This behavior is NOT consistent.

Yea, I thought so too. However, the sample code is so small, I see nothing that’s out of line. It is literally a side-by-side.  It’s easy to see the image sheet one not move on the first tap, while the onRelease function reporting the event. 

 

Also on startup, you easily see the std shows false, and the image sheet shows on. 

 

Thanks for looking at it.

I’m having trouble getting this to show up consistently.

Note: I further reduced and modified your code (not a fan of introducing extra elements like composer.* and more code; Also like to be able to see all code in one place for debug.)

main.lua

local widget = require("widget") -- local w = display.contentWidth;local h = display.contentHeight local fullW = display.actualContentWidth;local fullH = display.actualContentHeight local unusedWidth = fullW - w;local unusedHeight = fullH - h \_L = math.floor(0 - (unusedWidth \* 0.5));\_T = math.floor(0 - (unusedHeight \* 0.5)) \_R = math.floor(w + (unusedWidth \* 0.5));\_B = math.floor(h + (unusedHeight \* 0.5)) \_CW = \_R;\_CH = \_B;\_FullHeight = \_B;\_CX = math.floor(\_CW \* 0.5);\_CY = math.floor(\_CH \* 0.5) -- local widgetTheme = require("widgetTheme\_green\_sheet") local sdzImageSheet = graphics.newImageSheet( "images/widgetTheme.png", widgetTheme:getSheet() ) -- ============================================================== -- local function onSwitchPress(event) local switch = event.target local id = switch.id local onState = (switch.isOn) and "ON" or "OFF" -- print( "\nSwitch with ID '" .. id .. "' is: " .. onState .. " @ " .. system.getTimer() ) end -- local function dummySetState( button, on ) local switch = button local id = switch.id local onState0 = (switch.isOn) and "ON" or "OFF" local function onComplete() local onState1 = (switch.isOn) and "ON" or "OFF" -- print( "\nBefore - Switch with ID '" .. id .. "' is: " .. onState0 .. " @ " .. system.getTimer() ) print( "After - Switch with ID '" .. id .. "' is: " .. onState1 .. " @ " .. system.getTimer() ) end -- switch:setState( { isOn = on, isAnimated = true, onComplete = onComplete } ) end -- ============================================================== local switch1 = widget.newSwitch( { x = 100, y = 100, style = "onOff", id = "switch1", onRelease = onSwitchPress, initialSwitchState = false, }) -- local switch2 = widget.newSwitch( { x = 200, y = 100, style = "onOff", id = "switch2", onRelease = onSwitchPress, initialSwitchState = false, sheet = sdzImageSheet, onOffBackgroundFrame = 60, onOffBackgroundWidth = 165, onOffBackgroundHeight = 30, onOffMask = "images/widgetTheme\_onOff\_mask.png", onOffHandleDefaultFrame = 63, -- 63, onOffHandleOverFrame = 63, --64, onOffOverlayFrame = 65, onOffOverlayWidth = 84, onOffOverlayHeight = 32, --offDirection = "left" }) -- timer.performWithDelay(1500, function() dummySetState( switch1, true ) end, 1) timer.performWithDelay(1500, function() dummySetState( switch2, true ) end, 1)

Sorry. 

I can’t see a issue that I can point to and I can’t reproduce the issue I saw with toggling the second switch after setState() was called.

Dang.  As soon as I said that, I reproduced it consistently in the simulator by using

View As -> Borderless -> IPhone @2x (640 x 960)

I suspect an issue with your art, otherwise the issue would show up with both buttons.

I have taken this as far as I can.  I’m attaching my modified version of your app.

I added a folder called more with additional art (standard art) for you in case you want to experiment.

I’m using the onRelease method, which means that I’m supposed to be getting the isOn value after it has been changed.

the best thing to do is to actually watch the control move, via the timer, and then tap the control.  Have adb running and it reports what the sample app is doing - and you can see the event generated without the tab moving. 

Also on startup, you can see how the control doesnt show the initial state correctly.  The std does, the imageSheet doesnt.  When the timer fires, both controls switch - std reporting correctly, imageSheet incorrectly.  Tap the std and it moves, and reports the change correctlty.  Tap the imageSheet and it reports the change, but doesnt move.  tap it a second time and it reports the change and moves - now matching the proper state.

again, thanks.

Dave

OK.  The answer came to me.  It is your mask.

DO NOT ever make size variant masks.  Delete the @2x and @3x masks and the button will start behaving properly.

Thanks,

All of your posts came in while I was typing the other.

I’ll take a look at your art and see what the differences could be.  Thanks for the attempt.

Dave

Here is a super-minimal example that works perfectly.

Post back if you don’t think so, but I don’t see any errors in behavior.

**UPDATED** Attached minimal2.zip

Your mask was still wrong.  I fixed it.  Gotta be super careful about following masking rules.

Thank.  I appreciate your looking at it.  It works perfectly in the simulator.  I built it and pushed it to a device.  Same problem as before.

I also tried it with the halo dark theme and got exactly the same results.  Fine in the simulator and broken on the device.  I know it’s crazy because I suspect that corona uses the halo theme as a default for android.

What was wrong with the mask?  This was from a pack purchased from the marketplace.

You need to make sure all masks follow the mask guidelines.

w and h - divisible by 4

at least three pixels of opaque black on all edges.

Your 1x mask has translucent pixels on the 3rd pixel from top and bottom

Sorry to correct you but masks do not need to be divisible by 4 anymore.

I create all my masks at 1x size and with 4px of solid black around.  I reduce these to 2 bit but you can use 8 bit if you want semi-transparent masking.

So for a 100x100px image (200x200px @2x and 400x400px @4x) I will create a single mask of 104x104px.