How to Create a Rectangle Variable

The %WINDOW% token and the %FoundImage% Token consist of four values, left, top, width, and height. These values can be referenced with calculations like WINDOW.x for the left value or ImageLoc.height if ImageLoc has been set to the value of FoundImage. (You can't access FoundImage.x directly.)

Is it possible to create a new rectangle variable, like SearchArea that has the four values in sequence, as a text string, delimited by commas, and then reference the parts of that rectangle using the Var.x notation?

I'm asking instead of trying because I've never made an array in KBM of any kind and I don't trust that if a test macro doesn't work that it will be a valid test and not just a demonstration of other unidentified ignorance.

Thanks.

Example – accessing two arrays:

  1. an array generated by KM
  2. an array written out by hand

Accessing parts of comma-delimited strings.kmmacros (3.9 KB)

3 Likes

And just to add to @ComplexPoint's example. The delimiter can be any character (not just a comma) if it is also referenced for when the value needs to be recalled. This can be useful when you want to have commas in the actual text items. I often use the ★ symbol as it would be unlikely to be used in a sentence (and it is easy to spot in the Macro coding).

And... if you want to convert a list like

one
two
three
four

into a Keyboard Maestro Variable in a form to make its individual lines easy to access you can do it like this:

@peternlewis has hinted that at some point he might allow the Return Symbol
image
to be used as the delimiter which would then remove the need to do a search and replace.

In which case the below would work (it doesn't work at present):

1 Like

Thanks @ComplexPoint and @Zabobon,

I appreciate the tutorials on using arrays, and I really like the global search and replace trick. That gives me a good start.

What I was really asking was, is it possible to refer to elements of that array using KBM‘s notation of e.g., handFrame.x or handFrame.MidX?

I figure either KBM has some internal flag that says “this array is a rectangle“ and then allows the dot operators, or it doesn’t, and then dot operators are allowed anywhere.

Worst case, I suppose I could create a variable as a rectangle by setting it to WindowFrame or FoundImage, and then changing the values to whatever I needed.

Unfortunately, these are all thought experiments for me right now, because I kept it to my laptop for a couple of days.

Thanks,
August

Yes, as long as the variable contains 2, 4 or 5 numbers separated by commas, then you can treat it as a point, size, rectangle, or rectangle with fuzz.

There is no internal flag to say the variable is a rectangle - it is a rectangle if it contains four numbers separated by commas (or five with fuzz).

SWEET!

Does that mean that the .MidX and .MidY suffixes can be used to automatically calculate midpoints of an arbitrary rectangle this way?

1 Like

Yes. There isn't any magic about either of them. v.x is just short for v[1], and v.MidX is basically just short for v[1]+v[3]/2 (and errors if the variable does not have two, four or five array members (4 or 5 for MidX)).

2 Likes

:slight_smile: FWIW the term Array tends to refer by default to a collection of data which is addressible by position (positional indices, iteration etc)

When the elements are addressed by an associated name, people tend to speak of Objects (e.g. in JS and JSON) Dictionaries (e.g. Python) or Symbol tables, Records (various other).
(Or, of course Associative array, if we don't mean the default ordered structure)

Keyboard Maestro variables are always strings.

They can be referenced as an array to extract parts of them, but they are still strings underneath.

And the dot notation is just syntactic sugar for simple array accesses and simple arithmetic.

I definitely wouldn't refer to Keyboard Maestro variables as objects, dictionaries or records.

I'm still missing something.

When I run @ComplexPoint 's sample above:
image

... the displayed text is 160.

But when I attempt to use the dot-suffixes, %Variable%handFrame.x% displays as %Variable%handFrame.x%.

To get the display I want, I have to use %Calculate%handFrame.x%

So these two tokens in a text display are equivalent:
%Variable%handFrame[1]%
%Calculate%handFrame.x%

I find that confusing. Can someone offer a description of how to think about this to keep it straight?

Thanks.

The dot notation is for use in calculations. (That’s why you had to use %Calculate% at the front to force it to display in a Text field.)

So, in your Display text in a Window Action either of these works:

%Variable%handFrame[1]%
%Calculate%handFrame.x%

And even this will work (although not recommended)

%handFrame[1]%

Or if you were in a Calculate field (such as a Set Variable to Calculation Action) you could use:

handFrame.x

Or

handFrame[1]

The . Notation is for calculations. The Notation is for calculations and text.

EDIT - and as Peter has pointed out in the following post, for . notation to mean anything the Variable has to contain the amount of individual numbers it expects to find.

They are two very different things. In a text field, you can use:

  • %Variable%handFrame[3]% is a string array lookup in the variable. It will work if the variable contains, for example, “apple,banana,pear,peach”.

In a calculation, you can use:

  • handFrame[3] which works in a similar way, but returns a number only, and works regardless of the number of commas in handFrame (as long as there are at least two).
  • handFrame.width which treats handFrame as a rectangle, and works only if it contains 3 or 4 commas, and only numbers, and returns the third number.
1 Like

Thanks @peternlewis, @Zabobon,

I’m beginning to get it. The square bracket notation is a table look up while the dot notation actually performs a calculation. Table look up notation has been defined to be interpreted within the variable name syntax, while calculations have not.

That means, I think, as long as the values are numeric, one could use either %Calculate%handFrame[3]% or %Calculate%handFrame.x% because the table look up will return the number and a calculation on a single number will simply return that number.

The .MidX operation actually does a calculation using multiple values within the array. That is way beyond the capabilities of a simple table look up.

1 Like

No.

Square bracket notation is referencing the array by index and can be used anywhere. Dot notation is a combination of access by "human readable" reference (.left, .width) and built-in calculations using items in the array (.right doesn't "exist", it's calculated on-the-fly from .left + .width) -- and, importantly, can only be used in "Calculation" fields and %Calculate% tokens.

And you can only "get" values using dot notation, not "set" them.

You can do everything KM can do to/with arrays using [index] notation. You can do some things, in some circumstances, to a limited set of arrays using .dot notation. IMO, concentrate on understanding manipulation by index and save .dot for special occasions.

.MidX is simply half the width of the rectangle plus the position of the left-side:
%Calculate%myRect[3] / 2 + myRect[1]%

1 Like

More reasonably, use the dot notation for what it was designed for, which is accessing values from points or rectangles returned from various actions, especially the WindowFrame token and Find Image on Screen action and the like. For these cases, the dot notation in calculation fields makes the actions a lot more readable. For example:

image

3 Likes