Added Doxygen documentation (main draft) to src/core/piano.cpp

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1156 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Paul Wayper
2008-06-19 19:30:23 +00:00
parent e681070d47
commit 2321e4c1b0
2 changed files with 220 additions and 47 deletions

View File

@@ -1,3 +1,8 @@
2008-06-20 Paul Wayper <paulway/at/mabula/dot/net>
* src/core/piano.cpp:
added Doxygen documentation.
2008-06-19 Paul Wayper <paulway/at/mabula/dot/net>
* src/core/track.cpp:

View File

@@ -25,6 +25,18 @@
*
*/
/** \file piano.cpp
* \brief A piano keyboard to play notes on in the instrument plugin window.
*/
/*
* \mainpage Instrument plugin keyboard display classes
*
* \section introduction Introduction
*
* \todo fill this out
* \todo write isWhite inline function and replace throughout
*/
#include "piano.h"
@@ -50,7 +62,8 @@
#endif
/*! The black / white order of keys as they appear on the keyboard.
*/
const KeyTypes KEY_ORDER[] =
{
// C CIS D DIS E F
@@ -60,31 +73,37 @@ const KeyTypes KEY_ORDER[] =
} ;
/*! The scale of C Major - white keys only.
*/
Keys WhiteKeys[] =
{
Key_C, Key_D, Key_E, Key_F, Key_G, Key_A, Key_H
} ;
QPixmap * pianoView::s_whiteKeyPm = NULL;
QPixmap * pianoView::s_blackKeyPm = NULL;
QPixmap * pianoView::s_whiteKeyPressedPm = NULL;
QPixmap * pianoView::s_blackKeyPressedPm = NULL;
QPixmap * pianoView::s_whiteKeyPm = NULL; /*!< A white key released */
QPixmap * pianoView::s_blackKeyPm = NULL; /*!< A black key released */
QPixmap * pianoView::s_whiteKeyPressedPm = NULL; /*!< A white key pressed */
QPixmap * pianoView::s_blackKeyPressedPm = NULL; /*!< A black key pressed */
const int PIANO_BASE = 11;
const int PW_WHITE_KEY_WIDTH = 10;
const int PW_BLACK_KEY_WIDTH = 8;
const int PW_WHITE_KEY_HEIGHT = 57;
const int PW_BLACK_KEY_HEIGHT = 38;
const int LABEL_TEXT_SIZE = 7;
const int PIANO_BASE = 11; /*!< The height of the root note display */
const int PW_WHITE_KEY_WIDTH = 10; /*!< The width of a white key */
const int PW_BLACK_KEY_WIDTH = 8; /*!< The width of a black key */
const int PW_WHITE_KEY_HEIGHT = 57; /*!< The height of a white key */
const int PW_BLACK_KEY_HEIGHT = 38; /*!< The height of a black key */
const int LABEL_TEXT_SIZE = 7; /*!< The height of the key label text */
/*! \brief Create a new keyboard display
*
* \param _it the InstrumentTrack window to attach to
*/
piano::piano( instrumentTrack * _it ) :
model( _it ),
m_instrumentTrack( _it )
model( _it ), /*!< our model */
m_instrumentTrack( _it ) /*!< the instrumentTrack model */
{
for( int i = 0; i < KeysPerOctave * NumOctaves; ++i )
{
@@ -96,6 +115,9 @@ piano::piano( instrumentTrack * _it ) :
/*! \brief Destroy this new keyboard display
*
*/
piano::~piano()
{
}
@@ -103,6 +125,11 @@ piano::~piano()
/*! \brief Turn a key on or off
*
* \param _key the key number to change
* \param _on the state to set the key to
*/
void piano::setKeyState( int _key, bool _on )
{
m_pressedKeys[tLimit( _key, 0, KeysPerOctave * NumOctaves - 1 )] = _on;
@@ -112,6 +139,10 @@ void piano::setKeyState( int _key, bool _on )
/*! \brief Handle a note being pressed on our keyboard display
*
* \param _key the key being pressed
*/
void piano::handleKeyPress( int _key )
{
m_instrumentTrack->processInEvent( midiEvent( MidiNoteOn, 0, _key,
@@ -123,6 +154,10 @@ void piano::handleKeyPress( int _key )
/*! \brief Handle a note being released on our keyboard display
*
* \param _key the key being releassed
*/
void piano::handleKeyRelease( int _key )
{
m_instrumentTrack->processInEvent( midiEvent( MidiNoteOff, 0, _key, 0 ),
@@ -136,12 +171,17 @@ void piano::handleKeyRelease( int _key )
/*! \brief Create a new keyboard display view
*
* \param _parent the parent instrument plugin window
* \todo are the descriptions of the m_startkey and m_lastkey properties correct?
*/
pianoView::pianoView( QWidget * _parent ) :
QWidget( _parent ),
modelView( NULL ),
m_piano( NULL ),
m_startKey( Key_C + Octave_3*KeysPerOctave ),
m_lastKey( -1 )
QWidget( _parent ), /*!< Our parent */
modelView( NULL ), /*!< Our view model */
m_piano( NULL ), /*!< Our piano model */
m_startKey( Key_C + Octave_3*KeysPerOctave ), /*!< The first key displayed? */
m_lastKey( -1 ) /*!< The last key displayed? */
{
if( s_whiteKeyPm == NULL )
{
@@ -183,6 +223,9 @@ pianoView::pianoView( QWidget * _parent ) :
/*! \brief Destroy this piano display view
*
*/
pianoView::~pianoView()
{
}
@@ -190,39 +233,53 @@ pianoView::~pianoView()
/*! \brief Map a keyboard key being pressed to a note in our keyboard view
*
* \param _k The keyboard scan code of the key being pressed.
* \todo check the scan codes for ',' = c, 'L' = c#, '.' = d, ':' = d#,
* '/' = d, '[' = f', '=' = f'#, ']' = g' - Paul's additions
*/
int pianoView::getKeyFromScancode( int _k )
{
switch( _k )
{
case 52: return( 0 ); // Y
case 39: return( 1 ); // S
case 53: return( 2 ); // X
case 40: return( 3 ); // D
case 54: return( 4 ); // C
case 55: return( 5 ); // V
case 42: return( 6 ); // G
case 56: return( 7 ); // B
case 43: return( 8 ); // H
case 57: return( 9 ); // N
case 44: return( 10 ); // J
case 58: return( 11 ); // M
case 24: return( 12 ); // Q
case 11: return( 13 ); // 2
case 25: return( 14 ); // W
case 12: return( 15 ); // 3
case 26: return( 16 ); // E
case 27: return( 17 ); // R
case 14: return( 18 ); // 5
case 28: return( 19 ); // T
case 15: return( 20 ); // 6
case 29: return( 21 ); // Z
case 16: return( 22 ); // 7
case 30: return( 23 ); // U
case 31: return( 24 ); // I
case 18: return( 25 ); // 9
case 32: return( 26 ); // O
case 19: return( 27 ); // 0
case 33: return( 28 ); // P
case 52: return( 0 ); // Y = C
case 39: return( 1 ); // S = C#
case 53: return( 2 ); // X = D
case 40: return( 3 ); // D = D#
case 54: return( 4 ); // C = E
case 55: return( 5 ); // V = F
case 42: return( 6 ); // G = F#
case 56: return( 7 ); // B = G
case 43: return( 8 ); // H = G#
case 57: return( 9 ); // N = A
case 44: return( 10 ); // J = A#
case 58: return( 11 ); // M = B
case 59: return( 12 ); // , = c
case 46: return( 13 ); // L = c#
case 60: return( 14 ); // . = d
case 47: return( 15 ); // ; = d#
case 61: return( 16 ); // / = e
case 24: return( 12 ); // Q = c
case 11: return( 13 ); // 2 = c#
case 25: return( 14 ); // W = d
case 12: return( 15 ); // 3 = d#
case 26: return( 16 ); // E = e
case 27: return( 17 ); // R = f
case 14: return( 18 ); // 5 = f#
case 28: return( 19 ); // T = g
case 15: return( 20 ); // 6 = g#
case 29: return( 21 ); // Z = a
case 16: return( 22 ); // 7 = a#
case 30: return( 23 ); // U = b
case 31: return( 24 ); // I = c'
case 18: return( 25 ); // 9 = c'#
case 32: return( 26 ); // O = d'
case 19: return( 27 ); // 0 = d'#
case 33: return( 28 ); // P = e'
case 34: return( 29 ); // [ = f'
case 21: return( 30 ); // - = f'#
case 21: return( 31 ); // ] = g'
}
return( -100 );
@@ -231,6 +288,9 @@ int pianoView::getKeyFromScancode( int _k )
/*! \brief Register a change to this piano display view
*
*/
void pianoView::modelChanged( void )
{
m_piano = castModel<piano>();
@@ -246,6 +306,25 @@ void pianoView::modelChanged( void )
// gets the key from the given mouse-position
/*! \brief Get the key from the mouse position in the piano display
*
* First we determine it roughly by the position of the point given in
* white key widths from our start. We then add in any black keys that
* might have been skipped over (they take a key number, but no 'white
* key' space). We then add in our starting key number.
*
* We then determine whether it was a black key that was pressed by
* checking whether it was within the vertical range of black keys.
* Black keys sit exactly between white keys on this keyboard, so
* we then shift the note down or up if we were in the left or right
* half of the white note. We only do this, of course, if the white
* note has a black key on that side, so to speak.
*
* This function returns const because there is a linear mapping from
* the point given to the key returned that never changes.
*
* \param _p The point that the mouse was pressed.
*/
int pianoView::getKeyFromMouse( const QPoint & _p ) const
{
int key_num = (int)( (float) _p.x() / (float) PW_WHITE_KEY_WIDTH );
@@ -292,6 +371,12 @@ int pianoView::getKeyFromMouse( const QPoint & _p ) const
// handler for scrolling-event
/*! \brief Handle the scrolling on the piano display view
*
* We need to update our start key position based on the new position.
*
* \param _new_pos the new key position.
*/
void pianoView::pianoScrolled( int _new_pos )
{
m_startKey = WhiteKeys[_new_pos % WhiteKeysPerOctave]+
@@ -303,6 +388,11 @@ void pianoView::pianoScrolled( int _new_pos )
/*! \brief Handle a context menu selection on the piano display view
*
* \param _me the ContextMenuEvent to handle.
* \todo Is this right, or does this create the context menu?
*/
void pianoView::contextMenuEvent( QContextMenuEvent * _me )
{
if( _me->pos().y() > PIANO_BASE || m_piano == NULL )
@@ -324,6 +414,23 @@ void pianoView::contextMenuEvent( QContextMenuEvent * _me )
// handler for mouse-click-event
/*! \brief Handle a mouse click on this piano display view
*
* We first determine the key number using the getKeyFromMouse() method.
*
* If we're below the 'root key selection' area,
* we set the volume of the note to be proportional to the vertical
* position on the keyboard - lower down the key is louder, within the
* boundaries of the (white or black) key pressed. We then tell the
* instrument to play that note, scaling for MIDI max loudness = 127.
*
* If we're in the 'root key selection' area, of course, we set the
* root key to be that key.
*
* We finally update ourselves to show the key press
*
* \param _me the mouse click to handle.
*/
void pianoView::mousePressEvent( QMouseEvent * _me )
{
if( _me->button() == Qt::LeftButton && m_piano != NULL )
@@ -372,6 +479,13 @@ void pianoView::mousePressEvent( QMouseEvent * _me )
// handler for mouse-release-event
/*! \brief Handle a mouse release event on the piano display view
*
* If a key was pressed by the in the mousePressEvent() function, we
* turn the note off.
*
* \param _me the mousePressEvent to handle.
*/
void pianoView::mouseReleaseEvent( QMouseEvent * _me )
{
if( m_lastKey != -1 )
@@ -395,6 +509,19 @@ void pianoView::mouseReleaseEvent( QMouseEvent * _me )
// handler for mouse-move-event
/*! \brief Handle a mouse move event on the piano display view
*
* This handles the user dragging the mouse across the keys. It uses
* code from mousePressEvent() and mouseReleaseEvent(), also correcting
* for if the mouse movement has stayed within one key and if the mouse
* has moved outside the vertical area of the keyboard (which is still
* allowed but won't make the volume go up to 11).
*
* \param _me the ContextMenuEvent to handle.
* \todo Paul Wayper thinks that this code should be refactored to
* reduce or remove the duplication between this, the mousePressEvent()
* and mouseReleaseEvent() methods.
*/
void pianoView::mouseMoveEvent( QMouseEvent * _me )
{
if( m_piano == NULL )
@@ -465,6 +592,14 @@ void pianoView::mouseMoveEvent( QMouseEvent * _me )
/*! \brief Handle a key press event on the piano display view
*
* We determine our key number from the getKeyFromScanCode() method,
* and pass the event on to the piano's handleKeyPress() method if
* auto-repeat is off.
*
* \param _ke the KeyEvent to handle.
*/
void pianoView::keyPressEvent( QKeyEvent * _ke )
{
int key_num = getKeyFromScancode( _ke->nativeScanCode() ) +
@@ -487,6 +622,12 @@ void pianoView::keyPressEvent( QKeyEvent * _ke )
/*! \brief Handle a key release event on the piano display view
*
* The same logic as the keyPressEvent() method.
*
* \param _ke the KeyEvent to handle.
*/
void pianoView::keyReleaseEvent( QKeyEvent * _ke )
{
int key_num = getKeyFromScancode( _ke->nativeScanCode() ) +
@@ -508,6 +649,12 @@ void pianoView::keyReleaseEvent( QKeyEvent * _ke )
/*! \brief Handle the focus leaving the piano display view
*
* Turn off all notes if we lose focus.
*
* \todo Is there supposed to be a parameter given here?
*/
void pianoView::focusOutEvent( QFocusEvent * )
{
if( m_piano == NULL )
@@ -533,6 +680,20 @@ void pianoView::focusOutEvent( QFocusEvent * )
/*! \brief Convert a key number to an X coordinate in the piano display view
*
* We can immediately discard the trivial case of when the key number is
* less than our starting key. We then iterate through the keys from the
* start key to this key, adding the width of each key as we go. For
* black keys, and the first white key if there is no black key between
* two white keys, we add half a white key width; for that second white
* key, we add a whole width. That takes us to the boundary of a white
* key - subtract half a width to get to the middle.
*
* \param _key_num the keyboard key to translate
* \todo is this description of what the method does correct?
* \todo replace the final subtract with initialising x to width/2.
*/
int pianoView::getKeyX( int _key_num ) const
{
int k = m_startKey;
@@ -575,6 +736,13 @@ int pianoView::getKeyX( int _key_num ) const
/*! \brief Paint the piano display view in response to an event
*
* This method draws the piano and the 'root note' base. It draws
* the base first, then all the white keys, then all the black keys.
*
* \todo Is there supposed to be a parameter given here?
*/
void pianoView::paintEvent( QPaintEvent * )
{
QPainter p( this );