It is currently April 18th, 2024, 9:44 pm

Splitting String

Get help with creating, editing & fixing problems with skins
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Splitting String

Post by jsmorley »

The problem is that [SectionVariables] can't be used in the Path option of a FileView parent measure.

https://docs.rainmeter.net/manual/plugins/fileview/#Path
Note: While #Variables# can be used in the parent Path option, [SectionVariables] cannot, as this is ambiguous with the parent definition in a child measure.
This can be resolved like this:

Code: Select all

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

[Variables]
Name1=Rainmeter
Link1="C:\Program Files\Rainmeter\Rainmeter.exe"

[MeasurePath1]
Measure=String
String=#Link1#

[MeasureFolder1]
Measure=String
String=#Link1#
RegExpSubstitute=1
Substitute="^(.*)\\(.*)$":"\1"
OnUpdateAction=[!SetOption MeasureExeIcon1 Path "[MeasureFolder1]"]
UpdateDivider=-1
DynamicVariables=1

[MeasureFileName1]
Measure=String
String=#Link1#
RegExpSubstitute=1
Substitute="^(.*)\\(.*)$":"\2"

[MeasureExeIcon1]
Measure=Plugin
Plugin=FileView
;Path=WaitForIt
DynamicVariables=1
ShowDotDot=0
ShowFolder=0
WildcardSearch=[MeasureFileName1]
Index=1
Type=Icon

[MeterImage1]
Meter=Image
MeasureName=MeasureExeIcon1
LeftMouseUpAction=["[MeasurePath1]"]
So we simply set the value of Path to the literal folder name we got, rather than just using a reference to it with a [SectionVariable].
1.png
Aside...

I'm not crazy about this limitation, as I'm not a fan of "this always works this way unless it doesn't" stuff. Having said that, the problem is that with parent / child functionality like WebParser and FileView, there is great advantage to the fact that a parent can also be a child (as [MeasureExeIcon1] is in this case) and a child can also be a parent (which can be used to good effect in WebParser). That raises this issue, where Path=[SomeMeasure] risks being ambiguous. If you think about it, Path=[SomeMeasure] could clearly be a reference to a parent in a child, and could clearly be a [SectionVariable] in a parent, but those roles are not, and should not be, that clearly defined.

We probably should never have used [MeasureName] as the format defining a relationship between a child and and parent in these types of measures, but should have used something unique like URL={SomeMeasure} or whatever, but in fairness, the current approach was created long, long before the idea of [SectionVariables] was even a twinkle in our eyes. Sometimes we have to sleep in the bed we have made, that is the cost of backwards compatibility.

For the sake of consistency, I think we will need to look at the approach we used with WebParser, where you use URL=[SomeMeasure] to define a child relationship to a parent, and URL=[&SomeMeasure] to alert Rainmeter that this is a reference to the value of another measure, that it should be treated as a [SectionVariable].
You do not have the required permissions to view the files attached to this post.
puppy333
Posts: 9
Joined: July 26th, 2017, 5:57 pm

Re: Splitting String

Post by puppy333 »

Ok that fixed that issue :) now to figure out how to reduce the size of this thing :P
puppy333
Posts: 9
Joined: July 26th, 2017, 5:57 pm

Re: Splitting String

Post by puppy333 »

So now I need to repeat this same fileview thing for each image meter :P

I haven't found any comparable function like MeterStyle for measures. I'm hoping there is some way short of copy-pasting the same 3 measures for each image meter.

Image
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Splitting String

Post by jsmorley »

I'd be tempted to jump to Lua, where you can have a "for / next" loop that can reduce a lot of repetitive code.

Skin:

Code: Select all

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

[Variables]
NumOfLinks=5
Name1=Rainmeter
Link1="C:\Program Files\Rainmeter\Rainmeter.exe"
Name2=Photoshop
Link2="C:\Program Files\Adobe\Adobe Photoshop CC 2015\Photoshop.exe"
Name3=CCLeaner
Link3="C:\Program Files\CCleaner\CCleaner64.exe"
Name4=Guild Wars
Link4="C:\Program Files (x86)\Games\Guild Wars\Gw.exe"
Name5=VLC Media Player
Link5="C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"

[MeasureGetPaths]
Measure=Script
ScriptFile=#CURRENTPATH#GetPaths.lua
UpdateDivider=-1

[MeasureExeIcon1]
Measure=Plugin
Plugin=FileView
;Path=WaitForIt
;WildcardSearch=WaitForIt
ShowDotDot=0
ShowFolder=0
Index=1
Type=Icon
IconPath=ExeIcon1.ico

