It is currently April 27th, 2024, 7:36 am

MeasureName in MeterStyle

Get help with creating, editing & fixing problems with skins
User avatar
vakot
Posts: 4
Joined: February 6th, 2024, 12:50 pm

MeasureName in MeterStyle

Post by vakot »

Is there a way to use MeasureName inside of MeterStyle?

I just want to change some shape parameters based on measure. But i still want to make my component reusable for other situations with defferent measures. As i can see it's possible to get options like X,Y,W,H from #CURRENTSECTION# varibale, but i cant find any way to get the MeasureName and use it.

Here is a simple example that describes my problem (maybe it's not not that useful in this case but i find it very helpful in more complex situations):

Code: Select all

[Measure]
Measure=Calc
Formula=24

[Style]
Shape=Rectangle 0,0,([#CURRENTSECTION#:W]*(get_parent_measure_value_here)),[#CURRENTSECTION#:H] | Fill Color 0,0,0 | StrokeWidth 0

[Example]
Meter=Shape
MeterStyle=Style
MeasureName=Measure
W=10
H=10
All i know about using Measure without call it by "global" name is to use "%n" in string meters, like this:

Code: Select all

[StringExample]
Meter=String
MeasureName=Measure
Text=Measure values is: %1
Also, in this case it's possible to use Measure in Style the same way:

Code: Select all

[StringStyle]
Text=Measure value is: %1

[StringExample]
Meter=String
MeterStyle=StringStyle
MeasureName=Measure
Would be proud of someone who could help me find a way to make this possible.
RicardoTM
Posts: 268
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: MeasureName in MeterStyle

Post by RicardoTM »

The measure should include the name of the meter on its name in order to be used with currentsection variable.

If your meter is called [Example], you gotta call your measure [ExampleMeasure] and call it from the meter with [#CurrentSection#Measure].
User avatar
vakot
Posts: 4
Joined: February 6th, 2024, 12:50 pm

Re: MeasureName in MeterStyle

Post by vakot »

RicardoTM wrote: February 6th, 2024, 1:37 pm The measure should include the name of the meter on its name in order to be used with currentsection variable.

If your meter is called [Example], you gotta call your measure [ExampleMeasure] and call it from the meter with [#CurrentSection#Measure].
[#CurrentSection#Measure] is a good solution, but it's not exactly what i want to have. Imagine debbugin southands of Meters without MeasureName option. It would be a nightmare to always check if Meter has it's own Measure, or not. Of course Ctrl+F still exists, but...

And another problem appears when i want to use some global Measures. For example. In the code below i forced to create a "copy" of my [GlobalMeasure] to contain exactly the same value. I also noted the absence of MeasureName in [Example]:

Code: Select all

[GlobalMeasure]
Measure=Calc
Formula=24

[ExampleMeasure]
Measure=Calc
Formula=[GlobalMeasure:]
DynamicVariables=1

[Style]
Shape=Rectangle 0,0,([#CURRENTSECTION#:W]*[#CURRENTSECTION#Measure:]),[#CURRENTSECTION#:H] | Fill Color 0,0,0 | StrokeWidth 0
DynamicVariables=1

[Example]
Meter=Shape
MeterStyle=Style
; MeasureName=ExampleMeasure ; option is unnecessary
Y=32
W=10
H=20

[GlobalExample]
Meter=String
MeasureName=GlobalMeasure
SolidColor=100,100,100
Padding=5,5,5,5
That a good and working solution. But it's not perfect for me.
User avatar
Yincognito
Rainmeter Sage
Posts: 7175
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: MeasureName in MeterStyle

Post by Yincognito »

vakot wrote: February 6th, 2024, 1:11 pm Is there a way to use MeasureName inside of MeterStyle?
I get what you mean. If you find RicardoTM's advice inconvenient for mass usage (though, like you said, CTRL + F exists), then the alternative is to write a short Lua function to retrieve the value of an option from a section, then use it inline via a Script measure:
https://docs.rainmeter.net/manual/lua-scripting/
https://docs.rainmeter.net/manual/lua-scripting/inline-lua/

It might seem complicated, but it's not. Lua's integration with Rainmeter provides a couple of functions that you can use in your own, to make it happen. Some time ago, I wrote a small function to get the "index" of a section, e.g. the 3 from [SectionName3] or even from [S3ctionName], so I know for sure that what you want is possible.

Think about what approach you'd like to go with, if any, and let us know your decision. RicardoTM's suggestion is an easy one (and I use it myself, when needed) but obviously requires sections to be named according to a certain pattern for it to work. The Lua route is slightly more complex and might seem even more inconvenient than RicardoTM's, but it will not depend on any particular naming pattern. I could post some script on this later on, but since I don't like to do pointless things, I'll only tackle this if you think you need it. Or, you can try to do it on your own, if you feel confident - we'll be here to help if needed anyway. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7175
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: MeasureName in MeterStyle

Post by Yincognito »

vakot wrote: February 6th, 2024, 2:34 pm [#CurrentSection#Measure] is a good solution, but it's not exactly what i want to have.
As promised, here is the Lua alternative...

...\@Resources\Script.lua:

Code: Select all

function OptionValue(section, option)
  return ((SKIN:GetMeasure(section) or SKIN:GetMeter(section)) and (SKIN:GetMeasure(section) or SKIN:GetMeter(section)):GetOption(option) or '')
end
...\Skin.ini:

Code: Select all

[Variables]

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1

[Number]
Measure=Calc
Formula=(7+3)
UpdateDivider=-1
DynamicVariables=1

---Meters---

[Result]
Meter=String
FontColor=255,255,255,255
FontFace=Consolas
FontSize=16
Padding=5,5,5,5
AntiAlias=1
MeasureName=Number
Text=Measure Name (literal) = [&Script:OptionValue('[#CURRENTSECTION]','MeasureName')]#CRLF#Measure Value (number) = [[&Script:OptionValue('[#CURRENTSECTION]','MeasureName')]:]
UpdateDivider=-1
DynamicVariables=1
Details in the two links I posted above. The "A and B or C" construct in Lua is equivalent to a numerical conditional in plain Rainmeter and basically means "if A is true, then return B, else return C". The "A or B" construct in Lua basically means "if A is valid, then return A, else return B" (where valid might mean that it exists and it's not nil, for example). Notice how the round brackets are placed, to understand the order of these tests. Obviously, the function's contents can also be written using plain "if ... then ... else ... end" statements (equivalent implementation in the spoiler below), it's just that I like compact one-liners so I used the logical operators instead for this error handling system.

Code: Select all

function OptionValue(section, option)
  local sectionhandle
  if SKIN:GetMeasure(section) then sectionhandle = SKIN:GetMeasure(section) else sectionhandle = SKIN:GetMeter(section) end
  if sectionhandle then return sectionhandle:GetOption(option) else return '' end
end
P.S. The return value of the function is a string (similar to how #CURRENTSECTION# works), so its parsing can be then adjusted as desired in plain Rainmeter, ensuring maximum flexibility. Because of that, no variable replacing or formula parsing was done in Lua. Also, I used the nested syntax for CURRENTSECTION in the inline Lua because of this.

EDIT: Adjusted the alternative in the spoiler to use "sectionhandle" as a local variable in that function, instead of a global one like it was in the original version. A minor omission due to successive editing of the .lua file.
Last edited by Yincognito on February 6th, 2024, 11:51 pm, edited 1 time in total.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
vakot
Posts: 4
Joined: February 6th, 2024, 12:50 pm

Re: MeasureName in MeterStyle

Post by vakot »

Yincognito wrote: February 6th, 2024, 5:13 pm As promised, here is the Lua alternative...
This is definitely a good one and I like it. Thank you very much. I'm glad the Rainmeter community is so responsive.

But I'm still a bit confused. Why some options can be accessed with regular [SectionName:OptionName] and others can't :(. Especially when you can create such a simple third-party implementation.
RicardoTM
Posts: 268
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: MeasureName in MeterStyle

Post by RicardoTM »

vakot wrote: February 6th, 2024, 2:34 pm I also noted the absence of MeasureName in [Example]:

Code: Select all

[GlobalMeasure]
Measure=Calc
Formula=24

[ExampleMeasure]
Measure=Calc
Formula=[GlobalMeasure:]
DynamicVariables=1

[Style]
Shape=Rectangle 0,0,([#CURRENTSECTION#:W]*[#CURRENTSECTION#Measure:]),[#CURRENTSECTION#:H] | Fill Color 0,0,0 | StrokeWidth 0
DynamicVariables=1

[Example]
Meter=Shape
MeterStyle=Style
; MeasureName=ExampleMeasure ; option is unnecessary
Y=32
W=10
H=20

[GlobalExample]
Meter=String
MeasureName=GlobalMeasure
SolidColor=100,100,100
Padding=5,5,5,5
That a good and working solution. But it's not perfect for me.
vakot wrote: February 6th, 2024, 6:31 pm This is definitely a good one and I like it. Thank you very much. I'm glad the Rainmeter community is so responsive.

But I'm still a bit confused. Why some options can be accessed with regular [SectionName:OptionName] and others can't :(. Especially when you can create such a simple third-party implementation.
While looking at your code, I just realized that maybe you just want to reference the value of a measure multiple times. You can just use [GlobalMeasure], this returns the value of the measure wherever you use it.
[GlobalMeasure] returns the string value.
[GlobalMeasure:] returns the number value as is.
[GlobalMeasure:0] returns the number value without decimals.
[GlobalMeasure:1] returns the number value with 1 decimal.
[GlobalMeasure:2] returns the number value with 2 decimals.
And so on.

So you could just go like this:

Code: Select all

[Style]
Shape=Rectangle 0,0,([#CURRENTSECTION#:W]*[GlobalMeasure:]),[#CURRENTSECTION#:H] | Fill Color 0,0,0 | StrokeWidth 0
DynamicVariables=1
You can also reference this measure on a meter without MeasureName, just with Text=The Number Value is [GlobalMeasure:].

More info here: https://docs.rainmeter.net/tips/measure-as-a-variable/

And here: https://docs.rainmeter.net/manual/variables/section-variables/#Colon
User avatar
Yincognito
Rainmeter Sage
Posts: 7175
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: MeasureName in MeterStyle

Post by Yincognito »

vakot wrote: February 6th, 2024, 6:31 pm This is definitely a good one and I like it. Thank you very much. I'm glad the Rainmeter community is so responsive.

But I'm still a bit confused. Why some options can be accessed with regular [SectionName:OptionName] and others can't :(. Especially when you can create such a simple third-party implementation.
You're welcome - glad you like it, hopefully you'll make good use of it. ;-)

I don't have a definitive answer as to why only certain options are available as section variable parameters and others are not, that's something to ask the developers of Rainmeter over the years. I imagine that it's either because some options were considered more likely to be interrogated like that, or, depending on how Rainmeter evolved they were already implemented and available in Lua via the above methods (which, by the way, even though it's a separate programming language, it's not really 3rd party since it's integrated into Rainmeter specifically for that reason - to do things that are tricky or cumbersome to do when using the plain Rainmeter .ini syntax). A secondary reason might have been the intention to keep Rainmeter as lightweight as possible, both in terms of syntax and internally, so as to not negatively affect the expected user experience. Might also have been due to the potential volatility of certain options (e.g. how you'd return certain more complex Shape options and such). Just guessing here, of course, but I suspect these were some potential reasons for such features that might seem "incomplete" at times... :???:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
vakot
Posts: 4
Joined: February 6th, 2024, 12:50 pm

Re: MeasureName in MeterStyle

Post by vakot »

RicardoTM wrote: February 6th, 2024, 8:48 pm While looking at your code, I just realized that maybe you just want to reference the value of a measure multiple times. You can just use
My target is absolutely opposite. I want to create a custom reusable componen, just like existed Meter=Rouundline or Meter=Bar. I found this way of building skin layouts is the best one. Sounds like OOP btw. So, in result i may have my [CustomMeterStyle] and use it with different Measures, just like Meter=Roundline and Meter=Bar.

Code: Select all

[MyComponent1]
Meter=Shape
MeterStyle=CutomMeterStyle
MeasureName=Measure1

[MyComponent2]
Meter=Shape
MeterStyle=CustomMeterStyle
MeasureName=Measure2
In example above i want to use a "reference" to the MeasureName of parent component inside my [CustomMeterStyle]. So, basically, i would have the same components with different measures. This way i minimize code repeatance and make it more "elegant".
RicardoTM
Posts: 268
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: MeasureName in MeterStyle

Post by RicardoTM »

vakot wrote: February 7th, 2024, 11:08 am make it more "elegant".
Happy you found your way. I personally prefer my way:

Code: Select all

;Style;
[Meters]
MeasureName=m#CURRENTSECTION#
Text=%1

;Measures;
[mMeter1]
Measure=Calc
Formula=1+1

[mMeter2]
Measure=Calc
Formula=3+2

[mMeter3]
Measure=Calc
Formula=6/2

;Meters;
[Meter1]
Meter=String
MeterStyle=Meters

[Meter2]
Meter=String
MeterStyle=Meters

[Meter3]
Meter=String
MeterStyle=Meters
Each meter is bound to its own measure using only one MeterStyle. This is with string meters but is practically the same stuff. The thing is to keep a good naming practice, you can use prefixes and suffixes to bind the meters to the measures. Anyway, maybe I don't get what you want, but the good part is you already nailed it. Have a nice time making your skin!