mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
217 lines
5.3 KiB
Lua
217 lines
5.3 KiB
Lua
|
|
--[[
|
||
|
|
| This file was obtained through the combined efforts
|
||
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
||
|
|
|
|
||
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
||
|
|
|
|
||
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||
|
|
--]]
|
||
|
|
|
||
|
|
-- Piano renderer
|
||
|
|
local Piano = {
|
||
|
|
keys = {},
|
||
|
|
whiteCount = 0,
|
||
|
|
transpose = 0,
|
||
|
|
|
||
|
|
noteMin = 0,
|
||
|
|
noteMax = 128,
|
||
|
|
|
||
|
|
w = 16,
|
||
|
|
keyW = 22
|
||
|
|
}
|
||
|
|
|
||
|
|
MKeyboard.piano = Piano
|
||
|
|
|
||
|
|
local keyNameOverride = {
|
||
|
|
[KEY_SEMICOLON] = ";"
|
||
|
|
}
|
||
|
|
|
||
|
|
local function GetButtonName( button )
|
||
|
|
return language.GetPhrase( keyNameOverride[button] or input.GetKeyName( button ) or "NONE" )
|
||
|
|
end
|
||
|
|
|
||
|
|
function Piano:SetLayout( layout )
|
||
|
|
self.keys = {}
|
||
|
|
self.whiteCount = 0
|
||
|
|
|
||
|
|
for _, key in ipairs( layout ) do
|
||
|
|
self.keys[#self.keys + 1] = {
|
||
|
|
button = key[1],
|
||
|
|
altButton = key[5],
|
||
|
|
label = GetButtonName( key[1] ),
|
||
|
|
note = key[2],
|
||
|
|
isBlack = key[3],
|
||
|
|
needsShift = key[4],
|
||
|
|
isPressed = false
|
||
|
|
}
|
||
|
|
|
||
|
|
if not key[3] then
|
||
|
|
self.whiteCount = self.whiteCount + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self.w = self.keyW * self.whiteCount
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Set the note limits. Keys with notes
|
||
|
|
--- outside this range will be grayed out.
|
||
|
|
function Piano:SetNoteRange( min, max )
|
||
|
|
self.noteMin, self.noteMax = min, max
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Find the normal and shifted keys linked to this button.
|
||
|
|
function Piano:FindKeys( button )
|
||
|
|
local normal, shifted
|
||
|
|
|
||
|
|
for _, key in ipairs( self.keys ) do
|
||
|
|
if key.button == button or key.altButton == button then
|
||
|
|
if key.needsShift then
|
||
|
|
shifted = key
|
||
|
|
else
|
||
|
|
normal = key
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return normal, shifted
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Find the key linked to this note.
|
||
|
|
function Piano:FindKeyByNote( note )
|
||
|
|
for _, key in ipairs( self.keys ) do
|
||
|
|
if key.note == note then
|
||
|
|
return key
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Press the key linked to this note.
|
||
|
|
function Piano:PressNote( note, velocity, instrument, color, automated )
|
||
|
|
local key = self:FindKeyByNote( note )
|
||
|
|
|
||
|
|
if key then
|
||
|
|
key.color = color
|
||
|
|
key.isPressed = true
|
||
|
|
end
|
||
|
|
|
||
|
|
self.OnNoteOn( note, velocity, instrument, automated )
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Release the key linked to this note.
|
||
|
|
function Piano:ReleaseNote( note )
|
||
|
|
local key = self:FindKeyByNote( note )
|
||
|
|
|
||
|
|
if key then
|
||
|
|
key.color = nil
|
||
|
|
key.isPressed = false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Releases all notes.
|
||
|
|
function Piano:ReleaseAllNotes()
|
||
|
|
for _, key in ipairs( self.keys ) do
|
||
|
|
key.color = nil
|
||
|
|
key.isPressed = false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Press the key linked to this button.
|
||
|
|
function Piano:PressButton( button, velocity, instrument, color )
|
||
|
|
velocity = velocity or 127
|
||
|
|
|
||
|
|
local normal, shifted = self:FindKeys( button )
|
||
|
|
|
||
|
|
if input.IsShiftDown() then
|
||
|
|
if shifted then
|
||
|
|
shifted.color = color
|
||
|
|
shifted.isPressed = true
|
||
|
|
self.OnNoteOn( shifted.note + self.transpose, velocity, instrument )
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if normal then
|
||
|
|
normal.color = color
|
||
|
|
normal.isPressed = true
|
||
|
|
self.OnNoteOn( normal.note + self.transpose, velocity, instrument )
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--- Release the key linked to this button.
|
||
|
|
function Piano:ReleaseButton( button )
|
||
|
|
-- Always release both normal and shifted keys, to handle a key that was
|
||
|
|
-- pressed with shift previously but does not have shift pressed now.
|
||
|
|
local normal, shifted = self:FindKeys( button )
|
||
|
|
|
||
|
|
if normal and normal.isPressed then
|
||
|
|
normal.color = nil
|
||
|
|
normal.isPressed = false
|
||
|
|
end
|
||
|
|
|
||
|
|
if shifted and shifted.isPressed then
|
||
|
|
shifted.color = nil
|
||
|
|
shifted.isPressed = false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local SetColor = surface.SetDrawColor
|
||
|
|
local DrawRect = surface.DrawRect
|
||
|
|
local DrawRoundedBox = draw.RoundedBoxEx
|
||
|
|
local DrawText = draw.SimpleText
|
||
|
|
|
||
|
|
local COLOR_WHITE = Color( 255, 255, 255 )
|
||
|
|
local COLOR_BLACK = Color( 0, 0, 0 )
|
||
|
|
|
||
|
|
local ALIGN_CENTER = TEXT_ALIGN_CENTER
|
||
|
|
local ALIGN_BOTTOM = TEXT_ALIGN_BOTTOM
|
||
|
|
|
||
|
|
local settings = MKeyboard.settings
|
||
|
|
|
||
|
|
function Piano:Draw( x, y, h )
|
||
|
|
local min, max = self.noteMin, self.noteMax
|
||
|
|
local transpose = self.transpose
|
||
|
|
local labels = settings.drawKeyLabels
|
||
|
|
local w = self.keyW
|
||
|
|
|
||
|
|
local labelY = y + h - 4
|
||
|
|
local blackLabelY = y + ( h * 0.6 ) - 4
|
||
|
|
local blackW = w * 0.7
|
||
|
|
|
||
|
|
local note, deferKey
|
||
|
|
|
||
|
|
for _, key in ipairs( self.keys ) do
|
||
|
|
note = key.note + transpose
|
||
|
|
|
||
|
|
if note < min or note > max then
|
||
|
|
-- empty space
|
||
|
|
if not key.isBlack then
|
||
|
|
x = x + w
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif key.isBlack then
|
||
|
|
-- draw it on top of the next one
|
||
|
|
deferKey = key
|
||
|
|
else
|
||
|
|
SetColor( key.color or COLOR_WHITE )
|
||
|
|
DrawRect( x, y, w - 1, h )
|
||
|
|
|
||
|
|
if labels then
|
||
|
|
DrawText( key.label, "MKeyboard_Key", x + w * 0.5, labelY, COLOR_BLACK, ALIGN_CENTER, ALIGN_BOTTOM )
|
||
|
|
end
|
||
|
|
|
||
|
|
if deferKey then
|
||
|
|
DrawRoundedBox( 4, x - blackW * 0.5, y, blackW, h * 0.6, deferKey.color or COLOR_BLACK, false, false, true, true )
|
||
|
|
|
||
|
|
if labels then
|
||
|
|
DrawText( deferKey.label, "MKeyboard_Key", x, blackLabelY, COLOR_WHITE, ALIGN_CENTER, ALIGN_BOTTOM )
|
||
|
|
end
|
||
|
|
|
||
|
|
deferKey = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
x = x + w
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|