It is currently March 28th, 2024, 11:12 pm

New Loop measure type

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

New Loop measure type

Post by jsmorley »

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.

Additional features

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]
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
StartAngle=(0-(Rad([MeasureLoop])))
RotationAngle=(0-(Rad(180)))
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
StartAngle=(Rad([MeasureLoop]))
RotationAngle=(Rad(180))
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
StartAngle=(0-(Rad([MeasureLoop])))
RotationAngle=(0-(Rad(180)))
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
StartAngle=(Rad([MeasureLoop]))
RotationAngle=(Rad(180))
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
Padding=5,5,5,5
AntiAlias=1

[MeterOnceForward]
Meter=String
Y=10R
FontSize=11
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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
Padding=5,5,5,5
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.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5384
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: New Loop measure type

Post by eclectic-tech »

SWEET! 8-)

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

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

Re: New Loop measure type

Post by suixin812 »

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

Re: New Loop measure type

Post by Dank420 »

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

Re: New Loop measure type

Post by jsmorley »

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.
User avatar
AlC
Posts: 329
Joined: June 9th, 2011, 6:46 pm

Re: New Loop measure type

Post by AlC »

Really nice and useful addition!! :thumbup:
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

Post by rainopelit »

Great !
Work with roundline :D

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
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: New Loop measure type

Post by Yincognito »

Great addition!
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.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
StArL0rd84
Posts: 424
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

Re: New Loop measure type

Post by StArL0rd84 »

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# : </>))
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: New Loop measure type

Post by balala »

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).