918 lines
27 KiB
C++
918 lines
27 KiB
C++
#include <guitar/GUIFretboard.hpp>
|
|
#include <guitar/TabEntry.hpp>
|
|
#include <guitar/GlobalDefs.hpp>
|
|
#include <guitar/registry.hpp>
|
|
#include <guitar/fretboard.hpp>
|
|
#include <guitar/MessageBox.hpp>
|
|
#include <music/scale.hpp>
|
|
#include <common/guiwnd.hpp>
|
|
#include <common/resbmp.hpp>
|
|
#include <common/font.hpp>
|
|
#include <common/clipbrd.hpp>
|
|
#include <common/versioninfo.hpp>
|
|
#include <common/keydata.hpp>
|
|
|
|
RGBColor GUIFretboard::smColorBlack=RGBColor(0,0,0);
|
|
RGBColor GUIFretboard::smColorLtGreen=RGBColor(156,156,74);
|
|
RGBColor GUIFretboard::smColorWhite=RGBColor(255,255,255);
|
|
RGBColor GUIFretboard::smColorRed=RGBColor(231,33,33);
|
|
RGBColor GUIFretboard::smColorGreen=RGBColor(0,128,0);
|
|
RGBColor GUIFretboard::smColorBlue=RGBColor(0,0,255);
|
|
|
|
/* Construct the GUIFretboard
|
|
* @param parent - The owning parent window
|
|
* @param tuning - The tuning for this fretboard
|
|
* @param frets - The number of frets on this fretboard
|
|
*/
|
|
GUIFretboard::GUIFretboard(GUIWindow &parent,const Tuning &tuning,int frets)
|
|
: mTuning(tuning), mTextFont("Small Fonts",6), mShowNotes(false),
|
|
mPrevBrush(0), mPrevFont(0), mPrevBkMode(0), mPrevTextColor(0), mClearNotes(true),
|
|
mCurrFret(0), mCurrString(0), mRedBrush(smColorRed), mLtGreenBrush(smColorLtGreen),
|
|
mWhiteBrush(smColorWhite), mGreenBrush(smColorGreen), mBlueBrush(smColorBlue)
|
|
{
|
|
Registry registry;
|
|
setShowNotes(registry.getShowNotes());
|
|
mParent=SmartPointer<GUIWindow>(&parent);
|
|
mSizeHandler.setCallback(this,&GUIFretboard::sizeHandler);
|
|
mLeftButtonDownHandler.setCallback(this,&GUIFretboard::leftButtonDownHandler);
|
|
mKeyDownHandler.setCallback(this,&GUIFretboard::keyDownHandler);
|
|
mKeyUpHandler.setCallback(this,&GUIFretboard::keyUpHandler);
|
|
mSetFocusHandler.setCallback(this,&GUIFretboard::setFocusHandler);
|
|
mKillFocusHandler.setCallback(this,&GUIFretboard::killFocusHandler);
|
|
mParent->insertHandler(VectorHandler::SizeHandler,&mSizeHandler);
|
|
mParent->insertHandler(VectorHandler::LeftButtonDownHandler,&mLeftButtonDownHandler);
|
|
mParent->insertHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler);
|
|
mParent->insertHandler(VectorHandler::KeyUpHandler,&mKeyUpHandler);
|
|
mParent->insertHandler(VectorHandler::KillFocusHandler,&mKillFocusHandler);
|
|
mParent->insertHandler(VectorHandler::SetFocusHandler,&mSetFocusHandler);
|
|
mParent.disposition(PointerDisposition::Assume);
|
|
mResBitmap=::new ResBitmap("FRETBOARD");
|
|
mResBitmap.disposition(PointerDisposition::Delete);
|
|
parent.setWindowPos(mResBitmap->width()+RightBorder,mResBitmap->height()+BottomBorder);
|
|
createVirtualFretboard();
|
|
mParent->invalidate();
|
|
mParent->update();
|
|
}
|
|
|
|
/*
|
|
* Destructor
|
|
*/
|
|
GUIFretboard::~GUIFretboard()
|
|
{
|
|
mParent->removeHandler(VectorHandler::SizeHandler,&mSizeHandler);
|
|
mParent->removeHandler(VectorHandler::LeftButtonDownHandler,&mLeftButtonDownHandler);
|
|
mParent->removeHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler);
|
|
mParent->removeHandler(VectorHandler::KeyUpHandler,&mKeyUpHandler);
|
|
mParent->removeHandler(VectorHandler::KillFocusHandler,&mKillFocusHandler);
|
|
mParent->removeHandler(VectorHandler::SetFocusHandler,&mSetFocusHandler);
|
|
}
|
|
|
|
/*
|
|
* Draw the fretboard
|
|
* @param device - The device context on which to draw
|
|
*/
|
|
void GUIFretboard::draw(PureDevice &device)
|
|
{
|
|
mDIBitmap->usePalette(device,true);
|
|
mDIBitmap->bitBlt(device);
|
|
mDIBitmap->usePalette(device,false);
|
|
refreshNotes();
|
|
}
|
|
|
|
/*
|
|
* Repeat the selected notes at every location on the fretboard
|
|
* @param None
|
|
*/
|
|
void GUIFretboard::showAllPositions(void)
|
|
{
|
|
Array<FrettedBoundingNote> frettedBoundingNotes;
|
|
|
|
mActiveFrets.treeItems(frettedBoundingNotes);
|
|
clearNotes();
|
|
for(int index=0;index<frettedBoundingNotes.size();index++)
|
|
{
|
|
setNote(frettedBoundingNotes[index],false,false);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Sets the notes of the given frettedNotes on the fretboard
|
|
* @param frettedNotes - the notes to set
|
|
* @param play - indicates whether the notes of the scale should be played
|
|
*/
|
|
void GUIFretboard::setNote(Block<FrettedNote> &frettedNotes,bool play)
|
|
{
|
|
FrettedNotes notes;
|
|
notes.size(frettedNotes.size());
|
|
for(int index=0;index<frettedNotes.size();index++)notes[index]=frettedNotes[index];
|
|
setNote(notes,play);
|
|
}
|
|
|
|
/*
|
|
* Sets the notes of the given frettedNotes on the fretboard
|
|
* @param frettedNotes - the notes to set
|
|
* @param play - indicates whether the notes of the scale should be played
|
|
*/
|
|
void GUIFretboard::setNote(const FrettedNotes &frettedNotes,bool play)
|
|
{
|
|
getSequencer();
|
|
|
|
clearNotes();
|
|
PureDevice device(*mParent);
|
|
prepareDevice(device,true);
|
|
for(int index=0;index<frettedNotes.size();index++)
|
|
{
|
|
FrettedNote &frettedNote=((FrettedNotes&)frettedNotes)[index];
|
|
GuitarString &string=operator[](5-frettedNote.getString());
|
|
FrettedBoundingNote &frettedBoundingNote=string[frettedNote.getFret()];
|
|
frettedBoundingNote.setBkGndColor(smColorRed);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
drawNote(frettedBoundingNote,device);
|
|
mActiveFrets.insert(frettedBoundingNote);
|
|
if(play)frettedBoundingNote.noteOn(mSequencer->getDevice());
|
|
}
|
|
prepareDevice(device,false);
|
|
}
|
|
|
|
/*
|
|
#include <guitar/ChordMapper.hpp>
|
|
|
|
void GUIFretboard::setNote(const Music::Chord &chord,bool play)
|
|
{
|
|
Block<FrettedNote> frettedNotes;
|
|
Block<Block<FrettedNote> > frettedNotesBlock;
|
|
Fretboard fretboard;
|
|
ChordMapper chordMapper;
|
|
|
|
getSequencer();
|
|
|
|
chordMapper.map(chord,frettedNotesBlock);
|
|
for(int index=0;index<frettedNotesBlock.size();index++)
|
|
{
|
|
Block<FrettedNote> &frettedNotes=frettedNotesBlock[index];
|
|
clearNotes();
|
|
// if(!fretboard.getAt(chord,frettedNotes))
|
|
// MessageBox::messageBox("Error mapping notes","some notes were not mapped.");
|
|
setNote(frettedNotes,false);
|
|
::Sleep(2000);
|
|
}
|
|
|
|
if(play)
|
|
{
|
|
Registry registry;
|
|
((Music::Chord&)chord).play(mSequencer->getDevice());
|
|
::Sleep(registry.getMillisecondsPerQuarterNote());
|
|
}
|
|
}
|
|
*/
|
|
|
|
|
|
#include <guitar/ChordMapper.hpp>
|
|
|
|
void GUIFretboard::setNote(const Music::Chord &chord,bool play)
|
|
{
|
|
Block<FrettedNote> frettedNotes;
|
|
Fretboard fretboard;
|
|
ChordMapper chordMapper;
|
|
|
|
clearNotes();
|
|
if(!chordMapper.map(chord,frettedNotes))return;
|
|
setNote(frettedNotes,false);
|
|
if(!play)return;
|
|
if(play)
|
|
{
|
|
Registry registry;
|
|
getSequencer();
|
|
((Music::Chord&)chord).play(mSequencer->getDevice());
|
|
::Sleep(registry.getMillisecondsPerQuarterNote());
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Sets the notes of the given chord on the fretboard
|
|
* @param chord - the chord from which notes will be set
|
|
* @param play - indicates whether the notes of the chord should be played
|
|
* needs work (ie) selects multiple notes per string, does not optimize
|
|
* for finger position
|
|
*/
|
|
|
|
/*
|
|
void GUIFretboard::setNote(const Music::Chord &chord,bool play)
|
|
{
|
|
Block<FrettedNote> frettedNotes;
|
|
Fretboard fretboard;
|
|
|
|
getSequencer();
|
|
clearNotes();
|
|
if(!fretboard.getAt(chord,frettedNotes))
|
|
MessageBox::messageBox("Error mapping notes","some notes were not mapped.");
|
|
setNote(frettedNotes,false);
|
|
if(play)
|
|
{
|
|
Registry registry;
|
|
((Music::Chord&)chord).play(mSequencer->getDevice());
|
|
::Sleep(registry.getMillisecondsPerQuarterNote());
|
|
}
|
|
}
|
|
|
|
*/
|
|
/*
|
|
* Sets the notes of the given scale on the fretboard
|
|
* @param scale - the scale from which notes will be set
|
|
* @param play - indicates whether the notes of the scale should be played
|
|
*/
|
|
void GUIFretboard::setNote(const Scale &scale,bool play)
|
|
{
|
|
Registry registry;
|
|
Note degreeI;
|
|
Note degreeIII;
|
|
Note degreeV;
|
|
Note degreeVII;
|
|
|
|
getSequencer();
|
|
clearNotes();
|
|
if(scale.has(Degree::I))degreeI=scale.getDegree(Degree::I);
|
|
if(scale.has(Degree::III))degreeIII=scale.getDegree(Degree::III);
|
|
if(scale.has(Degree::V))degreeV=scale.getDegree(Degree::V);
|
|
if(scale.has(Degree::VII))degreeVII=scale.getDegree(Degree::VII);
|
|
for(int index=0;index<scale.size();index++)
|
|
{
|
|
const Note ¬e=((Scale&)scale)[index];
|
|
for(int strIndex=0;strIndex<size();strIndex++)
|
|
{
|
|
GuitarString &string=operator[](strIndex);
|
|
for(int frIndex=0;frIndex<getFrets()+1;frIndex++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=string[frIndex];
|
|
if(note==(Note&)frettedBoundingNote)
|
|
{
|
|
PureDevice device(*mParent);
|
|
if(scale.has(Degree::I)&&(Note&)frettedBoundingNote==degreeI)
|
|
{
|
|
frettedBoundingNote.setBkGndColor(smColorRed);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
}
|
|
else if(scale.has(Degree::III)&&(Note&)frettedBoundingNote==degreeIII)
|
|
{
|
|
frettedBoundingNote.setBkGndColor(smColorBlue);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
}
|
|
else if(scale.has(Degree::V)&&(Note&)frettedBoundingNote==degreeV)
|
|
{
|
|
frettedBoundingNote.setBkGndColor(smColorGreen);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
}
|
|
else if(scale.has(Degree::VII)&&(Note&)frettedBoundingNote==degreeVII)
|
|
{
|
|
frettedBoundingNote.setBkGndColor(smColorWhite);
|
|
frettedBoundingNote.setTextColor(smColorBlack);
|
|
}
|
|
else
|
|
{
|
|
frettedBoundingNote.setBkGndColor(smColorLtGreen);
|
|
frettedBoundingNote.setTextColor(smColorBlack);
|
|
}
|
|
prepareDevice(device,frettedBoundingNote.getBkGndColor(),frettedBoundingNote.getTextColor());
|
|
drawNote(frettedBoundingNote,device);
|
|
mActiveFrets.insert(frettedBoundingNote);
|
|
mCurrFret=frIndex;
|
|
mCurrString=5-strIndex;
|
|
prepareDevice(device,false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(play)
|
|
{
|
|
Music::Chord chord=scale.getI7Chord();
|
|
chord.play(mSequencer->getDevice());
|
|
::Sleep(Notes::DefaultDelay);
|
|
scale.play(mSequencer->getDevice(),registry.getMillisecondsPerQuarterNote()/4); // play scale as 16th notes
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Sets a note on the fretboard
|
|
* @param note - the note to set
|
|
* @param clear - indicates whether fretboard should be cleared prior to note being set
|
|
* @param play - indicates whether the note should be played
|
|
*/
|
|
void GUIFretboard::setNote(const Note ¬e,bool clear,bool play)
|
|
{
|
|
getSequencer();
|
|
if(clear)clearNotes();
|
|
for(int strIndex=0;strIndex<size();strIndex++)
|
|
{
|
|
GuitarString &string=operator[](strIndex);
|
|
for(int frIndex=0;frIndex<getFrets()+1;frIndex++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=string[frIndex];
|
|
if(note==(Note&)frettedBoundingNote)
|
|
{
|
|
PureDevice device(*mParent);
|
|
prepareDevice(device,true);
|
|
frettedBoundingNote.setBkGndColor(smColorRed);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
drawNote(frettedBoundingNote,device);
|
|
prepareDevice(device,false);
|
|
mActiveFrets.insert(frettedBoundingNote);
|
|
if(play)frettedBoundingNote.noteOn(mSequencer->getDevice());
|
|
mCurrFret=frIndex;
|
|
mCurrString=5-strIndex;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Sets a note(s) on the fretboard
|
|
* @param entry - the tabentry containing the note(s)
|
|
* @param clear - indicates whether fretboard should be cleared prior to note(s) being set
|
|
* @param play - indicates whether the note(s) should be played
|
|
*/
|
|
void GUIFretboard::setNote(const TabEntry &entry,bool clear,bool play)
|
|
{
|
|
PureDevice device(*mParent);
|
|
getSequencer();
|
|
if(clear)clearNotes();
|
|
prepareDevice(device,true);
|
|
for(int index=0;index<entry.size();index++)
|
|
{
|
|
const FrettedNote &frettedNote=((TabEntry&)entry)[index];
|
|
GuitarString &guitarString=operator[]((size()-1)-frettedNote.getString());
|
|
FrettedBoundingNote &frettedBoundingNote=guitarString[frettedNote.getFret()];
|
|
frettedBoundingNote.setBkGndColor(smColorRed);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
drawNote(frettedBoundingNote,device);
|
|
mActiveFrets.insert(frettedBoundingNote);
|
|
if(play)((Note&)frettedNote).noteOn(mSequencer->getDevice());
|
|
}
|
|
prepareDevice(device,false);
|
|
}
|
|
|
|
/*
|
|
* Sets a note on the fretboard
|
|
* @param string - the string to set the note on
|
|
* @param fret - the fret to set the note on
|
|
* @param clear - indicates whether fretboard should be cleared prior to note(s) being set
|
|
* @param play - indicates whether the note(s) should be played
|
|
*/
|
|
void GUIFretboard::setNote(int string,int fret,bool clear,bool play)
|
|
{
|
|
PureDevice device(*mParent);
|
|
getSequencer();
|
|
GuitarString &guitarString=operator[]((size()-1)-string);
|
|
FrettedBoundingNote &frettedBoundingNote=guitarString[fret];
|
|
if(clear)clearNotes();
|
|
frettedBoundingNote.setBkGndColor(smColorRed);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
mActiveFrets.insert(frettedBoundingNote);
|
|
prepareDevice(device,true);
|
|
drawNote(frettedBoundingNote,device);
|
|
if(play)frettedBoundingNote.noteOn(mSequencer->getDevice());
|
|
prepareDevice(device,false);
|
|
}
|
|
|
|
/*
|
|
* Sets a note on the fretboard from mouse input
|
|
* @param clickPoint - the point at which the mouse was clicked
|
|
* @param clear - indicates whether fretboard should be cleared prior to note(s) being set
|
|
* @param play - indicates whether the note(s) should be played
|
|
*/
|
|
bool GUIFretboard::setNote(const GDIPoint &clickPoint,bool clear,bool play)
|
|
{
|
|
getSequencer();
|
|
if(clear)clearNotes();
|
|
for(int strIndex=0;strIndex<size();strIndex++)
|
|
{
|
|
GuitarString &string=operator[](strIndex);
|
|
for(int frIndex=0;frIndex<getFrets()+1;frIndex++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=string[frIndex];
|
|
Rect boundingRect(frettedBoundingNote.getBoundingRect());
|
|
boundingRect.left(boundingRect.left()-ClickTolerance);
|
|
boundingRect.right(boundingRect.right()+ClickTolerance);
|
|
boundingRect.top(boundingRect.top()-ClickTolerance);
|
|
boundingRect.bottom(boundingRect.bottom()+ClickTolerance);
|
|
if(boundingRect.ptInRect(clickPoint))
|
|
{
|
|
PureDevice device(*mParent);
|
|
frettedBoundingNote.setBkGndColor(smColorRed);
|
|
frettedBoundingNote.setTextColor(smColorWhite);
|
|
prepareDevice(device,true);
|
|
drawNote(frettedBoundingNote,device);
|
|
prepareDevice(device,false);
|
|
mActiveFrets.insert(frettedBoundingNote);
|
|
if(play)frettedBoundingNote.noteOn(mSequencer->getDevice());
|
|
mCurrFret=frIndex;
|
|
mCurrString=5-strIndex;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Unsets a note on the fretboard from mouse input
|
|
* @param clickPoint - the point at which the mouse was clicked
|
|
* @param clear - indicates whether fretboard should be cleared prior to note(s) being set
|
|
* @param play - indicates whether the note(s) should be played
|
|
*/
|
|
bool GUIFretboard::unsetNote(const GDIPoint &clickPoint)
|
|
{
|
|
for(int strIndex=0;strIndex<size();strIndex++)
|
|
{
|
|
GuitarString &string=operator[](strIndex);
|
|
for(int frIndex=0;frIndex<getFrets()+1;frIndex++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=string[frIndex];
|
|
Rect boundingRect(frettedBoundingNote.getBoundingRect());
|
|
boundingRect.left(boundingRect.left()-ClickTolerance);
|
|
boundingRect.right(boundingRect.right()+ClickTolerance);
|
|
boundingRect.top(boundingRect.top()-ClickTolerance);
|
|
boundingRect.bottom(boundingRect.bottom()+ClickTolerance);
|
|
if(boundingRect.ptInRect(clickPoint))
|
|
{
|
|
PureDevice device(*mParent);
|
|
mActiveFrets.remove(frettedBoundingNote);
|
|
mParent->invalidate(boundingRect,false);
|
|
mParent->update();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* isNoteSet a note on the fretboard from mouse input
|
|
* @param clickPoint - the point at which the mouse was clicked
|
|
* @param clear - indicates whether fretboard should be cleared prior to note(s) being set
|
|
* @param play - indicates whether the note(s) should be played
|
|
*/
|
|
bool GUIFretboard::isNoteSet(const GDIPoint &clickPoint)
|
|
{
|
|
for(int strIndex=0;strIndex<size();strIndex++)
|
|
{
|
|
GuitarString &string=operator[](strIndex);
|
|
for(int frIndex=0;frIndex<getFrets()+1;frIndex++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=string[frIndex];
|
|
Rect boundingRect(frettedBoundingNote.getBoundingRect());
|
|
boundingRect.left(boundingRect.left()-ClickTolerance);
|
|
boundingRect.right(boundingRect.right()+ClickTolerance);
|
|
boundingRect.top(boundingRect.top()-ClickTolerance);
|
|
boundingRect.bottom(boundingRect.bottom()+ClickTolerance);
|
|
if(boundingRect.ptInRect(clickPoint))
|
|
{
|
|
if(mActiveFrets.searchItem(frettedBoundingNote))return true;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Redraws all of the currently active notes onto the fretboard bitmap
|
|
* @param None
|
|
*/
|
|
void GUIFretboard::refreshNotes(void)
|
|
{
|
|
Array<FrettedBoundingNote> frettedBoundingNotes;
|
|
|
|
PureDevice device(*mParent);
|
|
mActiveFrets.treeItems(frettedBoundingNotes);
|
|
for(int index=0;index<frettedBoundingNotes.size();index++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=frettedBoundingNotes[index];
|
|
prepareDevice(device,frettedBoundingNote.getBkGndColor(),frettedBoundingNote.getTextColor(),true);
|
|
drawNote(frettedBoundingNote,device);
|
|
prepareDevice(device,false);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Get all selected notes into the given TabEntry object
|
|
* @param entry - TabEntry object in which to place the notes
|
|
*/
|
|
void GUIFretboard::getNotes(TabEntry &entry)
|
|
{
|
|
Array<FrettedBoundingNote> frettedBoundingNotes;
|
|
|
|
entry.remove();
|
|
mActiveFrets.treeItems(frettedBoundingNotes);
|
|
for(int index=0;index<frettedBoundingNotes.size();index++)
|
|
{
|
|
FrettedBoundingNote frettedBoundingNote=frettedBoundingNotes[index]; // make a copy so we can
|
|
frettedBoundingNote.setString(5-frettedBoundingNote.getString()); // translate the string position
|
|
entry.insert(&frettedBoundingNote); // .. and insert into entry
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Draw the note given by the FrettedBoundingNote
|
|
* @param currFret - The fretted bounding note
|
|
* @param device - The display device on which to draw the note
|
|
*/
|
|
void GUIFretboard::drawNote(FrettedBoundingNote &currFret,PureDevice &device)
|
|
{
|
|
Rect boundingRect;
|
|
device.roundRectangle(currFret.getDisplayPoint(),Radius);
|
|
boundingRect=currFret.getBoundingRect();
|
|
if(getShowNotes())
|
|
{
|
|
String &strNote=((Note&)currFret).toString();
|
|
if(strNote.length()>1)device.textOut(boundingRect.left(),boundingRect.top(),strNote);
|
|
else device.textOut(boundingRect.left()+1,boundingRect.top()+1,strNote);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Prepare to do some drawing
|
|
* @param device - The device on which we are going to draw
|
|
* @param prepare - indicates whether to prepare for drawing or cleanup after drawing
|
|
*/
|
|
void GUIFretboard::prepareDevice(PureDevice &device,bool prepare)
|
|
{
|
|
prepareDevice(device,smColorRed,smColorWhite,prepare);
|
|
}
|
|
|
|
/*
|
|
* Prepare to do some drawing
|
|
* @param device - The device on which we are going to draw
|
|
* @param brushColor - The color of the drawing brush
|
|
* @param textColor - The text color
|
|
* @param prepare - Indicates whether to prepare for drawing or cleanup after drawing
|
|
*/
|
|
void GUIFretboard::prepareDevice(PureDevice &device,const RGBColor &brushColor,const RGBColor &textColor,bool prepare)
|
|
{
|
|
if(prepare)
|
|
{
|
|
mPrevBrush=::SelectObject(device.getDC(),(GDIObj)getBrush(brushColor));
|
|
if(getShowNotes())
|
|
{
|
|
mPrevFont=::SelectObject(device.getDC(),(GDIObj)mTextFont);
|
|
mPrevBkMode=device.setBkMode(PureDevice::Transparent);
|
|
mPrevTextColor=device.setTextColor(textColor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
::SelectObject(device.getDC(),mPrevBrush);
|
|
::SelectObject(device.getDC(),mPrevFont);
|
|
device.setBkMode(PureDevice::BkMode(mPrevBkMode));
|
|
device.setTextColor(mPrevTextColor);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Get the brush for the given color
|
|
* @param brushColor - The color of the brush we desire
|
|
* @return - A reference to the brush for the given color
|
|
*/
|
|
Brush &GUIFretboard::getBrush(const RGBColor &brushColor)
|
|
{
|
|
if(brushColor==mRedBrush.getColor())return mRedBrush;
|
|
else if(brushColor==mWhiteBrush.getColor())return mWhiteBrush;
|
|
else if(brushColor==mGreenBrush.getColor())return mGreenBrush;
|
|
else if(brushColor==mBlueBrush.getColor())return mBlueBrush;
|
|
return mLtGreenBrush;
|
|
}
|
|
|
|
/*
|
|
* Clears all of the notes on the fretboard
|
|
* @param None
|
|
* @return None
|
|
*/
|
|
void GUIFretboard::clearNotes(void)
|
|
{
|
|
Array<FrettedBoundingNote> frettedBoundingNotes;
|
|
|
|
mActiveFrets.treeItems(frettedBoundingNotes);
|
|
for(int index=0;index<frettedBoundingNotes.size();index++)
|
|
{
|
|
const Rect &rect=frettedBoundingNotes[index].getBoundingRect();
|
|
mParent->invalidate(rect,false);
|
|
}
|
|
mActiveFrets.remove();
|
|
mParent->update();
|
|
}
|
|
|
|
/*
|
|
* Initialize the fretboard and create it's underlying bitmap
|
|
* @param None
|
|
* @return None
|
|
*/
|
|
void GUIFretboard::createVirtualFretboard(void)
|
|
{
|
|
SmartPointer<FrettedBoundingNote> activeFret;
|
|
size(mTuning.size());
|
|
for(int strIndex=0;strIndex<size();strIndex++)
|
|
{
|
|
Note note=mTuning[mTuning.size()-strIndex-1];
|
|
GuitarString &string=operator[](strIndex);
|
|
string.size(getFrets()+1);
|
|
for(int frIndex=0;frIndex<getFrets()+1;frIndex++)
|
|
{
|
|
FrettedBoundingNote &frettedBoundingNote=string[frIndex];
|
|
frettedBoundingNote.setNote(note);
|
|
frettedBoundingNote.setString(strIndex);
|
|
frettedBoundingNote.setFret(frIndex);
|
|
frettedBoundingNote.setDisplayPoint(getPoint(strIndex,frIndex));
|
|
frettedBoundingNote.setBoundingRect(getBoundingRect(strIndex,frIndex));
|
|
note++;
|
|
if(mActiveFrets.searchItem(frettedBoundingNote,activeFret))
|
|
{
|
|
activeFret->setBoundingRect(frettedBoundingNote.getBoundingRect());
|
|
}
|
|
}
|
|
}
|
|
PureDevice pureDevice(*mParent);
|
|
if(mDIBitmap.isOkay())mDIBitmap.destroy();
|
|
mDIBitmap=::new DIBitmap(pureDevice,(BitmapInfo&)*mResBitmap,(PurePalette&)*mResBitmap);
|
|
for(int row=0;row<mResBitmap->height();row++)
|
|
{
|
|
for(int col=0;col<mResBitmap->width();col++)
|
|
{
|
|
mDIBitmap->setByte(row,col,*(mResBitmap->ptrData()+((row*mResBitmap->width())+col)));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Get the rectangle that bounds the given string and fret
|
|
* @param string - The string
|
|
* @param fret - The fret
|
|
* @return - The bounding rectangle
|
|
*/
|
|
Rect GUIFretboard::getBoundingRect(int string,int fret)const
|
|
{
|
|
Rect boundingRect;
|
|
Point point(getPoint(string,fret));
|
|
boundingRect.left(point.x()-Radius);
|
|
boundingRect.top(point.y()-Radius);
|
|
boundingRect.right(point.x()+Radius);
|
|
boundingRect.bottom(point.y()+Radius);
|
|
return boundingRect;
|
|
}
|
|
|
|
/*
|
|
* Get the point for the given string and fret
|
|
* @param string - The string
|
|
* @param fret - The fret
|
|
* @return - The point
|
|
*/
|
|
Point GUIFretboard::getPoint(int string,int fret)const
|
|
{
|
|
Point point;
|
|
int starty=15;
|
|
int incy=10;
|
|
|
|
switch(fret)
|
|
{
|
|
case 0 :
|
|
point.x(10);
|
|
break;
|
|
case 1 :
|
|
point.x(23);
|
|
break;
|
|
case 2 :
|
|
point.x(55);
|
|
break;
|
|
case 3 :
|
|
point.x(83);
|
|
break;
|
|
case 4 :
|
|
point.x(111);
|
|
break;
|
|
case 5 :
|
|
point.x(138);
|
|
break;
|
|
case 6 :
|
|
point.x(164);
|
|
break;
|
|
case 7 :
|
|
point.x(193);
|
|
break;
|
|
case 8 :
|
|
point.x(220);
|
|
break;
|
|
case 9 :
|
|
point.x(249);
|
|
break;
|
|
case 10 :
|
|
point.x(280);
|
|
break;
|
|
case 11 :
|
|
point.x(307);
|
|
break;
|
|
case 12 :
|
|
point.x(335);
|
|
break;
|
|
case 13 :
|
|
point.x(362);
|
|
break;
|
|
case 14 :
|
|
point.x(392);
|
|
break;
|
|
case 15 :
|
|
point.x(420);
|
|
break;
|
|
case 16 :
|
|
point.x(446);
|
|
break;
|
|
case 17 :
|
|
point.x(473);
|
|
break;
|
|
case 18 :
|
|
point.x(501);
|
|
break;
|
|
case 19 :
|
|
point.x(528);
|
|
break;
|
|
case 20 :
|
|
point.x(558);
|
|
break;
|
|
case 21 :
|
|
point.x(585);
|
|
break;
|
|
case 22 :
|
|
point.x(611);
|
|
break;
|
|
case 23 :
|
|
point.x(640);
|
|
break;
|
|
case 24 :
|
|
point.x(668);
|
|
break;
|
|
}
|
|
point.y(starty+((string)*incy));
|
|
return point;
|
|
}
|
|
|
|
/*
|
|
* Cut the notes from the fretboard
|
|
* @param None
|
|
* @return None
|
|
*/
|
|
void GUIFretboard::cut(void)
|
|
{
|
|
copy(); // copy the fretboard notes to the clipboard first
|
|
clearNotes();
|
|
}
|
|
|
|
/*
|
|
* Copy all selected notes to the clipboard
|
|
* @param None
|
|
* @return None
|
|
*/
|
|
void GUIFretboard::copy(void)
|
|
{
|
|
Clipboard clipboard(*mParent);
|
|
String strHeader;
|
|
TabEntry entry;
|
|
VersionInfo versionInfo;
|
|
|
|
getNotes(entry);
|
|
strHeader=String("[")+versionInfo.getProductNameString()+String(",")+versionInfo.getProductVersion()+String("]");
|
|
clipboard.setClipboard(GlobalDefs::getRegisteredClipboardFormat(),strHeader+entry.toString());
|
|
}
|
|
|
|
/*
|
|
* Paste notes from clipboard
|
|
* @param None
|
|
* @return None
|
|
*/
|
|
void GUIFretboard::paste(void)
|
|
{
|
|
Clipboard clipboard(*mParent);
|
|
String strText;
|
|
String strHeader;
|
|
TabEntry entry;
|
|
VersionInfo versionInfo;
|
|
|
|
clipboard.getClipboard(GlobalDefs::getRegisteredClipboardFormat(),strText);
|
|
if(strText.isNull())return;
|
|
GlobalDefs::outDebug(strText);
|
|
strHeader=strText.betweenString('[',']');
|
|
if(strHeader.isNull())return;
|
|
if(!(versionInfo.getProductNameString()==strHeader.betweenString(0,',')))return;
|
|
if(!(versionInfo.getProductVersion()==strHeader.betweenString(',',0)))return;
|
|
entry.fromString(strText.betweenString(']',0));
|
|
setNote(entry,true,true);
|
|
}
|
|
|
|
// callbacks
|
|
|
|
/*
|
|
* Handles resizing of the fretboard window
|
|
* @param callbackData - Contains information about the resize event
|
|
* @return success status
|
|
*/
|
|
CallbackData::ReturnType GUIFretboard::sizeHandler(CallbackData &callbackData)
|
|
{
|
|
GlobalDefs::outDebug("[GUIFretboard::sizeHandler]");
|
|
Point sizePoint(callbackData.loWord(),callbackData.hiWord());
|
|
if(sizePoint.x()>mResBitmap->width()+RightBorder||
|
|
sizePoint.y()>mResBitmap->height()+BottomBorder)
|
|
mParent->setWindowPos(mResBitmap->width()+10,mResBitmap->height()+30);
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Handles left button down event
|
|
* @param callbackData - Contains information about the event
|
|
* @return success status
|
|
*/
|
|
CallbackData::ReturnType GUIFretboard::leftButtonDownHandler(CallbackData &callbackData)
|
|
{
|
|
GDIPoint clickPoint(callbackData.loWord(),callbackData.hiWord());
|
|
|
|
if(KeyData::controlKeyPressed())setNote(clickPoint,mClearNotes,true);
|
|
else
|
|
{
|
|
if(isNoteSet(clickPoint))unsetNote(clickPoint);
|
|
else setNote(clickPoint,mClearNotes,true);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Handles keyboard event
|
|
* @param callbackData - Contains information about the event
|
|
* @return success status
|
|
*/
|
|
CallbackData::ReturnType GUIFretboard::keyDownHandler(CallbackData &callbackData)
|
|
{
|
|
if(KeyData::controlKeyPressed())mClearNotes=false;
|
|
else mClearNotes=true;
|
|
KeyData keyData(callbackData);
|
|
switch(keyData.virtualKey())
|
|
{
|
|
case KeyDown :
|
|
if(KeyData::shiftKeyPressed())mCurrString-=2;
|
|
else mCurrString--;
|
|
if(mCurrString<0)mCurrString=0;
|
|
setNote(mCurrString,mCurrFret,mClearNotes,true);
|
|
break;
|
|
case KeyLeft :
|
|
if(KeyData::shiftKeyPressed())mCurrFret-=2;
|
|
else mCurrFret--;
|
|
if(mCurrFret<0)mCurrFret=0;
|
|
setNote(mCurrString,mCurrFret,mClearNotes,true);
|
|
break;
|
|
case KeyRight :
|
|
if(KeyData::shiftKeyPressed())mCurrFret+=2;
|
|
else mCurrFret++;
|
|
if(mCurrFret>DefaultFrets)mCurrFret=DefaultFrets;
|
|
setNote(mCurrString,mCurrFret,mClearNotes,true);
|
|
break;
|
|
case KeyUp :
|
|
if(KeyData::shiftKeyPressed())mCurrString+=2;
|
|
else mCurrString++;
|
|
if(mCurrString>=DefaultStrings)mCurrString=DefaultStrings-1;
|
|
setNote(mCurrString,mCurrFret,mClearNotes,true);
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Handles key up event
|
|
* @param callbackData - Contains information about the event
|
|
* @return success status
|
|
*/
|
|
CallbackData::ReturnType GUIFretboard::keyUpHandler(CallbackData &callbackData)
|
|
{
|
|
KeyData keyData(callbackData);
|
|
if(CtrlKey==keyData.virtualKey())mClearNotes=true;
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Handles focus event
|
|
* @param callbackData - Contains information about the event
|
|
* @return success status
|
|
*/
|
|
CallbackData::ReturnType GUIFretboard::setFocusHandler(CallbackData &callbackData)
|
|
{
|
|
getSequencer();
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Handles kill focus event
|
|
* @param callbackData - Contains information about the event
|
|
* @return success status
|
|
*/
|
|
CallbackData::ReturnType GUIFretboard::killFocusHandler(CallbackData &callbackData)
|
|
{
|
|
mSequencer.destroy();
|
|
return false;
|
|
}
|
|
|