Tools/com.renoise.ScaleMate.xrnx/main.lua
--[[===============================================================================================
com.renoise.ScaleMate.xrnx/main.lua
===============================================================================================]]--
--[[

ScaleMate tool registration

]]

--=================================================================================================
-- Require files (app+libraries)

-- where to find the cLib classes (required) 
_clibroot = 'source/cLib/classes/'
_xlibroot = 'source/xLib/classes/'

-- debug/trace filters can be configured here
-- (see cDebug for more details)
_trace_filters = nil  -- no tracing
--_trace_filters = {".*"} -- trace everything

require (_clibroot..'cLib')
require (_clibroot..'cDebug')
require (_clibroot..'cObservable')

cLib.require (_xlibroot..'xCursorPos')
cLib.require (_xlibroot..'xTrack')
cLib.require (_xlibroot..'xPatternPos')
cLib.require (_xlibroot..'xColumns')
cLib.require (_xlibroot..'xScale')
cLib.require (_xlibroot..'xMidiCommand')
cLib.require (_xlibroot..'xEffectColumn')
cLib.require (_xlibroot..'xLinePattern')

require ('source/ScaleMate')
require ('source/ScaleMate_UI')
require ('source/ScaleMate_Prefs')

---------------------------------------------------------------------------------------------------
-- Variables

rns = nil

local TOOL_NAME = "ScaleMate"
local MIDI_PREFIX = "Tools:"..TOOL_NAME..":"

local app = nil
local prefs = ScaleMate_Prefs()
renoise.tool().preferences = prefs

---------------------------------------------------------------------------------------------------
-- Menu entries & MIDI/Key mappings

-- toggle_message_value
local function toggle_message_value(message, value)
  if (message:is_trigger()) then
    return not value
  else
    return value
  end
end

renoise.tool():add_menu_entry {
  name = "Main Menu:Tools:"..TOOL_NAME.."...",
  invoke = function() 
    show() 
  end
} 
renoise.tool():add_keybinding {
  name = "Global:"..TOOL_NAME..":Show dialog...",
  invoke = function(repeated)
    if (not repeated) then 
      show() 
    end
  end
}

--== scale modes ==--

for k,v in ipairs(xScale.SCALES) do 
  renoise.tool():add_keybinding {
    name = "Global:"..TOOL_NAME..(":Set Scale Mode (%.2d - %s)"):format(k-1,v.name),
    invoke = function(repeated)
      if (not repeated) then 
        app:set_scale(v.name)
      end
    end
  }
  midi_mapping = MIDI_PREFIX..("Set Scale Mode (%.2d - %s) [Trigger]"):format(k-1,v.name)
  renoise.tool():add_midi_mapping{
    name = midi_mapping,
    invoke = function(message)     
      if app and message:is_trigger() then
        app:set_scale(v.name)
      end
    end
  }
end 

for k = 1,12 do
  renoise.tool():add_keybinding {
    name = "Global:"..TOOL_NAME..(":Set Scale Key (%.2d - %s)"):format(k-1,xScale.KEYS[k]),
    invoke = function(repeated)
      if (not repeated) then 
        app:set_key(k)
      end
    end
  }
  midi_mapping = MIDI_PREFIX..("Set Scale Key (%.2d - %s) [Trigger]"):format(k-1,xScale.KEYS[k])
  renoise.tool():add_midi_mapping{
    name = midi_mapping,
    invoke = function(message)     
      if app and message:is_trigger() then
        app:set_key(k)
      end
    end
  }

end

--== write-to-pattern ==--

renoise.tool():add_keybinding {
  name = "Global:"..TOOL_NAME..":Write to Pattern [Toggle]",
  invoke = function(repeated)
    if (not repeated) then 
      prefs.write_to_pattern.value = not prefs.write_to_pattern.value
    end
  end
}
midi_mapping = MIDI_PREFIX.."Write to Pattern [Toggle]"
renoise.tool():add_midi_mapping{
  name = midi_mapping,
  invoke = function(message)     
    if app then
      prefs.write_to_pattern.value = toggle_message_value(
        message, prefs.write_to_pattern.value)
    end
  end
}

--== clear commands ==--

renoise.tool():add_keybinding {
  name = "Global:"..TOOL_NAME..":Clear Commands (Track in Pattern)",
  invoke = function(repeated)
    if (not repeated) then 
      app:clear_pattern_track()
    end
  end
}
midi_mapping = MIDI_PREFIX.."Clear Commands (Track in Pattern) [Trigger]"
renoise.tool():add_midi_mapping{
  name = midi_mapping,
  invoke = function(message)     
    if app and message:is_trigger() then
      app:clear_pattern_track()
    end
  end
}

---------------------------------------------------------------------------------------------------
-- Create the application instance
-- will register keyboard shortcuts/midi mappings...

function create()
  rns = renoise.song()
  if not app then  
    app = ScaleMate{
      dialog_title = TOOL_NAME,
      midi_prefix = MIDI_PREFIX,
    }
  end
end

---------------------------------------------------------------------------------------------------
-- Show the application UI 

function show()
  if not app then 
    create()
  end 
  if app.ui then
    app.ui:show()
  end
end

---------------------------------------------------------------------------------------------------
-- Notifications

renoise.tool().app_new_document_observable:add_notifier(function()
  rns = renoise.song()
  create() 
end)

--show()
