It is currently September 29th, 2024, 3:36 pm

Skin Browsing Skin

General topics related to Rainmeter.
User avatar
exper1mental
Posts: 269
Joined: January 9th, 2013, 7:52 pm
Location: Clemson University

Re: Skin Browsing Skin

Post by exper1mental »

killall-q wrote:It's based on this snippet I wrote a while ago. Mordasius's revision is good code. It's just that it doesn't do an awful lot on its own.

Well, since it would take a comparable amount of effort to explain how to write code around it, I just wrote the code. I hope this will teach you a lot about Lua. Feel free to embellish it.

• Shows a maximum of 50 skins.
• Left-click to toggle skins.
• Middle-click to open skin folders.

Image
Thanks a million man! :)

It appears you already did all the work for me. :D That lua script in the skin has all the functionality needed for a proof-of-concept skin that can replicate a major portion of the functionality of the !Manage window.

There are two limitations I immediately noticed though:
  • It can only list skins that are or have at one point been active (and thus added to the list of skins in the .ini file). The only workaround for this I can see is by browsing the skins folder itself with a script (fileview
  • The skins are listed in order of when first activated, not alphabetically. (not a big deal but could be annoying if you have hundreds of skins)
Even still, it's a solid foundation to build upon while I learn lua in order to find solutions for the above problems.
Image
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5534
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Skin Browsing Skin

Post by eclectic-tech »

I wanted to see all the skins the script finds, so I added a paging scheme. :sly:

Had to add @include=sk.inc file to track the current page on !Refresh.
Set skins variable from the numSkins found by the script (used in paging).
Added mouse scroll to page through the list.
Added a page display and a close button.

The issues exper1mental listed still need to examined, but now you can see everything in the Rainmeter.ini

Told you I'd be watching! ;-)
You do not have the required permissions to view the files attached to this post.
User avatar
exper1mental
Posts: 269
Joined: January 9th, 2013, 7:52 pm
Location: Clemson University

Re: Skin Browsing Skin

Post by exper1mental »

eclectic-tech wrote:I wanted to see all the skins the script finds, so I added a paging scheme. :sly:

Had to add @include=sk.inc file to track the current page on !Refresh.
Set skins variable from the numSkins found by the script (used in paging).
Added mouse scroll to page through the list.
Added a page display and a close button.

The issues exper1mental listed still need to examined, but now you can see everything in the Rainmeter.ini

Told you I'd be watching! ;-)
Slick, although if there are not enough entries to fill given page (assuming the total number of entries is over 1 page long), the "empty" entries will display what they listed on the previous page instead of being hidden (like when the total number of entries is less than 1 page long)...

Adding meters for each entry (meaning, each meter is attached to one entry, not however many pages there are) would work but would be time consuming and limit the number of skins possible to display, which is kinda self defeating since that is what this is supposed to solve...

Honestly I'd be happy if I could figure out how to make those should-be-hidden text entries blank, as that would work fine for my purposes (and I could always then add a substitute measure that would hide those entries if needed)
Image
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5534
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Skin Browsing Skin

Post by eclectic-tech »

@exper1mental

I am just starting to try Lua so my methods were pretty much practice... :)

I am able to get rid of the names with a few changes to the script (below) and I add Group=Skins to the [sSkin] section.

But as you noticed, the updates in the script are not apparent in the skin until it is redrawn after a mouseoveraction or refreshed (they not dynamic).

Still working on ways to get this corrected...
Try the attached rmskin and see how that works for you...

I just noticed I did not use the variable listMax in the while statement of the DispalySkins function: "... and i <= 50" (50 should be listMax; something to change later!)

SkinBrowser3.lua:

Code: Select all

function Initialize()
   arraySkins, numSkins, pageNum, listMax = {}, 0, 0, 50
   DetectSkins()
   DisplaySkins()
end

function Update()
    local New = SKIN:GetVariable('page')
	local i = 1
    if pageNum ~= New then
		pageNum = New
		SKIN:Bang('!WriteKeyValue', 'Variables', 'page', pageNum, 'sk.inc') 
		while i <= 50 do
			SKIN:Bang('!SetOption Skin'..i..' Text ""')
			SKIN:Bang('!SetOptionGroup Skins MeterStyle "sSkin"')
			i = i + 1
		end
		DisplaySkins()
	end
end

