It is currently July 27th, 2021, 2:15 pm

## New Loop measure type

Changes made during the Rainmeter 3.3 beta cycle. jsmorley
Developer
Posts: 21973
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

### New Loop measure type

We have added a new Measure=Loop measure type to Rainmeter.

http://docs.rainmeter.net/manual-beta/measures/loop

The problem

Currently, creating a looping "counter" in Rainmeter is done with a Calc measure and a modulo mathematical function:

Code: Select all

``````[MeasureName]
Measure=Calc
Formula=(MeasureName % 100) + 1``````
This has some limitations that we wanted to address:

1) The "starting" value of the counter can't easily be "0", or really any number other than "1".
2) It is difficult to increment by other than "1", as that impacts the starting value as well.
3) It is difficult to count "backwards".
4) You must manually set MinValue and MaxValue to use as a percentage.
5) This can only create an "endless" loop, you can't loop 3 times and stop for instance.
6) Overall, the function is not very intuitive to new or non-programmer Rainmeter users.

The solution

The new Loop measure can be used in place of this modulo approach. The way it works is:

The measure will be the value of StartValue for one update, will increment based on the value of Increment on each subsequent update, and will be the value of EndValue for one update. If LoopCount is other than 1, the loop will then repeat.

A couple of simple examples might be:

Code: Select all

``````[MeasureLoop]
Measure=Loop
StartValue=0
EndValue=50
Increment=1
LoopCount=0
``````
The measure's value will count from 0 to 50, incrementing by 1 on each update, and will repeat endless times.

Code: Select all

``````[MeasureLoop]
Measure=Loop
StartValue=100
EndValue=0
Increment=-10
LoopCount=1
``````
The measure's value will count backwards from 100 to 0, incrementing by -10 on each update, and will stop after 1 loop.

If you set InvertMeasure=1 on the measure, the value that is returned is the "opposite" of the measured value. This has the effect of "counting backwards", with no other change to the measure options required.

The measure can be reset and will start over with all current option values when the !CommandMesasure MeasureName "Reset" bang is sent to the measure.

Some rules

There are some rules for how this measure works that should be kept in mind:

1) All options must be positive or negative whole numbers, or formulas that resolve to whole numbers. Fractional values will be truncated.
2) The measure will have a range that is the difference between StartValue and EndValue for use by meters requiring a percentage. There cannot be a negative percentage, so the range will always be lowest value to highest value. MinValue will be set to the lower of StartValue / EndValue, and MaxValue will be set to the higher of StartValue / EndValue.
3) Any dynamic change to any of the four measure options, or dynamically changing InvertMeasure on the measure, will cause the loop to be reset and start over with the new values.

Examples

First, here is a .rmskin that has all the example skins included:
LoopMeasure_1.0.rmskin
AlphaLoop:

Code: Select all

``````[Rainmeter]
Update=20
DynamicWindowSize=1
AccurateText=1

[MeasureAlpha]
Measure=Loop
StartValue=30
EndValue=255
Increment=20
LoopCount=1
Paused=1

[MeterAlpha]
Meter=String
MeasureName=MeasureAlpha
W=154
H=50
X=77
StringAlign=Center
FontSize=35
FontColor=255,255,255,[MeasureAlpha]
SolidColor=30,40,50,[MeasureAlpha]
AntiAlias=1
DynamicVariables=1
MouseOverAction=[!SetOption MeasureAlpha InvertMeasure 0][!UnpauseMeasure MeasureAlpha]
MouseLeaveAction=[!SetOption MeasureAlpha InvertMeasure 1]
``````
This demonstrates using the value to dynamically change meter options, and shows how InvertMeasure can be used to change the "direction" of the loop.
alpha.gif
BarLoop:

Code: Select all

``````[Rainmeter]
Update=500
DynamicWindowSize=1
AccurateText=1

[Variables]
Invert=0

[MeasureLoop]
Measure=Loop
StartValue=-50
EndValue=50
Increment=5
LoopCount=0
InvertMeasure=#Invert#
DynamicVariables=1

[MeterLoopBar]
Meter=Bar
MeasureName=MeasureLoop
W=400
H=20
BarColor=74,143,186,255
SolidColor=47,47,47,255
BarOrientation=Horizontal

[MeterLoopValue]
Meter=String
MeasureName=MeasureLoop
X=10
Y=2
FontSize=11
FontColor=255,255,255,255
AntiAlias=1

[MeterLoopPercent]
Meter=String
MeasureName=MeasureLoop
X=390
Y=2
StringAlign=Right
FontSize=11
FontColor=255,255,255,255
AntiAlias=1
Percentual=1
Text=%1%

[MeterBackwards]
Meter=String
X=0
Y=10R
W=70
H=16
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Backwards
LeftMouseUpAction=[!SetVariable Invert 1]

