443 lines
13 KiB
C++
443 lines
13 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#pragma hdrstop
|
|
|
|
#include "ListViewPattern.h"
|
|
#include "GlobalUnit.h"
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
//---------------------------------------------------------------------------
|
|
#define LP_ITEM_OVER RGB(67, 73, 80)
|
|
#define LP_ITEM_SELECTED RGB(0, 0, 0)
|
|
#define LP_ITEM_DEF RGB(39, 42, 47)
|
|
#define CELL_HEIGHT 18
|
|
|
|
#define LINE_COLOR RGB(123, 123, 123)
|
|
#define FontClolor TColor(0xBDAA9C)
|
|
|
|
const BYTE u_arrChordPreset[2][4][4] = { //预设和弦
|
|
{{0,37,9,30},{0,37,20,28},{0,9,20,28},{0,17,37,30}},
|
|
{{37,9,28,16},{37,17,20,28},{37,0,9,17},{37,28,20,16}} };
|
|
|
|
TPngImage *pngCol = NULL;
|
|
TPngImage *pngUnCol = NULL;
|
|
TPngImage *pngCharge = NULL;
|
|
void LoadImg()
|
|
{
|
|
if( !pngCol ) pngCol = new TPngImage();
|
|
if( !pngUnCol ) pngUnCol = new TPngImage();
|
|
if( !pngCharge ) pngCharge = new TPngImage();
|
|
|
|
pngCol->LoadFromResourceName(int(HInstance), L"imgCollect");
|
|
pngUnCol->LoadFromResourceName(int(HInstance), L"imgUnCollect");
|
|
pngCharge->LoadFromResourceName(int(HInstance), L"imgStyleCharge");
|
|
}
|
|
void ReleaseImg()
|
|
{
|
|
SAFE_DELETE(pngCol);
|
|
SAFE_DELETE(pngUnCol);
|
|
SAFE_DELETE(pngCharge);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TListViewPattern::TListViewPattern(TComponent* Owner, bool bChan9,
|
|
TStageList* lstStages, int iPlayBar)
|
|
: TListViewBase( Owner )
|
|
{
|
|
m_nPlayIndex = -1;
|
|
m_iFont = -1;
|
|
m_iProg = -1;
|
|
m_pPtInfo = NULL;
|
|
|
|
m_bChan9 = bChan9;
|
|
m_iPlayBar = iPlayBar;
|
|
m_lstStages = lstStages;
|
|
FOnTextureChanged = NULL;
|
|
|
|
ShowHint = true;
|
|
m_btnHint = NULL;
|
|
|
|
LoadImg();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TListViewPattern::~TListViewPattern()
|
|
{
|
|
ReleaseImg();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListViewPattern::DoCellHgt(TTableView *Sender, int iCellIndex)
|
|
{
|
|
return CELL_HEIGHT;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListViewPattern::DoMDNum(TTableView *Sender)
|
|
{
|
|
NULL_RETURN0(m_LstParttern)
|
|
return m_LstParttern->size();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListViewPattern::DoCellData(TStateBtn *sender)
|
|
{
|
|
NULL_RETURN0(m_LstParttern)
|
|
sender->SetData((void *)((*m_LstParttern)[sender->Index]));
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListViewPattern::DoCellDraw(TStateBtn *sender, int BsTmp, TRect rtTmp, TCanvas *pCanvas)
|
|
{
|
|
TStateBtn *pBtn = (TStateBtn *)sender;
|
|
TTextureInfo *pPtInfo = (TTextureInfo*)pBtn->m_Data;
|
|
|
|
if( Bs_NORMAL==BsTmp ) {
|
|
pCanvas->Brush->Color = LP_ITEM_DEF;
|
|
}else if( Bs_ENTER==BsTmp ){
|
|
pCanvas->Brush->Color = LP_ITEM_OVER;
|
|
}else if( Bs_DOWN==BsTmp ){
|
|
pCanvas->Brush->Color = LP_ITEM_SELECTED;
|
|
}
|
|
|
|
if( BsTmp==Bs_NORMAL || BsTmp==Bs_ENTER || BsTmp==Bs_DOWN ) {
|
|
pCanvas->FillRect(rtTmp);
|
|
|
|
int iLeft, iTop;
|
|
TSize sizeFont;
|
|
String strText;
|
|
|
|
pCanvas->Brush->Style = bsClear;
|
|
pCanvas->Font->Color = GetSegmentColor( pPtInfo->segType, 0, false );
|
|
|
|
//绘制乐器
|
|
if( !m_bChan9 ) strText = GM_INSTRUMENT[pPtInfo->prog];
|
|
else strText = L"GM鼓";
|
|
sizeFont = pCanvas->TextExtent( strText );
|
|
iLeft = LEFT_CAPTION+(WIDTH_PROG(Width)-sizeFont.Width)/2;
|
|
iTop = rtTmp.Top+(rtTmp.Height()-sizeFont.Height)/2;
|
|
pCanvas->TextOutW(iLeft, iTop, strText);
|
|
pCanvas->Pen->Color = LINE_COLOR;
|
|
pCanvas->MoveTo( LEFT_CAPTION+WIDTH_PROG(Width)+WIDTH_LINE/2 , rtTmp.Top);
|
|
pCanvas->LineTo( LEFT_CAPTION+WIDTH_PROG(Width)+WIDTH_LINE/2, rtTmp.Bottom);
|
|
|
|
String oriFontName = pCanvas->Font->Name;
|
|
pCanvas->Font->Name = "Times New Roman";
|
|
|
|
//绘制风格id号
|
|
char styleID[256];
|
|
if( pPtInfo->idLoc==0 )
|
|
sprintf(styleID, "[%d]", pPtInfo->idStyle);
|
|
else if( pPtInfo->idLoc==1 )
|
|
sprintf(styleID, "[S%d]", pPtInfo->idStyle);
|
|
else if( pPtInfo->idLoc!=(UINT)-1 )
|
|
sprintf( styleID, "[L%d] ", LOWORD(pPtInfo->idStyle) );
|
|
|
|
iLeft = LEFT_STYLE(Width);
|
|
strText = styleID;
|
|
sizeFont = pCanvas->TextExtent( strText );
|
|
iLeft = LEFT_STYLE(Width)+(WIDTH_STYLE(Width)-sizeFont.Width)/2;
|
|
iTop = rtTmp.Top+(rtTmp.Height()-sizeFont.Height)/2;
|
|
pCanvas->TextOutW(iLeft, iTop, strText);
|
|
|
|
pCanvas->Pen->Color = LINE_COLOR;
|
|
pCanvas->MoveTo( LEFT_STYLE(Width)+WIDTH_STYLE(Width)+WIDTH_LINE/2 , rtTmp.Top);
|
|
pCanvas->LineTo( LEFT_STYLE(Width)+WIDTH_STYLE(Width)+WIDTH_LINE/2 , rtTmp.Bottom);
|
|
|
|
//绘制伴奏类型
|
|
char segName[256];
|
|
sprintf(segName, "[%s-%d]", NAME_SEG[pPtInfo->segType], pPtInfo->segNo+1);
|
|
strText = segName;
|
|
sizeFont = pCanvas->TextExtent( strText );
|
|
iLeft = LEFT_SEG(Width)+(WIDTH_SEG(Width)-sizeFont.Width)/2;
|
|
iTop = rtTmp.Top+(rtTmp.Height()-sizeFont.Height)/2;
|
|
|
|
pCanvas->TextOutW(iLeft, iTop, strText);
|
|
|
|
pCanvas->Pen->Color = LINE_COLOR;
|
|
pCanvas->MoveTo( LEFT_SEG(Width)+WIDTH_SEG(Width)+WIDTH_LINE/2 , rtTmp.Top);
|
|
pCanvas->LineTo( LEFT_SEG(Width)+WIDTH_SEG(Width)+WIDTH_LINE/2 , rtTmp.Bottom);
|
|
|
|
pCanvas->Font->Name = oriFontName;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListViewPattern::DoIconDraw(TStateBtn *sender, int BsTmp, TRect rtTmp, TCanvas *pCanvas)
|
|
{
|
|
TStateBtn *pBtn = (TStateBtn *)sender;
|
|
TStateBtn *pCell = pBtn->m_PAR;
|
|
TTextureInfo *info = (TTextureInfo*)pCell->m_Data;
|
|
TPngImage *pIMG = NULL;
|
|
String sHint;
|
|
|
|
if(sender->Index==0) {
|
|
pIMG = info->bCollected?pngCol:pngUnCol;
|
|
if(BsTmp==Bs_ENTER ) {
|
|
sHint = info->bCollected ? "点击取消收藏" : "点击收藏";
|
|
}
|
|
}
|
|
else if(sender->Index==1) {
|
|
TPROSTYLE* styleInfo = GetStyleInfo( info->idLoc, info->idStyle );
|
|
if( styleInfo && styleInfo->idLoc==0 && styleInfo->pOrigin->cost>0 ) {
|
|
pIMG = pngCharge;
|
|
if(BsTmp==Bs_ENTER ) {
|
|
sHint = "收费:";
|
|
sHint += IntToStr( styleInfo->pOrigin->cost );
|
|
sHint += "唱作音符";
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pIMG ) {
|
|
int iWidth = pIMG->Width/3;
|
|
int nTrans = BsTmp==Bs_NORMAL ? 0
|
|
: BsTmp==Bs_ENTER ? (-iWidth)
|
|
: BsTmp==Bs_DOWN ? (-2*iWidth)
|
|
: (-3*iWidth);
|
|
|
|
if( Bs_NORMAL==BsTmp || Bs_ENTER==BsTmp || Bs_DOWN==BsTmp ) {
|
|
HRGN rgnClip = CreateRectRgn( rtTmp.Left, rtTmp.Top,
|
|
rtTmp.Left+rtTmp.Width(), rtTmp.Top+rtTmp.Height() );
|
|
|
|
SelectClipRgn( pCanvas->Handle, rgnClip );
|
|
pCanvas->Draw(rtTmp.Left+nTrans, rtTmp.Top, pIMG);
|
|
SelectClipRgn( pCanvas->Handle, NULL );
|
|
DeleteObject(rgnClip);
|
|
}
|
|
}
|
|
|
|
if( sHint.Length() ){
|
|
m_btnHint = sender;
|
|
Hint = sHint;
|
|
}
|
|
else if(m_btnHint==sender ){
|
|
m_btnHint = NULL;
|
|
Hint = "";
|
|
Application->CancelHint();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListViewPattern::DoIconsNum(TStateBtn *parent)
|
|
{
|
|
return 2;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListViewPattern::DoIconsBounds(TStateBtn *sender, TRect &rtBounds)
|
|
{
|
|
int iLeft, iTop, iWidth, iHeight;
|
|
|
|
if(sender->Index==0) {
|
|
|
|
iLeft = Width - WIDTH_SB - WIDTH_IMG_COL;
|
|
iTop = (CELL_HEIGHT - 15) / 2;
|
|
iWidth = 21;
|
|
iHeight = 15;
|
|
}
|
|
else if(sender->Index==1) {
|
|
|
|
iLeft = LEFT_SEG(Width) - WIDTH_IMG_CHARGE - 1;
|
|
iTop = (CELL_HEIGHT - pngCharge->Height)/2;
|
|
iWidth = pngCharge->Width/3;
|
|
iHeight = pngCharge->Height;
|
|
}
|
|
|
|
rtBounds = TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListViewPattern::DoCellLClick(TStateBtn *sender)
|
|
{
|
|
TStateBtn *pBtn = (TStateBtn *)sender;
|
|
|
|
if( m_pPtInfo!=(TTextureInfo*)pBtn->m_Data ){
|
|
if( m_nPlayIndex!=this->IndSel )
|
|
f_MM_Stop();
|
|
|
|
m_pPtInfo = (TTextureInfo *)pBtn->m_Data;
|
|
|
|
if( FOnTextureChanged )
|
|
FOnTextureChanged((TObject*)m_pPtInfo);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListViewPattern::DoCellDBClick(TStateBtn *sender)
|
|
{
|
|
TTextureInfo *pPtInfo = NULL;
|
|
|
|
if( sender ) {
|
|
TStateBtn *pBtn = (TStateBtn *)sender;
|
|
pPtInfo = (TTextureInfo*)pBtn->m_Data;
|
|
m_nPlayIndex = pBtn->Index;
|
|
}
|
|
else {
|
|
pPtInfo = m_pPtInfo;
|
|
}
|
|
|
|
if( pPtInfo ){
|
|
TPROSTYLE* info = GetStyleInfo( pPtInfo->idLoc, pPtInfo->idStyle );
|
|
if( !info )
|
|
return;
|
|
|
|
int stype = pPtInfo->segType,
|
|
sno = pPtInfo->segNo,
|
|
iChno = -1,
|
|
nStageNum = m_lstStages ? m_lstStages->size() : 1,
|
|
nBarCount = 0,
|
|
iPlayBar = m_iPlayBar,
|
|
iFBar = -1;
|
|
|
|
TStage* aStages = new TStage[nStageNum];
|
|
|
|
for( int i=0; i<nStageNum; i++ ){
|
|
TStage* pStage = &aStages[i];
|
|
|
|
if( m_lstStages ){
|
|
TStage* pTemp = (*m_lstStages)[i];
|
|
memcpy( pStage, pTemp, sizeof(TStage) );
|
|
|
|
if( pTemp->aChords ){
|
|
pStage->aChords = new TBarChords[pTemp->nBarNum];
|
|
memcpy( pStage->aChords, pTemp->aChords, sizeof(TBarChords)*pTemp->nBarNum );
|
|
}
|
|
}
|
|
else{
|
|
int seed = time(NULL);
|
|
int barNum = 4;
|
|
if( stype>=SEGTYPE_INTRO ){
|
|
if( info->idLoc==0 ) {
|
|
if( stype==SEGTYPE_INTRO )
|
|
barNum = info->pOrigin->detail.aIntroBars[sno];
|
|
else
|
|
barNum = info->pOrigin->detail.aEndingBars[sno];
|
|
}
|
|
else if( info->idLoc==1 )
|
|
barNum = info->pShare->aIEBars[stype][sno];
|
|
else
|
|
barNum = info->pLocal->aIEBars[stype][sno];
|
|
}
|
|
|
|
pStage->nBarNum = barNum;
|
|
|
|
int key = g_iMelodyKey;
|
|
if( key<0 || key>11 )
|
|
key = seed % 12;
|
|
|
|
pStage->iSegKey = key;
|
|
pStage->iSegType = stype;
|
|
|
|
char cType = (seed>>1) % 2;
|
|
int iPreset = (seed>>2) % 4;
|
|
|
|
aStages->aChords = new TBarChords[barNum];
|
|
for( int j=0; j<barNum; j++ ){
|
|
char chordType = u_arrChordPreset[cType][iPreset][j] % 4;
|
|
char chordKey = u_arrChordPreset[cType][iPreset][j] / 4;
|
|
|
|
aStages->aChords[j].iKey[0]
|
|
= aStages->aChords[j].iKey[1]
|
|
= aStages->aChords[j].iKey[2]
|
|
= aStages->aChords[j].iKey[3] = chordKey;
|
|
aStages->aChords[j].iType[0]
|
|
= aStages->aChords[j].iType[1]
|
|
= aStages->aChords[j].iType[2]
|
|
= aStages->aChords[j].iType[3] = chordType;
|
|
}
|
|
}
|
|
|
|
if( pStage->iSegType==stype ){
|
|
pStage->nTrkNum = 1;
|
|
pStage->aTracks = new TComposeTrack;
|
|
|
|
TComposeTrack* pTrack = pStage->aTracks;
|
|
|
|
pTrack->iProg = pPtInfo->prog;
|
|
pTrack->nVol = pPtInfo->vol;
|
|
|
|
if( info->idLoc==0 ){
|
|
pTrack->iStyleLoc = 0;
|
|
pTrack->iStyleId = info->idStyle;
|
|
pTrack->iSegNo = sno;
|
|
iChno = pTrack->iChanSpec = pTrack->iChanNo
|
|
= info->pOrigin->detail.tracks[stype][sno][pPtInfo->chNo].no;
|
|
}
|
|
else if( info->idLoc==1 ){
|
|
TSTYLESHARE* pShare = info->pShare;
|
|
TSHARETRACKREF& rRef = pShare->trkRef[stype][sno][pPtInfo->chNo];
|
|
|
|
pTrack->iStyleLoc = 0;
|
|
pTrack->iStyleId = rRef.idStyle;
|
|
pTrack->iSegNo = rRef.segNo;
|
|
iChno = pTrack->iChanSpec = pTrack->iChanNo = rRef.chan;
|
|
}
|
|
else{
|
|
TSTYLELOCAL* pLocal = info->pLocal;
|
|
TTRACKREF& rRef = pLocal->trkRef[stype][sno][pPtInfo->chNo];
|
|
pTrack->iStyleLoc = rRef.idLoc;
|
|
pTrack->iStyleId = rRef.idStyle;
|
|
pTrack->iSegNo = rRef.segNo;
|
|
iChno = pTrack->iChanSpec = pTrack->iChanNo = rRef.chan;
|
|
}
|
|
|
|
if( iFBar<0 )
|
|
iFBar = nBarCount;
|
|
}
|
|
|
|
nBarCount += pStage->nBarNum;
|
|
}
|
|
|
|
if( iPlayBar>=0 && iFBar>iPlayBar )
|
|
iPlayBar = iFBar;
|
|
|
|
int len = 1000000;
|
|
BYTE* data = new BYTE[len];
|
|
HRESULT ret = f_CM_Compose( &len, data, g_iMelodyTimeSignature, g_nMelodyTempo,
|
|
nStageNum, aStages, false, NULL, NULL );
|
|
|
|
if( ret==0 ){
|
|
f_MM_LoadDemo( data, len );
|
|
char* strFile = m_iFont==0xFF ? NULL : m_iFont<0x80 ? g_lstFonts[m_iFont]->strFileName
|
|
: g_lstVSTi[m_iFont-0x80]->strFileName;
|
|
f_MM_PlayDemo( NULL, iPlayBar, -1, m_iProg, m_iFont, strFile );
|
|
}
|
|
else
|
|
DebugPrint( "Compose error: %d", ret );
|
|
|
|
delete[] data;
|
|
|
|
SAFE_DELETE_ARRAY(aStages);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListViewPattern::DoIconLClick(TStateBtn *sender)
|
|
{
|
|
if(sender->Index==0) {
|
|
|
|
TStateBtn *pBtn = (TStateBtn *)sender;
|
|
TStateBtn *pCell = pBtn->m_PAR;
|
|
TTextureInfo *pPtInfo = (TTextureInfo *)pCell->m_Data;
|
|
pPtInfo->bCollected = !pPtInfo->bCollected;
|
|
|
|
TPROSTYLE* info = GetStyleInfo( pPtInfo->idLoc, pPtInfo->idStyle );
|
|
char chan = info->idLoc==0 ?
|
|
info->pOrigin->detail.tracks[pPtInfo->segType][pPtInfo->segNo][pPtInfo->chNo].no
|
|
: info->idLoc==1 ?
|
|
info->pShare->trkRef[pPtInfo->segType][pPtInfo->segNo][pPtInfo->chNo].chan
|
|
: info->pLocal->trkRef[pPtInfo->segType][pPtInfo->segNo][pPtInfo->chNo].chan;
|
|
|
|
SetFavorTexture( pPtInfo->idLoc, pPtInfo->idStyle, pPtInfo->segType, pPtInfo->segNo,
|
|
chan, pPtInfo->bCollected );
|
|
// InsColSet( pInsRefTmp, pPtInfo->bCollected );
|
|
|
|
pBtn->Paint();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListViewPattern::DoMouseWheel(TObject *Sender)
|
|
{
|
|
TListViewBase::DoMouseWheel(Sender);
|
|
// m_Hint->ReleaseHandle();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
//void __fastcall TListViewPattern::HintTimerProc(System::TObject* Sender)
|
|
//{
|
|
// if( m_HintTimer )
|
|
// m_HintTimer->Enabled = false;
|
|
// if( m_Hint && HintStr.Length()>0 ){
|
|
// m_Hint->ShowHintWindow( ClientToScreen(m_ptMove), HintStr );
|
|
// }
|
|
//}
|
|
//// ---------------------------------------------------------------------------
|