Substitute inside a link

Help with creating, editing & fixing problems with skins

Substitute inside a link

November 15th, 2017, 6:46 pm
Nickcz
   [9 posts]

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:/Us ... 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

Re: Substitute inside a link

November 15th, 2017, 7:45 pm
balala
Rainmeter Sage   [4985 posts]

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).

Re: Substitute inside a link

November 15th, 2017, 8:06 pm
Nickcz
   [9 posts]

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

Re: Substitute inside a link

November 15th, 2017, 8:10 pm
balala
Rainmeter Sage   [4985 posts]

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.

Re: Substitute inside a link

November 15th, 2017, 8:15 pm
Nickcz
   [9 posts]

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

Re: Substitute inside a link

November 15th, 2017, 8:18 pm
Nickcz
   [9 posts]

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

Re: Substitute inside a link

November 15th, 2017, 8:39 pm
balala
Rainmeter Sage   [4985 posts]

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.

Re: Substitute inside a link

November 15th, 2017, 9:22 pm
Nickcz
   [9 posts]

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

Re: Substitute inside a link

November 15th, 2017, 9:56 pm
balala
Rainmeter Sage   [4985 posts]

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.

Re: Substitute inside a link

November 15th, 2017, 10:03 pm
Nickcz
   [9 posts]

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

Return to “Help: Rainmeter Skins”



Who is online

Users browsing this forum: No registered users and 3 guests