function DetectSkins()
   local RMini, i, tempSkin = io.open(SKIN:GetVariable('SETTINGSPATH').."Rainmeter.ini", "r"), 1
   for line in RMini:lines() do
      if line:sub(1, 1) == "[" then 
         tempSkin = line:match("%[(.*)%]")
      elseif line:match("Active") then
         arraySkins[i] = {name = tempSkin, active = 0}
         if tonumber(line:sub(8, 8)) > 0 then
            arraySkins[i].active = 1
         end
         i = i + 1
      end
   end
   numSkins = i - 1
   RMini:close()
   SKIN:Bang('!SetVariable', 'skins', numSkins)
end

function DisplaySkins()
   local i = 1
	while (listMax * pageNum + i) <= numSkins and i <= 50 do
      SKIN:Bang('!SetOption Skin'..i..' Text " '..arraySkins[(listMax * pageNum + i)].name)
      SKIN:Bang('!SetOption', 'Skin'..i, 'MiddleMouseDownAction', '["#SKINSPATH#'..arraySkins[(listMax * pageNum + i)].name..'"]')
      if arraySkins[(listMax * pageNum + i)].active > 0 then
         SKIN:Bang('!SetOption Skin'..i..' MeterStyle "sSkin | sActive"')
         SKIN:Bang('!SetOption', 'Skin'..i, 'LeftMouseUpAction', '[!DeactivateConfig "'..arraySkins[(listMax * pageNum + i)].name..'"][!Refresh]')
      else
         SKIN:Bang('!SetOption Skin'..i..' MeterStyle "sSkin"')
         SKIN:Bang('!SetOption', 'Skin'..i, 'LeftMouseUpAction', '[!ActivateConfig "'..arraySkins[(listMax * pageNum + i)].name..'"][!Refresh]')
      end
      i = i + 1
   end
 end
You do not have the required permissions to view the files attached to this post.
User avatar
exper1mental
Posts: 269
Joined: January 9th, 2013, 7:52 pm
Location: Clemson University

Re: Skin Browsing Skin

Post by exper1mental »

eclectic-tech wrote:@exper1mental

I am just starting to try Lua so my methods were pretty much practice... :)
Still, your light-years ahead of me in terms of knowledge of Lua. Prior to working on this skin the only thing I did with Lua was a 11 line script comparing two variables and returning a value based on whether or not they were equal. :p
eclectic-tech wrote:I am able to get rid of the names with a few changes to the script (below) and I add Group=Skins to the [sSkin] section.

But as you noticed, the updates in the script are not apparent in the skin until it is redrawn after a mouseoveraction or refreshed (they not dynamic).

Still working on ways to get this corrected...
Try the attached rmskin and see how that works for you...

I just noticed I did not use the variable listMax in the while statement of the DispalySkins function: "... and i <= 50" (50 should be listMax; something to change later!)

SkinBrowser3.lua:

Code: Select all

function Initialize()
   arraySkins, numSkins, pageNum, listMax = {}, 0, 0, 50
   DetectSkins()
   DisplaySkins()
end

function Update()
    local New = SKIN:GetVariable('page')
	local i = 1
    if pageNum ~= New then
		pageNum = New
		SKIN:Bang('!WriteKeyValue', 'Variables', 'page', pageNum, 'sk.inc') 
		while i <= 50 do
			SKIN:Bang('!SetOption Skin'..i..' Text ""')
			SKIN:Bang('!SetOptionGroup Skins MeterStyle "sSkin"')
			i = i + 1
		end
		DisplaySkins()
	end
end

function DetectSkins()
   local RMini, i, tempSkin = io.open(SKIN:GetVariable('SETTINGSPATH').."Rainmeter.ini", "r"), 1
   for line in RMini:lines() do
      if line:sub(1, 1) == "[" then 
         tempSkin = line:match("%[(.*)%]")
      elseif line:match("Active") then
         arraySkins[i] = {name = tempSkin, active = 0}
         if tonumber(line:sub(8, 8)) > 0 then
            arraySkins[i].active = 1
         end
         i = i + 1
      end
   end
   numSkins = i - 1
   RMini:close()
   SKIN:Bang('!SetVariable', 'skins', numSkins)
end

