It is currently May 26th, 2019, 2:25 am

Tips & Tricks Thread

Discuss the use of Lua in Script measures.
User avatar
smurfier
Moderator
Posts: 1937
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Tips & Tricks Thread

smurfier » March 3rd, 2012, 7:05 pm

Because....

Table={Index=Value}

If you do not specify an index, a number is used.

So... Table={'One';'Two';'Three'}

Is Really... Table={1='One';2='Two';3='Three'}

And for what we're doing we only want to use the Value portion.
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
jsmorley
Developer
Posts: 19245
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Tips & Tricks Thread

jsmorley » March 3rd, 2012, 7:10 pm

smurfier wrote:Because....

Table={Index=Value}

If you do not specify an index, a number is used.

So... Table={'One';'Two';'Three'}

Is Really... Table={1='One';2='Two';3='Three'}

And for what we're doing we only want to use the Value portion.
Yeah, that makes sense.
User avatar
smurfier
Moderator
Posts: 1937
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Tips & Tricks Thread

smurfier » March 3rd, 2012, 9:43 pm

This function allows the use of Rainmeter style substitute strings inside Lua.

Code: Select all

function Substitute(Val,Sub)
	Val=tostring(Val)
	Sub='"'..string.gsub(Sub,'%[','%%%[')..'"'
	local Strip=function(a) return string.match(a,'^[\'"](.*)[\'"]$') or '' end
	for a in string.gmatch(Sub,'[^,]+') do
		local l,r=string.match(a,'(.*):(.*)')
		Val=string.gsub(Val,Strip(l),Strip(r))
	end
	return Val
end
Note: The substitute string must follow all of Lua's string rules. This includes using the escape character \ when necessary.
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
smurfier
Moderator
Posts: 1937
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Tips & Tricks Thread

smurfier » May 18th, 2012, 1:17 am

Bars, Roundlines, Lines, and Histograms all need to be bound to a measure. This makes it a bit difficult to set their values from Lua. The solution is actually rather simple. Just create a Calc Measure in Rainmeter and use !SetOption Measure Formula NumberValue to drive the meter.

If you're using this method with several Meters it may be easier to just grab the MeasureName from the meter. This function makes that a bit easier.

Code: Select all

function SetValue(Meter,Value)
	local mHandle=assert(SKIN:GetMeter(Meter),'Invalid Meter '..Meter)
	local MeasureName=assert(mHandle:GetOption('MeasureName'),'MeasureName not found in '..Meter)
	if assert(SKIN:GetMeasure(MeasureName),'Invalid Measure '..MeasureName) then
		SKIN:Bang('!SetOption',MeasureName,'Formula',Value)
		SKIN:Bang('!UpdateMeasure',MeasureName)
	end
end -- SetValue
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
smurfier
Moderator
Posts: 1937
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Tips & Tricks Thread

smurfier » June 18th, 2012, 8:06 pm

This function will apply your current timezone and daylight savings time to a Date and Time in the GMT timezone. Simply pass it the year, month, day, hour, minute and second and it will return a date formatted table. The last argument that you can send is an optional timezone, such as -6 for Central Standard Time.

Code: Select all

function TimeStamp(y,m,d,h,mn,s,t)
	local Time=os.date('*t')
	local offset=t and t*3600 or os.time()-os.time(os.date('!*t'))
	local t=os.time({day=d,month=m,year=y,hour=h,min=mn,sec=s})+offset+(Time.isdst and 3600 or 0)
	return os.date('*t',t)
end
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
smurfier
Moderator
Posts: 1937
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Tips & Tricks Thread

smurfier » July 1st, 2012, 1:09 am

This function serves as a very simple replacement for !WriteKeyValue when you need to write to an ini outside of the skins folder, as well as when you need to write an Environment Variable without Rainmeter expanding it.

Code: Select all

function WriteIni(file,section,key,value)
	local hFile=io.input(file,'r')
	if not io.type(hFile)=='file' then
		print('Cannot open file: '..file)
	else
		local Text=io.read('*all')
		hFile=io.output(file,'w')
		local NewText=string.gsub(Text,
			'%['..section..']([^%[]+)',
			function(a)
				if string.match(a,'\n%s-'..key..'%s-=') then
					a=string.gsub(a,'\n%s-'..key..'%s-=%s-([^;\n]+)','\n'..key..'='..value)
				else
					a=(string.match(a,'(.+)\n$') or '')..'\n'..key..'='..value..'\n\n'
				end
				return '['..section..']'..a
			end
		)
		io.write(NewText)
		io.close(hFile)
	end