[MeterForwards]
Meter=String
X=0
Y=5R
W=70
H=16
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Forwards
LeftMouseUpAction=[!SetVariable Invert 0]

[MeterToggle]
Meter=String
X=0
Y=5R
W=70
H=16
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Toggle
LeftMouseUpAction=[!SetVariable Invert (1-#Invert#)]
DynamicVariables=1
``````
This demonstrates using the percentage value of the measure in a meter requiring a percentage.

Click to view animation:
bar.gif
ImageLoop:

Code: Select all

``````[Rainmeter]
Update=250
DynamicWindowSize=1
AccurateText=1

[Variables]
Start=0
End=9
Incr=1

[MeasureLoop]
Measure=Loop
StartValue=#Start#
EndValue=#End#
Increment=#Incr#
LoopCount=1

[MeasurePingPong]
Measure=Calc
IfCondition=MeasureLoop >= #End#
IfTrueAction=[!SetOption MeasureLoop InvertMeasure 1][!UpdateMeasure MeasureLoop]
IfCondition2=MeasureLoop <= #Start#
IfTrueAction2=[!SetOption MeasureLoop InvertMeasure 0][!UpdateMeasure MeasureLoop]
Disabled=1

[MeterImage]
Meter=Image
ImagePath=#@#GifFrames\
ImageName=Frame[MeasureLoop].png
DynamicVariables=1

[MeterOnceForward]
Meter=String
Y=10R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Once Forward
LeftMouseUpAction=[!DisableMeasure MeasurePingPong][!SetOption MeasureLoop InvertMeasure 0][!SetOption MeasureLoop LoopCount 1][!UnpauseMeasure MeasureLoop][!CommandMeasure MeasureLoop Reset]

[MeterOnceBackward]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Once Backward
LeftMouseUpAction=[!DisableMeasure MeasurePingPong][!SetOption MeasureLoop InvertMeasure 1][!SetOption MeasureLoop LoopCount 1][!UnpauseMeasure MeasureLoop][!CommandMeasure MeasureLoop Reset]

[MeterRepeat]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Repeat Current Direction
LeftMouseUpAction=[!DisableMeasure MeasurePingPong][!SetOption MeasureLoop LoopCount 0][!UnpauseMeasure MeasureLoop][!CommandMeasure MeasureLoop Reset]

[MeterPingPong]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=PingPong
LeftMouseUpAction=[!UnpauseMeasure MeasureLoop][!EnableMeasure MeasurePingPong]

[MeterTogglePause]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Toggle Pause
LeftMouseUpAction=[!TogglePauseMeasure MeasureLoop]
``````
This demonstrates using the value to set the image name in an animation.
image.gif
RoundLoop:

Code: Select all

``````[Rainmeter]
Update=25
DynamicWindowSize=1
AccurateText=1

[Variables]
Start=0
End=360
Incr=4
Loop=0
Invert=0

[MeasureLoop]
Measure=Loop
StartValue=#Start#
EndValue=#End#
Increment=#Incr#
LoopCount=#Loop#
InvertMeasure=#Invert#
DynamicVariables=1

[MeterRoundline1]
Meter=Roundline
X=0
Y=0
W=130
H=130
LineColor=178,221,240,255
Solid=1
LineStart=55
LineLength=65
AntiAlias=1
SolidColor=0,0,0,1
DynamicVariables=1
LeftMouseUpAction=[!SetVariable Invert (1-#Invert#)][!UpdateMeasure MeasureLoop]

[MeterRoundline2]
Meter=Roundline
X=0
Y=0
W=130
H=130
LineColor=254,222,135,255
Solid=1
LineStart=40
LineLength=50
AntiAlias=1
DynamicVariables=1

[MeterRoundline3]
Meter=Roundline
X=0
Y=0
W=130
H=130
LineColor=230,103,96,255
Solid=1
LineStart=25
LineLength=35
AntiAlias=1
DynamicVariables=1

[MeterRoundline4]
Meter=Roundline
X=0
Y=0
W=130
H=130
LineColor=196,218,135,255
Solid=1
LineStart=10
LineLength=20
AntiAlias=1
DynamicVariables=1
``````
This demonstrates using the value to control the "angles" in a Roundline meter.
round.gif
StringLoop:

Code: Select all

``````[Rainmeter]
Update=300
DynamicWindowSize=1
AccurateText=1

[Variables]
Start=0
End=10
Incr=1

[MeasureLoop]
Measure=Loop
StartValue=#Start#
EndValue=#End#
Increment=#Incr#
LoopCount=1

[MeasurePingPong]
Measure=Calc
IfCondition=MeasureLoop = #End#
IfTrueAction=[!SetOption MeasureLoop InvertMeasure 1][!UpdateMeasure MeasureLoop]
IfCondition2=MeasureLoop = #Start#
IfTrueAction2=[!SetOption MeasureLoop InvertMeasure 0][!UpdateMeasure MeasureLoop]
Disabled=1

[MeterString]
Meter=String
MeasureName=MeasureLoop
W=154
H=50
X=77
StringAlign=Center
FontSize=35
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1

[MeterOnceForward]
Meter=String
Y=10R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Once Forward
LeftMouseUpAction=[!DisableMeasure MeasurePingPong][!SetOption MeasureLoop InvertMeasure 0][!SetOption MeasureLoop LoopCount 1][!UnpauseMeasure MeasureLoop][!CommandMeasure MeasureLoop Reset][!UpdateMeasure MeasureLoop]

[MeterOnceBackward]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Once Backward
LeftMouseUpAction=[!DisableMeasure MeasurePingPong][!SetOption MeasureLoop InvertMeasure 1][!SetOption MeasureLoop LoopCount 1][!UnpauseMeasure MeasureLoop][!CommandMeasure MeasureLoop Reset][!UpdateMeasure MeasureLoop]

[MeterRepeat]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Repeat Current Direction
LeftMouseUpAction=[!DisableMeasure MeasurePingPong][!SetOption MeasureLoop LoopCount 0][!UnpauseMeasure MeasureLoop][!CommandMeasure MeasureLoop Reset][!UpdateMeasure MeasureLoop]

[MeterPingPong]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=PingPong
LeftMouseUpAction=[!UnpauseMeasure MeasureLoop][!EnableMeasure MeasurePingPong]

[MeterTogglePause]
Meter=String
Y=3R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
Text=Toggle Pause
LeftMouseUpAction=[!TogglePauseMeasure MeasureLoop]
``````
This demonstrates using the value in a String meter.
string.gif
You do not have the required permissions to view the files attached to this post. eclectic-tech
Rainmeter Sage
Posts: 4328
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

### Re: New Loop measure type

SWEET! It is going to simplify the code needed in a lot of areas...
I can't wait to try this out!

Thanks! suixin812
Posts: 13
Joined: November 19th, 2012, 5:28 am
Location: China

### Re: New Loop measure type

A useful measure for animation skin. But I think maybe a new Timer measure is more necessary for animation skin. Dank420
Posts: 145
Joined: April 3rd, 2013, 1:04 am
Location: O-High-O

### Re: New Loop measure type

...making so much Previous effort seem futile..
Thank you! jsmorley
Developer
Posts: 21973
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

### Re: New Loop measure type

Sharing a Loop measure...

Code: Select all

``````[Rainmeter]
Update=20
DynamicWindowSize=1
AccurateText=1

[Variables]

[MeasureLoop]
Measure=Loop
StartValue=30
EndValue=255
Increment=20
LoopCount=1
Paused=1
DynamicVariables=1

[MeterOne]
Meter=String
Group=Meters
FontSize=20
FontColor=255,255,255,255
SolidColor=0,0,0,1
AntiAlias=1
Text=Meter One
MouseOverAction=[!SetOptionGroup Meters FontColor "255,255,255,255"][!SetOption MeasureLoop InvertMeasure 1][!SetOption MeasureLoop OnUpdateAction """[!SetOption MeterOne FontColor "255,255,255,[*MeasureLoop*]"]"""][!UnpauseMeasure MeasureLoop][!UpdateMeasure MeasureLoop]
MouseLeaveAction=[!SetOptionGroup Meters FontColor "255,255,255,255"][!SetOption MeasureLoop InvertMeasure 0][!SetOption MeasureLoop OnUpdateAction """[!SetOption MeterOne FontColor "255,255,255,[*MeasureLoop*]"]"""][!UpdateMeasure MeasureLoop]

[MeterTwo]
Meter=String
Group=Meters
X=15R
FontSize=20
FontColor=255,255,255,255
SolidColor=0,0,0,1
AntiAlias=1
Text=Meter Two
MouseOverAction=[!SetOptionGroup Meters FontColor "255,255,255,255"][!SetOption MeasureLoop InvertMeasure 1][!SetOption MeasureLoop OnUpdateAction """[!SetOption MeterTwo FontColor "255,255,255,[*MeasureLoop*]"]"""][!UnpauseMeasure MeasureLoop][!UpdateMeasure MeasureLoop]
MouseLeaveAction=[!SetOptionGroup Meters FontColor "255,255,255,255"][!SetOption MeasureLoop InvertMeasure 0][!SetOption MeasureLoop OnUpdateAction """[!SetOption MeterTwo FontColor "255,255,255,[*MeasureLoop*]"]"""][!UpdateMeasure MeasureLoop]

[MeterThree]
Meter=String
Group=Meters
X=15R
FontSize=20
FontColor=255,255,255,255
SolidColor=0,0,0,1
AntiAlias=1
Text=Meter Three
MouseOverAction=[!SetOptionGroup Meters FontColor "255,255,255,255"][!SetOption MeasureLoop InvertMeasure 1][!SetOption MeasureLoop OnUpdateAction """[!SetOption MeterThree FontColor "255,255,255,[*MeasureLoop*]"]"""][!UnpauseMeasure MeasureLoop][!UpdateMeasure MeasureLoop]
MouseLeaveAction=[!SetOptionGroup Meters FontColor "255,255,255,255"][!SetOption MeasureLoop InvertMeasure 0][!SetOption MeasureLoop OnUpdateAction """[!SetOption MeterThree FontColor "255,255,255,[*MeasureLoop*]"]"""][!UpdateMeasure MeasureLoop]
``````
Click to animate:
test.gif
You do not have the required permissions to view the files attached to this post. AlC
Posts: 329
Joined: June 9th, 2011, 6:46 pm

### Re: New Loop measure type

Really nice and useful addition!! Rainmeter - You are only limited by your imagination and creativity.
rainopelit
Posts: 13
Joined: April 17th, 2015, 3:55 pm

### Re: New Loop measure type

Great !
Work with roundline Code: Select all

``````[Rainmeter]
Update=25
[mLine]
Measure=Loop
StartValue=25
EndValue=30
Increment=1
LoopCount=1
Paused=1

[MeasureSWAP]
Measure=SWAPMemory
UpdateDivider=40
[r3]
meter=roundline
W=80
H=80
StartAngle=4.712
RotationAngle=6.283
LineLength=25
LineColor=255,255,255,200
LineStart=0
Solid=1
AntiAlias=1
MouseOverAction=[!SetOption mLine InvertMeasure 0][!UnpauseMeasure mLine]
MouseLeaveAction=[!SetOption mLine InvertMeasure 1]

[MeterSWAP]
Meter=Roundline
MeasureName=MeasureSWAP
W=80
H=80
StartAngle=4.712
RotationAngle=6.283
LineLength=[mLine]
LineColor=50,50,220,255
LineStart=24
Solid=1
AntiAlias=1
DynamicVariables=1
`````` Yincognito
Rainmeter Sage
Posts: 3644
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

### Re: New Loop measure type

I was wondering when Rainmeter would have something like that...

Now maybe I'm thinking too much ahead, but a "for"-like statement would be a critical innovation in Rainmeter. I mean a "for"-like statement that would execute in one update only But I know Rainmeter is built on slightly different principles than a true programming language. StArL0rd84
Posts: 367
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

### Re: New Loop measure type

AMAZING!
This simplified my tray skin a lot!

ty

But a have one question about the loop measure.
I got it to show the icons in the tray once the animation was done.
But cannot hide them again once the value reaches 0 again.
BTW the animation images starts from 0 and goes to 19 (20 images)

Code: Select all

``````[MeterOpen]
Meter=Image
ImageName=#@#Images\Icons\Tray\#Tray1Icon#.png
ImageTint=#Tray1IconColor#
LeftMouseUpAction=[!SetOption MeasureAlpha InvertMeasure 0][!UnpauseMeasure MeasureAlpha]

[MeterClose]
Meter=Image
ImageName=#@#Images\Animation\[MeasureAlpha].png
MouseLeaveAction=[!SetOption MeasureAlpha InvertMeasure 1]
ImageTint=#Tray1BackgroundColor#
DynamicVariables=1

[MeasureAlpha]
Measure=Loop
StartValue=0
EndValue=19
Increment=1
LoopCount=1
Paused=1
IfEqualValue=19
IfEqualAction=#ShowItemsTray1#

IfBelowValue=1
IfBelowAction=#HideItemsTray1#

or

IfEqualValue=0
IfEqualAction=#HideItemsTray1#``````
It looks like it hides the items but shows the them again right after.
Am i missing something?

Michael.
([mWorkTime] = 1 ? #Work# : ([mEnergyLoss:%] >= 70% ? #Chillmode# : </>)) balala
Rainmeter Sage
Posts: 12970
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

### Re: New Loop measure type

You could try to replace the IfActions, with IfConditions. They are more powerful and being a newer tool, are more recommended (at least in my opinion).
So, try to replace the

Code: Select all

``````IfEqualValue=19
IfEqualAction=#ShowItemsTray1#
IfBelowValue=1
IfBelowAction=#HideItemsTray1#

or

IfEqualValue=0
IfEqualAction=#HideItemsTray1#``````
options with:

Code: Select all

``````IfCondition=(MeasureAlpha=0)
IfTrueAction=#HideItemsTray1#
IfFalseAction=#ShowItemsTray1#``````
(on the [MeasureAlpha] measure).