function DisplaySkins()
   local i = 1
	while (listMax * pageNum + i) <= numSkins and i <= 50 do
      SKIN:Bang('!SetOption Skin'..i..' Text " '..arraySkins[(listMax * pageNum + i)].name)
      SKIN:Bang('!SetOption', 'Skin'..i, 'MiddleMouseDownAction', '["#SKINSPATH#'..arraySkins[(listMax * pageNum + i)].name..'"]')
      if arraySkins[(listMax * pageNum + i)].active > 0 then
         SKIN:Bang('!SetOption Skin'..i..' MeterStyle "sSkin | sActive"')
         SKIN:Bang('!SetOption', 'Skin'..i, 'LeftMouseUpAction', '[!DeactivateConfig "'..arraySkins[(listMax * pageNum + i)].name..'"][!Refresh]')
      else
         SKIN:Bang('!SetOption Skin'..i..' MeterStyle "sSkin"')
         SKIN:Bang('!SetOption', 'Skin'..i, 'LeftMouseUpAction', '[!ActivateConfig "'..arraySkins[(listMax * pageNum + i)].name..'"][!Refresh]')
      end
      i = i + 1
   end
 end
Works like a charm!

I'm working on disabling the MouseOverActions and MouseLeaveActions. I modified the code so that the lua uses !SetVariable for the text values instead of !SetOption. This will allow another lua script to compare the text values to determine if the mouse actions should be disabled for a given skin, which in English means that blank text entries won't have a change of background when hovered over.

Once that is done I'm planning on building a prototype skin browser.

