How to trigger a move action to a group of elements?


#1

Hi
I would like to run a move action to a group of elements.
Then in each of those elements I would like to do something if that element has been moved.

If I move the group, then the move action can only be called by the group itself but not by its elements.

Example:
Each time a specific button is clicked, then each of the number should check if their text equals to a variable value (it contains an hour value). If the value of the variable equals to the text of the number element, the element will be set to “selected” to hightlight it.
image

Do I have to move each element separatly or can I do that in a more economic way? :slight_smile:
Or can I do something with a “selection group”?

Kind regards,
Alain


#2

From your description, it sounds like you are using the Move event as a “listener” or “substitute function” and not actually moving elements on the canvas. If you trigger a Move event on the group without an actual pixel movement, then it would not trigger the Move event of individual elements of that group. However, if there were actual movement, then each element’s Move would get triggered.

I’ll answer your specific questions in reverse order because the second is easier…

Yes, and you should do so. Select all of your 12 “hour widgets” within the group and assign them to a Selection Group. This will mean that only one “hour widget” may be selected at a time–which is what you want. For instance, selecting “3” will automatically unselect all other “hour widgets”. Be sure to assign this Selection Group name to all the individual widgets and NOT the group.

The classic solution would be to use a repeater, but of course repeaters don’t have a built-in radial layout option. With a repeater you would have only 1 element (the clock hour number) repeated 12 times, and triggering its Move would thus automatically trigger all repeated instances. You would gain further economy by having only one Moved action to code instead of replicating it for all 12 widgets. *See below for further discussion on using a repeater in this situation.

Other than a repeater, you could set up a “chain reaction” in which you only move the “hour 1” widget, which tests itself against the variable; if a match it selects itself; else move the “hour 2” widget, and so forth. Something like,

If [[This.text]] equals MyHourVar
Select This
Else if true
Move HourWidget2

…then HourWidget2 would have

If [[This.text]] equals MyHourVar
Select This
Else if true
Move HourWidget3

Or, if you actually move the group (by 1 px) and then immediately move it back (by -1 px), this motion would likely not be rendered in the browser–in other words, you would not notice any actual movement, but each individual widget’s Moved event should be triggered. You might need a way to differentiate the first movement from the second, but if the only action is to select one hour it may not matter that everything moves twice. In other words, if the hour variable is set to “3” and the group is moved by (1, 0) it would mean all 12 widgets would move by (1, 0) and the “hour 3” widget would select itself, then the group would be moved by (-1, 0) and the “hour 3” widget would select itself again–with no resulting change because it is already selected. However, if you are doing something else based on this hour selection you would not want to repeat it twice. In that case, you could try one of the following:

  • Set another variable, say “HourMoveVar” to “true”, then move the group, then set HourMoveVar to “false” then move the group again. Each hour widget’s test would include "If [[This.text]] equals MyHourVar and HourMoveVar equals "true" , Select This".

  • Or, initially set the value of your variable with a hash, then remove that hash for the second move. for example,

    • Set value of MyHourVar to "#3"
    • Move ClockGroup by (1, 0)
      (This would result in no matches, so no hour widgets would change selection states)
      …then ClockGroup would have a Moved event with,
    • If MyHourVar contains "#"
      • Set value of MyHourVar to [[MyHourVar.substring(1)]]
        (which strips out the first character–the ‘#’ hash thus setting it to just “3”)
      • Move This by (-1, 0)
        (which should result in the “hour 3” widget matching and selecting itself.)
  • Or, if you can devise another way to “highlight” an hour (maybe show and/or move a background widget, and/or set that widget’s text to match the “current” hour with the same styling you currently have for Selected) then you could select the group instead of “moving” it, because changing the selection state of a group automatically changes the selection state of all its widgets. Then you could use Selection Changed event of each widget to test itself against the variable instead of Moved.


*Repeater approach…

  • I have actually made a circular repeater in the past, but it took a lot more setup work than simply targeting 12 widgets in an action. Once set up, was easier to maintain though.
  • The basic approach was to use radial math to determine the location of a point on the circumference–each hour on the clock dial in your case, or 360 / 12 = 30 degrees offset–and include an action in the Item Loaded event that calculates the location for each row’s number, based on [[Item.index]] .
  • …Or, come to think of it, you could kind of brute force it by using your current widget locations as you’ve laid them out in your screenshot. You could even create a column for the x-value and column for the y-value and refer to these data in the Item Loaded event. For example, if “hour 1” is located at, say (50, 5) and “hour 2” is located at (80, 18) then the first two rows in the repeater dataset could be:

Num | locX | locY
1 | 50 | 5
2 | 80 | 18

…and the Item Loaded event would have:

Set Text on MyHourWidget to [[Item.Num]]
Move MyHourWidget to ( [[Item.locX]], [[Item.locY]] )

Pro Tip: if you do this, move your clock group to location (0, 0) and then note down the location of all the hour widgets, so they’ll have the proper locations in the repeater cell.


#3

Thanks for your detailed answer.
Copy and modify the move action 12 times tooks less minutes than reading this :smiley:
It is not an elegant but economic implementation.

But maybe I can use one of your approaches later on another project.