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

IfConditions

Changes made during the Rainmeter 3.1 beta cycle.
User avatar
Brian
Developer
Posts: 2673
Joined: November 24th, 2011, 1:42 am
Location: Utah

IfConditions

Post by Brian »

We have added a new IfAction option called IfConditions.

IfConditions allow you to evaluate a mathematical formula that will execute an action based on when the formula is either true or false. IfConditions can be used in any type of measure and you may have multiple IfConditions per measure (eg. IfCondition2/IfTrueAction2/IfFalseAction2). Formulas need to follow the same rules as the Formula option for Calc measures. All the mathematical operators, constants, and functions (except Random and Counter) are available to use. Like Calc, measure names do not need [brackets] and are always dynamic when referenced inside the condition.

Options:
  • IfCondition - A mathematical formula that will evaluate to either true or false.
  • IfTrueAction - If the condition is true, this action is executed only once when the condition becomes "true", so it needs to become "false" and again "true" to execute again.
  • IfFalseAction - If the condition is false, this action is executed only once when the condition becomes "false", so it needs to become "true" and again "false" to execute again.
  • IfConditionMode - If set to 1, the appropriate actions will execute on every update of the measure instead of the default behavior (described above).


Here's how it works:
  1. Define a boolean condition, which is a formula that evaluates to true or false.
    Example: IfCondition=(MeasureCPU >= 10) && (MeasureCPU < 90)
  2. Define a True and/or False action to perform when the IfCondition is evaluated.
    Example: IfTrueAction=[!SetOption MeterCPU Text "CPU usage is between 10 and 90 percent!"]
Note: The comparison on either side of logical AND && and OR || operators must be enclosed in (parentheses).


That's it!



Here are some example skins made by jsmorley. They are all included in the .rmskin:
IfCondition_1.0.rmskin
IfCondition.jpg
Counter
This skin has two "counters", one that counts up to "Limit" and starts over, and the other that counts down from "Limit". Since we want the current value of the measure to change the formula that is doing the counting on every update, we need to use IfConditionMode=1 on this skin.

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[Variables]
Limit=30

[MeasureCountUp]
Measure=Calc
Formula=0
IfCondition=MeasureCountUp = #Limit#
IfTrueAction=[!SetOption MeasureCountUp Formula 0]
IfFalseAction=[!SetOption MeasureCountUp Formula "([MeasureCountUp] + 1)"]
IfConditionMode=1

