Counters Guide


Tip by smurfier

This method of creating individual counters has been around for a bit but I decided that they should be written up as there are a few tricks that I've figured out. The advantages of using independent counters are numerous and include the ability to increase their amount by any number you want and being able to pause or reset their values.

Understanding Modulus

Before we take on the task of explaining how to create and use counters we need to understand what the % operator means. What it is called is the Modulo operator. The first form of division most of us were taught in school was long division. This is also known as Remainder Division to some people.

The main concept of this type of division is that when you take one number and divide it by another number sometimes there is something left over. For example when you take the number 10 and divide it by 3 you don't simply have the number 3. There's the little problem of having an extra 1 to deal with. There are two ways this can be dealt with. You can either express it as a decimal which can get a bit messy (3.3333...) or you can simply say "3 with a remainder of 1". The second method is what we will be working with.

The modulus operator simply returns the remainder of any division you would do. For example if you were to do 10 % 3 the number 1 would be returned.

There is a simplified explanation how the % operator works with counters in Rainmeter at Using the modulo '%' operator in a counter measure.

Creating Counters

First we're going to create some variables that we are going to use later on.

[Variables]
MaxNumber=30
Pause=1
Reset=1

Now we need to create the counter.

[cCounter]
Measure=Calc
Formula=cCounter+1

The reason this works is that when calling a measure the value from the last update cycle is used. With this in mind, by calling the measure inside itself we can easily change it's value.

Note: When naming your counter always remember that there is a built in Variable/Function named Counter so yours should be named something else.

Though the counter we just created will continue counting forever just like the built in Counter Variable/Function it does have one advantage. The built in version does not reset unless the skin is unloaded and reloaded. This can sometimes create issues. The counter we just created will always reset when the skin is refreshed.

Making the counter reset at a given value

Having it reset after a given value is easy and is accomplished the same way as if you were using the Counter variable.

[cCounter]
Measure=Calc
Formula=(cCounter+1)%(#MaxNumber#+1)

This will have the counter reset to zero after it hits 30, which is what we have MaxNumber set to. We have the measure add 1 to MaxNumber so that it will reset after the value else it will reset at that value. This is due to the fact that including the number 0 counting to 30 is actually 31 numbers.

If you want your counter to reset to one instead of zero we just need to move things around a bit.

[cCounter]
Measure=Calc
Formula=cCounter%#MaxNumber#+1

With this method we also don't need to worry about adding one to the reset value.

Resetting a counter via Mouse Actions

How about having it reset to zero when we click on the skin.

[Rainmeter]
LeftMouseUpAction=!SetVariable Reset 0
[cCounter]
Measure=Calc
Formula=(cCounter+1)*#Reset#
IfBelowValue=1
IfBelowAction=!SetVariable Reset 1
DynamicVariables=1

Multiplying the counter by zero will easily reset it. Just make sure to set an action to set the Reset variable back to one when you're done.

Or an alternative for resetting the counter with just a MouseOver:

[Rainmeter]
MouseOverAction=!DisableMeasure cCounter
MouseLeaveAction=!EnableMeasure cCounter
[cCounter]
Measure=Calc
Formula=cCounter+1

Note: This method only works if the counter is disabled for at least one update cycle.

Now we can combine a couple methods of resetting to have the counter count up, reset, and wait for us to tell it restart again.

[cCounter]
Measure=Calc
Formula=cCounter+1
IfEqualValue=#MaxNumber#
IfEqualAction=!DisableMeasure #CURRENTSECTION#

When we want the counter to start counting again we just need to use !EnableMeasure cCounter.

Pausing a counter

Lets pause the counter when you mouse-over the skin.

[Rainmeter]
MouseOverAction=!SetVariable Pause 0
MouseLeaveAction=!SetVariable Pause 1
[cCounter]
Measure=Calc
Formula=cCounter+#Pause#
DynamicVariables=1

When the MouseOver action is triggered you stop adding 1 to the counter yet it retains it's value. When the mouse leaves the skin you start adding 1 to it again.

Note: This functionality may also be accomplished using the !PauseMeasure, !UnpauseMeasure and !TogglePauseMeasure bangs.

We can also have the counter stop counting at a certain value and stay there.

[cCounter]
Measure=Calc
Formula=cCounter+(cCounter<#MaxNumber#)

What we did was added a conditional statement. Conditional statements without an "if ? then : else" format resolve to either 1 for true or 0 for false. Using this fact we can easily use conditional statements in mathematical formulas.

Triggering Actions with a Counter

[cCounter]
Measure=Calc
Formula=cCounter+1
IfAboveValue=#MaxNumber#
IfAboveAction=[!DisableMeasure #CURRENTSECTION#]["Some Action"]

This will count up to the MaxNumber, disable itself so it doesn't continue to count, and execute some action such as opening an addon. This method can be used to execute some action a certain number of updates after the skin is loaded.

We can use the built in Counter function/variable to accomplish the same thing. Please note that Counter returns the number of updates since the skin was initially loaded and only returns to zero when Rainmeter is loaded or a !RefreshApp bang is used.

[cCounter]
Measure=Calc
Formula=Counter
IfAboveValue=#MaxNumber#
IfAboveAction=[!DisableMeasure #CURRENTSECTION#]["Some Action"]

Note: To execute a set of commands when the skin is loaded or refreshed, without using a counter, use OnRefreshAction=!SomeAction in the [Rainmeter] section of the skin.

Bonus Lesson: Making a counter that counts down, not up

[cCounter]
Measure=Calc
Formula=(cCounter-1+(#MaxNumber#+1))%(#MaxNumber#+1)

This one is a bit harder to explain. What we are doing is taking the value of the counter and subtracting 1. Then we have to add the value of our MaxNumber else we'll just end up with a negative value. Now we have to take the remainder of that value using Modulo to get our final value.

Using Counters

Cycling Images

[cCounter]
Measure=Calc
Formula=cCounter%#MaxNumber#+1
[MeterImage]
Meter=Image
MeasureName=cCounter
ImageName=#@#Images/%1.png

Cycling Between Measures

[Variables]
MaxNumber=3
[cCounter]
Measure=Calc
Formula=cCounter%#MaxNumber#+1
[Measure1]
Measure=String
String=This is the first measure.
[Measure2]
Measure=String
String=This is the second measure.
[Measure3]
Measure=String
String=This is the third measure.
[MeterString]
Meter=String
MeasureName=Measure1
MeasureName2=Measure2
MeasureName3=Measure3
Text=%[cCounter]
DynamicVariables=1