It is currently October 21st, 2019, 4:11 am

Example of String Gradient Bar Meter

Tips and Tricks from the Rainmeter Community
User avatar
jsmorley
Developer
Posts: 19591
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Example of String Gradient Bar Meter

jsmorley » November 6th, 2015, 3:18 pm

This example just shows how you might use a String meter, and the new InlineSetting GradientColor setting, to get a bar meter that can be re-sized by simply changing the FontSize option.

Code: Select all

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

[Variables]
BarSize=20
Sq1=CPU Percentage Of Usage
Sq2=■■■■■■■■■■■■■■■■■■■■
Sq3=●●●●●●●●●●●●●●●●●●●●

[MeasureCPU]
Measure=CPU

[MeterBack]
Meter=Image
W=335
H=87
SolidColor=47,47,47,255

[MeterStringBar1]
Meter=String
X=5
FontSize=#BarSize#
SolidColor=0,0,0,1
Text=#Sq1#
AntiAlias=1
DynamicVariables=1
InlineSetting=GradientColor | 180 | 119,217,108,255 ; 0.0 | 119,217,108,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; 1.0
InlinePattern=.*

[MeterStringBar2]
Meter=String
X=5
Y=0R
FontSize=#BarSize#
SolidColor=0,0,0,1
Text=#Sq2#
AntiAlias=1
DynamicVariables=1
InlineSetting=GradientColor | 180 | 119,217,108,255 ; 0.0 | 119,217,108,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; 1.0
InlinePattern=.*

[MeterStringBar3]
Meter=String
X=5
Y=0R
FontSize=#BarSize#
SolidColor=0,0,0,1
Text=#Sq3#
AntiAlias=1
DynamicVariables=1
InlineSetting=GradientColor | 180 | 119,217,108,255 ; 0.0 | 119,217,108,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; 1.0
InlinePattern=.*
test.gif
https://forum.rainmeter.net/viewtopic.php?f=115&t=21479

http://docs.rainmeter.net/manual-beta/meters/string/inline/#InlineSetting

The trick to this is here:

InlineSetting=GradientColor | 180 | 119,217,108,255 ; 0.0 | 119,217,108,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; ([MeasureCPU:%]/100) | 196,196,196,255 ; 1.0

What we are doing is setting a gradient from color A to color A (so the same color) that ends at the percentage value. Then we are setting an immediate change to Color B at that same point. So there is no "gradient" as such, just a clean transition from Color A to Color B at the point of the percentage value. Then we just finish up with Color B out to the end.

The string can be any characters and any length, just be sure that if you are using Unicode characters, as I am above, that you encode the skin .ini file as UTF-16 Little Endian before you paste in the characters.
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 19591
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Example of String Gradient Bar Meter

jsmorley » November 7th, 2015, 4:36 pm

Here is another slightly different example:

Code: Select all

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

[Variables]
Char=●
CharString=●●●●●●●●●●●●●●●●●●●●
CharPoints=18

[MeasureCPU]
Measure=CPU

[MeasurePercent]
Measure=Calc
; Create a "bitmap / frames" effect, always filling in chars entirely
; Divide 100 by the number of chars in the string
; So 100 / 20 = 5
; Divide the measure value by 5
; Round to the nearest whole number
; Then multiply by 5 again
Formula=(Round(MeasureCPU / 5) * 5)
; Get the target char by multiplying the number of chars
; in the string by the percentage, then subtracting 1
; Use this to set another color for the target char
IfCondition=[MeasurePercent] > 0
IfTrueAction=[!SetVariable TargetChar "(20 * ([MeasurePercent] / 100) - 1)"]
; If the target char would be "0", don't let the
; regular expression in InlinePattern2 treat that as "1"
IfFalseAction=[!SetVariable TargetChar ""]
; Change the gradient and target colors if the value is over 70 percent
IfCondition2=[MeasurePercent] > 70
IfTrueAction2=[!SetVariable GradientColor "204,45,45,255"][!SetVariable TargetColor "250,127,127,255"]
IfFalseAction2=[!SetVariable GradientColor "84,166,75,255"][!SetVariable TargetColor "234,247,233,255"]
IfConditionMode=1
DynamicVariables=1