Planned Features:
  • Separate lists for active and inactive skins (which should be easy since I already successfully did it with and older version of the Skin Browser)
  • Buttons to refresh all, edit settings, reset statistics, Rainmeter docs link, open rainmeter manager, and open log
  • More buttons to change skins folder path and config editor
  • Even more buttons to enable/disable dragging, D2D, Debug mode, Version Check, and Logging to file
  • Ability to change Languages (although this one might not be worth the effort :p )
  • Clicking on a skin will load more detail information and list settings including:
    • Buttons to load/unload, refresh, edit (this one not be possible though), and open the file location of the selected skin
    • Button to view the selected skin in the rainmeter manager
    • Ability to change X, Y and Z positions (Z options are On Desktop, Bottom, Normal, Topmost, or Always Topmost)
    • Buttons to enable/disable click-through, dragging, saving position, snapping to edges, and keeping on screen
    • Buttons to hide on, fade in on, or fade out on mouse over
    • Ability to set transparency (percentage or alpha value)
    • Ability to set display monitor and auto select screen[
    • Ability to change load order


Limitations:
  • Layouts won't be apart of the browser at least at first b/c I have no idea how access them without using fileview (which wouldn't be able to load them into rainmeter) or an external window (which is self-defeating since that is what we're trying to avoid using :p )
  • Metadata may not be displayable b/c the Rainmeter.ini and lua only know the file path of the skins within the skin folder. Without knowing the name of the specific .ini file there is no way to retrieve the metadata. :-( This also means skins may not be editable from the browser, but you can still open the file location and then edit it from there.
  • Only skins that are or have at one point been active (and thus added to the list of skins in the .ini file) are listed. The only workaround for this I can see is by browsing the skins folder itself with a script. See edit below.
  • The skins are listed in order of when first activated, not alphabetically. (not a big deal but could be annoying if you have hundreds of skins). Note: This now only applies to the active skin list, see the edit below.

EDIT: I was playing around with one of my skins which uses FileView and just realized that I can use the parent measure (i.e. [MeasurePath]) and a child measure with the filename (i.e. [MeasureIndex1Name]) to determine the filepath of things being viewed in fileview (extensions would have to be enabled to open files from the skin though). This will resolve the problem of never-used-skins never being displayed.

I'll upload a skin using fileview for the inactive skins and the lua for the active ones when I have some more spare time.
Image
User avatar
killall-q
Posts: 307
Joined: August 14th, 2009, 8:04 am

Re: Skin Browsing Skin

Post by killall-q »

Beta 4 (I don't prefer the decimal versioning system because 0.9 implies that it's close to 1.0, and I don't want 0.9.9.2 shenanigans)

- Scrolling by line
- Alphabetization
- Top buttons are now log and refresh, middle click for manage and refresh all

Thanks for the scrolling idea, now there's no arbitrary limit to the number of skins that can be displayed and the skin will always fit on the screen.

As frivolous as I thought this skin was at first, it's turning out really handy when iterating ideas really fast, to have a palette for loading/unloading skins quickly.

There was an issue where the !SetOptions in MouseOver/LeaveAction would lock those options so that the !SetOptions from lua would stop working until refresh, so I just changed the mouseovers to set different options. I would still like to know the cause of this and if it's a bug. Tacking [!Update][!Redraw] on the lua bangs did not help.

FileView is gonna be a pain in the *** because folders can be infinitely nested. The idea I have right now is to have a single array for all folders, with keys being name, path, stubFlag (to mark folders that don't contain other folders). I hope folder collapsing/expanding can be done this way, by arranging child folders directly beneath parent folders in the array and using some smart parsing. Clicking on stub folders will load/unload skins as it does now.

Layouts access is not a good idea because the skin browser will be unloaded everytime you load a layout without it.
Skin Browser - Beta 4.rmskin
Edit: I have updated the skin to work with UTF-16 Rainmeter.ini files that were introduced in Rainmeter 4.2 beta r3088.
Skin Browser - Beta 5.rmskin
You do not have the required permissions to view the files attached to this post.
Last edited by killall-q on August 9th, 2018, 2:18 am, edited 1 time in total.
User avatar
exper1mental
Posts: 269
Joined: January 9th, 2013, 7:52 pm
Location: Clemson University

Re: Skin Browsing Skin

Post by exper1mental »

killall-q wrote:Beta 4 (I don't prefer the decimal versioning system because 0.9 implies that it's close to 1.0, and I don't want 0.9.9.2 shenanigans)
Honestly I'm considering these as alpha builds because of how little of the actual manager's functionality is currently implemented in them (not that its bad to have a skin just listing skins, but I want and I'm building a skin that will replicate a lot more of the manager's functionality).
killall-q wrote:- Scrolling by line
- Alphabetization
- Top buttons are now log and refresh, middle click for manage and refresh all

Thanks for the scrolling idea, now there's no arbitrary limit to the number of skins that can be displayed and the skin will always fit on the screen.
I see what you did there with the table.sort, slick. Scrolling is definitely nice, although probably isn't as practical as having pages for people who have more than a hundred skins
killall-q wrote:As frivolous as I thought this skin was at first, it's turning out really handy when iterating ideas really fast, to have a palette for loading/unloading skins quickly.
In all honestly I had no idea there would be any use to this beyond simply having a cool looking manager. I was a bit surprised how handy having a skin list actually was.
killall-q wrote:There was an issue where the !SetOptions in MouseOver/LeaveAction would lock those options so that the !SetOptions from lua would stop working until refresh, so I just changed the mouseovers to set different options. I would still like to know the cause of this and if it's a bug. Tacking [!Update][!Redraw] on the lua bangs did not help.
Don't think I've had that problem. Are you using Rainmeter 3.0.2 or 3.1.0?
killall-q wrote:FileView is gonna be a pain in the *** because folders can be infinitely nested. The idea I have right now is to have a single array for all folders, with keys being name, path, stubFlag (to mark folders that don't contain other folders). I hope folder collapsing/expanding can be done this way, by arranging child folders directly beneath parent folders in the array and using some smart parsing. Clicking on stub folders will load/unload skins as it does now.
FileView is something I can relatively easily implement into the skin I'm working on, and can always be replaced with something better later.
killall-q wrote:Layouts access is not a good idea because the skin browser will be unloaded everytime you load a layout without it.
True, but a warning could be placed in the skin explaining that.
Image
User avatar
killall-q
Posts: 307
Joined: August 14th, 2009, 8:04 am

Re: Skin Browsing Skin

Post by killall-q »

exper1mental wrote:Scrolling is definitely nice, although probably isn't as practical as having pages for people who have more than a hundred skins
Well I do have a Logitech mouse with the flywheel scrollwheel, but if you really have that many skins you can up the lines-per-scroll. You will have to change the bounds checking in SetScroll() a little.
exper1mental wrote: Don't think I've had that problem. Are you using Rainmeter 3.0.2 or 3.1.0?
Beta 4 has a workaround but mouseovers are not as visible as I'd like. I'm on 3.1.0. You can see the issue if you replace the styles with this. Mousing over meters causes their FontColor and SolidColor to not change with scrolling, while text and everything else works correctly.

Code: Select all

[sSkin]
Y=R
W=240
H=24
StringAlign=LeftCenter
FontSize=10
FontColor=160,160,160
SolidColor=48,48,48
AntiAlias=1
MouseOverAction=[!SetOption #CURRENTSECTION# SolidColor "128,128,128"][!SetOption #CURRENTSECTION# FontColor "48,48,48"][!UpdateMeter #CURRENTSECTION#][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# SolidColor "48,48,48"][!SetOption #CURRENTSECTION# FontColor "160,160,160"][!UpdateMeter #CURRENTSECTION#][!Redraw]

[sActive]
FontColor=224,224,224
SolidColor=32,32,32
MouseOverAction=[!SetOption #CURRENTSECTION# SolidColor "0,0,0"][!SetOption #CURRENTSECTION# FontColor "255,255,255"][!UpdateMeter #CURRENTSECTION#][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# SolidColor "32,32,32"][!SetOption #CURRENTSECTION# FontColor "224,224,224"][!UpdateMeter #CURRENTSECTION#][!Redraw]
User avatar
exper1mental
Posts: 269
Joined: January 9th, 2013, 7:52 pm
Location: Clemson University

Re: Skin Browsing Skin

Post by exper1mental »

killall-q wrote:Well I do have a Logitech mouse with the flywheel scrollwheel, but if you really have that many skins you can up the lines-per-scroll. You will have to change the bounds checking in SetScroll() a little.
Already tried that, the problem with it is that if you scroll the bottom of the list, depending on the number of skins you have, there will be lines that should be empty, but instead they still display their previous entries.

Example:
Lines-per-scroll is 10
Total number of lines is 113
Scrolling to the end there will be 7 entries at the bottom of the skin that should be empty, but instead display skins from the previous time the user scrolled.

I tried various things to fix it including the solution used in Skin Browser v0.3 but to no affect.
killall-q wrote:Beta 4 has a workaround but mouseovers are not as visible as I'd like. I'm on 3.1.0. You can see the issue if you replace the styles with this. Mousing over meters causes their FontColor and SolidColor to not change with scrolling, while text and everything else works correctly.

Code: Select all

[sSkin]
Y=R
W=240
H=24
StringAlign=LeftCenter
FontSize=10
FontColor=160,160,160
SolidColor=48,48,48
AntiAlias=1
MouseOverAction=[!SetOption #CURRENTSECTION# SolidColor "128,128,128"][!SetOption #CURRENTSECTION# FontColor "48,48,48"][!UpdateMeter #CURRENTSECTION#][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# SolidColor "48,48,48"][!SetOption #CURRENTSECTION# FontColor "160,160,160"][!UpdateMeter #CURRENTSECTION#][!Redraw]

[sActive]
FontColor=224,224,224
SolidColor=32,32,32
MouseOverAction=[!SetOption #CURRENTSECTION# SolidColor "0,0,0"][!SetOption #CURRENTSECTION# FontColor "255,255,255"][!UpdateMeter #CURRENTSECTION#][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# SolidColor "32,32,32"][!SetOption #CURRENTSECTION# FontColor "224,224,224"][!UpdateMeter #CURRENTSECTION#][!Redraw]
Ah I see... Only thing I can think of is make a group of strings (and images if you want a change of background
) that are the MouseOver effects. Then, when the user scrolls, send a bang that hides this group of strings. This will hide the current hover affect though, not change it to the correct one.

I'm separating the active and inactive skin lists for my skin though so I won't have to deal with this problem.
Image
User avatar
killall-q
Posts: 307
Joined: August 14th, 2009, 8:04 am

Re: Skin Browsing Skin

Post by killall-q »

Stick this at the end of Update():

Code: Select all

   for k = i, lineMax do
      SKIN:Bang('[!SetOption Skin'..k..' Text ""][!SetOption Skin'..k..' MeterStyle ""]')
   end
Inside SetScroll():

Code: Select all

   if n < 0 and lineScroll > 1 or n > 0 and lineScroll + lineMax <= numSkins then
exper1mental wrote:I'm separating the active and inactive skin lists for my skin though so I won't have to deal with this problem.
For loading/unloading a skin quickly, it's going to move between the lists each time you do so and you'll have to go hunt for it in the list each time. It's better if it stays in the same place, and near related skins.