[MeasureCountDown]
Measure=Calc
Formula=#Limit#
IfCondition=MeasureCountDown = 0
IfTrueAction=[!SetOption MeasureCountDown Formula #Limit#]
IfFalseAction=[!SetOption MeasureCountDown Formula "([MeasureCountDown] - 1)"]
IfCondition2=MeasureCountUp = MeasureCountDown
IfTrueAction2=[!ShowMeter MeterEqual]
IfFalseAction2=[!HideMeter MeterEqual]
IfConditionMode=1

[MeterCountUp]
Meter=String
MeasureName=MeasureCountUp
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1

[MeterCountDown]
Meter=String
MeasureName=MeasureCountDown
X=5R
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1

[MeterEqual]
Meter=String
X=5R
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=Equal
Dice
This skin simply rolls two dice and sets the appropriate Image meters. Then it evaluates the roll, and sets a String meter to The results. Again, since we are dynamically using the value of the measure and some text in the String meter on each "roll", we need to use IfConditionMode=1 on the measures.

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[MeasureDieOne]
Measure=Calc
Formula=Random
LowBound=1
HighBound=6
UpdateRandom=1
UpdateDivider=5
OnUpdateAction=[!SetOption MeterDieOne ImageName [MeasureDieOne]]

[MeasureDieTwo]
Measure=Calc
Formula=Random
LowBound=1
HighBound=6
UpdateRandom=1
UpdateDivider=5
OnUpdateAction=[!SetOption MeterDieTwo ImageName [MeasureDieTwo]]

[MeasureBothDice]
Measure=Calc
Formula=MeasureDieOne + MeasureDieTwo
IfCondition=MeasureDieOne = MeasureDieTwo
IfTrueAction=[!SetOption MeterBothDice Text "Roll is [MeasureBothDice] and is doubles!"]
IfFalseAction=[!SetOption MeterBothDice Text "Roll is [MeasureBothDice]"]
IfCondition2=MeasureBothDice = 2
IfTrueAction2=[!SetOption MeterBothDice Text "Roll is Snake Eyes"]
IfCondition3=MeasureBothDice = 12
IfTrueAction3=[!SetOption MeterBothDice Text "Roll is Boxcars"]
IfCondition4=MeasureBothDice = 7
IfTrueAction4=[!SetOption MeterBothDice Text "Roll is Lucky Seven"]
IfConditionMode=1
UpdateDivider=5

[MeterDieOne]
Meter=Image
ImagePath=#@#Images\
W=50
PreserveAspectRatio=1
AntiAlias=1

[MeterDieTwo]
Meter=Image
ImagePath=#@#Images\
X=8R
W=50
AntiAlias=1
PreserveAspectRatio=1

[MeterBothDice]
Meter=String
X=0
Y=8R
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
OddEven
This skin simply generates a random number, and tests whether it is a single digit number or not, and whether it is "odd" or "even". Since we are using %1 in the bangs, and MeasureName=MeasureRandom in the Meter, we don't need to have the measure with the IfConditions execute on every update, and we leave IfConditionMode=1 off, so it defaults to "0".

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[MeasureRandom]
Measure=Calc
Formula=Random
LowBound=1
HighBound=50
UpdateRandom=1
UniqueRandom=1
IfCondition=((MeasureRandom % 2) = 0) && (MeasureRandom < 10)
IfTrueAction=[!SetOption MeterOutput Text "%1 is single digits and EVEN"]
IfCondition2=((MeasureRandom % 2) = 0) && (MeasureRandom > 9)
IfTrueAction2=[!SetOption MeterOutput Text "%1 is double digits and EVEN"]
IfCondition3=((MeasureRandom % 2) > 0) && (MeasureRandom < 10)
IfTrueAction3=[!SetOption MeterOutput Text "%1 is single digits and ODD"]
IfCondition4=((MeasureRandom % 2) > 0) && (MeasureRandom > 9)
IfTrueAction4=[!SetOption MeterOutput Text "%1 is double digits and ODD"]
UpdateDivider=2

[MeterOutput]
Meter=String
MeasureName=MeasureRandom
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
SameDifferent
This skin generates a random number in [MeasureTwo]. On the next update, it checks [MeasureOne] to see if the number is a "new" one on this update, or is the same one as last time.

Note that we are using a Substitute to turn the number into text. Since the Substitute changes the value from a number to text, it can't be used in IfCondition to do the comparison. So what we do is use the Section Variables form of the measure [MeasureTwo:] in order to obtain the original number value of the measure. While measures are always "dynamic" when used in Calc measures or (as in this case) IfCondition options, Section Variables are not. So we need to use DynamicVariables=1 on the measure.

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[MeasureOne]
Measure=Calc
Formula=0
UpdateDivider=2

[MeasureTwo]
Measure=Calc
Formula=Random
LowBound=1
HighBound=5
UpdateRandom=1
IfCondition=(MeasureOne <> [MeasureTwo:])
IfTrueAction=[!SetOption MeterOutput Text "The number is now %1"]
IfFalseAction=[!SetOption MeterOutput Text "The number stayed %1"]
OnUpdateAction=[!SetOption MeasureOne Formula [MeasureTwo:]]
Substitute="1":"ONE","2":"TWO","3":"THREE","4":"FOUR","5":"FIVE"
UpdateDivider=2
DynamicVariables=1

[MeterOutput]
Meter=String
MeasureName=MeasureTwo
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Weekday
This skin gets the day of the week as text (Sunday, Monday etc.) and the day of the week as a number (0=Sunday, 1=Monday etc.). Then it checks to see if the number reflects a weekend (6 or 0) or a weekday. The appropriate text is set on the String meter. Note that while we need IFConditionMode=1 in order to set the correct text on each update, we really don't need to update the measure at all unless the day of the week changes. So we use an OnChangeAction on the measure getting the day of the week as text, and have it update the measure getting the number and doing the comparison, which is patiently waiting without acting due to UpdateDivider=-1.

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[MeasureWeekdayName]
Measure=Time
Format=%A
OnChangeAction=[!UpdateMeasure MeasureWeekdayNum]

[MeasureWeekdayNum]
Measure=Time
Format=%w
IfCondition=(MeasureWeekdayNum = 6) || (MeasureWeekdayNum = 0)
IfTrueAction=[!SetOption MeterOutput Text "[MeasureWeekdayName]#CRLF#It's the weekend#CRLF#Go back to bed!"]
IfFalseAction=[!SetOption MeterOutput Text "[MeasureWeekdayName]#CRLF#It's a weekday#CRLF#Go to work!"]
ConditionMode=1
UpdateDivider=-1

[MeterOutput]
Meter=String
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
-Brian
You do not have the required permissions to view the files attached to this post.
User avatar
moshi
Posts: 1740
Joined: November 13th, 2012, 9:53 pm

Re: IfConditions

Post by moshi »

very nice addition! and probably easier to understand than the IfAboveValue, IfBelowValue conditions.

now give me:

Code: Select all

IfConditionRegExp="(?si)^.*(rain).*$"
IfMatchAction=...
IfNoMatchAction=...
to execute something when the weather is Rain, Heavy Rain, Rainshowers, etc. for example :)
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: IfConditions

