Files
Work/guitar/backup/20030501/tabpage.cpp
2024-08-07 09:16:27 -04:00

983 lines
32 KiB
C++

#include <guitar/tabpage.hpp>
#include <guitar/tabdlg.hpp>
#include <guitar/fretdlg.hpp>
#include <guitar/registry.hpp>
#include <guitar/GlobalDefs.hpp>
#include <guitar/viewwnd.hpp>
#include <midiseq/ProgramChange.hpp>
#include <common/guiwnd.hpp>
#include <common/font.hpp>
#include <common/bitmap.hpp>
#include <common/crsctrl.hpp>
#include <common/clipbrd.hpp>
#include <common/keydata.hpp>
#include <common/versioninfo.hpp>
#include <sgi_stl/map.h>
TabPage::TabPage(ViewWindow &parent)
: mItemsPerTab(0), mNumTabs(0), mCharWidth(0), mOutlinePen(RGBColor(0,0,0),Pen::PDot) ,
mDrawFont("Courier New",10), mHasFocus(false), mIsCancelled(false), mIsInPlay(false),
mIsPaused(false), mIsDirty(false), mKeepOutline(false), mCurrEntryIndex(0), mIsInSetRange(false)
{
mMIDIDevice=::new Sequencer();
mMIDIDevice.disposition(PointerDisposition::Delete);
mSizeHandler.setCallback(this,&TabPage::sizeHandler);
mPaintHandler.setCallback(this,&TabPage::paintHandler);
mVerticalScrollHandler.setCallback(this,&TabPage::verticalScrollHandler);
mHorizontalScrollHandler.setCallback(this,&TabPage::horizontalScrollHandler);
mLeftButtonUpHandler.setCallback(this,&TabPage::leftButtonUpHandler);
mLeftButtonDownHandler.setCallback(this,&TabPage::leftButtonDownHandler);
mMouseMoveHandler.setCallback(this,&TabPage::mouseMoveHandler);
mKillFocusHandler.setCallback(this,&TabPage::killFocusHandler);
mSetFocusHandler.setCallback(this,&TabPage::setFocusHandler);
mLeftButtonDoubleHandler.setCallback(this,&TabPage::leftButtonDoubleHandler);
mKeyDownHandler.setCallback(this,&TabPage::keyDownHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::SizeHandler,&mSizeHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::PaintHandler,&mPaintHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::VerticalScrollHandler,&mVerticalScrollHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::HorizontalScrollHandler,&mHorizontalScrollHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::LeftButtonUpHandler,&mLeftButtonUpHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::LeftButtonDownHandler,&mLeftButtonDownHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::MouseMoveHandler,&mMouseMoveHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::KillFocusHandler,&mKillFocusHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::SetFocusHandler,&mSetFocusHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::LeftButtonDoubleHandler,&mLeftButtonDoubleHandler);
((GUIWindow&)parent).insertHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler);
mParent=&parent;
mParent.disposition(PointerDisposition::Assume);
mScrollInfo.hwndOwner(parent);
createBitmap(parent);
}
TabPage::TabPage(const TabPage &/*someTabPage*/)
{ // private implementation
}
TabPage::~TabPage()
{
((GUIWindow&)*mParent).removeHandler(VectorHandler::SizeHandler,&mSizeHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::PaintHandler,&mPaintHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::VerticalScrollHandler,&mVerticalScrollHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::HorizontalScrollHandler,&mHorizontalScrollHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::LeftButtonUpHandler,&mLeftButtonUpHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::LeftButtonDownHandler,&mLeftButtonDownHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::KillFocusHandler,&mKillFocusHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::SetFocusHandler,&mSetFocusHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::MouseMoveHandler,&mMouseMoveHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::LeftButtonDoubleHandler,&mLeftButtonDoubleHandler);
((GUIWindow&)*mParent).removeHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler);
}
bool TabPage::insert(const TabRanges &ranges)
{
GlobalDefs::outDebug("[TabPage::insert]TabRanges",GlobalDefs::Debug);
if(!ranges.size())return false;
for(int index=0;index<ranges.size();index++)
{
mTabRanges.insert(&((TabRanges&)ranges)[index]);
}
return true;
}
bool TabPage::insert(const TabEntries &entries)
{
GlobalDefs::outDebug("[TabPage::insert]TabEntries",GlobalDefs::Debug);
if(!entries.size())return false;
for(int index=0;index<entries.size();index++)
{
mTabEntries.insert(&((TabEntries&)entries)[index]);
}
GlobalDefs::outDebug(String("[TabPage::insert] Added ")+String().fromInt(entries.size())+String(" entries."),GlobalDefs::Debug);
createBitmap(*mParent);
return true;
}
bool TabPage::update(GUIWindow &guiWindow)
{
GlobalDefs::outDebug("[TabPage::update]",GlobalDefs::Debug);
return createBitmap(guiWindow);
}
bool TabPage::createBitmap(GUIWindow &guiWindow)
{
CursorControl cursorControl;
PureDevice pureDevice(guiWindow);
GDIPoint gdiPoint;
int elapsedTime;
GlobalDefs::outDebug("[TabPage::createBitmap]",GlobalDefs::Debug);
if(!guiWindow.isValid())return false;
getDimensions(guiWindow,gdiPoint);
elapsedTime=::GetTickCount();
cursorControl.waitCursor(true);
if(mDIBitmap.isOkay())mDIBitmap.destroy();
PurePalette purePalette;
purePalette.systemPalette(true);
mDIBitmap=::new DIBitmap(pureDevice,gdiPoint.x(),gdiPoint.y(),purePalette);
mDIBitmap.disposition(PointerDisposition::Delete);
mDIBitmap->setBits(BkColorBits);
drawTabPage();
drawEntries();
cursorControl.waitCursor(false);
mScrollInfo.scrollableObjectDimensions(mDIBitmap->width(),mDIBitmap->height());
elapsedTime=(::GetTickCount()-elapsedTime)/1000;
GlobalDefs::outDebug(String("[TabPage::createBitmap]took ")+String().fromInt(elapsedTime)+String(" seconds."),GlobalDefs::Debug);
return mDIBitmap.isOkay();
}
bool TabPage::drawEntries(const RGBColor &rgbColor)
{
Point p1;
Point p2;
String strFret;
Registry registry;
bool showAction(registry.getShowAction());
if(!isOkay())return false;
GlobalDefs::outDebug(String("[TabPage::drawEntries]"),GlobalDefs::Debug);
PureDevice &pureDevice=mDIBitmap->getDevice();
pureDevice.select(mDIBitmap->getBitmap());
pureDevice.setTextColor(rgbColor);
::SelectObject(pureDevice.getDC(),(HFONT)mDrawFont);
for(int entryIndex=0;entryIndex<mTabEntries.size();entryIndex++)
{
p1=getEntryPoint(entryIndex);
TabEntry &entry=mTabEntries[entryIndex];
for(int index=0;index<entry.size();index++)
{
FrettedNote &frettedNote=entry[index];
if(!showAction)strFret=String().fromInt(frettedNote.getFret());
else
{
Action action=frettedNote.getAction();
strFret=action.toStringShort();
strFret+=String().fromInt(frettedNote.getFret());
}
p2.x(p1.x());
// p2.y((p1.y()+((5-frettedNote.getString())*TabSpacing))-(mDrawFont.charHeight()/2));
p2.y((p1.y()+((5-frettedNote.getString())*TabSpacing))-(mDrawFont.charHeight()*.5));
pureDevice.textOut(p2.x(),p2.y(),strFret);
}
}
return true;
}
bool TabPage::drawEntry(int entryIndex,const RGBColor &rgbColor)
{
if(!isOkay())return false;
GlobalDefs::outDebug(String("[TabPage::drawEntry]"),GlobalDefs::Debug);
PureDevice &pureDevice=mDIBitmap->getDevice();
pureDevice.select(mDIBitmap->getBitmap());
pureDevice.setTextColor(rgbColor);
::SelectObject(pureDevice.getDC(),(HFONT)mDrawFont);
Point p1=getEntryPoint(entryIndex);
Point p2;
TabEntry &entry=mTabEntries[entryIndex];
for(int index=0;index<entry.size();index++)
{
FrettedNote &frettedNote=entry[index];
String strFret(String().fromInt(frettedNote.getFret()));
p2.x(p1.x());
p2.y((p1.y()+((5-frettedNote.getString())*TabSpacing))-(mDrawFont.charHeight()/2));
pureDevice.textOut(p2.x(),p2.y(),strFret);
}
return true;
}
bool TabPage::outlineRect(const Rect &outlineRect)
{
if(!isOkay())return false;
GlobalDefs::outDebug(String("[TabPage::outlineRect]"),GlobalDefs::Debug);
setStatusText(String("Entry #")+String().fromInt(mCurrEntryIndex+1)+String(" of ")+String().fromInt(mTabEntries.size()));
if(mPrevOutlineRect==outlineRect)return false;
if(!mOverlay.isOkay())
{
mDIBitmap->getAt(mOverlay,outlineRect);
Rect rect(outlineRect);
rect.left(rect.left()+1);
rect.top(rect.top()+1);
rect.right(rect.right()-1);
rect.bottom(rect.bottom()-1);
mDIBitmap->outlineRect(rect);
invalidate(outlineRect);
}
else
{
mDIBitmap->overlay(*mOverlay,Point(mPrevOutlineRect.left(),mPrevOutlineRect.top()));
invalidate(mPrevOutlineRect);
mDIBitmap->getAt(mOverlay,outlineRect);
Rect rect(outlineRect);
rect.left(rect.left()+1);
rect.top(rect.top()+1);
rect.right(rect.right()-1);
rect.bottom(rect.bottom()-1);
mDIBitmap->outlineRect(rect);
invalidate(outlineRect);
}
mPrevOutlineRect=outlineRect;
return true;
}
bool TabPage::clearUpdate(void)
{
GlobalDefs::outDebug(String("[TabPage::clearUpdate]"),GlobalDefs::Debug);
if(!isOkay())return false;
if(!mOverlay.isOkay())return false;
mDIBitmap->overlay(*mOverlay,Point(mPrevOutlineRect.left(),mPrevOutlineRect.top()));
invalidate(mPrevOutlineRect);
mPrevOutlineRect=Rect(-1,-1,-1,-1);
mOverlay.destroy();
return true;
}
bool TabPage::getOutlineRect(Point mousePoint,int &entryIndex,Rect &outlineRect)
{
Point xyPoint(LeftMargin,TopMargin);
GlobalDefs::outDebug(String("[TabPage::getOutlineRect]"),GlobalDefs::Debug);
if(!isOkay())return false;
for(int index=0;index<mTabEntries.size();index++)
{
outlineRect.left(xyPoint.x());
outlineRect.top(xyPoint.y());
outlineRect.right(xyPoint.x()+getCharWidth()-1);
if(outlineRect.right()>=getWidth()-(RightMargin+LeftMargin))
outlineRect.right(getWidth()-(RightMargin+1));
outlineRect.bottom(xyPoint.y()+TabHeight-TabSpacing);
if(outlineRect.ptInRect(mousePoint))
{
entryIndex=index;
return true;
}
if(xyPoint.x()+getCharWidth()>=getWidth()-(RightMargin+LeftMargin))
{
xyPoint.x(LeftMargin);
xyPoint.y(xyPoint.y()+TabHeight+TabSeparator);
}
else xyPoint.x(xyPoint.x()+getCharWidth());
}
return false;
}
bool TabPage::getOutlineRect(int entryIndex,Rect &outlineRect)
{
Point xyPoint(LeftMargin,TopMargin);
GlobalDefs::outDebug(String("[TabPage::getOutlineRect]"),GlobalDefs::Debug);
if(!isOkay())return false;
for(int index=0;index<mTabEntries.size();index++)
{
outlineRect.left(xyPoint.x());
outlineRect.top(xyPoint.y());
outlineRect.right(xyPoint.x()+getCharWidth()-1);
if(outlineRect.right()>=getWidth()-(RightMargin+LeftMargin))
outlineRect.right(getWidth()-(RightMargin+1));
outlineRect.bottom(xyPoint.y()+TabHeight-TabSpacing);
if(index==entryIndex)return true;
if(xyPoint.x()+getCharWidth()>=getWidth()-(RightMargin+LeftMargin))
{
xyPoint.x(LeftMargin);
xyPoint.y(xyPoint.y()+TabHeight+TabSeparator);
}
else xyPoint.x(xyPoint.x()+getCharWidth());
}
return false;
}
bool TabPage::getNearestString(const Point &clickPoint,int &nearestString)
{
Rect outlineRect;
map<int,int> distanceMap;
if(mCurrEntryIndex<0||mCurrEntryIndex>=mTabEntries.size())return false;
if(!getOutlineRect(mCurrEntryIndex,outlineRect))return false;
distanceMap[abs(clickPoint.y()-outlineRect.top())]=5;
distanceMap[abs(clickPoint.y()-(outlineRect.top()+TabSpacing))]=4;
distanceMap[abs(clickPoint.y()-(outlineRect.top()+(TabSpacing*2)))]=3;
distanceMap[abs(clickPoint.y()-(outlineRect.top()+(TabSpacing*3)))]=2;
distanceMap[abs(clickPoint.y()-(outlineRect.top()+(TabSpacing*4)))]=1;
distanceMap[abs(clickPoint.y()-(outlineRect.top()+(TabSpacing*5)))]=0;
nearestString=(*distanceMap.begin()).second;
return true;
}
Point TabPage::getEntryPoint(int entryIndex)
{
Point xyPoint(LeftMargin,TopMargin);
GlobalDefs::outDebug(String("[TabPage::getEntryPoint]"),GlobalDefs::Debug);
for(int index=0;index<mTabEntries.size()&&index!=entryIndex;index++)
{
if(xyPoint.x()+getCharWidth()>=getWidth()-(RightMargin+LeftMargin))
{
xyPoint.x(LeftMargin);
xyPoint.y(xyPoint.y()+TabHeight+TabSeparator);
}
else xyPoint.x(xyPoint.x()+getCharWidth());
}
return xyPoint;
}
bool TabPage::showCurrent(void)
{
Rect outlineRect;
Rect clientRect;
if(!getOutlineRect(mCurrEntryIndex,outlineRect))return false;
mOverlay.destroy();
mPrevOutlineRect=Rect(-1,-1,-1,-1);
isInOutline(true);
mParent->clientRect(clientRect);
bringOutlineIntoView(outlineRect,clientRect);
this->outlineRect(outlineRect);
showFretEntry(mTabEntries[mCurrEntryIndex]);
return true;
}
bool TabPage::drawTabPage(void)
{
int yStart=TopMargin;
int xStart=0;
int elapsedTime;
GlobalDefs::outDebug(String("[TabPage::drawTabPage]"),GlobalDefs::Debug);
elapsedTime=::GetTickCount();
if(!getNumTabs())drawTab(LeftMargin,RightMargin,xStart,yStart,TabSpacing,TabLines); // draw at least one
for(int index=0;index<getNumTabs();index++)
{
drawTab(LeftMargin,RightMargin,xStart,yStart,TabSpacing,TabLines);
yStart+=TabHeight+TabSeparator;
}
elapsedTime=(::GetTickCount()-elapsedTime)/1000;
GlobalDefs::outDebug(String("[TabPage::drawTabPage]took ")+String().fromInt(elapsedTime)+String(" seconds."),GlobalDefs::Debug);
return true;
}
int TabPage::drawTab(int marginLeft,int marginRight,int xStart,int yStart,int spacing,int lineCount)
{
int xPos=xStart;
int yPos=yStart;
GlobalDefs::outDebug(String("[TabPage::drawTab]"),GlobalDefs::Debug);
mDIBitmap->line(Point(marginLeft-1,yStart),Point(marginLeft-1,1+yStart+((lineCount-1)*spacing)),TabLineColor);
for(int line=0;line<lineCount;line++)
{
xPos=marginLeft;
mDIBitmap->line(Point(xPos,yPos),Point(mDIBitmap->width()-marginRight,yPos),TabLineColor);
yPos+=spacing;
}
mDIBitmap->line(Point(mDIBitmap->width()-marginRight,yStart),Point(mDIBitmap->width()-marginRight,1+yStart+((lineCount-1)*spacing)),TabLineColor);
mDIBitmap->line(Point(mDIBitmap->width()-marginRight,yStart),Point((mDIBitmap->width()-marginRight)+2,yStart),TabLineColor);
mDIBitmap->line(Point(mDIBitmap->width()-marginRight,yStart+((lineCount-1)*spacing)),Point((mDIBitmap->width()-marginRight)+2,yStart+((lineCount-1)*spacing)),TabLineColor);
mDIBitmap->line(Point((mDIBitmap->width()-marginRight)+2,yStart),Point((mDIBitmap->width()-marginRight)+2,1+yStart+((lineCount-1)*spacing)),TabLineColor);
return yStart+((lineCount-1)*spacing);
}
int TabPage::getDimensions(GUIWindow &guiWindow,GDIPoint &gdiPoint)
{
PureDevice pureDevice(guiWindow);
setCharWidth(getWidestEntry(pureDevice));
gdiPoint=GDIPoint();
GlobalDefs::outDebug(String("[TabPage::getDimensions]"),GlobalDefs::Debug);
setItemsPerTab(((guiWindow.width())-(RightMargin+LeftMargin))/getCharWidth());
setNumTabs((mTabEntries.size()/getItemsPerTab()));
setNumTabs(getNumTabs()+(mTabEntries.size()%getItemsPerTab()?1:0));
if(!getNumTabs())gdiPoint.y(TopMargin+((TabHeight+TabSeparator)));
else gdiPoint.y(TopMargin+(getNumTabs()*(TabHeight+TabSeparator)));
gdiPoint.x(guiWindow.width());
GlobalDefs::outDebug(String("[TabPage::getDimensions]ItemsPerTab:")+String().fromInt(getItemsPerTab()));
GlobalDefs::outDebug(String("[TabPage::getDimensions]NumTabs:")+String().fromInt(getNumTabs()));
GlobalDefs::outDebug(String("[TabPage::getDimensions]AvgCharWidth:")+String().fromInt(getCharWidth()));
GlobalDefs::outDebug(String("[TabPage::getDimensions]BmWidth:")+String().fromInt(gdiPoint.x()));
GlobalDefs::outDebug(String("[TabPage::getDimensions]BmHeight:")+String().fromInt(gdiPoint.y()));
return getNumTabs();
}
int TabPage::getWidestEntry(PureDevice &pureDevice)const
{
String string;
int widestEntry;
SIZE sizeStruct;
GlobalDefs::outDebug(String("[TabPage::getWidestEntry]"),GlobalDefs::Debug);
if(!mTabEntries.size())return MinCharWidth;
widestEntry=0;
for(int entryIndex=0;entryIndex<mTabEntries.size();entryIndex++)
{
TabEntry &entry=((TabEntries&)mTabEntries)[entryIndex];
for(int index=0;index<entry.size();index++)
{
const FrettedNote &frettedNote=((TabEntry&)entry)[index];
string=String().fromInt(frettedNote.getFret());
getEntryExtents(pureDevice,sizeStruct,string);
if(sizeStruct.cx>widestEntry)widestEntry=sizeStruct.cx;
}
}
return widestEntry*2;
}
void TabPage::bitBlt(PureDevice &pureDevice,const Rect &dstRect,const Point &srcPoint)
{
GlobalDefs::outDebug(String("[TabPage::bitBlt]"),GlobalDefs::Debug);
if(!mDIBitmap.isOkay())return;
mDIBitmap->usePalette(pureDevice,true); // the usePalette code can be removed...
mDIBitmap->bitBlt(pureDevice,dstRect,srcPoint); // but needs test on Win '98 first
mDIBitmap->usePalette(pureDevice,false);
}
void TabPage::invalidate(Rect rect)
{
GlobalDefs::outDebug(String("[TabPage::invalidate]"),GlobalDefs::Debug);
rect.left(rect.left()-mScrollInfo.currScrollx());
rect.top(rect.top()-mScrollInfo.currScrolly());
rect.right(rect.right()-mScrollInfo.currScrollx());
rect.bottom(rect.bottom()-mScrollInfo.currScrollx());
mParent->invalidate(rect,false);
}
void TabPage::bringOutlineIntoView(const Rect &outlineRect,const Rect &clientRect)
{
GlobalDefs::outDebug(String("[TabPage::bringOutlineIntoView]"),GlobalDefs::Debug);
if(outlineRect.bottom()+TabClearance>mScrollInfo.currScrolly()+clientRect.bottom())
{
while(outlineRect.bottom()+TabClearance>mScrollInfo.currScrolly()+clientRect.bottom())
{
if(!mScrollInfo.pageDown())break;
}
}
else if(outlineRect.top()<mScrollInfo.currScrolly()+clientRect.top())
{
while((outlineRect.top()<mScrollInfo.currScrolly()+clientRect.top()))
{
if(!mScrollInfo.pageUp())break;
}
}
}
bool TabPage::modifyProperties(void)
{
TabDialog tabDialog;
POINT cursorPoint;
GlobalDefs::outDebug(String("[TabPage::modifyProperties]"),GlobalDefs::Debug);
if(!isInOutline()||isInPlay())return false;
::GetCursorPos(&cursorPoint);
GDIPoint mousePoint(cursorPoint.x,cursorPoint.y);
TabEntry &entry=mTabEntries[mCurrEntryIndex];
keepOutline(true);
if(tabDialog.perform(*mParent,mTabEntries,mCurrEntryIndex))isDirty(true);
keepOutline(false);
::SetCursorPos(mousePoint.x(),mousePoint.y());
return true;
}
bool TabPage::increaseTempo(void)
{
GlobalDefs::outDebug(String("[TabPage::increaseTempo]"),GlobalDefs::Debug);
for(int index=0;index<mTabEntries.size();index++)
{
TabEntry &entry=mTabEntries[index];
NoteType noteType=entry.getNoteType();
noteType++;
entry.setNoteType(noteType);
}
isDirty(true);
return true;
}
bool TabPage::decreaseTempo(void)
{
GlobalDefs::outDebug(String("[TabPage::decreaseTempo]"),GlobalDefs::Debug);
for(int index=0;index<mTabEntries.size();index++)
{
TabEntry &entry=mTabEntries[index];
NoteType noteType=entry.getNoteType();
noteType--;
entry.setNoteType(noteType);
}
isDirty(true);
return true;
}
bool TabPage::playRange(int rangeIndex)
{
Rect outlineRect;
Rect clientRect;
GlobalDefs::outDebug(String("[TabPage::playRange]"),GlobalDefs::Debug);
setCancelled(false);
isInPlay(true);
const Range &range=mTabRanges[rangeIndex];
for(int index=range.getBeginRange();index<=range.getEndRange();index++)
{
if(getCancelled())break;
while(isPaused())::Sleep(250);
TabEntry &tabEntry=mTabEntries[index];
mParent->clientRect(clientRect);
getOutlineRect(index,outlineRect);
this->outlineRect(outlineRect);
bringOutlineIntoView(outlineRect,clientRect);
showFretEntry(tabEntry);
tabEntry.play(mMIDIDevice->getDevice());
mMIDIDevice->clearNotes();
}
isInPlay(false);
clearUpdate();
return true;
}
bool TabPage::play(void)
{
Rect outlineRect;
Rect clientRect;
GlobalDefs::outDebug(String("[TabPage::play]"),GlobalDefs::Debug);
setCancelled(false);
isInPlay(true);
for(int index=0;index<mTabEntries.size();index++)
{
if(getCancelled())break;
while(isPaused())::Sleep(250);
TabEntry &tabEntry=mTabEntries[index];
mParent->clientRect(clientRect);
getOutlineRect(index,outlineRect);
this->outlineRect(outlineRect);
bringOutlineIntoView(outlineRect,clientRect);
showFretEntry(tabEntry);
tabEntry.play(mMIDIDevice->getDevice());
mMIDIDevice->clearNotes();
}
isInPlay(false);
clearUpdate();
return true;
}
bool TabPage::playFromCurrent(void)
{
Rect outlineRect;
Rect clientRect;
GlobalDefs::outDebug(String("[TabPage::playFromCurrent]"),GlobalDefs::Debug);
setCancelled(false);
isInPlay(true);
for(int index=mCurrEntryIndex;index<mTabEntries.size();index++)
{
if(getCancelled())break;
while(isPaused())::Sleep(250);
TabEntry &tabEntry=mTabEntries[index];
mParent->clientRect(clientRect);
getOutlineRect(index,outlineRect);
this->outlineRect(outlineRect);
bringOutlineIntoView(outlineRect,clientRect);
showFretEntry(tabEntry);
tabEntry.play(mMIDIDevice->getDevice());
mMIDIDevice->clearNotes();
}
isInPlay(false);
clearUpdate();
return true;
}
void TabPage::showFretEntry(const TabEntry &entry)
{
GlobalDefs::outDebug(String("[TabPage::showFretEntry]"),GlobalDefs::Debug);
if(!mPlayNoteHandler.isOkay())return;
CallbackData cbData(0,(DWORD)&entry);
mPlayNoteHandler.callback(cbData);
}
void TabPage::setStartRange(void)
{
GlobalDefs::outDebug(String("[TabPage::setStartRange]"),GlobalDefs::Debug);
isInSetRange(true);
mCurrRange.setBeginRange(mCurrEntryIndex);
}
void TabPage::setEndRange(void)
{
GlobalDefs::outDebug(String("[TabPage::setEndRange]"),GlobalDefs::Debug);
isInSetRange(false);
mCurrRange.setEndRange(mCurrEntryIndex);
mCurrRange.autoName();
mTabRanges.insert(&mCurrRange);
isDirty(true);
GlobalDefs::outDebug(mCurrRange.toString());
}
void TabPage::cut(void)
{
Clipboard clipboard(*mParent);
String strHeader;
VersionInfo versionInfo;
GlobalDefs::outDebug(String("[TabPage::cut]"),GlobalDefs::Debug);
if(isInPlay())return;
if(mCurrEntryIndex<0||mCurrEntryIndex>=mTabEntries.size())return;
TabEntry &entry=mTabEntries[mCurrEntryIndex];
strHeader=String("[")+versionInfo.getProductNameString()+String(",")+versionInfo.getProductVersion()+String("]");
clipboard.setClipboard(GlobalDefs::getRegisteredClipboardFormat(),strHeader+entry.toString());
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex--;
isDirty(true);
update(*mParent);
mParent->invalidate(true);
mParent->update();
mParent->enablePaste(true);
if(!mTabEntries.size())mParent->enableCut(false);
showCurrent();
}
void TabPage::copy(void)
{
Clipboard clipboard(*mParent);
String strHeader;
VersionInfo versionInfo;
GlobalDefs::outDebug(String("[TabPage::copy]"),GlobalDefs::Debug);
if(isInPlay())return;
if(mCurrEntryIndex<0||mCurrEntryIndex>=mTabEntries.size())return;
TabEntry &entry=mTabEntries[mCurrEntryIndex];
strHeader=String("[")+versionInfo.getProductNameString()+String(",")+versionInfo.getProductVersion()+String("]");
clipboard.setClipboard(GlobalDefs::getRegisteredClipboardFormat(),strHeader+entry.toString());
mParent->enablePaste(true);
}
bool TabPage::paste(void)
{
Clipboard clipboard(*mParent);
String strText;
String strHeader;
TabEntry entry;
VersionInfo versionInfo;
GlobalDefs::outDebug(String("[TabPage::paste] Current position is ")+String().fromInt(mCurrEntryIndex),GlobalDefs::Debug);
clipboard.getClipboard(GlobalDefs::getRegisteredClipboardFormat(),strText);
if(strText.isNull())return false;
GlobalDefs::outDebug(strText);
strHeader=strText.betweenString('[',']');
if(strHeader.isNull())return false;
if(!(versionInfo.getProductNameString()==strHeader.betweenString(0,',')))return false;
if(!(versionInfo.getProductVersion()==strHeader.betweenString(',',0)))return false;
entry.fromString(strText.betweenString(']',0));
if(!mTabEntries.size())
{
mTabEntries.insert(&entry);
mCurrEntryIndex=0;
}
else mTabEntries.insertAfter(mCurrEntryIndex,&entry);
isDirty(true);
update(*mParent);
mParent->invalidate(true);
mParent->update();
showCurrent();
return true;
}
// *********************************************************************************************
// callback handlers
CallbackData::ReturnType TabPage::sizeHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::sizeHandler]ENTER",GlobalDefs::Verbose);
if(isInPlay())
{
GlobalDefs::outDebug("[TabPage::sizeHandler]Pausing play...",GlobalDefs::Debug);
isPaused(true);
}
Point sizePoint(someCallbackData.loWord(),someCallbackData.hiWord());
if(!sizePoint.x()||!sizePoint.y())
{
if(isInPlay())isPaused(false);
return false;
}
clearUpdate();
if(!update(*mParent))
{
GlobalDefs::outDebug("[TabPage::sizeHandler]Resuming play",GlobalDefs::Debug);
if(isInPlay())isPaused(false);
return false;
}
if(!mDIBitmap.isOkay())
{
GlobalDefs::outDebug("[TabPage::sizeHandler]Resuming play",GlobalDefs::Debug);
if(isInPlay())isPaused(false);
return false;
}
if(isInPlay())isPaused(false);
GlobalDefs::outDebug("[TabPage::sizeHandler]LEAVE",GlobalDefs::Verbose);
return false;
}
CallbackData::ReturnType TabPage::paintHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::paintHandler]",GlobalDefs::Verbose);
PaintInformation &paintInfo=*((PaintInformation*)someCallbackData.lParam());
PureDevice &paintDevice=(PureDevice&)paintInfo;
if(!mDIBitmap.isOkay())return false;
if(mScrollInfo.sizeEvent())
{
mScrollInfo.sizeEvent(FALSE);
bitBlt(paintDevice,Rect(0,0,getWidth(),getHeight()),Point(mScrollInfo.currScrollx(),mScrollInfo.currScrolly()));
}
if(mScrollInfo.scrollEvent()||(!mScrollInfo.sizeEvent()&&!mScrollInfo.scrollEvent()))
{
Rect paintRect(paintInfo.paintRect());
mScrollInfo.scrollEvent(FALSE);
paintRect.right(paintRect.right()-paintRect.left());
paintRect.bottom((paintRect.bottom()-paintRect.top()));
bitBlt(paintDevice,paintRect,Point(paintRect.left()+mScrollInfo.currScrollx(),paintRect.top()+mScrollInfo.currScrolly()));
}
return false;
}
CallbackData::ReturnType TabPage::verticalScrollHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::verticalScrollHandler]",GlobalDefs::Verbose);
mScrollInfo.handleVerticalScroll(someCallbackData);
return false;
}
CallbackData::ReturnType TabPage::horizontalScrollHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::horizontalScrollHandler]",GlobalDefs::Verbose);
mScrollInfo.handleHorizontalScroll(someCallbackData);
return false;
}
CallbackData::ReturnType TabPage::leftButtonDoubleHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::leftButtonDoubleHandler]",GlobalDefs::Verbose);
return false;
}
CallbackData::ReturnType TabPage::leftButtonDownHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::leftButtonDownHandler]",GlobalDefs::Verbose);
if(isInPlay())setCancelled(true);
Point mousePoint;
int selectedString;
Rect outlineRect;
int entryIndex;
mousePoint.x(someCallbackData.loWord()+mScrollInfo.currScrollx());
mousePoint.y(someCallbackData.hiWord()+mScrollInfo.currScrolly());
if(!getOutlineRect(mousePoint,entryIndex,outlineRect))return false;
if(!getNearestString(mousePoint,selectedString))return false;
getFretEntry(selectedString);
return false;
}
bool TabPage::getFretEntry(int selectedString)
{
FretDialog fretDialog;
bool returnCode=false;
keepOutline(true);
if((returnCode=fretDialog.perform(*mParent,mTabEntries,selectedString,mCurrEntryIndex)))
{
if(!mTabEntries[mCurrEntryIndex].size())
{
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex--;
}
isDirty(true);
update(*mParent);
mParent->invalidate(true);
mParent->update();
showCurrent();
}
keepOutline(false);
return returnCode;
}
CallbackData::ReturnType TabPage::leftButtonUpHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::leftButtonUpHandler]",GlobalDefs::Verbose);
return false;
}
CallbackData::ReturnType TabPage::setFocusHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::setFocusHandler]",GlobalDefs::Verbose);
hasFocus(true);
if(Clipboard::hasData(GlobalDefs::getRegisteredClipboardFormat()))mParent->enablePaste(true);
else mParent->enablePaste(false);
if(!mMIDIDevice.isOkay())mMIDIDevice=::new Sequencer();
if(!mMIDIDevice->hasDevice()&&!mMIDIDevice->openDevice())return false;
if(isInPlay())isPaused(false);
// showCurrent(); // smk
// mParent->setCapture();
return false;
}
CallbackData::ReturnType TabPage::killFocusHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("[TabPage::killFocusHandler]",GlobalDefs::Verbose);
hasFocus(false);
if(isInPlay())isPaused(true);
if(!mMIDIDevice.isOkay()||!mMIDIDevice->hasDevice())return false;
mMIDIDevice->closeDevice();
if(isInOutline()&&!keepOutline())
{
isInOutline(false);
clearUpdate();
}
mParent->releaseCapture();
return false;
}
CallbackData::ReturnType TabPage::mouseMoveHandler(CallbackData &someCallbackData)
{
int entryIndex;
Rect outlineRect;
Rect clientRect;
GlobalDefs::outDebug("[TabPage::mouseMoveHandler]",GlobalDefs::Verbose);
if(isInPlay())return false;
// user is free-playing
Point mousePoint(someCallbackData.loWord(),someCallbackData.hiWord());
mParent->clientRect(clientRect);
if(!clientRect.ptInRect(mousePoint)) // user glides off the tab window
{
mParent->releaseCapture();
if(isInOutline()) // are we in an outline??
{
clearUpdate(); // if so, clear the outline rectangle
isInOutline(false); // we're no longer outlining
}
return false; // return
}
if(!hasFocus()) // we're within the window, but we don't have focus
{
if(isInOutline()) // are we outlining a rectangle??
{
clearUpdate(); // if so, clear the update
isInOutline(false); // we're no longer outlining
}
return false; // we're done with this mouse movement
}
mousePoint.x(mousePoint.x()+mScrollInfo.currScrollx());
mousePoint.y(mousePoint.y()+mScrollInfo.currScrolly());
if(getOutlineRect(mousePoint,entryIndex,outlineRect))
{
isInOutline(true);
mParent->enableCut(true);
mParent->enableCopy(true);
mCurrEntryIndex=entryIndex;
bringOutlineIntoView(outlineRect,clientRect);
if(this->outlineRect(outlineRect))
{
TabEntry &entry=mTabEntries[entryIndex];
showFretEntry(entry);
entry.play(mMIDIDevice->getDevice(),false);
}
}
else if(isInOutline())
{
isInOutline(false);
clearUpdate();
// mCurrEntryIndex=-1; smk
}
return false;
}
CallbackData::ReturnType TabPage::keyDownHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("TabPage::keyDownHandler");
KeyData keyData(someCallbackData);
if(keyData.controlKeyPressed()&&Home==keyData.virtualKey())
{
clearUpdate();
mCurrEntryIndex=0;
showCurrent();
}
else if(keyData.controlKeyPressed()&&End==keyData.virtualKey())
{
clearUpdate();
mCurrEntryIndex=mTabEntries.size()-1;
showCurrent();
}
else if(RightArrow==keyData.virtualKey())
{
if(mCurrEntryIndex+1<mTabEntries.size())
{
mCurrEntryIndex++;
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else ::MessageBeep(0);
}
else if(LeftArrow==keyData.virtualKey())
{
if(mCurrEntryIndex-1>=0)
{
mCurrEntryIndex--;
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else ::MessageBeep(0);
}
else if(DownArrow==keyData.virtualKey())
{
if(mCurrEntryIndex+mItemsPerTab+1>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
else mCurrEntryIndex+=(mItemsPerTab+1);
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else if(UpArrow==keyData.virtualKey())
{
if(mCurrEntryIndex-(mItemsPerTab+1)<0)mCurrEntryIndex=0;
else mCurrEntryIndex-=(mItemsPerTab+1);
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else if(!keyData.shiftKeyPressed()&&Delete==keyData.virtualKey())
{
cut();
}
else if(!keyData.shiftKeyPressed()&&Insert==keyData.virtualKey()) // insert after current position
{
Rect outlineRect;
TabEntry entry;
GDIPoint cursorPos;
clearUpdate();
if(!mTabEntries.size())
{
mTabEntries.insert(&entry);
mCurrEntryIndex=0;
}
else
{
mTabEntries.insertAfter(mCurrEntryIndex,&entry);
mCurrEntryIndex++;
}
if(!getFretEntry())
{
mTabEntries.remove(mCurrEntryIndex);
mCurrEntryIndex--;
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
cursorPos.y(outlineRect.top());
::SetCursorPos(cursorPos.x(),cursorPos.y());
clearUpdate();
showCurrent();
}
return false;
}