[MeterBack]
Meter=Image
W=([MeterStringBar:W] + 10)
H=([MeterStringBar:H] + 5)
SolidColor=47,47,47,255
DynamicVariables=1

[MeterStringBar]
Meter=String
X=5
FontSize=#CharPoints#
SolidColor=0,0,0,1
Text=#CharString#
AntiAlias=1
DynamicVariables=1
InlineSetting=GradientColor | 180 | #GradientColor# ; 0.0 | #GradientColor# ; ([MeasurePercent]/100) | 150,150,150,255 ; ([MeasurePercent]/100) | 150,150,150,255 ; 1.0
InlinePattern=.*
InlineSetting2=Color | #TargetColor#
InlinePattern2=(?siU)[#Char#]{#TargetChar#}(#Char#).*$
test.gif
A couple of little notes / gotchas with regular expression in this case:

1) While you can use #VarName# in regular expressions in Rainmeter, (Substitute, IfMatch, InLinePattern etc.) you can't use (formulas) in them, as there is no way to be unambiguous between a Rainmeter formula and a regular expression directive.

2) If you are matching on a "count" of characters, as in "[SomeChar]{SomeCount}", you can't count using the "any char" . character if you are using multi-byte Unicode characters. The count will be wrong. In my example I had to specifically count "[●]{SomeCount}" in order to properly count those Unicode characters.
You do not have the required permissions to view the files attached to this post.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 3575
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Example of String Gradient Bar Meter

eclectic-tech » November 8th, 2015, 4:01 am

I especially like your second post, and as always, your helpful descriptions! :thumbup:

Here are a few I threw together, based on your code, they just using gradients (not ready to count characters yet!) :D
The last 2 are still works-in-progress :)

Code: Select all

[Rainmeter]
Update=200
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=20,20,20,190

[Variables]
Angle=180
; 0 (360) = RightToLeft
; 90 = BottomToTop
; 180 = LeftToRight
; 270 = TopToBottom
SQ1="-----------------"
Sq3="|||||||||||||||||||||"
Sq4="I"
Sq5="I"
Sq6="/"
Sq7="\"
Sq9="___"

[MeasureCPU]
Measure=CPU
AverageSize=5
InvertMeasure=0

[Meter1Text]
Meter=String
Y=-16R
FontSize=24
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq1#
InlineSetting=GradientColor | #Angle# | 94,252,37 ; 0.0 | 252,117,41 ; ([MeasureCPU:%]/100) | 251,163,48 ; ([MeasureCPU:%]/100) | 249,215,56 ; ([MeasureCPU:%]/100) | 249,242,61 ; 1.0
InlinePattern=.*

[Meter3Text]
Meter=String
Y=-16R
FontSize=24
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq3#
InlineSetting=GradientColor1 | 0 | 94,252,37 ; 0.0 | 252,117,41 ; ([MeasureCPU:%]/100) | 251,163,48 ; ([MeasureCPU:%]/100) | 249,215,56 ; ([MeasureCPU:%]/100) | 249,242,61 ; 1.0
InlinePattern=.*

[Meter4Text]
Meter=String
Y=-8R
FontSize=48
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq4#
InlineSetting=GradientColor | 90 | 94,252,37 ; 0.0 | 252,117,41 ; ([MeasureCPU:%]/100) | 251,163,48 ; ([MeasureCPU:%]/100) | 249,215,56 ; ([MeasureCPU:%]/100) | 249,242,61 ; 1.0
InlinePattern=.*

