It is currently November 15th, 2018, 3:34 pm

Substitute inside a link

Help with creating, editing & fixing problems with skins
Nickcz
Posts: 9
Joined: January 21st, 2017, 10:27 pm

Substitute inside a link

Nickcz » November 15th, 2017, 6:46 pm

Hi I've got a problem with a code, which I hope someone can help me with

Essentially the code is used to open a specific page on the Steam Store

Code: Select all

LeftMouseUpAction=!Execute ["http://store.steampowered.com/app/#SlotImage1#"]
#SlotImage1# is the variable being called which currently calls http://store.steampowered.com/app/C:/Users/Nick/Documents/Rainmeter/Skins/LauhdutinV2/@Resources/Banners/Steam/359870.jpg

obviously this wont work so I'm trying to remove the majority of the called data leaving only "359870" so the resulting link would be http://store.steampowered.com/app/359870

I've tried adding a substitute line after but I'm pretty sure I'm using it in the wrong way so I have

Code: Select all

LeftMouseUpAction=!Execute ["http://store.steampowered.com/app/#SlotImage1#"]
Substitute="C:/Users/Nick/Documents/Rainmeter/Skins/LauhdutinV2/@Resources/Banners/Steam/":"",".jpg":""
Any help would be greatly appreciated as I've been pulling my hair out thinking about this :???:

Thanks in advance
User avatar
balala
Rainmeter Sage
Posts: 6975
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Substitute inside a link

balala » November 15th, 2017, 7:45 pm

The posted Substitute option won't change the variable used into the meter and can't even be added to a meter, just to a measure. So, you have to add a this kind of String measure to your code:

Code: Select all

[MeasureVar]
Measure=String
String=#SlotImage1#
RegExpSubstitute=1
Substitute=".*/(.*)\..*":"\1"
This Substitute is needed if in the SlotImage1 variable the path is changing. If it's always the posted one, you can remove the RegExpSubstitute=1 option and use your own Substitute option.
Then in the LeftMouseUpAction option replace the #SlotImage1# variable with the [MeasureVar] measure: LeftMouseUpAction=!Execute ["http://store.steampowered.com/app/[MeasureVar]"]. This solution will require to add to the meter which has set the above LeftMouseUpAction, the DynamicVariables=1 option (if it's not added yet).
Nickcz
Posts: 9
Joined: January 21st, 2017, 10:27 pm

Re: Substitute inside a link

Nickcz » November 15th, 2017, 8:06 pm

Thanks for your reply, however the code is taking me to "http://store.steampowered.com/app/"

So it doesn't look like its grabbing the variable

Code: Select all