end
Limitations:
  • You may not use Key=[Value] with the brackets in the target section.
  • The function is case sensitive.
  • Since it's Lua, no unicode.
If a Key=Value pair does not exist, it is created at the end of the section.
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
Kaelri
Developer
Posts: 1739
Joined: July 25th, 2009, 4:47 am

Re: Tips & Tricks Thread

Kaelri » August 30th, 2012, 8:22 pm

Here's a simple way to make your script "watch" some value in the skin - for example, a variable - and take some action only on updates when the value has changed.

Code: Select all

function Initialize()
    Old = nil
end

function Update()
    local New = SKIN:GetVariable('SomeVar')
    if Old ~= New then
        -- do stuff
        Old = New
    end
end
User avatar
Mordasius
Posts: 1059
Joined: January 22nd, 2011, 4:23 pm
Location: GMT +8

Re: Tips & Tricks Thread

Mordasius » September 13th, 2012, 10:55 am

You can't mix left, right and center justification in a single meter with native Rainmeter but you can by using string.format in a LUA script. In following example [MeterNetIn] displays a left justified label and a right justified download speed.

Code: Select all

[MeasureNetIn]
Measure=NetIn

[mLuaScript]
Measure=Script
ScriptFile=LuaScriptFile.lua

[MeterNetIn]
Meter=STRING
FontFace=Consolas
LuaScriptFile.lua:

Code: Select all

function Initialize()
	msNumber = SKIN:GetMeasure('MeasureNetIn')
end

function Update()
	SKIN:Bang('!SetOption', 'MeterNetIn', 'Text',  string.format("%-15s %5d %-s", "Download:", msNumber:GetValue()/1000, "kB/s") ) 
end 
simple.jpg
The above replaces just one string meter with a LUA script but the method really comes into its own if you need to display a table or list of items that requires a mix of left, right and/or center justification for strings and numbers all on the same line. The screenshot below shows the output of 12 string meters formated with:

Code: Select all

for n, s in ipairs(StreamsByViewer) do
 SKIN:Bang('!SetOption','MeterStream'..n..'','Text',string.format("%-8s %-20s %5d  %-6s %-10s",s.stream.Type,s.stream.Owner, s.stream.Viewers,center(s.stream.Races,7),center(s.stream.Rating,10)))
end   
Formating_wid_LUA.jpg
There is a summary of the formating directives for string.format in the LUA 5.1 Quick Guide. They are biased toward numerical output but it's fairly easy to add your own string formating functions like the center function above which is:

Code: Select all

function center(str, width)
	return string.rep(' ',math.floor( (width - string.len(str))/2 ))..str
end
The most serious limitation to the use of string.format is that it only formats text correctly with monospaced fonts like Courier or Consolas.
You do not have the required permissions to view the files attached to this post.
Alex Becherer

Re: Tips & Tricks Thread

Alex Becherer » September 13th, 2012, 4:31 pm

pretty cool :)
User avatar
thatsIch
Posts: 464
Joined: August 7th, 2012, 9:18 pm

Re: Tips & Tricks Thread

thatsIch » September 13th, 2012, 5:27 pm

A simple "Pretty Printer" of Lua Tables in JSON format

Code: Select all

function printTableHelper(t,spacing)
    local spacing = spacing or ''
    local result = spacing .. "{\n"

   for k,v in pairs(t) do
        if type(v)=='table' then 
            result = result .. printTableHelper(v,spacing..'\t') ..",\n"
        else 
        	result = result .. spacing .. "\t[\"" .. tostring(k) .. "\"] = \"" .. v .. "\",\n"
        end
    end

    result = result .. spacing .. "}"

    return result
end
Usage

Code: Select all

printTableHelper({{"a"},{"b"}})
>
{
    {
        ["1"] = "a",
    },
    {
        ["2"] = "b",
    },
}