Post by jsmorley »

moshi wrote:very nice addition! and probably easier to understand than the IfAboveValue, IfBelowValue conditions.

now give me:

Code: Select all

IfConditionRegExp="(?si)^.*(rain).*$"
IfMatchAction=...
IfNoMatchAction=...
to execute something when the weather is Rain, Heavy Rain, Rainshowers, etc. for example :)
You are like a bad, spoiled child! ;-)

I would think that you could use RegExpSubtitute on the WebParser measure to turn the "weather condition" into a number with that regular expression. Then use as many IfConditionN as you need to take actions based on the "true" or "false" tests.

Sort of "anything with rain is 1", "anything with cloudy is 2", "anything with thunder is 3", etc... ;-)

Not that some kind of regular expression based IfCondition wouldn't be nice, but it is a different animal to create than the one that is based on the existing math "conditional formula" functionality we use. We didn't really have to invent any wheels to get this. We basically just add "? 1 : 0" to the end of the formula in IfCondition, and off it goes.
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: IfConditions

Post by jsmorley »

P.S. Moshi, this can in fact pretty much replace the IFAction functionality, while being arguably easier to understand and certainly much more powerful.

Same thing done with IFActions and IFConditions:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[MeasureIfActionTime]
Measure=Time
Format=%#S
IfAboveValue=29
IfAboveAction=[!SetOption MeterIfAction SolidColor "76,179,54,255"]
IfBelowValue=30
IfBelowAction=[!SetOption MeterIfAction SolidColor "54,124,179,255"]

[MeasureIfConditionTime]
Measure=Time
Format=%#S
IfCondition=MeasureIfConditionTime >= 30
IfTrueAction=[!SetOption MeterCondition SolidColor "76,179,54,255"]
IfFalseAction=[!SetOption MeterCondition SolidColor "54,124,179,255"]

[MeterIfAction]
Meter=String
MeasureName=MeasureIfActionTime
FontSize=14
FontColor=226,252,220,255
StringStyle=Bold
Padding=5,5,5,5
AntiAlias=1

[MeterCondition]
Meter=String
MeasureName=MeasureIfConditionTime
X=5R
FontSize=14
FontColor=226,252,220,255
StringStyle=Bold
Padding=5,5,5,5
AntiAlias=1
User avatar
moshi
Posts: 1740
Joined: November 13th, 2012, 9:53 pm

Re: IfConditions

Post by moshi »

jsmorley wrote:I would think that you could use RegExpSubtitute on the WebParser measure to turn the "weather condition" into a number with that regular expression. Then use as many IfConditionN as you need to take actions based on the "true" or "false" tests.
yeah, pretty much everything is possible with RegExpSubstitute, i just would love to add this to the tips & tricks section:

Code: Select all

Measure=Plugin
Plugin=SysInfo
SysInfoType=USER_NAME
IfConditionRegExp="^(Rogers1967)$"
IfMatchAction=[PLAYLOOP beep.wav]
:twisted:
User avatar
AlC
Posts: 329
Joined: June 9th, 2011, 6:46 pm

Re: IfConditions

Post by AlC »

Very nice addition !!!

Code: Select all

Measure=Plugin
Plugin=SysInfo
SysInfoType=USER_NAME
IfConditionRegExp="^(Rogers1967)$"
IfMatchAction=[PLAYLOOP beep.wav]
xD
Rainmeter - You are only limited by your imagination and creativity.
amc242
Posts: 25
Joined: July 12th, 2012, 2:02 pm

Re: IfConditions

Post by amc242 »

Code: Select all

Measure=Plugin
Plugin=SysInfo
SysInfoType=USER_NAME
IfConditionRegExp="^(Rogers1967)$"
IfMatchAction=[PLAYLOOP beep.wav]
This won't work. His username is "Rogers", and that could hurt millions of innocent Rogers.
But his PC name is "Rogers-PC"... :twisted:
MikeG621
Posts: 87
Joined: March 18th, 2013, 1:59 pm

Re: IfConditions

Post by MikeG621 »

Excellent, I've been wanting this functionality for a while because the current methods are quite tedious.