[Meter5Text]
Meter=String
X=8R
Y=r
FontSize=48
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq5#
InlineSetting=GradientColor | 270 | 94,252,37 ; 0.0 | 252,117,41 ; ([MeasureCPU:%]/100) | 251,163,48 ; ([MeasureCPU:%]/100) | 249,215,56 ; ([MeasureCPU:%]/100) | 249,242,61 ; 1.0
InlinePattern=.*

[Meter6Text]
Meter=String
X=8R
Y=r
FontSize=48
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq6#
InlineSetting=GradientColor | 90 | 94,252,37 ; 0.0 | 252,117,41 ; ([MeasureCPU:%]/100) | 251,163,48 ; ([MeasureCPU:%]/100) | 249,215,56 ; ([MeasureCPU:%]/100) | 249,242,61 ; 1.0
InlinePattern=.*

[Meter7Text]
Meter=String
X=8R
Y=r
FontSize=48
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq7#
InlineSetting=GradientColor | 270 | 94,252,37 ; 0.0 | 252,117,41 ; ([MeasureCPU:%]/100) | 251,163,48 ; ([MeasureCPU:%]/100) | 249,215,56 ; ([MeasureCPU:%]/100) | 249,242,61 ; 1.0
InlinePattern=.*

[Meter9Text]
Meter=String
Y=-100R
FontSize=80
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq9#
InlineSetting=GradientColor | 180 | 0,0,0 ; -0.1 | 255,43,43 ; ([MeasureCPU:%]/100) | 0,0,0 ; 1.01
InlinePattern=.*

[Meter10Text]
Meter=String
Y=-100R
FontSize=80
StringStyle=Bold
Padding=5,5,10,5
AntiAlias=1
DynamicVariables=1
Text=#Sq9#
InlineSetting=GradientColor | 180 | 0,0,0 ; -0.1 | 10,0,0 ; ([MeasureCPU:%]*0.9/100) | 255,43,43 ; ([MeasureCPU:%]/100) | 10,0,0 ; ([MeasureCPU:%]*1.1/100) | 0,0,0 ; 1.01
InlinePattern=.*
CPU3.gif
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 19591
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Example of String Gradient Bar Meter

jsmorley » November 8th, 2015, 12:58 pm

The "counting chars" bit is really pretty straightforward. The goal is to identify the character in the string that indicates the current "value" of the measure, and have that have some different attribute. Might be a different color, or size or weight or whatever you like.

It could even be an entirely different character, but you can't do that in an InlineSetting. However, you could pretty easily do that in a RegExpSubstitute / Substitute on a string measure.

So we get the position number, what I called "TargetChar" of the character that represents the value by multiplying the number of chars in the string by the percentage.

IfCondition=[MeasurePercent] > 0
IfTrueAction=[!SetVariable TargetChar "(20 * ([MeasurePercent] / 100) - 1)"]


Edit: Now that I think about it, you might want to use "Floor" in the calculation, so you always get an integer.
IfTrueAction=[!SetVariable TargetChar "(20 * (Floor(([MeasurePercent] / 100) - 1))"]

Note that we subtract -1 from the result. That is because what we are going to do below is:

Count the number of character "up to" the "TargetChar". Then change the single character at the position "TargetChar". So you subtract -1 from the value, to let you count "up to but not including".

So then the regular expression looks like:

InlinePattern2=(?siU)[#Char#]{#TargetChar#}(#Char#).*$

That uses the regular expression [character set]{range} functionality. While it has many uses, we are using it in its most simple form:

[character to match]{how many of that character}

So we are counting / skipping #TargetChar# instances of the character #Char#. Then we are capturing a single (#Char#) and skipping out to the end of the string.

The InlineSetting will be applied to that single #Char# we captured.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 3575
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Example of String Gradient Bar Meter

eclectic-tech » November 8th, 2015, 2:53 pm

I followed the logic and math for your example, I just didn't take the time to incorporate it... :oops:
but thanks for the expanded description.

Using RegExpSubstitute to change the target character is an interesting idea. 8-)
Yeah, I agree that Floor() is tool of choice in that formula.

Thanks Again for the idea and examples