[OpenStorePage]
Meter=String
X=60
;(0*#SlotWidth#+#SlotWidth#/2+40)
Y=330
;(#SlotHeight#/2)
W=536
H=500
Text=Open Store Page
FontFace=Arial
FontSize=(#SlotWidth#/20)
FontColor=#SlotTextColor#
StringAlign=Left
;CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots
LeftMouseUpAction=!Execute ["http://store.steampowered.com/app/[MeasureVar]"]

Code: Select all

[MeasureVar]
Measure=String
String=#SlotImage1#
RegExpSubstitute=1
Substitute="C:/Users/Nick/Documents/Rainmeter/Skins/LauhdutinV2/@Resources/Banners/Steam/":"",".jpg":""
Any idea? (#SlotImage1# changes all the time as its the first game in the launcher as I scroll though the games the variable changes)

Thanks
User avatar
balala
Rainmeter Sage
Posts: 6975
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Substitute inside a link

balala » November 15th, 2017, 8:10 pm

Nickcz wrote:Any idea? (#SlotImage1# changes all the time as its the first game in the launcher as I scroll though the games the variable changes)
Replace the Substitute with mine one.
Nickcz
Posts: 9
Joined: January 21st, 2017, 10:27 pm

Re: Substitute inside a link

Nickcz » November 15th, 2017, 8:15 pm

Code: Select all

[Variables]
ToolbarWidth=1750
SlotCount=7
SlotWidth=290
SlotHeight=135
SlotBackgroundColor=0,0,0,100
SlotTextColor=255,255,255,255
SlotPath1=
SlotImage1=
SlotName1=
SlotHighlightMessage1=
SlotPath2=
SlotImage2=
SlotName2=
SlotHighlightMessage2=
SlotPath3=
SlotImage3=
SlotName3=
SlotHighlightMessage3=
SlotPath4=
SlotImage4=
SlotName4=
SlotHighlightMessage4=
SlotPath5=
SlotImage5=
SlotName5=
SlotHighlightMessage5=
SlotPath6=
SlotImage6=
SlotName6=
SlotHighlightMessage6=
SlotPath7=
SlotImage7=
SlotName7=
SlotHighlightMessage7=

[MeasureVar]
Measure=String
String=#SlotImage1#
RegExpSubstitute=1
Substitute="C:/Users/Nick/Documents/Rainmeter/Skins/LauhdutinV2/@Resources/Banners/Steam/":"",".jpg":""

[SlotBackground]
Meter=Image
X=39
Y=0
SolidColor=#SlotBackgroundColor#
W=538
H=381
;W=(#SlotCount#*#SlotWidth#)
;H=#SlotHeight#

[SlotBackground2]
Meter=Image
X=630
Y=0
SolidColor=#SlotBackgroundColor#
H=285
W=(3*#SlotWidth#+20)
;H=#SlotHeight#

[SlotText1]
Meter=String
X=50
;(0*#SlotWidth#+#SlotWidth#/2+40)
Y=260
;(#SlotHeight#/2)
W=525
H=50
Text=Play: #SlotName1#
FontFace=Arial
FontSize=(#SlotWidth#/16)
FontColor=#SlotTextColor#
StringAlign=Left
;CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[Underline]
Meter=Shape
Shape=Rectangle 50,290,500,1 | Fill Color 250,250,250,100 | StrokeWidth 0 | Stroke Color 0,0,0,170

[Timespent]
Meter=String
X=55
;(0*#SlotWidth#+#SlotWidth#/2+40)
Y=190
;(#SlotHeight#/2)
W=536
H=500
Text=#SlotHighlightMessage1#
FontFace=Arial
FontSize=(#SlotWidth#/20)
FontColor=#SlotTextColor#
StringAlign=Left
;CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[Underline2]
Meter=Shape
Shape=Rectangle 50,320,480,1 | Fill Color 250,250,250,100 | StrokeWidth 0 | Stroke Color 0,0,0,170


[OpenStorePage]
Meter=String
X=60
;(0*#SlotWidth#+#SlotWidth#/2+40)
Y=330
;(#SlotHeight#/2)
W=536
H=500
Text=Open Store Page
FontFace=Arial
FontSize=(#SlotWidth#/20)
FontColor=#SlotTextColor#
StringAlign=Left
;CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots
LeftMouseUpAction=!Execute ["http://store.steampowered.com/app/[MeasureVar]"]




[Underline3]
Meter=Shape
Shape=Rectangle 50,328,4,25 | Fill Color 250,250,250,200 | StrokeWidth 0 | Stroke Color 0,0,0,170

[SlotBanner1]
Meter=Image
ImageName=#SlotImage1#
X=(0*#SlotWidth#+40)
Y=2
W=536
H=249
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('1')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath1#')"]
Group=Slots

[SlotHighlightBackground1]
Meter=Image
X=0r
Y=0r
W=536
H=249
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight1

[SlotHighlight1]
Meter=Image
ImageName=
X=0r
Y=0r
W=536
H=249
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight1

;[SlotHighlightText1]
;Meter=String
;X=(536 / 2)r
;Y=(249 / 2)r
;W=536
;H=249
;Text=#SlotHighlightMessage1#
;FontFace=Arial
;FontSize=(#SlotWidth#/25)
;FontColor=#SlotTextColor#
;StringAlign=CenterCenter
;StringEffect=Shadow
;ClipString=1
;AntiAlias=1
;DynamicVariables=1
;Group=SlotHighlight1


[SlotTextRecentGames]
Meter=String
X=(1*#SlotWidth#+306+40)
Y=290
;(#SlotHeight#/2)
W=536
H=500
Text=Recently Played Games
FontFace=Arial
FontSize=(#SlotWidth#/16)
FontColor=#SlotTextColor#
StringAlign=Left
;CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots



[SlotText2]
Meter=String
X=(1*#SlotWidth#+306+40+#SlotWidth#/2)
Y=(#SlotHeight#/2)
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotName2#
FontFace=Arial
FontSize=(#SlotWidth#/15)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[SlotBanner2]
Meter=Image
ImageName=#SlotImage2#
X=(1*#SlotWidth#+306+40)
Y=0
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=1
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('2')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath2#')"]
Group=Slots

[SlotHighlightBackground2]
Meter=Image
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight2

[SlotHighlight2]
Meter=Image
ImageName=
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight2

[SlotHighlightText2]
Meter=String
X=(#SlotWidth# / 2)r
Y=(#SlotHeight# / 2)r
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotHighlightMessage2#
FontFace=Arial
FontSize=(#SlotWidth#/25)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=SlotHighlight2

[SlotText3]
Meter=String
X=(2*#SlotWidth#+311+40+#SlotWidth#/2)
Y=(#SlotHeight#/2)
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotName3#
FontFace=Arial
FontSize=(#SlotWidth#/15)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[SlotBanner3]
Meter=Image
ImageName=#SlotImage3#
X=(2*#SlotWidth#+311+40)
Y=0
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=1
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('3')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath3#')"]
Group=Slots

[SlotHighlightBackground3]
Meter=Image
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight3

[SlotHighlight3]
Meter=Image
ImageName=
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight3

[SlotHighlightText3]
Meter=String
X=(#SlotWidth# / 2)r
Y=(#SlotHeight# / 2)r
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotHighlightMessage3#
FontFace=Arial
FontSize=(#SlotWidth#/25)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=SlotHighlight3

[SlotText4]
Meter=String
X=(3*#SlotWidth#+316+40+#SlotWidth#/2)
Y=(#SlotHeight#/2)
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotName4#
FontFace=Arial
FontSize=(#SlotWidth#/15)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[SlotBanner4]
Meter=Image
ImageName=#SlotImage4#
X=(3*#SlotWidth#+316+40)
Y=0
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=1
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('4')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath4#')"]
Group=Slots

[SlotHighlightBackground4]
Meter=Image
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight4

[SlotHighlight4]
Meter=Image
ImageName=
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight4

[SlotHighlightText4]
Meter=String
X=(#SlotWidth# / 2)r
Y=(#SlotHeight# / 2)r
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotHighlightMessage4#
FontFace=Arial
FontSize=(#SlotWidth#/25)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=SlotHighlight4

[SlotText5]
Meter=String
X=(1*#SlotWidth#+306+40+#SlotWidth#/2)
Y=230
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotName5#
FontFace=Arial
FontSize=(#SlotWidth#/15)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[SlotBanner5]
Meter=Image
ImageName=#SlotImage5#
X=(1*#SlotWidth#+306+40)
Y=142
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=1
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('5')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath5#')"]
Group=Slots

[SlotHighlightBackground5]
Meter=Image
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight5

[SlotHighlight5]
Meter=Image
ImageName=
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight5

[SlotHighlightText5]
Meter=String
X=(#SlotWidth# / 2)r
Y=(#SlotHeight# / 2)r
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotHighlightMessage5#
FontFace=Arial
FontSize=(#SlotWidth#/25)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=SlotHighlight5





[MeterShape1]
Meter=Shape
Shape=Rectangle 640,325,900,1 | Fill Color 250,250,250,100 | StrokeWidth 0 | Stroke Color 0,0,0,170

[MeterShape2]
Meter=Shape
Shape=Rectangle 605,0,1,260 | Fill Color 250,250,250,100 | StrokeWidth 0 | Stroke Color 0,0,0,170


[SlotText6]
Meter=String
X=(2*#SlotWidth#+311+40+#SlotWidth#/2)
Y=230
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotName6#
FontFace=Arial
FontSize=(#SlotWidth#/15)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[SlotBanner6]
Meter=Image
ImageName=#SlotImage6#
X=(2*#SlotWidth#+311+40)
Y=142
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('6')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath6#')"]
Group=Slots

[SlotHighlightBackground6]
Meter=Image
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight6

[SlotHighlight6]
Meter=Image
ImageName=
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight6

[SlotHighlightText6]
Meter=String
X=(#SlotWidth# / 2)r
Y=(#SlotHeight# / 2)r
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotHighlightMessage6#
FontFace=Arial
FontSize=(#SlotWidth#/25)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=SlotHighlight6

[SlotText7]
Meter=String
X=(3*#SlotWidth#+316+40+#SlotWidth#/2)
Y=230
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotName7#
FontFace=Arial
FontSize=(#SlotWidth#/15)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots

[SlotBanner7]
Meter=Image
ImageName=#SlotImage7#
X=(3*#SlotWidth#+316+40)
Y=142
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
MouseOverAction=[!CommandMeasure LauhdutinScript "Highlight('7')"][Play "C:\Users\Nick\Documents\Rainmeter\Skins\Click.wav"]
MouseLeaveAction=[!CommandMeasure LauhdutinScript "Highlight('-1')"]
LeftMouseUpAction=[!CommandMeasure LauhdutinScript "Launch('#SlotPath7#')"]
Group=Slots

[SlotHighlightBackground7]
Meter=Image
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,160
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight7

[SlotHighlight7]
Meter=Image
ImageName=
X=0r
Y=0r
W=#SlotWidth#
H=#SlotHeight#
SolidColor=0,0,0,1
PreserveAspectRatio=2
DynamicVariables=1
Group=SlotHighlight7

[SlotHighlightText7]
Meter=String
X=(#SlotWidth# / 2)r
Y=(#SlotHeight# / 2)r
W=#SlotWidth#
H=#SlotHeight#
Text=#SlotHighlightMessage7#
FontFace=Arial
FontSize=(#SlotWidth#/25)
FontColor=#SlotTextColor#
StringAlign=CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=SlotHighlight7
This is the entire part I'm working on but the skin also uses a lot more code contained within other files
Nickcz
Posts: 9
Joined: January 21st, 2017, 10:27 pm

Re: Substitute inside a link

Nickcz » November 15th, 2017, 8:18 pm

balala wrote:Replace the Substitute with mine one.
I've tried using your substitute as well as no substitute at all, but there's nothing after "http://store.steampowered.com/app/"
User avatar
balala
Rainmeter Sage
Posts: 6975
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Substitute inside a link

balala » November 15th, 2017, 8:39 pm

Nickcz wrote:I've tried using your substitute as well as no substitute at all, but there's nothing after "http://store.steampowered.com/app/"
How is set the SlotImage1 variable? In the [Variables] section or through a !SetVariable bang? Because if it is by a !SetVariable bang you have to add a DynamicVariables=1 option to the [MeasureVar] measure, because without this option the measure can't use the value of the dynamically set variable.
Nickcz
Posts: 9
Joined: January 21st, 2017, 10:27 pm

Re: Substitute inside a link

Nickcz » November 15th, 2017, 9:22 pm

balala wrote:How is set the SlotImage1 variable? In the [Variables] section or through a !SetVariable bang? Because if it is by a !SetVariable bang you have to add a DynamicVariables=1 option to the [MeasureVar] measure, because without this option the measure can't use the value of the dynamically set variable.
Unfortunately I'm not sure how the SlotImage1 variable is set, I've looked though all the files I can see but only found mention of it in a file called gui.lua attached below if it helps

Code: Select all

function Initialize()
	json = dofile(SKIN:GetVariable('@') .. 'Dependencies\\json4lua\\json.lua')
	S_PATH_RESOURCES = SKIN:GetVariable('@')
	S_VDF_SERIALIZING_INDENTATION = ''
	T_SETTINGS = ReadSettings()
	if T_SETTINGS == nil then
		SKIN:Bang('[!SetOption StatusMessage Text "Load Settings.ini and save settings."][!ShowMeterGroup Status #CURRENTCONFIG#][!Redraw]')
		return
	end
	N_LAUNCH_STATE = 0
	T_LAUNCH_STATES = {
		LAUNCH = 0,
		HIDE = 1,
		UNHIDE = 2
	}
	T_RECENTLY_LAUNCHED_GAME = nil
	N_SORT_STATE = 0 --0 = alphabetically, 1 = most recently played
	if T_SETTINGS['sortstate'] then
		N_SORT_STATE = tonumber(T_SETTINGS['sortstate']) - 1
		CycleSort()
	end
	S_SETTING_SLOT_COUNT = 'slot_count'
	N_SCROLL_INDEX = 1
	N_SCROLL_STEP = 1
	-- If GAME_KEYS values are changed, then they have to be copied to the GameKeys class in Enums.py.
	GAME_KEYS = {
		BANNER_ERROR = "bannererror",
		BANNER_PATH = "banner",
		BANNER_URL = "bannerurl",
		HIDDEN = "hidden",
		HOURS_LAST_TWO_WEEKS = "hourslast2weeks",
		HOURS_TOTAL = "hourstotal",
		LASTPLAYED = "lastplayed",
		NAME = "title",
		NOT_INSTALLED = "notinstalled",
		PATH = "path",
		PLATFORM = "platform",
		TAGS = "tags"
	}
	-- If PLATFORM values are changed, then they have to be copied to the Platform class in Enums.py.
	PLATFORM = {
		STEAM = 0,
		STEAM_SHORTCUT = 1,
		GOG_GALAXY = 2,
		WINDOWS_SHORTCUT = 3
	}
	PLATFORM_DESCRIPTION = {
		"Steam",
		"Steam",
		"GOG Galaxy",
		""
	}
	B_FORCE_TOOLBAR = false
	ShowToolbar()
end

-- Called once after Initialize() has been called. Runs Backend\GetGames.py.
function Update()
	if T_SETTINGS ~= nil then
		SKIN:Bang('[!SetOption StatusMessage Text ""][!ShowMeterGroup Status #CURRENTCONFIG#][!Redraw]')
		SKIN:Bang('"#Python#" "#@#Backend\\GetGames.py" "#PROGRAMPATH#;" "#@#;" "#CURRENTCONFIG#;"')
	end
end

-- Called by Backend\GetGames.py when it has successfully completed its task.
function Init()
	SKIN:Bang('[!HideMeterGroup Status #CURRENTCONFIG#][!Redraw]')
	local tGames = ReadGames()
	T_ALL_GAMES = {} -- all games found in 'games.json'
	T_FILTERED_GAMES = {} -- subset of T_ALL_GAMES
	T_HIDDEN_GAMES = {}
	T_NOT_INSTALLED_GAMES = {}
	for sKey, tTable in pairs(tGames) do
		if tTable[GAME_KEYS.HIDDEN] == true then
			table.insert(T_HIDDEN_GAMES, tTable)
		elseif tTable[GAME_KEYS.NOT_INSTALLED] == true then
			table.insert(T_NOT_INSTALLED_GAMES, tTable)
		else
			table.insert(T_ALL_GAMES, tTable)
		end
	end
	--T_FILTERED_GAMES = T_ALL_GAMES
	if T_ALL_GAMES ~= nil and #T_ALL_GAMES > 0 then
		FilterBy('')
	elseif T_NOT_INSTALLED_GAMES ~= nil and #T_NOT_INSTALLED_GAMES > 0 then
		FilterBy('installed:false')
	elseif T_HIDDEN_GAMES ~= nil and #T_HIDDEN_GAMES > 0 then
		FilterBy('hidden:true')
	else
		SKIN:Bang('[!SetOption StatusMessage Text "No games to display"][!ShowMeterGroup Status #CURRENTCONFIG#][!Redraw]')
	end
	for i=1, tonumber(T_SETTINGS['slot_count']) do
		SKIN:Bang('[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightPlay.png"]')
	end
	for i=1, tonumber(T_SETTINGS['slot_count']) do
		SKIN:Bang('[!HideMeterGroup "SlotHighlight' .. i .. '"]')
	end
	PopulateSlots()
	SKIN:Bang('[!Redraw]')
end

-- Utility
	function RecursiveTableSearch(atTable, asKey)
		for sKey, Value in pairs(atTable) do
			if sKey == asKey then
				return Value
			end
		end
		for sKey, Value in pairs(atTable) do
			if type(Value) == 'table' then
				local tResult = RecursiveTableSearch(Value, asKey)
				if tResult ~= nil then
					return tResult
				end
			end
		end
		return nil
	end

	function StartsWith(asString, asPrefix)
		if asString == nil or asPrefix == nil then
			return false
		end
		return asString:match('^(' .. asPrefix .. '.-)$') ~= nil
	end

	function EndsWith(asString, asSuffix)
		if asString == nil or asSuffix == nil then
			return false
		end
		return asString:match('^(.-' .. asSuffix .. ')$') ~= nil
	end

	function Trim(asString)
		return asString:match('^%s*(.-)%s*$')
	end

	function FileExists(asPath)
		local f = io.open(asPath, 'r')
		if f ~= nil then
			f:close()
			return true
		end
		return false
	end

	function ResourceExists(asPath)
		return FileExists(S_PATH_RESOURCES .. asPath)
	end

	function BannerExists(asPath)
		return FileExists(S_PATH_RESOURCES .. 'Banners\\' .. asPath)
	end

	function ReadJSON(asPath)
		local f = io.open(asPath, 'r')
		if f ~= nil then
			local json_string = f:read('*a')
			f:close()
			return json.decode(json_string)
		end
		return nil
	end

	function WriteJSON(asPath, atTable)
		local json_string = json.encode(atTable)
		if json_string == nil then
			return false
		end
		local f = io.open(asPath, 'w')
		if f ~= nil then
			f:write(json_string)
			f:close()
			return true
		end
		return false
	end

	function ReadGames()
		return ReadJSON(S_PATH_RESOURCES .. 'games.json')
	end

	function WriteGames()
		tTable = {}
		for i=1, #T_ALL_GAMES do
			table.insert(tTable, T_ALL_GAMES[i])
		end
		for i=1, #T_HIDDEN_GAMES do
			table.insert(tTable, T_HIDDEN_GAMES[i])
		end
		for i=1, #T_NOT_INSTALLED_GAMES do
			table.insert(tTable, T_NOT_INSTALLED_GAMES[i])
		end
		return WriteJSON(S_PATH_RESOURCES .. 'games.json', tTable)
	end

	function ReadSettings()
		return ReadJSON(S_PATH_RESOURCES .. 'settings.json')
	end

	function WriteSettings(atTable)
		return WriteJSON(S_PATH_RESOURCES .. 'settings.json', atTable)
	end

-- Slots
	function FilterBy(asPattern)
		if asPattern == '' then
			T_FILTERED_GAMES = ClearFilter(T_ALL_GAMES)
			Sort()
			PopulateSlots()
			return
		end
		asPattern = asPattern:lower()
		if StartsWith(asPattern, '+') then
			T_FILTERED_GAMES = Filter(T_FILTERED_GAMES, asPattern:sub(2))
		else
			T_FILTERED_GAMES = Filter(T_ALL_GAMES, asPattern)
		end
		Sort()
		PopulateSlots()
	end

	function Filter(atTable, asPattern)
		if atTable == nil then
			return
		end
		tResult = {}
		if StartsWith(asPattern, 'steam:') then
			asPattern = asPattern:sub(7)
			if StartsWith(asPattern, 't') then
				for i = 1, #atTable do
					if atTable[i][GAME_KEYS.PLATFORM] == PLATFORM.STEAM then
						table.insert(tResult, atTable[i])
					end
				end
			elseif StartsWith(asPattern, 'f') then
				for i = 1, #atTable do
					if atTable[i][GAME_KEYS.PLATFORM] ~= PLATFORM.STEAM then
						table.insert(tResult, atTable[i])
					end
				end
			else
				return tResult
			end
		elseif StartsWith(asPattern, 'galaxy:') then
			asPattern = asPattern:sub(8)
			if StartsWith(asPattern, 't') then
				for i = 1, #atTable do
					if atTable[i][GAME_KEYS.PLATFORM] == PLATFORM.GOG_GALAXY then
						table.insert(tResult, atTable[i])
					end
				end
			elseif StartsWith(asPattern, 'f') then
				for i = 1, #atTable do
					if atTable[i][GAME_KEYS.PLATFORM] ~= PLATFORM.GOG_GALAXY then
						table.insert(tResult, atTable[i])
					end
				end
			else
				return tResult
			end
		elseif StartsWith(asPattern, 'tags:') then
			asPattern = asPattern:sub(6)
			for i = 1, #atTable do
				if atTable[i][GAME_KEYS.TAGS] ~= nil then
					for sKey, sValue in pairs(atTable[i][GAME_KEYS.TAGS]) do
						if sValue:lower():find(asPattern) then
							table.insert(tResult, atTable[i])
							break
						end
					end
				end
			end
		elseif StartsWith(asPattern, 'installed:') then
			asPattern = asPattern:sub(11)
			if StartsWith(asPattern, 't') then
				for i, game in ipairs(T_ALL_GAMES) do
					table.insert(tResult, game)
				end
			elseif StartsWith(asPattern, 'f') then
				for i, game in ipairs(T_NOT_INSTALLED_GAMES) do
					table.insert(tResult, game)
				end
			else
				return tResult
			end
		elseif StartsWith(asPattern, 'hidden:') then
			asPattern = asPattern:sub(8)
			if StartsWith(asPattern, 't') then
				for i, game in ipairs(T_HIDDEN_GAMES) do
					table.insert(tResult, game)
				end
			elseif StartsWith(asPattern, 'f') then
				for i, game in ipairs(T_ALL_GAMES) do
					table.insert(tResult, game)
				end
			else
				return tResult
			end
		else
			for i = 1, #atTable do
				if atTable[i][GAME_KEYS.NAME]:lower():find(asPattern) then
					table.insert(tResult, atTable[i])
				end
			end
		end
		return tResult
	end

	function ClearFilter(atTable)
		if atTable == nil then
			return
		end
		local tResult = {}
		for i = 1, #atTable do
			if atTable[i][GAME_KEYS.HIDDEN] ~= true and atTable[i][GAME_KEYS.NOT_INSTALLED] ~= true  then
				table.insert(tResult, atTable[i])
			end
		end
		return tResult
	end

	function Sort()
		if T_FILTERED_GAMES ~= nil then
			if N_SORT_STATE == 1 then
				table.sort(T_FILTERED_GAMES, SortLastPlayed)
			else
				table.sort(T_FILTERED_GAMES, SortAlphabetically)
			end
		end
		N_SCROLL_INDEX = 1
	end

	function SortAlphabetically(atFirst, atSecond)
		if atFirst[GAME_KEYS.NAME]:lower():gsub(':', ' ') < atSecond[GAME_KEYS.NAME]:lower():gsub(':', ' ') then
			return true
		else
			return false
		end
	end

	function SortLastPlayed(atFirst, atSecond)
		if tonumber(atFirst[GAME_KEYS.LASTPLAYED]) > tonumber(atSecond[GAME_KEYS.LASTPLAYED]) then
			return true
		else
			return false
		end
	end

	function CycleSort()
		if N_SORT_STATE == nil then
			return
		end
		N_SORT_STATE = N_SORT_STATE + 1
		if N_SORT_STATE > 1 then
			N_SORT_STATE = 0
		end
		T_SETTINGS['sortstate'] = tostring(N_SORT_STATE)
		WriteSettings(T_SETTINGS)
		SKIN:Bang('[!SetOption "ToolbarButtonSort" "ImageName" "#@#Icons\\Sort' .. N_SORT_STATE .. '.png"][!UpdateMeterGroup Toolbar][!Redraw]')
		Sort()
		PopulateSlots()
	end

	function PopulateSlots()
		if T_FILTERED_GAMES ~= nil then
			local nSlotCount = tonumber(T_SETTINGS[S_SETTING_SLOT_COUNT])
			local j = N_SCROLL_INDEX
			for i = 1, nSlotCount do
				if j > 0 and j <= #T_FILTERED_GAMES then
					SKIN:Bang('[!SetVariable SlotPath' .. i .. ' "' .. tostring(j) .. '"][!SetVariable SlotName' .. i .. ' "' .. T_FILTERED_GAMES[j][GAME_KEYS.NAME] .. '"]')
					if BannerExists(T_FILTERED_GAMES[j][GAME_KEYS.BANNER_PATH]) then
						SKIN:Bang('!SetVariable SlotImage' .. i .. ' "#@#Banners\\' .. T_FILTERED_GAMES[j][GAME_KEYS.BANNER_PATH] .. '"')
					else
						SKIN:Bang('!SetVariable SlotImage' .. i .. ' ""')
					end
					if N_LAUNCH_STATE == T_LAUNCH_STATES.LAUNCH then
						if T_SETTINGS['show_hours_played'] and T_FILTERED_GAMES[j][GAME_KEYS.HOURS_TOTAL] then
							local totalHoursPlayed = T_FILTERED_GAMES[j][GAME_KEYS.HOURS_TOTAL]
							local hoursPlayed = math.floor(totalHoursPlayed)
							local minutesPlayed = math.floor((totalHoursPlayed - hoursPlayed) * 60)
							if T_FILTERED_GAMES[j][GAME_KEYS.NOT_INSTALLED] == true then
								SKIN:Bang('[!SetVariable "SlotHighlightMessage' .. i .. '" "Install via ' .. PLATFORM_DESCRIPTION[T_FILTERED_GAMES[j][GAME_KEYS.PLATFORM]+1] .. '#CRLF##CRLF##CRLF##CRLF##CRLF#' .. hoursPlayed .. ' hours ' .. minutesPlayed .. ' minutes played"]')--[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightInstall.png"]')
							else
								SKIN:Bang('[!SetVariable "SlotHighlightMessage' .. i .. '" "' .. PLATFORM_DESCRIPTION[T_FILTERED_GAMES[j][GAME_KEYS.PLATFORM]+1] .. '#CRLF##CRLF##CRLF##CRLF##CRLF#' .. hoursPlayed .. ' hours ' .. minutesPlayed .. ' minutes played"]')--[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightPlay.png"]')
							end
						else
							if T_FILTERED_GAMES[j][GAME_KEYS.NOT_INSTALLED] == true then
								SKIN:Bang('[!SetVariable "SlotHighlightMessage' .. i .. '" "Install via ' .. PLATFORM_DESCRIPTION[T_FILTERED_GAMES[j][GAME_KEYS.PLATFORM]+1] .. '#CRLF##CRLF##CRLF##CRLF##CRLF#"]')--[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightInstall.png"]')
							else
								SKIN:Bang('[!SetVariable "SlotHighlightMessage' .. i .. '" "' .. PLATFORM_DESCRIPTION[T_FILTERED_GAMES[j][GAME_KEYS.PLATFORM]+1] .. '#CRLF##CRLF##CRLF##CRLF##CRLF#"]')--[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightPlay.png"]')
							end
						end
						if T_FILTERED_GAMES[j][GAME_KEYS.NOT_INSTALLED] == true then
							SKIN:Bang('[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightInstall.png"]')
						else
							SKIN:Bang('[!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightPlay.png"]')
						end
					elseif N_LAUNCH_STATE == T_LAUNCH_STATES.HIDE then
						SKIN:Bang('[!SetVariable "SlotHighlightMessage' .. i .. '" "Hide"][!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightHide.png"]')
					elseif N_LAUNCH_STATE == T_LAUNCH_STATES.UNHIDE then
						SKIN:Bang('[!SetVariable "SlotHighlightMessage' .. i .. '" "Unhide"][!SetOption "SlotHighlight' .. i .. '" "ImageName" "#@#Icons\\SlotHighlightUnhide.png"]')
					end
				else
					SKIN:Bang('[!SetVariable SlotPath' .. i .. ' ""][!SetVariable SlotImage' .. i .. ' ""][!SetVariable SlotName' .. i .. ' ""][!SetVariable "SlotHighlightMessage' .. i .. '" ""]')
				end
				SKIN:Bang('[!UpdateMeterGroup "SlotHighlight' .. i .. '"]')
				j = j + 1
			end
		end
		SKIN:Bang('[!UpdateMeterGroup Slots][!Redraw]')
	end

	function Scroll(asDirection)
		if #T_FILTERED_GAMES > tonumber(T_SETTINGS[S_SETTING_SLOT_COUNT]) then
			local abUpwards = true
			if tonumber(asDirection) < 0 then
				abUpwards = false
			end
			if abUpwards then
				N_SCROLL_INDEX = N_SCROLL_INDEX - N_SCROLL_STEP
				if N_SCROLL_INDEX < 1 then
					N_SCROLL_INDEX = 1
				end
			else
				N_SCROLL_INDEX = N_SCROLL_INDEX + N_SCROLL_STEP
				if N_SCROLL_INDEX + tonumber(T_SETTINGS[S_SETTING_SLOT_COUNT]) > #T_FILTERED_GAMES + 1 then
					N_SCROLL_INDEX = #T_FILTERED_GAMES + 1 - tonumber(T_SETTINGS[S_SETTING_SLOT_COUNT])
				end
			end
			PopulateSlots()
		end
	end

	function Launch(asIndex)
		if T_FILTERED_GAMES == nil then
			return
		end
		local nIndex = tonumber(asIndex)
		local tGame = T_FILTERED_GAMES[nIndex]
		if tGame ~= nil then
			if N_LAUNCH_STATE == T_LAUNCH_STATES.LAUNCH then
				local sPath = tGame[GAME_KEYS.PATH]
				if sPath ~= nil then
					tGame[GAME_KEYS.LASTPLAYED] = os.time()
					if tGame[GAME_KEYS.HIDDEN] == true then
						tGame[GAME_KEYS.HIDDEN] = nil
						for i = 1, #T_HIDDEN_GAMES do -- Move game from T_HIDDEN_GAMES to T_ALL_GAMES
							if T_HIDDEN_GAMES[i] == tGame then
								table.insert(T_ALL_GAMES, table.remove(T_HIDDEN_GAMES, i))
								break
							end
						end
						if tGame[GAME_KEYS.NOT_INSTALLED] == true then
							tGame[GAME_KEYS.NOT_INSTALLED] = nil
						end
					elseif tGame[GAME_KEYS.NOT_INSTALLED] == true then
						tGame[GAME_KEYS.NOT_INSTALLED] = nil
						for i = 1, #T_NOT_INSTALLED_GAMES do -- Move game from T_NOT_INSTALLED_GAMES to T_ALL_GAMES
							if T_NOT_INSTALLED_GAMES[i] == tGame then
								table.insert(T_ALL_GAMES, table.remove(T_NOT_INSTALLED_GAMES, i))
								break
							end
						end
					end
					WriteGames()
					FilterBy('')
					Sort()
					PopulateSlots()
					T_RECENTLY_LAUNCHED_GAME = tGame
					if StartsWith(sPath, 'steam://') then
						SKIN:Bang('[!SetOption "ProcessMonitor" "ProcessName" "GameOverlayUI.exe"]')
					else
						local processPath = string.gsub(string.gsub(sPath, "\\", "/"), "//", "/")
						local processName = processPath:reverse():match("(exe%p[^\\/:%*?<>|]+)/"):reverse()
						SKIN:Bang('[!SetOption "ProcessMonitor" "ProcessName" "' .. processName .. '"]')
					end
					SKIN:Bang('[!UpdateMeasure "ProcessMonitor"]')
					SKIN:Bang('["' .. sPath .. '"]')
				end
			elseif N_LAUNCH_STATE == T_LAUNCH_STATES.HIDE then
				if tGame[GAME_KEYS.HIDDEN] ~= true then
					tGame[GAME_KEYS.HIDDEN] = true -- For (de)serializing purposes
					local bMoved = false
					for i = 1, #T_ALL_GAMES do -- Move game from T_ALL_GAMES to T_HIDDEN_GAMES
						if T_ALL_GAMES[i] == tGame then
							table.insert(T_HIDDEN_GAMES, table.remove(T_ALL_GAMES, i))
							bMoved = true
							break
						end
					end
					if not bMoved then
						for i = 1, #T_NOT_INSTALLED_GAMES do -- Move game from T_NOT_INSTALLED_GAMES to T_HIDDEN_GAMES
							if T_NOT_INSTALLED_GAMES[i] == tGame then
								table.insert(T_HIDDEN_GAMES, table.remove(T_NOT_INSTALLED_GAMES, i))
								break
							end
						end
					end
					WriteGames()
					for i = 1, #T_FILTERED_GAMES do -- Remove game from T_FILTERED_GAMES
						if T_FILTERED_GAMES[i] == tGame then
							table.remove(T_FILTERED_GAMES, i)
							break
						end
					end
					local scrollIndex = N_SCROLL_INDEX
					Sort()
					N_SCROLL_INDEX = scrollIndex
					PopulateSlots()
				end
			elseif N_LAUNCH_STATE == T_LAUNCH_STATES.UNHIDE then
				if tGame[GAME_KEYS.HIDDEN] == true then
					tGame[GAME_KEYS.HIDDEN] = nil -- For (de)serializing purposes
					if tGame[GAME_KEYS.NOT_INSTALLED] ~= true then
						for i = 1, #T_HIDDEN_GAMES do -- Move game from T_HIDDEN_GAMES to T_ALL_GAMES
							if T_HIDDEN_GAMES[i] == tGame then
								table.insert(T_ALL_GAMES, table.remove(T_HIDDEN_GAMES, i))
								break
							end
						end
					else
						for i = 1, #T_HIDDEN_GAMES do -- Move game from T_HIDDEN_GAMES to T_NOT_INSTALLED_GAMES
							if T_HIDDEN_GAMES[i] == tGame then
								table.insert(T_NOT_INSTALLED_GAMES, table.remove(T_HIDDEN_GAMES, i))
								break
							end
						end
					end
					WriteGames()
					for i = 1, #T_FILTERED_GAMES do -- Remove game from T_FILTERED_GAMES
						if T_FILTERED_GAMES[i] == tGame then
							table.remove(T_FILTERED_GAMES, i)
							break
						end
					end
					local scrollIndex = N_SCROLL_INDEX
					Sort()
					N_SCROLL_INDEX = scrollIndex
					PopulateSlots()
				end
			end
		end
	end

	function HideGame()
		if N_LAUNCH_STATE == T_LAUNCH_STATES.HIDE then
			N_LAUNCH_STATE = T_LAUNCH_STATES.LAUNCH
			PopulateSlots()
		else
			N_LAUNCH_STATE = T_LAUNCH_STATES.HIDE -- Set state where Launch function will instead set GAME_KEYS.HIDDEN to 'true'
			PopulateSlots()
		end
	end

	function UnhideGame()
		if N_LAUNCH_STATE == T_LAUNCH_STATES.UNHIDE then
			N_LAUNCH_STATE = T_LAUNCH_STATES.LAUNCH
			FilterBy('')
		else
			N_LAUNCH_STATE = T_LAUNCH_STATES.UNHIDE -- Set state where Launch function will instead set GAME_KEYS.HIDDEN to 'false'
			FilterBy('hidden:true') -- Adjust filtering to show games with GAME_KEYS.HIDDEN == 'true'.
		end
	end

	function UpdateTimePlayed()
		if T_RECENTLY_LAUNCHED_GAME ~= nil then
			local hoursPlayed = os.difftime(os.time(), T_RECENTLY_LAUNCHED_GAME[GAME_KEYS.LASTPLAYED]) / 3600
			T_RECENTLY_LAUNCHED_GAME[GAME_KEYS.HOURS_TOTAL] = hoursPlayed + T_RECENTLY_LAUNCHED_GAME[GAME_KEYS.HOURS_TOTAL]
			WriteGames()
			PopulateSlots()
		end
	end

	function Highlight(asIndex)
		if T_FILTERED_GAMES == nil then
			return
		end
		if not T_SETTINGS['slot_highlight'] then
			return
		end
		local nIndex = tonumber(asIndex)
		if asIndex == '-1' then
			for i=1, tonumber(T_SETTINGS['slot_count']) do
				SKIN:Bang('[!HideMeterGroup "SlotHighlight' .. i .. '"]')
			end
			SKIN:Bang('[!Redraw]')
		else
			local tGame = T_FILTERED_GAMES[nIndex]
			if tGame ~= nil then
				for i=1, tonumber(T_SETTINGS['slot_count']) do
					if i ~= nIndex then
						SKIN:Bang('[!HideMeterGroup "SlotHighlight' .. i .. '"]')
					end
				end
				SKIN:Bang('[!ShowMeterGroup "SlotHighlight' .. asIndex ..'"][!UpdateMeterGroup "SlotHighlight' .. asIndex ..'"][!Redraw]')
			end
		end
	end

-- Error messages
	function ShowMessage(asMessage)
		SKIN:Bang('[!SetVariable Message ' .. asMessage .. '][!ShowMeterGroup Message][!Redraw]')
	end

	function HideMessage()
		SKIN:Bang('[!HideMeterGroup Message][!Redraw]')
	end

-- Toolbar
	function ShowToolbar()
		SKIN:Bang('[!ShowMeterGroup Toolbar][!Redraw]')
	end

	function HideToolbar()
		if B_FORCE_TOOLBAR == false then
			SKIN:Bang('[!HideMeterGroup Toolbar][!Redraw]')
		end
	end

	function ForceShowToolbar()
		B_FORCE_TOOLBAR = true
		ShowToolbar()
	end

	function ForceHideToolbar()
		B_FORCE_TOOLBAR = false
		HideToolbar()
	end
I've added dynamic variables=1 to the measure but still the same result, where its doesn't insert anything into the url,
current code below

Code: Select all

[MeasureVar]
Measure=String
String=#SlotImage1#
RegExpSubstitute=1
DynamicVariables=1
Substitute=".*/(.*)\..*":"\1"

Code: Select all

[OpenStorePage]
Meter=String
X=60
;(0*#SlotWidth#+#SlotWidth#/2+40)
Y=330
;(#SlotHeight#/2)
W=536
H=500
Text=Open Store Page
FontFace=Arial
FontSize=(#SlotWidth#/20)
FontColor=#SlotTextColor#
StringAlign=Left
;CenterCenter
StringEffect=Shadow
ClipString=1
AntiAlias=1
DynamicVariables=1
Group=Slots
LeftMouseUpAction=!Execute ["http://store.steampowered.com/app/[MeasureVar]"]
The only thought I had, but could be completely wrong.
Is it possible that its looking for the variable early while its blank and not updating once the variable has a value?
User avatar
balala
Rainmeter Sage
Posts: 6975
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Substitute inside a link

balala » November 15th, 2017, 9:56 pm

Nickcz wrote:Unfortunately I'm not sure how the SlotImage1 variable is set, I've looked though all the files I can see but only found mention of it in a file called gui.lua attached below if it helps
I don't see the Script measure which uses the gui.lua file, so finally I'm not sure how to check everything, but I tried to add a !SetVariable bang to a meter of the code to set up the proper value of the SlotImage1 variable. With this option I got the skin working, the appropriate URL is set and the page opens on a click.
Maybe try to add the following String meter to the end of the code of the .ini file:

Code: Select all

[MeterVar]
Meter=STRING
MeasureName=MeasureVar
X=0
Y=0
Padding=15,5,15,5
FontColor=220,220,220
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=#SlotImage1##CRLF#%1
DynamicVariables=1
LeftMouseUpAction=[!SetClip "=#SlotImage1##CRLF#[MeasureVar]"]
This meter will show the value of the SlotImage1 variable as well as the substituted value returned by the MeasureVar measure. What do you see? Clicking the new string will copy the shown string to clipboard. Please past it here.
Nickcz wrote:The only thought I had, but could be completely wrong.
Is it possible that its looking for the variable early while its blank and not updating once the variable has a value?
Not having the lua file, I can't say more now. Maybe pack the whole config and upload it to can check.
Nickcz
Posts: 9
Joined: January 21st, 2017, 10:27 pm

Re: Substitute inside a link

Nickcz » November 15th, 2017, 10:03 pm

balala wrote:I don't see the Script measure which uses the gui.lua file, so finally I'm not sure how to check everything, but I tried to add a !SetVariable bang to a meter of the code to set up the proper value of the SlotImage1 variable. With this option I got the skin working, the appropriate URL is set and the page opens on a click.
Maybe try to add the following String meter to the end of the code of the .ini file:

Code: Select all

[MeterVar]
Meter=STRING
MeasureName=MeasureVar
X=0
Y=0
Padding=15,5,15,5
FontColor=220,220,220
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=#SlotImage1##CRLF#%1
DynamicVariables=1
LeftMouseUpAction=[!SetClip "=#SlotImage1##CRLF#[MeasureVar]"]
This meter will show the value of the SlotImage1 variable as well as the substituted value returned by the MeasureVar measure. What do you see? Clicking the new string will copy the shown string to clipboard. Please past it here.

Not having the lua file, I can't say more now. Maybe pack the whole config and upload it to can check.

Code: Select all

=
[MeasureVar]
that's all that's been copied to the clipboard

I'll pm you the entire skin