Page 1 of 1

within a certain distance of intersecting buttons

Posted: Mon Mar 16, 2009 10:25 am
by gyroscope
Hi, I've another small problemette I can't get to work (I'll see if I can explain or perhaps its better I upload my test file...):

I have a column of 10 or more buttons and when I drag one button over another, I would want the button to replace the one its over, and for the rest of the buttons to shunt up or down, depending on which direction (upwards or downwards) the dragged button is travelling.

Intersecting buttons are no problem but the amount of one button within another, i can't get to work (The buttons are only 6 or 7 pixels away from each other so I would want only the button with the most covered area to move, if you see what I mean, i.e a button could cover another button but also one below it for instance. If the first button has more "coverage" that's the one that shunts down out of the way for the dragged button to take its place. Don't know if I've explained this very clearly...

Anyhow, part of the code is:

Code: Select all

if intersect(button "ANIMATION", button "FIELDS") and item 2 of the location of me > tFieldsWherey -4 or item 2 of the location of the target < tFieldsWherey +4 then
 ---
end if
But however little or much coverage the other button receives, it always moves.

Can anyone help here please? (Can anyone understand what I'm going on about with my awful explanation :wink:)

Posted: Mon Mar 16, 2009 10:47 am
by malte
Hi Gyro,

who is me and who is the target?

Cheers,

Malte

Posted: Mon Mar 16, 2009 12:36 pm
by gyroscope
Hi Malte
who is me and who is the target?
Whoops! I see what you mean, they're one and the same thing in a way; changed the code to:

Code: Select all

if intersect(button "ANIMATION", button "FIELDS") and item 2 of the location of me > tFieldsWherey -4 or item 2 of the location of button "FIELDS" < tFieldsWherey +4 then 
 --- 
end if
and seems to be working as I want now. Thank you.

:)

Edit: still having probs: it seems to work if moving a button up to another button, but not down to another button.

Posted: Mon Mar 16, 2009 3:46 pm
by malte
Hi gyro,

I hope you excuse my shameless plug here. What I am posting will require animationEngine in use, as it uses some of its functions. If you do not have a copy please let me know and I will see what I can do.

0) open animationengine
type

Code: Select all

start using stack "animationEngine"
into the messagebox
1) create a stack with any number of buttons
2) in multiline messagebox (just needed once)

Code: Select all

repeat with i=1 to the number of buttons
  set the constrainRectangular of btn i to the rect of this cd
end repeat
You now have buttons you can drag around on the card.

3) In the stack script:

Code: Select all

on constrainRectangularCallBack
    local tCheck,tList
    local tMax,tWhich
    repeat with i=1 to the number of buttons
        if the id of the target=the id of btn i then next repeat
        put intersectRect(the rect of the target,the rect of btn i) into tCheck
        if tCheck is false then next repeat
        put computeArea(tCheck) into tList[i]
    end repeat
    repeat for each key theKey in tList
        if max(tMax,tList[theKey]) = tList[theKey] then
            put tList[theKey] into tMax
            put theKey into tWhich
        end if
    end repeat
    if tWhich is not empty then
        put the name of btn tWhich
    end if
end constrainRectangularCallBack

function computeArea pRect
    return (item 3 of pRect - item 1 of pRect) * (item 4 of pRect - item 2 of pRect)
end computeArea
Drag buttons around and watch the messagebox.

Hope that helps,

Malte

Posted: Mon Mar 16, 2009 4:15 pm
by gyroscope
Hi Malte
I hope you excuse my shameless plug here.
With your most excellent software plugin you deserve any plug that's around!

I have a copy of Animation Engine, thank you and many thanks also for taking the time out to write the code.

Unfortunately I can't get it to work; more than certain I've done something wrong!

• start using AE, no probs.

• Multiline messageBox I put your code then put the stuff in the Stack script, restarted (start using AE again) but although I can move individual buttons, nothing happens when I overlay them.

• I thought I might have to put:

Code: Select all

on mouseDown
constrainRectangularCallBack
end mouseDown
but that just froze the particular button I placed it in.

• Also, I changed your code to:

Code: Select all

repeat with i=1 to the number of buttons 
  set the constrainRectangular of btn i to the rect of graphic "Rectangle"
end repeat 
and ran this from the Message Box. This constrains it within the box left, top and bottom, but not the right.

:(

Posted: Mon Mar 16, 2009 4:33 pm
by malte
constrainrectangularCallBack is a message sent by AE, no need to send it from a button. Make sure mouseDown, mouseMove, mouseRelease and mouseUp are passed.

I have uploaded a working example:

http://www.derbrill.de/test1.rev

Make sure animationEngine is in use to look at it.

Cheers,

Malte

Posted: Mon Mar 16, 2009 4:42 pm
by gyroscope
That's great Malte, thank you. That certainly gives me something to work from. I'll need to work out now how to lock them in certain positions when they intersect. I'll get there eventually!

:)

Posted: Mon Mar 16, 2009 5:59 pm
by SparkOut
Hi Gyro,
I can't recommend Malte's animationEngine enough, but as an exercise (and really to give a demo about custom properties and setProps, which I thought might help kill two birds with one stone - or just muddy the waters) I thought I'd look at an alternative approach.

If you have a fixed spread of button locations (so you may need to revisit how you handle stack resizing, for example) you can get a list of locs in order and sort them according to new placements. If the y position of the mouseloc is lower or higher than one of the referenced locations, it can sort the button order and replace them in the setProp handler of the button group.

I've put a stack in my RevOnline space "GyroButtonSortRevisited" so you can see it working.

Posted: Mon Mar 16, 2009 8:22 pm
by gyroscope
I can't recommend Malte's animationEngine enough, but as an exercise (and really to give a demo about custom properties and setProps, which I thought might help kill two birds with one stone - or just muddy the waters) I thought I'd look at an alternative approach.

I've put a stack in my RevOnline space "GyroButtonSortRevisited" so you can see it working.
Hey SparkOut, that is terrific! I can't thank you enough. I been looking at the code and beginning to understand it; I'll really study it soon and hopefully custom properties and setprop will finally sink in. It's also a neat solution to shunt the relevant button which needs to be moved one button at a time; this avoids a lot of extra complication; good one!

I've ungrouped the items and it doesn't work so it's obviously working on the group; that's interesting. Also as far as I can see the setProp cYPos acts globally. I guess all setProp and getProp handlers work in this way?

I might have a few more questions concerning this later in the week, if that's OK.

Excellent stuff, thank you again!

:)

Posted: Mon Mar 16, 2009 8:50 pm
by SparkOut
getProps and setProps handlers are in the message hierarchy like the rest of them. Sorry I should have made more commentary - but the group script contains the setProp handler, and therefore triggers for all the target buttons in the group. If you move the setProp handler to the card, it will trigger for the buttons if they're ungrouped. (You'll get errors if you try because the script refers to custom properties of the group, but if you change those too, it will work - just don't set a cYpos on any other object on the card. ;) )

Posted: Tue Mar 17, 2009 1:40 am
by gyroscope
Understood SparkOut, thanks!

:)