IfConditions

Changes made during the Rainmeter 3.1 beta cycle.
User avatar

IfConditions

November 10th, 2013, 5:01 pm
Brian
Developer   [1443 posts]

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
(12.39 KiB) Downloaded 503 times




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
User avatar

Re: IfConditions

November 10th, 2013, 10:43 pm
moshi
   [1852 posts]

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

Re: IfConditions

November 10th, 2013, 10:51 pm
jsmorley
Developer   [15726 posts]

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

Re: IfConditions

November 10th, 2013, 10:58 pm
jsmorley
Developer   [15726 posts]

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

Re: IfConditions

November 10th, 2013, 11:02 pm
moshi
   [1852 posts]

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

Re: IfConditions

November 13th, 2013, 7:02 pm
AlC
   [331 posts]

Very nice addition !!!

Code: Select all

Measure=Plugin
Plugin=SysInfo
SysInfoType=USER_NAME
IfConditionRegExp="^(Rogers1967)$"
IfMatchAction=[PLAYLOOP beep.wav]
xD

Re: IfConditions

November 13th, 2013, 7:10 pm
amc242
   [38 posts]

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:

Re: IfConditions

November 15th, 2013, 1:28 pm
MikeG621
   [58 posts]

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

Return to “Rainmeter 3.1”



Who is online

Users browsing this forum: No registered users and 0 guests