snippet: Reading theme/skin colors

This simple snippet seems to work under Windows (and probably macos). I stole the function for finding the user folder from cLib by Danoise, but I’m not sure if he finished it.

If someone could run it in testpad.lua under linux and confirm, that would be sweet.

Click to view contents
function cLib_get_userdata_folder()
 
  local search_path = (os.platform() == "WINDOWS")
    and "\\Scripts\\Libraries\\?.lua"
    or "/Scripts/Libraries/?.lua"
   
  local iterator = string.gmatch(package.path,";([^;]+)")
  for str in iterator do
    if (string.sub(str,-24)==search_path) then
      if string.find(str,"Users") -- win 8
        or string.find(str,"Resources") -- unix/osx/win
        or string.find(str,"/usr/") -- linux
        -- TODO confirm with as many OS as possible
      then
        local unixslashes = function(file_path)
            local str = file_path:gsub("\\","/")
            return str:gsub("/+","/")
        end
        return unixslashes(string.sub(str,0,#str-#search_path)).."/"
      end
    end
  end
end
 
class 'SkinColors'
 
SkinColors.properties = {
"Main_Font", "Alternate_Main_Back", "Alternate_Main_Font", "Body_Back", "Body_Font", "Strong_Body_Font", "Button_Back", "Button_Font", "Button_Highlight_Font", "Selected_Button_Back", "Selected_Button_Font", "Selection_Back", "Selection_Font", "StandBy_Selection_Back", "StandBy_Selection_Font", "Midi_Mapping_Back", "Midi_Mapping_Font", "ToolTip_Back", "ToolTip_Font", "ValueBox_Back", "ValueBox_Font", "ValueBox_Font_Icons", "Scrollbar", "Slider", "Folder", "Pattern_Default_Back", "Pattern_Default_Font", "Pattern_Default_Font_Volume", "Pattern_Default_Font_Panning", "Pattern_Default_Font_Pitch", "Pattern_Default_Font_Delay", "Pattern_Default_Font_Global", "Pattern_Default_Font_Other", "Pattern_Default_Font_DspFx", "Pattern_Default_Font_Unused", "Pattern_Highlighted_Back", "Pattern_Highlighted_Font", "Pattern_Highlighted_Font_Volume", "Pattern_Highlighted_Font_Panning", "Pattern_Highlighted_Font_Pitch", "Pattern_Highlighted_Font_Delay", "Pattern_Highlighted_Font_Global", "Pattern_Highlighted_Font_Other", "Pattern_Highlighted_Font_DspFx", "Pattern_Highlighted_Font_Unused", "Pattern_PlayPosition_Back", "Pattern_PlayPosition_Font", "Pattern_CenterBar_Back", "Pattern_CenterBar_Font", "Pattern_CenterBar_Back_StandBy", "Pattern_CenterBar_Font_StandBy", "Pattern_Selection", "Pattern_StandBy_Selection", "Pattern_Mute_State", "Automation_Grid", "Automation_Line_Edge", "Automation_Line_Fill", "Automation_Point", "Automation_Marker_Play", "Automation_Marker_Single", "Automation_Marker_Pair", "Automation_Marker_Diamond", "VuMeter_Meter", "VuMeter_Meter_Low", "VuMeter_Meter_Middle", "VuMeter_Meter_High", "VuMeter_Peak", "VuMeter_Back_Normal", "VuMeter_Back_Clipped", "Default_Color_01", "Default_Color_02", "Default_Color_03", "Default_Color_04", "Default_Color_06", "Default_Color_05", "Default_Color_07", "Default_Color_08", "Default_Color_09", "Default_Color_10", "Default_Color_11", "Default_Color_12", "Default_Color_13", "Default_Color_14", "Default_Color_15", "Default_Color_16"
}
 
function SkinColors:__init()
 
  -- prepare document model
  local prefs_model = renoise.Document.create("RenoisePrefs") {
    SkinColors = { Main_Back = "string" } }
 
  for _, k in pairs(SkinColors.properties) do
    prefs_model.SkinColors:add_property(k, "string")
  end
 
  -- import data from xml to document
  assert(prefs_model:load_from(cLib_get_userdata_folder().."Config.xml"), "Failed to find Config.xml")
 
  -- transfer document values to class property rgb tables
  for _, k in pairs(SkinColors.properties) do
    SkinColors[k] = property(function()
      local rgb = { }
      for val in prefs_model.SkinColors:property(k).value:gmatch('([^,]+)') do
        rgb[#rgb+1] = val
      end
      return rgb
    end) -- theoretically ugly, but allows properties to be listed via oprint/objinfo
  end
 
end
 
 
-- test
local colors = SkinColors()
oprint(colors)
rprint(colors.Pattern_Mute_State)

On my machine that cLib_get_userdata_folder() function fails. I would’ve thought it should return a path string more like:

/home/*user*/.renoise/V3.1.1/

(Replace user with the users login name.) That seems to be more where the config.xml file sits with Linux. It seems to be fine once the path is corrected in this line…

-- import data from xml to document
  assert(prefs_model:load_from(cLib_get_userdata_folder().."Config.xml"), "Failed to find Config.xml")
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^

(N.B. However take with a pinch of salt as I didn’t use any installation script, don’t know if that changes anything.)

Thanks! I’ll fire up my old ubutu-laptop later to see if I have the same path, and that Config.xml is situated there also.

Hopefully the path can be found in package.path as well. Maybe it’s just a matter of searching for “.renoise” instead of “/usr/” …

(Just a clarify post) We assume then that to get a bit more consistent path from the ‘cLib_get_userdata_folder’ function between Linux and Windows you can modify line 36 of cFilesystem.lua -> https://github.com/renoise/cLib/blob/master/classes/cFilesystem.lua#L36 to read:

or string.find(str,".renoise") -- linux

But just mention about that function. At the moment the way in which it is written is (looking at lines 34,35,36):

if string.find(str,"Users") -- win 8
  or string.find(str,"Resources") -- unix/osx/win
  or string.find(str,"/usr/") -- linux (modify to ".renoise")

so you are assuming that ‘.renoise’ gets seen in string variable ‘str’ before “Resources” (or even “Users” in a very unlikely event) in the package.path string.