mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
216
lua/mkeyboard/client/piano.lua
Normal file
216
lua/mkeyboard/client/piano.lua
Normal file
@@ -0,0 +1,216 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
Reference in New Issue
Block a user