[MeterExeIcon1]
Meter=Image
MeasureName=MeasureExeIcon1
;LeftMouseUpAction=WaitForIt

[MeasureExeIcon2]
Measure=Plugin
Plugin=FileView
;Path=WaitForIt
;WildcardSearch=WaitForIt
ShowDotDot=0
ShowFolder=0
Index=1
Type=Icon
IconPath=ExeIcon2.ico

[MeterExeIcon2]
Meter=Image
MeasureName=MeasureExeIcon2
Y=5R
;LeftMouseUpAction=WaitForIt

[MeasureExeIcon3]
Measure=Plugin
Plugin=FileView
;Path=WaitForIt
;WildcardSearch=WaitForIt
ShowDotDot=0
ShowFolder=0
Index=1
Type=Icon
IconPath=ExeIcon3.ico

[MeterExeIcon3]
Meter=Image
MeasureName=MeasureExeIcon3
Y=5R
;LeftMouseUpAction=WaitForIt

[MeasureExeIcon4]
Measure=Plugin
Plugin=FileView
;Path=WaitForIt
;WildcardSearch=WaitForIt
ShowDotDot=0
ShowFolder=0
Index=1
Type=Icon
IconPath=ExeIcon4.ico

[MeterExeIcon4]
Meter=Image
MeasureName=MeasureExeIcon4
Y=5R
;LeftMouseUpAction=WaitForIt

[MeasureExeIcon5]
Measure=Plugin
Plugin=FileView
;Path=WaitForIt
;WildcardSearch=WaitForIt
ShowDotDot=0
ShowFolder=0
Index=1
Type=Icon
IconPath=ExeIcon5.ico

[MeterExeIcon5]
Meter=Image
MeasureName=MeasureExeIcon5
Y=5R
;LeftMouseUpAction=WaitForIt
GetPaths.lua:

Code: Select all

function Initialize()

	numOfLinks = SKIN:GetVariable('NumOfLinks')
   
	for inc = 1, numOfLinks do
   
		fullPath = SKIN:GetVariable('Link'..inc)
		linkPath, linkFile = string.match(fullPath, '^(.+)\\(.+)$')

		SKIN:Bang('!SetOption', 'MeasureExeIcon'..inc, 'Path', linkPath)
		SKIN:Bang('!SetOption', 'MeasureExeIcon'..inc, 'WildcardSearch', linkFile)
		SKIN:Bang('!SetOption', 'MeterExeIcon'..inc, 'LeftMouseUpAction', '["'..fullPath..'"]')
      
	end
   
end
1.png
Lua's Pattern Matching functionality in string.match() is a bit of a different animal than regular expression, although very similar.

http://lua-users.org/wiki/PatternsTutorial

Long and the short of it is that:

^(.+)\\(.+)$

Is very similar to what we used in regular expression in the skin, but "greedy" and "ungreedy" are handled a bit different. In this case, we use "+" to mean "one or more, as many as possible". In Lua pattern matching, greedy and ungreedy are handled by the repetition modifiers:

*, which matches 0 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
+, which matches 1 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
-, which also matches 0 or more repetitions of characters in the class. Unlike '*', these repetition items will always match the shortest possible sequence;
?, which means "optional", matches 0 or 1 of the characters in the class.

https://stackoverflow.com/questions/13619193/greed-non-greedy-pattern-matching-and-optional-suffixes-in-lua

The two (captures) are returned as the values for the linkPath and linkFile variables that are used to execute the function.
You do not have the required permissions to view the files attached to this post.
puppy333
Posts: 9
Joined: July 26th, 2017, 5:57 pm

Re: Splitting String

Post by puppy333 »

thanks so much for explaining that it helps alot. I've been thinking about LUA scripting and I believe I am at this point going to rework the whole skin in order to make it completely self constructing after simply entering the strings possibly into an array and either setting or getting the amount of strings in the array.
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Splitting String

Post by jsmorley »

puppy333 wrote:thanks so much for explaining that it helps alot. I've been thinking about LUA scripting and I believe I am at this point going to rework the whole skin in order to make it completely self constructing after simply entering the strings possibly into an array and either setting or getting the amount of strings in the array.
Just be careful that you keep in mind that you can't easily "construct" meters or measures. They must be defined up-front in the skin, and then you can use the Lua to populate, hide, disable etc. as needed.

What you can't do with !SetOption or any other bang or command in Lua are two things:

1) Create or remove a [Section] in the skin
2) Add or change a Measure= or Meter= "type" definition option on a [Section]