Files
AC_Pro/UseStylePanel.cpp
2026-06-13 00:05:19 +08:00

3554 lines
94 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#include <Vcl.Imaging.pngimage.hpp>
#pragma hdrstop
#include "GlobalUnit.h"
#include "UseStylePanel.h"
#include "MidiTrack.h"
#include "Undo.h"
#include "SwitchProgFormUnit.h"
#include "SwitchTextureForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
extern int w_xOffDrag, //图片左上角与鼠标距离
w_yOffDrag;
__fastcall TUseStylePanel::TUseStylePanel(TComponent* AOwner)
: TStylePanel(AOwner)
{
m_pContentPanel = NULL;
m_pPlayTimer = NULL;
m_bAddWeakupBar = true;
m_strTitle = "使用风格";
}
//---------------------------------------------------------------------------
void TUseStylePanel::ClearAllItems()
{
TStylePanel::ClearAllItems();
}
//---------------------------------------------------------------------------
void TUseStylePanel::CountTotalLine()
{
m_nTotalLine = 0;
if( m_pTopItem ){
//计算总行数
TCommonItem* pItem = m_pTopItem;
while( pItem ){ //所有显示的子孙项
m_nTotalLine++;
pItem = GetNextItem( pItem );
}
}
}
//---------------------------------------------------------------------------
bool __fastcall TUseStylePanel::Charge4Fonts()
{
for( int i=g_aMidiTracks.size()-1; i>=0; i-- ){
if( g_aMidiTracks[i]->bank!=0xFF ){
return true;
}
}
return false;
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::DoChangeFontProg(TObject* Sender)
{
Stop( STOP_ALL );
if( Sender )
SetSelect( m_pFocItem, m_iFocLine );
TTrackItem *pItem = (TTrackItem *)m_pSelItem ;
TTrack* pTrack = pItem->pTrack;
TSwitchProgForm *sPf = new TSwitchProgForm( NULL, pTrack->iBank, pTrack->iProg, pTrack->iChanNo );
BYTE data[100000];
int len = 100000;
GetDemoData( pItem, len, data, sPf->m_iStartBar, sPf->m_lenBar );
f_MM_LoadDemo( data, len );
if( sPf->ShowModal() == mrOk ){
bool bChanged = false;
int iStage = FindItemStage( pItem );
BYTE iBank = pTrack->iBank,
iBankSet = sPf->m_iFont==g_idFont ? 0xFF : sPf->m_iFont;
char iProg = sPf->m_iProg,
iChno = sPf->m_iChno;
if( iBank!=iBankSet || iProg!=pTrack->iProg || iChno!=pTrack->iChanNo ){
int range = g_Opus.StageRange(iStage),
iMT = g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec );
ChangeFont( LOWORD(range), HIWORD(range), iMT, iBankSet, iProg, iChno, pItem->iType );
}
}
delete sPf;
f_MM_LoadDemo( NULL, 0 );
}
//---------------------------------------------------------------------------
TTrackItem* TUseStylePanel::FindTrackItem( int iStage, TTrack* pTrk )
{
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[iStage];
for( int i=0; i<pSeg->aItems->Count; i++ ){
TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[i];
if( pTrkItem->pTrack==pTrk )
return pTrkItem;
}
return NULL;
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::ChangeFont( int iSBar, int iEBar, int iMT, int iBank, int iProg, int iChno, int op )
{
int iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ),
iEStage = iEBar<0 ? g_Opus.StageCount() : GetInsertStage( iEBar+1 );
int iDelMT = iMT, iAddMT = -1;
TMidiTrack *pDelMT = g_aMidiTracks[iMT], *pAddMT = NULL;
vector<DWORD>* aStagesBefore = new vector<DWORD>,
* aStagesAfter = new vector<DWORD>;
vector<TTrack*> aTracksBefore, aTracksAfter;
bool bInit = false;
vector<int> aAddStages;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
vector<int>::iterator itDelStage = pDelMT->aStages.begin();
while( itDelStage!=pDelMT->aStages.end() ){
int iStage = *itDelStage;//pDelMT->aStages[i];
if( iStage<iBStage )
itDelStage++;
else if( iStage>=iEStage )
break;
else{
TOpusStage* pStage = g_lstOpusStages[iStage];
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[iStage];
for( int j=0; j<pStage->aTracks.size(); j++ ){
TTrack* pTrack = pStage->aTracks[j];
if( pTrack->iFile==pDelMT->file && pTrack->iChanSpec==pDelMT->chno ){
int iFBar = g_Opus.StageFirstBar(iStage),
iLBar = g_Opus.StageLastBar(iStage);
aTracksBefore.push_back( new TTrack(pTrack) );
// aStagesBefore->push_back( MAKELONG(iStage, j) );
DWORD dwFLT = iFBar + (iLBar<<12) + (j<<24);
aStagesBefore->push_back( dwFLT );
pTrack->iBank = iBank;
pTrack->iProg = iProg;
pTrack->iChanSpec = iChno;
aTracksAfter.push_back( pTrack );
// aStagesAfter->push_back( MAKELONG(iStage, j) );
aStagesAfter->push_back( dwFLT );
aAddStages.push_back( iStage );
break;
}
}
itDelStage = pDelMT->aStages.erase( itDelStage );
}
}
TTrack *pBefore = NULL, *pAfter = NULL;
int count = aAddStages.size();
if( count==0 ){
delete aStagesBefore;
delete aStagesAfter;
return;
}
int stateDel = pDelMT->state,
volumeDel = pDelMT->volume,
panDel = pDelMT->pan,
iErase = g_Midi.ClearEmptyTrack();
int nMTOri = g_aMidiTracks.size();
pAddMT = g_Midi.GetValidMidiTrack( aAddStages, 0xFF, iChno, iBank, iProg );
if( nMTOri<g_aMidiTracks.size() ){
bInit = true;
if( iDelMT>=0 ){
pAddMT->state = stateDel;
pAddMT->volume = volumeDel;
pAddMT->pan = panDel;
}
}
if( iErase>=0 ){
if( bInit && iErase==iMT ){
g_aMidiTracks.pop_back();
g_aMidiTracks.insert( g_aMidiTracks.begin()+iMT, pAddMT );
iAddMT = iMT;
bInit = false;
}
else
bInit = true;
}
pBefore = new TTrack[count];
pAfter = new TTrack[count];
for( int i=0; i<count; i++ ){
memcpy( &pBefore[i], aTracksBefore[i], sizeof(TTrack) );
delete aTracksBefore[i];
aTracksAfter[i]->iFile = pAddMT->file;
aTracksAfter[i]->iChanSpec = pAddMT->chno;
memcpy( &pAfter[i], aTracksAfter[i], sizeof(TTrack) );
}
if( iAddMT<0 )
iAddMT = g_Midi.GetMidiTrackIndex( pAddMT->file, pAddMT->chno );
int iCode = op,
iExt1 = iDelMT>=0 ? iDelMT + (stateDel<<8) + (volumeDel<<16) + (panDel<<24) : -1,
iExt2 = iAddMT>=0 ? iAddMT + (pAddMT->state<<8) + (pAddMT->volume<<16) + (pAddMT->pan<<24) : -1;
g_Undo.AddUndo( UNDO_MIDI_FONT, op, iSBar, iEBar, (void*)pBefore, (void*)pAfter );
g_Undo.SetUndoExtra( iExt1, iExt2, -1, aStagesBefore, aStagesAfter );
int iShowTrack = -1;
if( !m_pContentPanel->IsVertical() ){
if( bInit ){
m_pContentPanel->InitialVars();
}
else{
if( iDelMT>=0 ){
int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT );
if( iST>0 )
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST );
}
}
}
IntegrateStages( iBStage );
Paint();
if( !m_pContentPanel->IsVertical() ){
if( iAddMT>=0 ){
if( iAddMT==iDelMT )
m_pContentPanel->SelectTrack( -1, -1, -1, false );
if( iShowTrack<0 )
iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iAddMT ) - 1;
if( iShowTrack>=0 ){
m_pContentPanel->SelectTrack( iShowTrack, -1, -1, false );
m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1 );
}
}
GenerateCompose();
}
if( g_iPreStage==0 ){
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
g_lstOpusStages );
}
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::ChangeTexture( int iSBar, int iEBar, char sType,
int iMT, TTrack* pSubTrack, int op )
{
int iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ),
iEStage = iEBar<0 ? g_Opus.StageCount() : GetInsertStage( iEBar+1 );
vector<DWORD>* aStagesBefore = new vector<DWORD>,
* aStagesAfter = new vector<DWORD>;
vector<TTrack*> aTracksBefore, aTracksAfter;
int iUndoType = iMT<0 ? UNDO_MIDI_ADD : ( pSubTrack ? UNDO_MIDI_SUB : UNDO_MIDI_DEL );
if( iSBar<0 && iEBar<0 ) {
if( iMT<0 )
iUndoType = UNDO_TRKMID_ADD;
else if( !pSubTrack )
iUndoType = UNDO_TRKMID_DEL;
}
int iDelMT = iMT,
iAddMT = -1;
if( pSubTrack && pSubTrack->iFile!=0xFF )
iAddMT = g_Midi.GetMidiTrackIndex( pSubTrack->iFile, pSubTrack->iChanSpec );
TMidiTrack* pDelMT = iDelMT<0 ? NULL : g_aMidiTracks[iDelMT],
* pAddMT = iAddMT<0 ? NULL : g_aMidiTracks[iAddMT];
BYTE iDelFile = pDelMT ? pDelMT->file : 0xFF,
iDelChan = pDelMT ? pDelMT->chno : 0xFF,
iAddFile = pAddMT ? pAddMT->file : 0xFF,
iAddChan = pAddMT ? pAddMT->chno : 0xFF;
bool bDrum = false;
if( pSubTrack ){
if( pSubTrack->iChanNo==9 )
bDrum = true;
}
vector<int> aAddStages;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
for( int i=iBStage; i<iEStage; i++ ){
TOpusStage* pStage = g_lstOpusStages[i];
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];
int iFBar = g_Opus.StageFirstBar(i),
iLBar = g_Opus.StageLastBar(i);
TTrack *pDelTrack = NULL,
*pAddTrack = NULL;
int iDelTrack = -1,
iAddTrack = -1;
if( iDelChan!=0xFF && ( sType<0 || pStage->iSegType==sType ) ){
for( int j=0; j<pStage->aTracks.size(); j++ ){
TTrack* pTmpTrack = pStage->aTracks[j];
if( iDelFile!=0xFF && pTmpTrack->iFile==iDelFile && pTmpTrack->iChanSpec==iDelChan ){
pDelTrack = pTmpTrack;
iDelTrack = j;
break;
}
}
}
if( pDelTrack ){
if( !pDelMT || pDelMT->file!=pDelTrack->iFile )
pDelMT = g_Midi.FindMidiTrack( pDelTrack->iFile, pDelTrack->iChanSpec );
pDelMT->DelStage( i );
// aStagesBefore->push_back( MAKELONG( i, iDelTrack ) );
DWORD dwFLT = iFBar + (iLBar<<12) + (iDelTrack<<24);
aStagesBefore->push_back( dwFLT );
if( pSubTrack ){
aTracksBefore.push_back( new TTrack(pDelTrack) );
if( pDelTrack->iStyleLoc!=pSubTrack->iStyleLoc
|| pDelTrack->iStyleId!=pSubTrack->iStyleId ){
TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];
pTrkItem->pStyle = GetStyleInfo( pSubTrack->iStyleLoc, pSubTrack->iStyleId );
}
memcpy( pDelTrack, pSubTrack, sizeof(TTrack) );
aTracksAfter.push_back( pDelTrack );
// aStagesAfter->push_back( MAKELONG(i, iDelTrack) );
aStagesAfter->push_back( dwFLT );
if( pAddMT )
pAddMT->AddStage( i );
else
aAddStages.push_back( i );
if( iUndoType!=UNDO_MIDI_SUB )
iUndoType==UNDO_MIDI_SUB;
}
else{
TTrackItem* pDelItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];//FindTrackItem( i, pDelTrack );
TStylePanel::DeleteItem( pDelItem, -1 );
aTracksBefore.push_back( pDelTrack );
pStage->aTracks.erase( pStage->aTracks.begin()+iDelTrack );
}
}
else if( pSubTrack && pStage->iSegType==sType && ( !bDrum || iMT<0 || iDelChan==9 ) ){
TTrack* pTrk = new TTrack( pSubTrack );
if( pAddMT )
pAddMT->AddStage( i );
else
aAddStages.push_back( i );
int iTrk = 0;
if( bDrum ){
pStage->aTracks.insert( pStage->aTracks.begin(), pTrk );
}
else{
iTrk = pStage->aTracks.size();
pStage->aTracks.push_back( pTrk );
}
AddTrack( pSeg, pTrk );
aTracksAfter.push_back( pTrk );
// aStagesAfter->push_back( MAKELONG(i, iTrk) );
DWORD dwFLT = iFBar + (iLBar<<12) + (iTrk<<24);
aStagesAfter->push_back( dwFLT );
}
}
TTrack *pBefore = NULL, *pAfter = NULL;
int iExt1 = iDelMT>=0 ? iDelMT + (pDelMT->state<<8) + (pDelMT->volume<<16) + (pDelMT->pan<<24) : -1,
iErase = g_Midi.ClearEmptyTrack();
if( !aStagesBefore->empty() ){
int count = aStagesBefore->size();
pBefore = new TTrack[count];
for( int i=0; i<count; i++ ){
memcpy( &pBefore[i], aTracksBefore[i], sizeof(TTrack) );
delete aTracksBefore[i];
}
}
else if( iUndoType==UNDO_MIDI_SUB ){
iUndoType = UNDO_MIDI_ADD;
}
bool bInit = false;
if( !aStagesAfter->empty() ){
if( !pAddMT && !aAddStages.empty() ){
int nMTOri = g_aMidiTracks.size();
pAddMT = g_Midi.GetValidMidiTrack( aAddStages, pSubTrack->iFile, pSubTrack->iChanNo,
pSubTrack->iBank, pSubTrack->iProg );
if( nMTOri<g_aMidiTracks.size() )
bInit = true;
}
int count = aStagesAfter->size();
pAfter = new TTrack[count];
for( int i=0; i<count; i++ ){
if( pAddMT ) {
aTracksAfter[i]->iFile = pAddMT->file;
aTracksAfter[i]->iChanSpec = pAddMT->chno;
}
memcpy( &pAfter[i], aTracksAfter[i], sizeof(TTrack) );
}
}
if( iErase>=0 ){
if( bInit && iErase==iMT && pAddMT ){
g_aMidiTracks.pop_back();
g_aMidiTracks.insert( g_aMidiTracks.begin()+iMT, pAddMT );
iAddMT = iMT;
bInit = false;
}
else
bInit = true;
}
if( pAddMT && iAddMT<0 )
iAddMT = g_Midi.GetMidiTrackIndex( pAddMT->file, pAddMT->chno );
int iCode = op,
iExt2 = iAddMT>=0 ? iAddMT + (pAddMT->state<<8) + (pAddMT->volume<<16) + (pAddMT->pan<<24) : -1;
g_Undo.AddUndo( iUndoType, iCode, iSBar, iEBar, (void*)pBefore, (void*)pAfter );
g_Undo.SetUndoExtra( iExt1, iExt2, -1, aStagesBefore, aStagesAfter );
int iShowTrack = -1;
if( !m_pContentPanel->IsVertical() ){
if( bInit ){
m_pContentPanel->InitialVars();
}
else{
if( iDelMT>=0 ){
int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT );
if( iST>0 )
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST );
}
}
}
IntegrateStages( iBStage );
Paint();
if( g_iSegColorMode==1 )
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_DATA );
if( !m_pContentPanel->IsVertical() ){
if( iAddMT>=0 ){
if( VIEW_TRACK!=g_iViewMode ){
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 );
}
else if( iAddMT==iDelMT )
m_pContentPanel->SelectTrack( -1, -1, -1, false );
if( iShowTrack<0 )
iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iAddMT ) - 1;
if( iShowTrack>=0 ){
m_pContentPanel->SelectTrack( iShowTrack, -1, -1, false );
m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1 );
}
}
GenerateCompose();
}
if( g_iPreStage==0 ){
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
g_lstOpusStages );
}
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::DoChangeTexture(TObject* Sender)
{
Stop( STOP_ALL );
if( Sender )
SetSelect( m_pFocItem, m_iFocLine );
TTrackItem *pItem = (TTrackItem *)m_pSelItem ;
TTrack* pTrack = pItem->pTrack;
int stype = pItem->GetSegType();
char progOri = pTrack->iProgOrig;
int iStage = FindItemStage( pItem );
TOpusStage* pStage = g_lstOpusStages[iStage];
int iSBar = g_Opus.StageFirstBar( iStage ),
lenBar = pStage->aBars.size();
TStageList m_lstStage;
TStage *stage = new TStage;
TStageList lstStages;
stage->iSegType = stype;
stage->iSegKey = pStage->iSegKey;
stage->nBarNum = lenBar;
stage->nTrkNum = 0;
lstStages.push_back( stage );
if( stype<=SEGTYPE_FILL ){
stage->aChords = new TBarChords[lenBar];
for( int j=0; j<lenBar; j++ ){
memcpy( &stage->aChords[j],
&pStage->aBars[j]->aChords,
sizeof(TBarChords) );
}
}
TSwitchTextureForm *pProgPar = new TSwitchTextureForm(NULL, (1<<stype), progOri,
pTrack->iBank, pTrack->iProg, pItem->pStyle,
pTrack->iChanNo, pTrack->iSegNo, &lstStages, 0);
if(pProgPar->ShowModal() == mrOk){
TTrack subTrk;
subTrk.iStyleLoc = pProgPar->m_pSetStyle->idLoc;
subTrk.iStyleId = pProgPar->m_pSetStyle->idStyle;
subTrk.iSegNo = pProgPar->m_cSetSegNo;
subTrk.iChanNo = pProgPar->m_cSetchan;
subTrk.iProgOrig = pProgPar->m_cSetProgOri;
subTrk.nVol = pProgPar->m_cSetVol;
subTrk.nVolOrig = pProgPar->m_cSetVolOri;
if( pProgPar->m_bSetCur ){
subTrk.iProg = pProgPar->m_cSetProg;
subTrk.iChanSpec = subTrk.iChanNo;
subTrk.iBank = 0xFF;
subTrk.iFile = 0xFF;
}
else{
subTrk.iProg = pTrack->iProg;
subTrk.iChanSpec = pTrack->iChanSpec;
subTrk.iBank = pTrack->iBank;
subTrk.iFile = pTrack->iFile;
}
int iMT = g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec );
ChangeTexture( iSBar, iSBar+lenBar-1, stype, iMT, &subTrk, SEGTYPE_TRACK );
}
delete pProgPar;
delete stage;
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::DeleteAllTexture( bool bAddUndo )
{
if( g_Midi.IsEmpty() || g_Opus.BarCount()==0 )
return;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TOpusStageList *lstStageBefore = NULL,
*lstStageAfter = NULL;
UINT idLocBefore(-1), idStyleBefore(-1),
idLocAfter(-1), idStyleAfter(-1);
int nTrks = g_aMidiTracks.size();
TMidiTrackList *lstTracksBefore = NULL;
if( bAddUndo ){
lstStageBefore = new TOpusStageList;
g_Opus.CopyStages( 0, g_Opus.BarCount()-1, lstStageBefore );
if( pStyleItem->pStyle ){
idLocBefore = pStyleItem->pStyle->idLoc;
idStyleBefore = pStyleItem->pStyle->idStyle;
}
lstTracksBefore = new TMidiTrackList;
for( int i=0; i<nTrks; i++ )
lstTracksBefore->push_back( new TMidiTrack(g_aMidiTracks[i]) );
}
for( int i=0; i<g_lstOpusStages.size(); i++ ){
TOpusStage* pStage = g_lstOpusStages[i];
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];
while( !pStage->aTracks.empty() ){
TTrackItem* pDelItem = (TTrackItem*)pSeg->aItems->Last();
TStylePanel::DeleteItem( pDelItem, -1 );
TTrack* pTrack = pStage->aTracks.back();
pStage->aTracks.pop_back();
}
}
g_Midi.ClearMidiTracks();
IntegrateStages( 0 );
Paint();
if( bAddUndo ){
lstStageAfter = new TOpusStageList;
g_Opus.CopyStages( 0, g_Opus.BarCount()-1, lstStageAfter );
if( pStyleItem->pStyle ){
idLocAfter = pStyleItem->pStyle->idLoc;
idStyleAfter = pStyleItem->pStyle->idStyle;
}
g_Undo.AddUndo( UNDO_TRKMID_DELALL, ST_MIDI, idStyleBefore, idStyleAfter,
(void*)lstStageBefore, (void*)lstStageAfter );
g_Undo.SetUndoExtra( idLocBefore, idLocAfter, 0, (void*)lstTracksBefore, NULL );
}
if( !m_pContentPanel->IsVertical() ){
m_pContentPanel->InitialVars();
GenerateCompose();
}
else if( g_iSegColorMode==1 ){
m_pContentPanel->InvalidateBars( 0, g_Opus.BarCount()-1, BAR_DATA );
}
if( g_iPreStage==0 ){
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
g_lstOpusStages );
}
}
//---------------------------------------------------------------------------
TSegmentItem* TUseStylePanel::AddStage( TOpusStage* pStage )
{
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
int ind = 0;
DWORD opts = OPT_DEL|OPT_VOL;
if( pStage->iSegType<=SEGTYPE_FILL ){
ind = pStyItem->nSegNum[0] + pStyItem->nSegNum[1];
opts |= OPT_BRUSH;
}
else
ind = pStyItem->nSegNum[pStage->iSegType];
TSegmentItem* pSegItem = pStyItem->AddSegment( pStage->iSegType,
pStage->iSegNo,
opts,
pStage->aBars.size(),
ind,
pStage->nVol,
false );
opts = OPT_DEL|OPT_FONTPROG|OPT_VOL;
if( pStage->iSegType<SEGTYPE_INTRO )
opts |= OPT_TEXTURE;
for( int j=0; j<pStage->aTracks.size(); j++ ){
TTrack* pTrack = pStage->aTracks[j];
pSegItem->AddTrack( NULL, pTrack, opts, false );
}
return pSegItem;
}
//---------------------------------------------------------------------------
int TUseStylePanel::GetDemoData( TCommonItem* pItem, int &nLen, BYTE* pData, int& iStartBar, int& lenBar )
{
int ret = 0;
if( pItem->iType==SEGTYPE_TRACK ){ //播放单一轨道{
int iStage = FindItemStage( pItem );
TOpusStage* pStage = g_lstOpusStages[iStage];
TSegmentItem* pSeg = (TSegmentItem*)pItem->up;
int stype = pItem->GetSegType();
TTrack* pTrk = ((TTrackItem*)pItem)->pTrack;
TStage stage;
stage.aTracks = new TComposeTrack[1];
int nStageNum = 1;
stage.iSegType = stype;
stage.iSegKey = pStage->iSegKey;
stage.nBarNum = lenBar;
stage.nTrkNum = 1;
stage.aTracks->iStyleId = pTrk->iStyleId;// >pStyle->idStyle;
stage.aTracks->iStyleLoc = pTrk->iStyleLoc;// >pStyle->idLoc;
if( stype>=SEGTYPE_INTRO ){
char cType = (pTrk->iSegNo / 4 + 1) << 4;
char sno = pTrk->iSegNo % 4;
stage.aTracks->iSegNo = sno + cType;
}
else
stage.aTracks->iSegNo = pTrk->iSegNo;
stage.aTracks->iChanNo = pTrk->iChanNo;
stage.aTracks->iChanSpec = pTrk->iChanSpec;
stage.aTracks->iProg = pTrk->iProg;
stage.aTracks->nVol = pTrk->nVol<0 ? 0 : pTrk->nVol * pSeg->volume / 100.0;
if( stype<=SEGTYPE_FILL ){
stage.aChords = new TBarChords[lenBar];
for( int j=0; j<lenBar; j++ ){
memcpy( &stage.aChords[j],
&pStage->aBars[j]->aChords,
sizeof(TBarChords) );
}
}
ret = f_CM_Compose( &nLen, pData, g_iMelodyTimeSignature, g_nMelodyTempo,
nStageNum, &stage, false, NULL, NULL );
}
return ret;
}
//---------------------------------------------------------------------------
void TUseStylePanel::PlayDemo( TCommonItem *pItem, int tempo )
{
if( !pItem || g_lstOpusStages.size()==0 )
return;
Stop( STOP_ALL );
if( pItem->iType!=SEGTYPE_TRACK ){
GenerateCompose();
SetTrackParams( false );
}
int iStartBar(0), lenBar(0);
if( pItem->iType==SEGTYPE_STYLE ){ //播放完整全曲
f_MM_Play( Handle, 0, TYPE_COMPOSE ); //仅播放编曲
m_bPlaying = true;
}
else{
int iStage = FindItemStage( pItem );
TOpusStage* pStage = g_lstOpusStages[iStage];
for( int i=0; i<iStage; i++ ){
iStartBar += g_lstOpusStages[i]->aBars.size();
}
lenBar = pStage->aBars.size();
if( pItem->iType==SEGTYPE_TRACK ){ //播放单一轨道
BYTE data[100000];
int len = 100000;
int ret = GetDemoData( pItem, len, data, iStartBar, lenBar );
if( ret==0 ){
BYTE iBank = ((TTrackItem*)pItem)->pTrack->iBank;
char* strFile = iBank==0xFF ? NULL : iBank<0x80 ? g_lstFonts[iBank]->strFileName
: g_lstVSTi[iBank-0x80]->strFileName;
f_MM_LoadDemo( data, len );
f_MM_PlayDemo( Handle, 0, -1, -1, iBank, strFile );
m_bPlaying = true;
}
else{
DebugPrint( "Compose error: %d", ret );
}
}
else{
f_MM_Play( Handle, iStartBar, TYPE_COMPOSE ); //仅播放编曲
m_bPlaying = true;
}
if( m_bPlaying ){
if( !m_pPlayTimer ){
m_pPlayTimer = new TTimer(this);
}
m_pPlayTimer->Interval = lenBar * g_dblTimePerBar - 100;
m_pPlayTimer->OnTimer = PlayEndProc;
m_pPlayTimer->Enabled = true;
}
}
if( m_bPlaying )
m_pPlayItem = pItem;
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::PlayEndProc(TObject* Sender)
{
Stop(STOP_SELF);
}
//---------------------------------------------------------------------------
void __fastcall TUseStylePanel::OnPlayEnd(TMessage &msg)
{
Stop(STOP_SELF);
}
//---------------------------------------------------------------------------
void TUseStylePanel::SetSelect( TCommonItem *pItem, int iLine )
{
TCommonItem * pOldSeg = NULL;
if( m_pSelItem && m_pSelItem->iType>=SEGTYPE_VAR
&& m_pSelItem->iType<=SEGTYPE_ENDING ){
pOldSeg = m_pSelItem;
}
if( !pItem || pItem->iType==SEGTYPE_STYLE ){
m_pContentPanel->SelectStage( -1 );
}
TStylePanel::SetSelect( pItem, iLine );
if( pOldSeg!=m_pSelItem && m_pSelItem && m_pSelItem->iType>=SEGTYPE_VAR
&& m_pSelItem->iType<=SEGTYPE_ENDING ){
TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0];
for( int i=0; i<pStyle->aItems->Count; i++ ){
if( m_pSelItem==pStyle->aItems->Items[i] ){
m_pContentPanel->SelectStage( i );
break;
}
}
}
}
//---------------------------------------------------------------------------
void TUseStylePanel::Stop( DWORD dwSpec )
{
if( m_pPlayTimer ){
delete m_pPlayTimer;
m_pPlayTimer = NULL;
}
if( m_bPlaying ){
dwSpec = STOP_SELF;
if( m_pPlayItem && m_pPlayItem->iType!=SEGTYPE_TRACK )
SetTrackParams();
}
TStylePanel::Stop( dwSpec );
}
//---------------------------------------------------------------------------
bool TUseStylePanel::HandleHoverEvent(TPoint ptMouse)
{
int X = ptMouse.X,
Y = ptMouse.Y;
TCommonItem* pHoverItem = NULL;
int iHoverLine = -1;
TCommonItem* pItem = HitTest( X, Y-m_nTitleHeight, NULL );
if( pItem && m_pDropItem ){
if( m_pDropItem->iType==SEGTYPE_TRACK ){
iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
pHoverItem = GetTrackHoverItem( pItem, iHoverLine );
}
else if( m_pDropItem->iType==SEGTYPE_STYLE ){
//查看风格是否缺少片段
if( ((TStyleItem*)m_pDropItem)->nSegNum[0]>0 ){
pHoverItem = (TCommonItem*)m_aItems->Items[0];
iHoverLine = -m_iTopLine;
}
}
else{
int iDropType = m_pDropItem->GetSegType(),
iHoverType = pItem->GetSegType();
if( iDropType==iHoverType //类型相同可替换
|| ( iHoverType==SEGTYPE_FILL
|| iHoverType==SEGTYPE_VAR)
&& (iDropType==SEGTYPE_FILL
|| iDropType==SEGTYPE_VAR )){ //伴奏与加花可替换
iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
pHoverItem = pItem;
}
}
}
SetUnfoldTimer( pItem, pHoverItem );
SetHover( pHoverItem, iHoverLine );
return pHoverItem!=NULL;
}
//---------------------------------------------------------------------------
void TUseStylePanel::HandleDropEvent( int iState )
{
if( m_pDropItem && m_pHoverItem ){
Stop();
if( m_pDropItem->iType==SEGTYPE_STYLE ){ //应用风格
PostMessage( Parent->Handle, UM_APPLYSTYLE, 1, LPARAM(m_pDropItem) );
}
else{ //应用片段
int iStage = FindItemStage( m_pHoverItem );
if( m_pDropItem->iType==SEGTYPE_TRACK ){ //添加track
TSegmentItem* pSeg = (TSegmentItem*)m_pHoverItem;
if( m_pHoverItem->iType==SEGTYPE_TRACK )
pSeg = (TSegmentItem*)m_pHoverItem->up;
TTrack *pSrcTrack = new TTrack( ((TTrackItem*)m_pDropItem)->pTrack ),
*pDstTrack = NULL;
if( pSrcTrack->iChanNo==9 ){
for( int i=0; i<pSeg->aItems->Count; i++ ){
TTrackItem* pTmpItem = (TTrackItem*)pSeg->aItems->Items[i];
if( pTmpItem->pTrack->iChanNo==9 ){
pDstTrack = pTmpItem->pTrack;
break;
}
}
}
int iMT = -1;
if( pDstTrack ){
iMT = g_Midi.GetMidiTrackIndex( pDstTrack->iFile, pDstTrack->iChanSpec );
}
else{
pSrcTrack->iFile = 0xFF;
pSrcTrack->iChanSpec = pSrcTrack->iChanNo;
}
TOpusStage* pStage = g_lstOpusStages[iStage];
int iSBar = FirstBar( iStage ),
iEBar = iSBar + pStage->aBars.size() - 1;
ChangeTexture( iSBar, iEBar, pStage->iSegType, iMT, pSrcTrack, SEGTYPE_TRACK );
}
else{
ReformStage( iStage, (TSegmentItem*)m_pDropItem );
}
}
}
}
//---------------------------------------------------------------------------
String TUseStylePanel::ChargeTip( TStyleItem* pItem )
{
String strTip = " 风格支付预估\n\n 风格 唱作音符\n";
strTip += "------------------------\n";
char buf[512];
int nFee = 0;
for( int i=0; i<m_aStyles.size(); i++ ){
if( m_aStyles[i]->idLoc==0 && m_aStyles[i]->pOrigin->cost>0 ){
TPROSTYLE* pStyle = m_aStyles[i];
sprintf( buf, "[%4d] %d\n", pStyle->idStyle, pStyle->pOrigin->cost );
strTip += buf;
nFee += pStyle->pOrigin->cost;
}
}
strTip += "------------------------\n";
strTip += " 合计 " + IntToStr( nFee );
return strTip;
}
//---------------------------------------------------------------------------
void TUseStylePanel::ApplyStyle( TStyleItem* pSrcStyle )
{
g_Midi.ClearMidiTracks();
TStyleItem* pDestStyle = (TStyleItem*)m_aItems->Items[0];
//Set Undo
bool bMMUndo = false;
int nBars = pDestStyle->nBars,
idLoc = (pDestStyle && pDestStyle->pStyle) ? pDestStyle->pStyle->idLoc : 0,
idStyle = (pDestStyle && pDestStyle->pStyle) ? pDestStyle->pStyle->idStyle : 0;
TAudioTrackList* lstAudio = NULL;
TOpusStageList* lstStageBefore = new TOpusStageList;
g_Opus.CopyStages( 0, nBars-1, lstStageBefore );
//替换风格
pDestStyle->pStyle = pSrcStyle->pStyle;
int nSegNum[4];
vector<TSegmentItem*> aSegments[4];
memset( nSegNum, 0, sizeof(int)*4 );
for( int i=0; i<pSrcStyle->aItems->Count; i++ ){
TSegmentItem* pSegment = (TSegmentItem*)pSrcStyle->aItems->Items[i];
int stype = pSegment->GetSegType();
aSegments[stype].push_back( pSegment );
nSegNum[stype]++;
}
m_pFocItem = NULL;
m_iFocLine = -1;
m_pSelItem = NULL;
m_iSelLine = -1;
for( int i=pDestStyle->aItems->Count-1; i>=0; i-- ){
TSegmentItem* pDestSeg = (TSegmentItem*)pDestStyle->aItems->Items[i];
TSegmentItem* pSrcSeg = NULL;
int stype = pDestSeg->iSegType;
int sno = pDestSeg->iSegNo;
if( stype>=SEGTYPE_INTRO ){
if( nSegNum[stype]>0 ){
TSegmentItem* pBackup = NULL;
int t = sno / 2,
c = sno % 2;
for( int j=0; j<nSegNum[stype]; j++ ){
if( aSegments[stype][j]->iSegNo % 2 == c ){
if( aSegments[stype][j]->iSegNo / 2 == t ){
pSrcSeg = aSegments[stype][j];
break;
}
else{
pBackup = aSegments[stype][j];
}
}
}
if( !pSrcSeg ){
if( pBackup )
pSrcSeg = pBackup;
else
pSrcSeg = aSegments[stype][0]; //大小调不分
}
}
if( !bMMUndo && ( !pSrcSeg || pSrcSeg->nBars!=pDestSeg->nBars ) ){
f_MM_AddUndoBefore( -1, NULL );
lstAudio = new TAudioTrackList;
g_Audio.CopyTrackList( 0, nBars, lstAudio );
bMMUndo = true;
}
}
else{
if( stype==SEGTYPE_FILL && nSegNum[SEGTYPE_FILL]==0 ){
stype = SEGTYPE_VAR;
}
else if( stype==SEGTYPE_VAR && nSegNum[SEGTYPE_VAR]==0 ){
stype = SEGTYPE_FILL;
}
sno = min( sno, nSegNum[stype]-1 );
pSrcSeg = aSegments[stype][sno];
}
if( pSrcSeg ){
ReplaceSegment( pDestSeg, pSrcSeg );
}
else{ //删除段落
RemoveSegment( pDestSeg );
}
}
IntegrateStages( 0 );
if( bMMUndo ){
f_MM_AddUndoAfter( -1, NULL );
}
TOpusStageList* lstStageAfter = new TOpusStageList;
g_Opus.CopyStages( 0, pDestStyle->nBars-1, lstStageAfter );
g_Undo.AddUndo( UNDO_OPUS_STYLE, 0, idLoc, idStyle, (void*)lstStageBefore,
(void*)lstStageAfter );
if( bMMUndo )
g_Undo.SetUndoExtra( 0, 0, 0, (void*)lstAudio, NULL );
if( !pDestStyle->IsUnfold() )
SetFold( pDestStyle, 0 );
else if( m_pTopItem!=pDestStyle )
ScrollView( 0, true );
else
InvalidateRgn( Handle, NULL, false );
m_pContentPanel->OnStageChanged( 0, MODE_INIT );
}
//---------------------------------------------------------------------------
void TUseStylePanel::ReplaceSegment( TSegmentItem* pDestSeg, TSegmentItem* pSrcSeg )
{
int iStage = FindItemStage( pDestSeg );
TOpusStage* pStage = g_lstOpusStages[iStage];
TStyleItem *pStyItem = (TStyleItem*)m_aItems->Items[0];
int nBar = pStage->aBars.size();
if( pSrcSeg->iSegType>=SEGTYPE_INTRO )
nBar = pSrcSeg->nBars;
bool bPreChange = g_iPreStage==0;
if( pStage->aBars.size()!=nBar ){ //段落长度调整
int offset = nBar - pStage->aBars.size();
int iOrigEnd = FirstBar(iStage) + pStage->aBars.size();
if( bPreChange ){
DuplicateRawBars();
SendMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 );
}
if( offset!=0 && pStage->iSegType==SEGTYPE_INTRO ){
if( g_Theme.IsWeadup() && !memcmp( g_aAudioTracks[1]->lstBars[iOrigEnd-1]->aVols,
g_aAudioTracks[0]->lstBars[0]->aVols,
POINTS_PER_BAR * sizeof(DWORD) )){
iOrigEnd--;
}
}
if( offset>0 ){ //添加小节
for( int i=0; i<offset; i++ ){
TBar* pBar = new TBar;
pStage->aBars.push_back(pBar);
for( int j=1; j<g_aAudioTracks.size(); j++ ){
TWaveBar* pWvBar = new TWaveBar;
g_aAudioTracks[j]->lstBars.insert( g_aAudioTracks[j]->lstBars.begin() + iOrigEnd, pWvBar );
}
}
for( int j=1; j<g_aAudioTracks.size(); j++ ){
f_MM_AudioMove( j, iOrigEnd, -1, 0, offset, MODE_INSERT );
}
}
else{ //删除小节
iOrigEnd--;
for( int i=0; i>offset; i-- ){
delete pStage->aBars.back();
pStage->aBars.pop_back();
for( int j=1; j<g_aAudioTracks.size(); j++ ){
delete g_aAudioTracks[j]->lstBars[iOrigEnd+i];
g_aAudioTracks[j]->lstBars.erase( g_aAudioTracks[j]->lstBars.begin() + iOrigEnd+i );
}
}
for( int j=1; j<g_aAudioTracks.size(); j++ ){
f_MM_AudioMove( -1, 0, j, iOrigEnd+offset+1, iOrigEnd+1, MODE_DELETE );
}
}
pDestSeg->nBars += offset;
pStyItem->nBars += offset;
g_Opus.CountBars();
}
if( pDestSeg->iType != pSrcSeg->iType ){
pStyItem->nSegNum[pDestSeg->iType]--;
pStyItem->nSegNum[pSrcSeg->iType]++;
}
pDestSeg->iType = pSrcSeg->iType;
pStage->nVol = pDestSeg->volume = pSrcSeg->volume;
pStage->iSegType = pDestSeg->iSegType = pSrcSeg->iSegType;
pStage->iSegNo = pDestSeg->iSegNo = pSrcSeg->iSegNo;
g_Midi.RemoveStage( iStage, false );
//清空tracks
while( pStage->aTracks.size()>0 ){
delete pStage->aTracks.back();
pStage->aTracks.pop_back();
}
int iSegLine = 0, nTrkBefore = 0, nTrkAfter = 0;
if( pStyItem->IsUnfold() ){
TCommonItem *pItem = pStyItem;
while( pItem && pItem!=pDestSeg ){
iSegLine++;
pItem = GetNextItem( pItem );
}
if( pDestSeg->IsUnfold() ){
if( m_pSelItem && m_pSelItem->up==pDestSeg ){
m_pSelItem = NULL;
m_iSelLine = -1;
}
nTrkBefore = pDestSeg->aItems->Count;
nTrkAfter = pSrcSeg->aItems->Count;
if( m_pTopItem && m_pTopItem->up==pDestSeg ){
TCommonItem * pItem = m_pTopItem;
int iTopLine = m_iTopLine;
while( pItem!=pDestSeg ){
iTopLine--;
pItem = GetPrevItem( pItem );
}
ScrollView( iTopLine, true );
}
}
}
pDestSeg->ClearSubItems();
DWORD opts = OPT_DEL|OPT_VOL;
if( pDestSeg->iSegType<SEGTYPE_INTRO )
opts |= OPT_TEXTURE;
int nMTCount = g_aMidiTracks.size();
for( int i=0; i<pSrcSeg->aItems->Count; i++ ){
TTrackItem* pTrkItem = (TTrackItem*)pSrcSeg->aItems->Items[i];
TTrack * pTrack = new TTrack( pTrkItem->pTrack );
pDestSeg->AddTrack( pTrkItem->pStyle, pTrack, opts, false );
pStage->aTracks.push_back( pTrack );
TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iStage, pTrack->iFile, pTrack->iChanNo,
pTrack->iBank, pTrack->iProg );
pTrack->iFile = pMT->file;
pTrack->iChanSpec = pMT->chno;
}
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
if( bPreChange || !m_pContentPanel->IsVertical() && ( bDeletedMT
|| nMTCount!=g_aMidiTracks.size() ))
m_pContentPanel->InitialVars();
m_nTotalLine += nTrkAfter - nTrkBefore;
if( m_iTopLine>iSegLine ){
m_iTopLine += nTrkAfter - nTrkBefore;
}
ResetScrollBar();
Paint();
}
//---------------------------------------------------------------------------
void TUseStylePanel::DeleteItem( TCommonItem *pItem, int iLine )
{
Stop();
TStyleItem *pStyItem = (TStyleItem*)m_aItems->Items[0];
int iStage = FindItemStage( pItem );
if( pItem->iType==SEGTYPE_TRACK ){
DeleteTrack( iStage, (TTrackItem*)pItem, iLine );
}
else{
RemoveStage( iStage );
if( pStyItem->aItems->Count==0 ){
// g_Midi.ClearMidiTracks();
ClearAllItems();
g_pUseStyle = NULL;
Paint();
}
}
}
//---------------------------------------------------------------------------
void TUseStylePanel::DeleteTrack( int iStage, TTrackItem* pTrkItem, int iLine )
{
TOpusStage* pStage = g_lstOpusStages[iStage];
for( int i=0; i<pStage->aTracks.size(); i++ ){
TTrack* pTrack = pStage->aTracks[i];
if( pTrkItem->pTrack==pTrack ){
int iFirstBar = FirstBar( iStage ),
iEndBar = iFirstBar + pStage->aBars.size() - 1;
int iMT= g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec );
ChangeTexture( iFirstBar, iEndBar, pStage->iSegType, iMT, NULL, SEGTYPE_TRACK );
break;
}
}
}
//---------------------------------------------------------------------------
TSegmentItem* TUseStylePanel::InsertSegment( int iStage, TSegmentItem* pSrcSeg, int nBars )
{
if( m_aItems->Count==0 ){
g_pUseStyle = AddStyle( ((TTrackItem*)pSrcSeg->aItems->Items[0])->pStyle );
}
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
int ind = 0;
DWORD opts = OPT_DEL|OPT_VOL;
int stype = pSrcSeg->iSegType;
if( pSrcSeg->iSegType<=SEGTYPE_FILL ){
stype = SEGTYPE_VAR;
opts |= OPT_BRUSH;
}
if( iStage<0 || iStage>=pStyleItem->aItems->Count ){
iStage = pStyleItem->aItems->Count;
if( pSrcSeg->iSegType<=SEGTYPE_FILL ){
ind = pStyleItem->nSegNum[SEGTYPE_VAR]
+ pStyleItem->nSegNum[SEGTYPE_FILL];
}
else
ind = pStyleItem->nSegNum[pSrcSeg->iSegType];
}
else{
for( int i=0; i<pStyleItem->aItems->Count; i++ ){
TSegmentItem* pTmpSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];
if( pTmpSeg->iSegType<=SEGTYPE_FILL && stype==SEGTYPE_VAR ){
if( i<iStage )
ind++;
else
pTmpSeg->iInd++;
}
else if( pTmpSeg->iSegType==stype ){
if( i<iStage )
ind++;
else
pTmpSeg->iInd++;
}
}
}
TSegmentItem* pDestSeg = new TSegmentItem( pStyleItem, pSrcSeg->iSegType, pSrcSeg->iSegNo,
opts, nBars, ind, pSrcSeg->volume, false );
opts = OPT_DEL|OPT_VOL;
if( pSrcSeg->iSegType<SEGTYPE_INTRO )
opts |= OPT_TEXTURE;
TOpusStage* pStage = g_lstOpusStages[iStage];
for( int i=0; i<pStage->aTracks.size(); i++ ){
TTrack* pTrack = pStage->aTracks[i];
pDestSeg->AddTrack( NULL, pTrack, opts, false );
}
if( pStyleItem->IsUnfold() ){
m_nTotalLine++;
int iTopStage = FindItemStage( m_pTopItem );
if( iTopStage>=iStage ){
m_iTopLine++;
}
}
pStyleItem->InsertSegment( iStage, pDestSeg, nBars );
return pDestSeg;
}
//---------------------------------------------------------------------------
void TUseStylePanel::RemoveSegment( TSegmentItem* pItem, bool bSetMM )
{
int iStage = FindItemStage( pItem );
TOpusStage* pStage = g_lstOpusStages[iStage];
int iFirstBar = FirstBar(iStage);
int iEndBar = iFirstBar + pStage->aBars.size();
if( bSetMM && iEndBar>iFirstBar ){
if( g_iPreStage==0 )
DuplicateRawBars();
for( int i=1; i<g_aAudioTracks.size(); i++ ){
MoveAudio( i, iFirstBar, iEndBar, -1, 0, MODE_DELETE | OPT_BARS );
}
}
g_Opus.RemoveStage( iStage );
g_Midi.RemoveStage( iStage, true );
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
if( m_pTopItem ){
int iTopStage = FindItemStage( m_pTopItem );
if( pStyItem->IsUnfold() ){
if( iTopStage>iStage ){
m_iTopLine--;
if( pItem->IsUnfold() ){
m_iTopLine -= pItem->aItems->Count;
}
}
else if( iTopStage==iStage && m_pTopItem!=pItem ){ //展开且TopItem是Track
TCommonItem* pTmpItem = m_pTopItem;
m_pTopItem = GetPrevItem( pItem );
while( pTmpItem!=m_pTopItem ){
m_iTopLine--;
pTmpItem = GetPrevItem( pTmpItem );
}
}
}
}
TStylePanel::DeleteItem( pItem, -1 );
pStyItem->nBars -= iEndBar - iFirstBar;
}
//---------------------------------------------------------------------------
int TUseStylePanel::FindItemStage( TCommonItem* pItem )
{
int iStage = -1;
TStyleItem* pStyle = (TStyleItem*)m_aItems->First();
TSegmentItem* pSeg = NULL;
if( pItem->iType!=SEGTYPE_STYLE ){
if( pItem->iType==SEGTYPE_TRACK )
pSeg = (TSegmentItem*)pItem->up;
else
pSeg = (TSegmentItem*)pItem;
for( int i=0; i<pStyle->aItems->Count; i++ ){
if( pSeg==pStyle->aItems->Items[i] ){
iStage = i;
break;
}
}
}
return iStage;
}
// ---------------------------------------------------------------------------
/*
TCommonItem* TUseStylePanel::DrawDragStageItem( int iStage )
{
TStyleItem* pStyle= (TStyleItem*)m_aItems->First();
TSegmentItem* pSeg = (TSegmentItem*)pStyle->aItems->Items[iStage];
DrawDragImg( pSeg );
return pSeg;
}
// ---------------------------------------------------------------------------
*/
void TUseStylePanel::SetSelectStage( int iStage )
{
if( m_aItems->Count==0 )
return;
TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0];
if( iStage>=0 && iStage<pStyle->aItems->Count ){
TSegmentItem* pSeg = (TSegmentItem*)pStyle->aItems->Items[iStage];
if( !pStyle->IsUnfold() ){
SetFold( pStyle, 0 );
}
TCommonItem* pItem = GetNextItem( pStyle );
int iLine = 1;
while( pItem!=pSeg ){
pItem = GetNextItem( pItem );
iLine++;
}
SetSelect( pSeg, iLine - m_iTopLine );
ShowSelItem();
}
else{
SetSelect( NULL, -1 );
}
}
// ---------------------------------------------------------------------------
void TUseStylePanel::VolumeChanged( TCommonItem *pItem, char volNew )
{
char volOld = pItem->iType==SEGTYPE_TRACK ? ((TTrackItem*)pItem)->pTrack->nVol
: ((TSegmentItem*)pItem)->volume;
if( volNew==(char)0x80 ){
if( pItem->IsMute() )
volNew = volOld & ~0x80;
else
volNew = volOld | 0x80;
}
else if( volOld<0 ){
volNew |= 0x80;
}
int iStage = FindItemStage( pItem );
if( iStage<0 )
return;
ChangeVolume( iStage, pItem, volNew );
}
// ---------------------------------------------------------------------------
void TUseStylePanel::ChangeVolume( int iStage, TCommonItem* pItem, char newVol, bool bAddUndo )
{
bool bSetUndo = false;
int volBefore, volAfter = newVol,
iUndoType = -1,
iUndoCode = -1;
TTrack* pUndoExt = NULL;
int iStartBar = FirstBar( iStage ),
iEndBar = iStartBar + g_lstOpusStages[iStage]->aBars.size();
TOpusStage* pStage = g_lstOpusStages[iStage];
TSegmentItem* pSeg = NULL;
TTrackItem* pTrkItem = NULL;
if( pItem->iType==SEGTYPE_TRACK ){
pSeg = (TSegmentItem*)pItem->up;
pTrkItem = (TTrackItem*)pItem;
}
else{
pSeg = (TSegmentItem*)pItem;
if( bAddUndo ){
bSetUndo = true;
iUndoType = UNDO_STAGE_VOL;
iUndoCode = MAKELONG( iStage, -1 );
volBefore = pStage->nVol;
}
pStage->nVol = pSeg->volume = newVol;
}
float fSegVol = pSeg->volume / 100.0;
for( int i=0; i<pStage->aTracks.size(); i++ ){
TTrack* pTrk = pStage->aTracks[i];
if( pTrkItem ){
if( pTrk==pTrkItem->pTrack ){
if( bAddUndo ){
bSetUndo = true;
iUndoType = UNDO_PROG_VOL;
iUndoCode = MAKELONG( iStage, (pTrk->iFile<<8) + pTrk->iChanSpec );
volBefore = (char)pTrk->nVol;
pUndoExt = new TTrack( pTrk );
}
pTrk->nVol = newVol;
int vol = pTrk->nVol<0 ? 0 : pTrk->nVol * fSegVol;
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, iStartBar, iEndBar,
pTrk->iChanSpec, vol, pTrk->iFile );
if( m_bPlaying && ( pTrkItem==m_pSelItem )){
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, 0, iEndBar-iStartBar,
pTrk->iChanSpec, vol, -1 );
}
int iMT = g_Midi.GetMidiTrackIndex( pTrk->iFile, pTrk->iChanSpec );
g_Midi.ChangeNotesVolume( iMT, iStartBar, iEndBar, vol );
if( !m_pContentPanel->IsVertical() ){
int iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT );
m_pContentPanel->InvalidateBars( iStartBar, iEndBar-1, BAR_TRACK | iShowTrack );
}
break;
}
}
else if( pTrk->nVol>0 ){
int vol = pTrk->nVol * fSegVol;
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, iStartBar, iEndBar,
pTrk->iChanSpec, vol, pTrk->iFile );
if( m_bPlaying && pSeg==m_pSelItem->up ){
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, 0, iEndBar-iStartBar,
pTrk->iChanSpec, vol, -1 );
}
int iMT = g_Midi.GetMidiTrackIndex( pTrk->iFile, pTrk->iChanSpec );
g_Midi.ChangeNotesVolume( iMT, iStartBar, iEndBar, vol );
if( !m_pContentPanel->IsVertical() ){
int iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT );
m_pContentPanel->InvalidateBars( iStartBar, iEndBar-1, BAR_TRACK | iShowTrack );
}
}
}
if( bSetUndo ){
TUndoLite* pLite = g_Undo.GetLastLite();
if( pLite && pLite->iType==iUndoType && pLite->iCode==iUndoCode ){
bool bMuteCurr = volBefore>=0 && volAfter<0 || volBefore<0 && volAfter>=0,
bMuteLast = ( (int)pLite->pBefore >= 0 && (int)pLite->pAfter < 0
|| (int)pLite->pBefore < 0 && (int)pLite->pAfter >= 0 );
if( bMuteCurr==bMuteLast ){
bSetUndo = false;
if( (char)pLite->pBefore==volAfter )
g_Undo.CancelUndo();
else
pLite->pAfter = (void*)volAfter;
if( pUndoExt )
delete pUndoExt;
}
}
if( bSetUndo ){
g_Undo.AddUndo( iUndoType, iUndoCode, iStartBar, iEndBar,
(void*)volBefore, (void*)volAfter );
if( pUndoExt )
g_Undo.SetUndoExtra( 0, 0, 0, pUndoExt, NULL );
}
}
if( g_iPreStage==0 ){
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
g_lstOpusStages );
}
}
// ---------------------------------------------------------------------------
bool TUseStylePanel::IntegrateStages( int iStageBegin, bool bSetMM )
{
iStageBegin--;
if( iStageBegin<0 )
iStageBegin = 0;
if( g_lstOpusStages.size()==0 ){
ClearAllItems();
g_pUseStyle = NULL;
}
if( g_lstOpusStages.size()<=iStageBegin ){
return false;
}
bool bIntegrated = false;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pSegItem1 = (TSegmentItem*)pStyleItem->aItems->Items[iStageBegin];
TOpusStageList::iterator iterFirst, iterSecond;
iterFirst = iterSecond = g_lstOpusStages.begin() + iStageBegin;
while( (++iterSecond)!=g_lstOpusStages.end() ){
TOpusStage *pStage1 = *iterFirst,
*pStage2 = *iterSecond;
TSegmentItem* pSegItem2 = (TSegmentItem*)pSegItem1->next;
if( pStage1->iSegType<=SEGTYPE_FILL && pStage2->iSegType==pStage1->iSegType
&& !DiffStages( pStage1, pStage2 ) ){
if( !pStage1->aTracks.empty() ){
int num = pStage1->aTracks.size();
bool* aMatch = new bool[num];
memset( aMatch, false, sizeof(bool)*num );
for( int i=0; i<num; i++ ){
TTrack* pTrk1 = pStage1->aTracks[i];
for( int j=0; j<num; j++ ){
TTrack* pTrk2 = pStage2->aTracks[j];
if( !aMatch[j] && pTrk1->iStyleId==pTrk2->iStyleId
&& pTrk1->iStyleLoc==pTrk2->iStyleLoc
&& pTrk1->iSegNo==pTrk2->iSegNo
&& pTrk1->iChanNo==pTrk2->iChanNo
&& pTrk1->iBank==pTrk2->iBank
&& pTrk1->iProg==pTrk2->iProg
&& pTrk1->nVol==pTrk2->nVol ){
if( pTrk1->iFile==0xFF && pTrk2->iFile!=0xFF ){
pTrk1->iFile = pTrk2->iFile;
pTrk1->iChanSpec = pTrk2->iChanSpec;
}
aMatch[j] = true;
break;
}
}
}
delete[] aMatch;
}
pSegItem1->nBars += pSegItem2->nBars;
for( int i=0; i<pStage2->aBars.size(); i++ ){
pStage1->aBars.push_back( pStage2->aBars[i] );
}
pStage2->aBars.clear();
g_Opus.ChangeStageBar( iterFirst - g_lstOpusStages.begin(), pSegItem2->nBars, false );
RemoveSegment( pSegItem2, bSetMM );
bIntegrated = true;
iterSecond = iterFirst;
}
else{
iterFirst++;
pSegItem1 = (TSegmentItem*)pSegItem1->next;
}
}
CountStyles();
HandleWeakup( iStageBegin, bSetMM );
return bIntegrated;
}
//---------------------------------------------------------------------------
void TUseStylePanel::HandleWeakup( int iStageBegin, bool bSetMM )
{
if( !g_Theme.IsWeadup() || g_aAudioTracks.size()<2
|| g_aAudioTracks[0]->lstBars.empty()
|| g_aAudioTracks[1]->lstBars.empty() )
return;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pSegItem1 = (TSegmentItem*)pStyleItem->aItems->Items[iStageBegin];
TOpusStageList::iterator iterFirst, iterSecond;
iterFirst = iterSecond = g_lstOpusStages.begin() + iStageBegin;
int iFirstBar = FirstBar( iStageBegin );
if( iFirstBar==0 ){
if( pSegItem1->iSegType<=SEGTYPE_FILL ){
if( m_bAddWeakupBar ){
TOpusStage *pStage0 = *iterFirst;
if( !memcmp( g_aAudioTracks[1]->lstBars[0]->aVols,
g_aAudioTracks[0]->lstBars[1]->aVols,
POINTS_PER_BAR * sizeof(DWORD) )){
TBar * pBar0 = new TBar( g_Theme.GetFirstBar() );
pStage0->aBars.insert( pStage0->aBars.begin(), pBar0 );
pSegItem1->nBars++;
pStyleItem->nBars++;
for( int i=1; i<g_aAudioTracks.size(); i++ ){
TWaveBar* pWvBar = NULL;
if( i==1 ){//音轨1添加弱起小节
pWvBar = new TWaveBar( g_aAudioTracks[0]->lstBars[0] );
if( bSetMM )
f_MM_AudioMove( 1, 0, 0, 0, 1, MODE_INSERT );
}
else{//其它音轨添加空白小节
pWvBar = new TWaveBar;
if( bSetMM )
f_MM_AudioMove( i, 0, -1, 0, 1, MODE_INSERT );
}
g_aAudioTracks[i]->lstBars.insert( g_aAudioTracks[i]->lstBars.begin(), pWvBar );
}
}
iFirstBar += pSegItem1->nBars;
iterFirst++;
iterSecond++;
}
}
else{
m_bAddWeakupBar = true;
}
}
while( pSegItem1->next && (++iterSecond)!=g_lstOpusStages.end() ){
TOpusStage *pStage1 = *iterFirst,
*pStage2 = *iterSecond;
TSegmentItem* pSegItem2 = (TSegmentItem*)pSegItem1->next;
if( pStage1->iSegType==SEGTYPE_INTRO ){
int iFirstBar2 = iFirstBar + pSegItem2->nBars;
if( pStage2->iSegType<=SEGTYPE_FILL
&& !memcmp( g_aAudioTracks[1]->lstBars[iFirstBar2]->aVols,
g_aAudioTracks[0]->lstBars[1]->aVols,
POINTS_PER_BAR * sizeof(DWORD) )){
bool bCopy = true;
for( int i=0; i<POINTS_PER_BAR; i++ ){
if( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols[i]!=0 ){
bCopy = false;
break;
}
}
if( bCopy ){
memcpy( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols,
g_aAudioTracks[0]->lstBars[0]->aVols,
POINTS_PER_BAR * sizeof(DWORD) );
if( bSetMM )
f_MM_AudioMove( 1, iFirstBar2-1, 0, 0, 1, MODE_COPY );
}
}
else{
if( !memcmp( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols,
g_aAudioTracks[0]->lstBars[0]->aVols,
POINTS_PER_BAR * sizeof(DWORD) )){
memset( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols, 0,
POINTS_PER_BAR * sizeof(DWORD) );
if( bSetMM )
f_MM_AudioMove( -1, 0, 1, iFirstBar2-1, iFirstBar2, MODE_ERASE );
}
}
}
iFirstBar += pSegItem1->nBars;
iterFirst++;
pSegItem1 = (TSegmentItem*)pSegItem1->next;
}
}
int TUseStylePanel::GetInsertStage( int iInsertBar )
{
int iFirstBar,
iDestStage = FindStage( iInsertBar, &iFirstBar );
if( iDestStage>=0 ){
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iDestStage];
if( iInsertBar!=iFirstBar ){//分段插入
int nBarNum = pSrcSeg->nBars - ( iInsertBar - iFirstBar );
g_Opus.CutStage( iDestStage, iInsertBar );
g_Midi.CutStage( iDestStage );
InsertSegment( iDestStage+1, pSrcSeg, nBarNum );
pSrcSeg->nBars -= nBarNum;
pStyleItem->nBars -= nBarNum;
iDestStage++;
}
}
else if( iInsertBar>0 ){
iDestStage = g_lstOpusStages.size();
}
return iDestStage;
}
//-----------------------------------------------------------------------------
TTrackItem* TUseStylePanel::AddTrack( TSegmentItem* pSeg, TTrack* pSrcTrk, int iInd )
{
TTrackItem* pDestTrk = NULL;
if( pSeg && pSrcTrk ){
int nTrksBefore = pSeg->aItems->Count;
TPROSTYLE* info = GetStyleInfo( pSrcTrk->iStyleLoc, pSrcTrk->iStyleId );
if( info ){
DWORD opts = OPT_DEL|OPT_VOL;
if( pSeg->iSegType<SEGTYPE_INTRO )
opts |= OPT_TEXTURE;
pDestTrk = pSeg->AddTrack( info, pSrcTrk, opts, false, iInd );
int nTrksAfter = pSeg->aItems->Count;
if( pSeg->IsUnfold() && nTrksAfter!=nTrksBefore ){
m_nTotalLine += nTrksAfter-nTrksBefore;
}
}
}
return pDestTrk;
}
void __fastcall TUseStylePanel::InsertStage( int iInsertBar, TSegmentItem* pSrcSeg )
{
Stop();
int iDestStage = GetInsertStage( iInsertBar );
TOpusStage* pNewStage = new TOpusStage;
pNewStage->iSegKey = g_iMelodyKey;
pNewStage->iSegNo = pSrcSeg->iSegNo;
pNewStage->iSegType = pSrcSeg->iSegType;
pNewStage->nVol = pSrcSeg->volume;
int nBarNum = 0;
if( pSrcSeg->iSegType>=SEGTYPE_INTRO )
nBarNum = pSrcSeg->nBars;
bool bPreChange = g_iPreStage==0;
if( bPreChange ){
DuplicateRawBars();
}
for( int j=0; j<nBarNum; j++ ){
TBar* pBar = new TBar;
pNewStage->aBars.push_back(pBar);
}
bool bCountDown = false;
for( int i=1; i<g_aAudioTracks.size(); i++ ){
bCountDown |= MoveAudio( -1, 0, nBarNum, i, iInsertBar, MODE_INSERT | OPT_BARS );
}
ProduceTracks( pNewStage, pSrcSeg );
g_Opus.InsertStage( iDestStage, pNewStage );
g_Midi.InsertStage( iDestStage );
int nMTCountOld = g_aMidiTracks.size();
for( int i=0; i<pNewStage->aTracks.size(); i++ ){
TTrack* pTrack = pNewStage->aTracks[i];
TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iDestStage, pTrack->iFile, pTrack->iChanNo,
pTrack->iBank, pTrack->iProg );
pTrack->iFile = pMT->file;
pTrack->iChanSpec = pMT->chno;
}
if( bPreChange || nMTCountOld!=g_aMidiTracks.size() )
m_pContentPanel->InitialVars();
InsertSegment( iDestStage, pSrcSeg, nBarNum );
IntegrateStages( iDestStage );
ResetScrollBar();
Paint();
m_pContentPanel->OnStageChanged( iDestStage, MODE_INSERT );
}
//-----------------------------------------------------------------------------
void __fastcall TUseStylePanel::RemoveStage( int iStage )
{
TStyleItem* pStyle = (TStyleItem*)m_aItems->First();
TSegmentItem* pSegItem = (TSegmentItem*)pStyle->aItems->Items[iStage];
bool bPreChange = g_iPreStage==0;
if( bPreChange )
DuplicateRawBars();
f_MM_AddUndoBefore( -1, NULL );
SetBarsUndo( UNDO_BAR_DELETE, FirstBar(iStage), pSegItem->nBars );
RemoveSegment( pSegItem );
f_MM_AddUndoAfter( -1, NULL );
IntegrateStages( iStage );
ResetScrollBar();
Paint();
// InvalidateRgn( Handle, NULL, false );
if( bPreChange )
m_pContentPanel->InitialVars();
m_pContentPanel->OnStageChanged( iStage, MODE_DELETE );
}
//-----------------------------------------------------------------------------
void __fastcall TUseStylePanel::MoveBars( int iStartBar, int iEndBar, int iInsertBar, int iMode )
{
if( iMode==MODE_MOVE && ( iInsertBar>=iStartBar && iInsertBar<=iEndBar+1 ) )//无须移动
return;
Stop();
bool bPreChange = g_iPreStage==0;
if( bPreChange )
DuplicateRawBars();
int nBars = iEndBar - iStartBar + 1,
nOrigBars = g_Opus.BarCount();
if( iMode==MODE_DELETE ){
SetBarsUndo( UNDO_BAR_DELETE, iStartBar, nBars );
}
else if( iMode==MODE_MOVE ){
SetBarsUndo( UNDO_BAR_MOVE, iStartBar, nBars, iInsertBar );
}
f_MM_AddUndoBefore( -1, NULL );
int iDestStage = GetInsertStage( iInsertBar ),
iSrcStage = FindStage( iStartBar, NULL ),
iFirstChangeStage = (iMode==MODE_MOVE) ? min(iSrcStage, iDestStage) :
(iMode==MODE_DELETE) ? iSrcStage : iDestStage;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
if( g_Theme.IsWeadup() && iStartBar==0 && iEndBar==0
&& ( iMode==MODE_MOVE || iMode==MODE_DELETE )){
TOpusStage* pFirstStage = g_lstOpusStages[iSrcStage];
if( pFirstStage->iSegType<=SEGTYPE_FILL ){
if( !memcmp( g_aAudioTracks[1]->lstBars[0]->aVols,
g_aAudioTracks[0]->lstBars[0]->aVols,
POINTS_PER_BAR * sizeof(DWORD) )){
m_bAddWeakupBar = false;
}
}
}
// 音频操作
bool bCountDown = false;
for( int i=1; i<g_aAudioTracks.size(); i++ ){
bCountDown |= MoveAudio( i, iStartBar, iEndBar+1, i, iInsertBar, iMode | OPT_BARS );
}
// 曲式操作
int iBar = iStartBar;
int nBarCount = 0, nMTCount = g_aMidiTracks.size();
while( iBar<=iEndBar ){
int iFirstBar, nOffsetBar;
iSrcStage = FindStage( iBar, &iFirstBar ),
nOffsetBar = iBar-iFirstBar;
TSegmentItem* pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iSrcStage];
TOpusStage* pOriStage = g_lstOpusStages[iSrcStage];
TOpusStage* pNewStage = (iMode==MODE_DELETE) ? NULL : new TOpusStage;
int nCopyBar = pOriStage->aBars.size() - nOffsetBar;
if( nCopyBar>iEndBar-iBar+1 )
nCopyBar = iEndBar-iBar+1;
if( pNewStage ){
pNewStage->iSegKey = pOriStage->iSegKey;
pNewStage->iSegNo = pOriStage->iSegNo;
pNewStage->iSegType = pOriStage->iSegType;
pNewStage->nVol = pOriStage->nVol;
for( int i=0; i<pOriStage->aTracks.size(); i++ ){
TTrack * pTrack = new TTrack( pOriStage->aTracks[i] );
pNewStage->aTracks.push_back( pTrack );
}
}
int iCopyBar = nOffsetBar;
for( int i=0; i<nCopyBar; i++ ){
if( pNewStage ){
TBar* pBar = NULL;
if( iMode==MODE_COPY )
pBar = new TBar( pOriStage->aBars[iCopyBar] );
else
pBar = pOriStage->aBars[iCopyBar];
pNewStage->aBars.push_back( pBar );
}
if( iMode==MODE_MOVE || iMode==MODE_DELETE )
pOriStage->aBars.erase( pOriStage->aBars.begin() + iCopyBar );
else
iCopyBar++;
}
if( iMode!=MODE_DELETE ){
g_lstOpusStages.insert( g_lstOpusStages.begin()+iDestStage, pNewStage );
g_Midi.CutStage( iDestStage );
InsertSegment( iDestStage, pSrcSeg, nCopyBar );
}
if( iMode==MODE_MOVE || iMode==MODE_DELETE ){
if( iMode==MODE_MOVE && iDestStage<=iSrcStage )
iSrcStage++;
else{
iBar -= nCopyBar;
iEndBar -= nCopyBar;
}
if( pOriStage->aBars.size()==0 ){ //删除原段落
RemoveSegment( pSrcSeg );
if( iMode!=MODE_DELETE && iDestStage>=iSrcStage )
iDestStage--;
}
else{
pSrcSeg->nBars -= nCopyBar;
}
pStyleItem->nBars -= nCopyBar;
}
else if( iDestStage<=iSrcStage ){
iBar += nCopyBar;
iEndBar += nCopyBar;
}
g_Opus.CountBars();
iBar += nCopyBar;
if( iMode!=MODE_DELETE ){
nBarCount += nCopyBar;
iDestStage++;
}
}
if( iMode!=MODE_MOVE )
g_Opus.CountBars();
IntegrateStages( iFirstChangeStage );
f_MM_AddUndoAfter( -1, NULL );
if( iMode==MODE_COPY ){
SetBarsUndo( UNDO_BAR_INSERT, iInsertBar, nBars );
}
else{
//计算是否AddWeakupBar
bool bAddWeakupBar = false;
int nCurrBars = g_Opus.BarCount();
if( iMode==MODE_MOVE && nCurrBars>nOrigBars
|| iMode==MODE_DELETE && nCurrBars>nOrigBars-nBars )
bAddWeakupBar = true;
if( bAddWeakupBar )
g_Undo.SetUndoCode( bAddWeakupBar );
}
if( iMode==MODE_DELETE ){
m_pContentPanel->SelectBars( -1, - 1 );
/* if( pStyleItem->aItems->Count==0 ){
// g_Midi.ClearMidiTracks();
ClearAllItems();
g_pUseStyle = NULL;
}
*/
}
else if( iMode==MODE_COPY || iInsertBar<iStartBar ){
m_pContentPanel->SelectBars( iInsertBar, iInsertBar + nBars - 1 );
}
else if( iInsertBar>iEndBar ){
m_pContentPanel->SelectBars( iInsertBar - nBars, iInsertBar - 1 );
}
ResetScrollBar();
Paint();
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
if( bPreChange || (bDeletedMT || nMTCount!=g_aMidiTracks.size() )
&& !m_pContentPanel->IsVertical() )
m_pContentPanel->InitialVars();
m_pContentPanel->OnStageChanged( bCountDown ? 0 : iFirstChangeStage, iMode );
}
//-----------------------------------------------------------------------------
void __fastcall TUseStylePanel::ReformBars( int iStartBarP, int iEndBarP,
TSegmentItem* pSrcSeg, bool bAddUndo )
{
Stop();
int iStartBar = iStartBarP;
int iChangeStage = -1;
TOpusStageList* lstStageBefore = NULL;
if( bAddUndo ){
lstStageBefore = new TOpusStageList;
g_Opus.CopyStages( iStartBarP, iEndBarP, lstStageBefore );
}
while( iStartBar<=iEndBarP ){
int iFirstBar,
iStage = FindStage( iStartBar, &iFirstBar );
TOpusStage* pOriStage = g_lstOpusStages[iStage];
if( pOriStage->iSegType>=SEGTYPE_INTRO ){
iStartBar = iFirstBar + pOriStage->aBars.size();
}
else{
bool bChange = false;
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pOriSegItem = (TSegmentItem*)pStyleItem->aItems->Items[iStage];
TSegmentItem* pDestSegItem = NULL;
if( pOriStage->iSegType==pSrcSeg->iSegType
&& pOriStage->iSegNo==pSrcSeg->iSegNo
&& pOriStage->nVol==pSrcSeg->volume
&& pOriStage->aTracks.size()==pSrcSeg->aItems->Count ){
if( pOriStage->aTracks.size()>0 ){
int num = pOriStage->aTracks.size();
bool* aMatch = new bool[num];
memset( aMatch, false, sizeof(bool)*num );
for( int i=0; i<num; i++ ){
TTrack* pTrk1 = pOriStage->aTracks[i];
bool bFound = false;
for( int j=0; j<num; j++ ){
TTrack* pTrk2 = ((TTrackItem*)pSrcSeg->aItems->Items[j])->pTrack;
if( !aMatch[j] && pTrk1->iStyleId==pTrk2->iStyleId
&& pTrk1->iStyleLoc==pTrk2->iStyleLoc
&& pTrk1->iSegNo==pTrk2->iSegNo
&& pTrk1->iChanNo==pTrk2->iChanNo
&& pTrk1->iBank==pTrk2->iBank
&& pTrk1->iProg==pTrk2->iProg
&& pTrk1->nVol==pTrk2->nVol ){
bFound = true;
aMatch[j] = true;
break;
}
}
if( !bFound ){
bChange = true;
break;
}
}
delete[] aMatch;
}
}
else
bChange = true;
if( !bChange )
iStartBar = iFirstBar + pOriStage->aBars.size();
else{
TOpusStage* pBrushStage = NULL;
int iEndBar = iFirstBar + pOriStage->aBars.size()-1;
if( iEndBar>iEndBarP ){
g_Opus.CutStage( iStage, iEndBarP+1 );
g_Midi.CutStage( iStage );
InsertSegment( iStage+1, pOriSegItem, iEndBar - iEndBarP );
pOriSegItem->nBars -= iEndBar - iEndBarP;
pStyleItem->nBars -= iEndBar - iEndBarP;
iEndBar = iEndBarP;
}
if( iStartBar>iFirstBar ){
g_Opus.CutStage( iStage, iStartBar );
g_Midi.CutStage( iStage );
pDestSegItem = InsertSegment( iStage+1, pOriSegItem, iEndBar-iStartBar+1 );
pOriSegItem->nBars -= iEndBar-iStartBar+1;
pStyleItem->nBars -= iEndBar-iStartBar+1;
iStage++;
}
else{
pBrushStage = pOriStage;
pDestSegItem = pOriSegItem;
}
ReplaceSegment( pDestSegItem, pSrcSeg );
//g_Opus.CountBars();
iStartBar = iEndBar + 1;
if( iChangeStage<0 )
iChangeStage = iStage;
}
}
}
if( iChangeStage>=0 ){
IntegrateStages( iChangeStage );
if( bAddUndo ){
TOpusStageList* lstStageAfter = new TOpusStageList;
g_Opus.CopyStages( iStartBarP, iEndBarP, lstStageAfter );
g_Undo.AddUndo( UNDO_BAR_CHANGE, 0, iStartBarP, iEndBarP,
(void*)lstStageBefore, (void*)lstStageAfter );
}
ResetScrollBar();
Paint();
m_pContentPanel->OnStageChanged( iChangeStage, MODE_CHANGE );
}
else if( lstStageBefore ){
for( int i=0; i<lstStageBefore->size(); i++ ){
delete (*lstStageBefore)[i];
}
delete lstStageBefore;
}
}
void __fastcall TUseStylePanel::ReformStage( int iDestStage, TSegmentItem* pSrcSeg )
{
Stop();
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pDestSeg = (TSegmentItem*)pStyleItem->aItems->Items[iDestStage];
int iStartBar = FirstBar( iDestStage ),
iEndBar = iStartBar + pDestSeg->nBars -1,
nOffset = 0;
bool bMMUndo = false;
TAudioTrackList* lstAudio = NULL;
TOpusStageList* lstStageBefore = new TOpusStageList;
g_Opus.CopyStages( iStartBar, iEndBar, lstStageBefore );
if( pSrcSeg->iSegType>=SEGTYPE_INTRO && pSrcSeg->nBars!=pDestSeg->nBars ){
nOffset = pSrcSeg->nBars - pDestSeg->nBars;
if( nOffset<0 ){ //小节减少,复制将删除部分波形
int nWaveBars = -nOffset;
lstAudio = new TAudioTrackList;
g_Audio.CopyTrackList( iEndBar+nOffset+1, nWaveBars, lstAudio );
}
bMMUndo = true;
}
if( bMMUndo ){
f_MM_AddUndoBefore( -1, NULL );
}
ReplaceSegment( pDestSeg, pSrcSeg );
IntegrateStages( iDestStage );
// if( bMMUndo ){
// f_MM_AddUndoAfter( -1, NULL );
// }
TOpusStageList* lstStageAfter = new TOpusStageList;
g_Opus.CopyStages( iStartBar, iEndBar+nOffset, lstStageAfter );
g_Undo.AddUndo( UNDO_BAR_CHANGE, 0, iStartBar, iEndBar,
(void*)lstStageBefore, (void*)lstStageAfter );
if( bMMUndo ){
f_MM_AddUndoAfter( -1, NULL );
g_Undo.SetUndoExtra( nOffset, 0, 0, (void*)lstAudio, NULL );
}
ResetScrollBar();
Paint();
m_pContentPanel->OnStageChanged( iDestStage, MODE_CHANGE );
}
//-----------------------------------------------------------------------------
void __fastcall TUseStylePanel::InitOpus( TStyleItem* pPreStyle, int iMode )
{
//清空内容
ClearGlobalVars( LIST_OPUSSTAGES | LIST_OPUSAUDIOS );
ClearAllItems();
g_pUseStyle = NULL;
m_bAddWeakupBar = true;
if( iMode<0 || !pPreStyle ){
ClearGlobalVars( LIST_RAWAUDIO );
m_pContentPanel->InitialVars();
Paint();
return;
}
if( iMode==0 ){
UINT idLoc, idStyle;
g_Theme.Get( idLoc, idStyle, g_lstOpusStages );
g_pUseStyle = AddStyle( GetStyleInfo( idLoc, idStyle ) );
for( int i=0; i<g_lstOpusStages.size(); i++ ){
TOpusStage* pStage = g_lstOpusStages[i];
AddStage( pStage );
}
g_aAudioTracks[0]->Hide(false);
((TStyleItem*)m_aItems->First())->SetCharge( g_pUseStyle->pStyle->idLoc==0
&& g_pUseStyle->pStyle->pOrigin->cost>0 );
}
else{
g_pUseStyle = AddStyle( pPreStyle->pStyle );
int iFirstStage = g_Theme.IsWeadup() ? 1 : 0;
int nRepeat = iMode>=2 ? 2 : 1;
int nSegNum[4];
vector<TSegmentItem*> aSegments[4];
memset( nSegNum, 0, sizeof(int)*4 );
for( int i=0; i<pPreStyle->aItems->Count; i++ ){
TSegmentItem* pSegment = (TSegmentItem*)pPreStyle->aItems->Items[i];
int stype = pSegment->GetSegType();
aSegments[stype].push_back( pSegment );
nSegNum[stype]++;
}
if( g_aAudioTracks[0]->lstBars.size()>0 ){
DuplicateRawBars();
if( iMode==2 )
MoveAudio( 1, 0, g_aAudioTracks[0]->lstBars.size(), 1, 0, MODE_COPY | OPT_BARS );
}
int iSegNo;
int nBarCount = 0;
int nThemeStages = g_Theme.StageCount();
while( nRepeat>0 ){
if( iMode>0 && iMode<=3 && nSegNum[SEGTYPE_INTRO]>0 ){ //添加前奏
int iM = iMode>=2 ? 2 : 1;
iSegNo = (iM - nRepeat) % nSegNum[SEGTYPE_INTRO];
int iChord = g_Theme.GetFirstChord();
int ctype = LOWORD( iChord ),
key = HIWORD( iChord );
if( ctype==3 ) ctype = 1;
else if( ctype>1 ) ctype = 0;
if( ctype==1 )
key = ( key + 3 ) % 12;
TSegmentItem *pSegment = NULL;
TSegmentItem* pBackup = NULL;
for( int j=0; j<nSegNum[SEGTYPE_INTRO]; j++ ){
if( aSegments[SEGTYPE_INTRO][j]->iSegNo / 4 == ctype ){
if( aSegments[SEGTYPE_INTRO][j]->iSegNo % 4 == iSegNo ){
pSegment = aSegments[SEGTYPE_INTRO][j];
break;
}
else{
pBackup = aSegments[SEGTYPE_INTRO][j];
}
}
}
if( !pSegment ){
if( pBackup )
pSegment = pBackup;
else
pSegment = aSegments[SEGTYPE_INTRO][0]; //大小调不分
}
TOpusStage* pNewStage = new TOpusStage;
pNewStage->iSegNo = pSegment->iSegNo;
pNewStage->iSegType = SEGTYPE_INTRO;
pNewStage->iSegKey = key;
pNewStage->nVol = pSegment->volume;
int nBarNum = pSegment->nBars;
for( int i=0; i<nBarNum; i++ ){
TBar* pBar = new TBar;
pNewStage->aBars.push_back(pBar);
}
ProduceTracks( pNewStage, pSegment );
g_lstOpusStages.push_back( pNewStage );
int nWaveBars = nBarNum;
if( iFirstStage>0 )
nWaveBars--;
if( g_aAudioTracks.size()>1 )
MoveAudio( -1, 0, nWaveBars, 1, nBarCount, MODE_INSERT | OPT_BARS );
InsertSegment( -1, pSegment, nBarNum );
nBarCount += nBarNum;
}
//添加主旋律部分
iSegNo = 0;
int iStartStage = iFirstStage;
if( iMode>2 && nRepeat==1 && nThemeStages>iFirstStage + 2 ){
iStartStage++;
if( nSegNum[SEGTYPE_VAR]>1 )
iSegNo = 1;
}
for( int i=iStartStage; i<nThemeStages; i++ ){
TOpusStage* pStage = g_Theme.CopyStageAt( i );
g_lstOpusStages.push_back( pStage );
TSegmentItem* pSegItem = AddStage( pStage );
nBarCount += pStage->aBars.size();
if( i==nThemeStages-1 && nSegNum[SEGTYPE_FILL]>0 && pStage->aBars.size()>1
&& iMode>0 && iMode<=3 && ( nRepeat>0 && nSegNum[SEGTYPE_INTRO]>0
|| nRepeat==0 && nSegNum[SEGTYPE_ENDING]>0 )){
int iFill = 1 % nSegNum[SEGTYPE_FILL];
TSegmentItem *pSegFill = aSegments[SEGTYPE_FILL][iFill];
TOpusStage * pFillStage = new TOpusStage;
pFillStage->iSegType = SEGTYPE_FILL;
pFillStage->iSegNo = pSegFill->iSegNo;
pFillStage->iSegKey = pStage->iSegKey;
pFillStage->nVol = pStage->nVol;
pFillStage->aBars.push_back( pStage->aBars.back() );
pStage->aBars.pop_back();
pSegItem->nBars--;
g_pUseStyle->nBars--;
ProduceTracks( pFillStage, pSegFill );
g_lstOpusStages.push_back( pFillStage );
AddStage( pFillStage );
}
}
nRepeat--;
}
if( iMode<=3 && nSegNum[SEGTYPE_ENDING]>0 ){ //添加尾奏
int iChord = g_Theme.GetLastChord();
int ctype = LOWORD( iChord ),
key = HIWORD( iChord );
if( ctype==3 ) ctype = 1;
else if( ctype>1 ) ctype = 0;
if( ctype==1 )
key = ( key + 3 ) % 12;
TSegmentItem *pSegment = NULL;
for( int j=0; j<nSegNum[SEGTYPE_ENDING]; j++ ){
if( aSegments[SEGTYPE_ENDING][j]->iSegNo / 4 == ctype ){
pSegment = aSegments[SEGTYPE_ENDING][j];
break;
}
}
if( !pSegment ){
pSegment = aSegments[SEGTYPE_ENDING][0]; //大小调不分
}
TOpusStage* pNewStage = new TOpusStage;
pNewStage->iSegType = SEGTYPE_ENDING;
pNewStage->iSegNo = pSegment->iSegNo;
pNewStage->iSegKey = key;
pNewStage->nVol = pSegment->volume;
int nBarNum = pSegment->nBars;
for( int i=0; i<nBarNum; i++ ){
TBar* pBar = new TBar;
pNewStage->aBars.push_back(pBar);
}
ProduceTracks( pNewStage, pSegment );
g_lstOpusStages.push_back( pNewStage );
if( g_aAudioTracks.size()>1 )
MoveAudio( -1, 0, nBarNum, 1, nBarCount, MODE_INSERT | OPT_BARS );
InsertSegment( -1, pSegment, nBarNum );
nBarCount += nBarNum;
}
}
g_Opus.CountBars();
IntegrateStages( 0 );
g_Midi.SortMidiTracks();
SetFold( (TCommonItem*)m_aItems->First(), 0 );
ResetScrollBar();
Paint();
// InvalidateRgn( Handle, NULL, false );
m_pContentPanel->OnStageChanged( 0, MODE_INIT );
}
// ---------------------------------------------------------------------------
void __fastcall TUseStylePanel::SetStyleItem( TStyleItem* pStyItem )
{
TStylePanel::SetStyleItem( pStyItem );
if( pStyItem ){
IntegrateStages( 0, false );
if( g_Midi.IsEmpty() )
g_Midi.SortMidiTracks();
}
}
// ---------------------------------------------------------------------------
void TUseStylePanel::RestoreItems()
{
for( int i=0; i<g_lstOpusStages.size(); i++ ){
AddStage( g_lstOpusStages[i] );
}
}
// ---------------------------------------------------------------------------
void __fastcall TUseStylePanel::InsertBlankBar( int iInsertBar )
{
Stop();
TOpusStage* pNewStage = new TOpusStage;
TBar * pNewBar = new TBar;
pNewStage->aBars.push_back( pNewBar ); //添加一个小节
int iBarT1 = iInsertBar;
// 处理弱起
if( g_bWeakup ){
if( iInsertBar>0 ){
int iFirstBar,
iLastStage = FindStage( iInsertBar-1, &iFirstBar );
TOpusStage *pLastStage = g_lstOpusStages[iLastStage];
if( pLastStage->iSegType>SEGTYPE_FILL
&& !memcmp( g_aAudioTracks[1]->lstBars[iInsertBar-1]->aVols,
g_aAudioTracks[0]->lstBars[0]->aVols,
POINTS_PER_BAR * sizeof(DWORD) )){
iBarT1--;
}
}
}
bool bCountDown = false;
for( int i=1; i<g_aAudioTracks.size(); i++ ){
// 音效处理
bCountDown |= MoveAudio( -1, 0, 1, i, iInsertBar, MODE_INSERT | OPT_BARS );
}
int iDestStage = GetInsertStage( iInsertBar );
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
//根据前后小节位置确定和弦与伴奏型
TSegmentItem *pSrcSeg = NULL;
int iFirstBar1, iFirstBar2,
iLastStage = FindStage( iInsertBar-1, &iFirstBar1 ),
iNextStage = FindStage( iInsertBar, &iFirstBar2 );
TOpusStage *pLastStage = iLastStage>=0 ? g_lstOpusStages[iLastStage] : NULL,
*pNextStage = g_lstOpusStages[iNextStage];
//是否前一小节可用
if( pLastStage && pLastStage->iSegType<=SEGTYPE_FILL ){
pNewStage->iSegKey = pLastStage->iSegKey;
TBar *pLastBar = pLastStage->aBars[iInsertBar-iFirstBar1-1];
pNewBar->iBarKey = pLastBar->iBarKey;
for( int i=0; i<g_nChordNumPerBar; i++ ){
pNewBar->aChords.iKey[i] = pLastBar->aChords.iKey[g_nChordNumPerBar-1];
pNewBar->aChords.iType[i] = pLastBar->aChords.iType[g_nChordNumPerBar-1];
}
pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iLastStage];
}
else if( pNextStage->iSegType<=SEGTYPE_FILL ){ //是否后一小节可用
pNewStage->iSegKey = pNextStage->iSegKey;
TBar *pNextBar = pNextStage->aBars[iInsertBar-iFirstBar2];
pNewBar->iBarKey = pNextBar->iBarKey;
for( int i=0; i<g_nChordNumPerBar; i++ ){
pNewBar->aChords.iKey[i] = pNextBar->aChords.iKey[0];
pNewBar->aChords.iType[i] = pNextBar->aChords.iType[0];
}
pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iNextStage];
}
else{ //前后小节皆不可用
int iSegKey,
iKey,
iType = 0;
if( pLastStage ){
iKey = pNewBar->iBarKey = pNewStage->iSegKey = pLastStage->iSegKey;
if( pLastStage->iSegNo % 2 > 0 ){
iKey = ( iKey + 9 ) % 12;
iType = 1;
}
}
else{
iKey = pNewBar->iBarKey = pNewStage->iSegKey = pNextStage->iSegKey;
if( pNextStage->iSegNo % 2 > 0 ){ //小调
iKey = ( iKey + 9 ) % 12;
iType = 1;
}
}
for( int i=0; i<g_nChordNumPerBar; i++ ){
pNewBar->aChords.iKey[i] = iKey;
pNewBar->aChords.iType[i] = iType;
}
for( int i=0; i<g_pPreStyle->aItems->Count; i++ ){
TSegmentItem* pSegment = (TSegmentItem*)g_pPreStyle->aItems->Items[i];
int stype = pSegment->GetSegType();
if( stype==SEGTYPE_VAR || stype==SEGTYPE_FILL ){
pSrcSeg = pSegment;
break;
}
}
}
pNewStage->iSegType = pSrcSeg->iSegType;
pNewStage->iSegNo = pSrcSeg->iSegNo;
// ProduceTracks( pNewStage, pSrcSeg );
g_Opus.InsertStage( iDestStage, pNewStage );
g_Midi.InsertStage( iDestStage );
InsertSegment( iDestStage, pSrcSeg, 1 );
IntegrateStages( iDestStage );
ResetScrollBar();
Paint();
m_pContentPanel->OnStageChanged( iDestStage, MODE_INSERT );
}
// ---------------------------------------------------------------------------
void TUseStylePanel::CountStyles()
{
m_aStyles.clear();
if( m_aItems->Count==0 )
return;
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
TPROSTYLE* pStyle = pStyItem->pStyle,
*pMainStyle = NULL;
vector<int> lstCount;
for( int i=0; i<pStyItem->aItems->Count; i++ ){
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
for( int j=0; j<pSeg->aItems->Count; j++ ){
TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
bool bMatch = false;
for( int k=0; k<m_aStyles.size(); k++ ){
// if( pTrk->pStyle->idLoc==m_aStyles[k]->idLoc
// && pTrk->pStyle->idStyle==m_aStyles[k]->idStyle ){
if( pTrk->pStyle==m_aStyles[k] ){
bMatch = true;
lstCount[k]++;
break;
}
}
if( !bMatch ){
m_aStyles.push_back( pTrk->pStyle );
lstCount.push_back( 1 );
}
}
}
bool bKeep = false;
bool bCharge = false;
int maxCount = 0;
for( int i=0; i<lstCount.size(); i++ ){
if( lstCount[i]>maxCount ){
maxCount = lstCount[i];
pMainStyle = m_aStyles[i];
}
if( pStyle && pStyle->idLoc==m_aStyles[i]->idLoc
&& pStyle->idStyle==m_aStyles[i]->idStyle ){
bKeep = true;
}
if( !bCharge && m_aStyles[i]->idLoc==0
&& m_aStyles[i]->pOrigin->cost>0 ){
bCharge = true;
}
}
if( !pStyle || !bKeep ){
pStyItem->pStyle = pMainStyle;
if( m_pTopItem==pStyItem )
DrawItem( pStyItem, 0, -1 );
}
pStyItem->SetCharge( bCharge );
}
// ---------------------------------------------------------------------------
void TUseStylePanel::CopyUndoBars( int iStartBar, int iEndBar, TOpusStageList* lstStages,
TAudioTrackList* lstAudio, bool bFx )
{
if( lstStages )
g_Opus.CopyStages( iStartBar, iEndBar, lstStages );
if( lstAudio )
g_Audio.CopyTrackList( iStartBar, iEndBar-iStartBar+1, lstAudio, bFx );
}
void TUseStylePanel::CopyBars( int iStartBar, int iEndBar, TOpusStageList* lstStages,
TSegmentList* lstSegments, TAudioTrackList* lstAudio )
{
int iBar = iStartBar;
while( iBar<=iEndBar ){
int iFirstBar, iSrcStage = FindStage( iBar, &iFirstBar ),
nOffsetBar = iBar-iFirstBar;
TOpusStage* pOriStage = g_lstOpusStages[iSrcStage];
int nCopyBar = pOriStage->aBars.size() - nOffsetBar;
if( nCopyBar>iEndBar-iBar+1 )
nCopyBar = iEndBar-iBar+1;
if( lstStages ){
TOpusStage* pNewStage = new TOpusStage( pOriStage );
for( int i=nOffsetBar; i<nCopyBar; i++ ){
pNewStage->aBars.push_back( new TBar( pOriStage->aBars[i] ) );
}
for( int j=0; j<pOriStage->aTracks.size(); j++ ){
pNewStage->aTracks.push_back( new TTrack( pOriStage->aTracks[j] ));
}
lstStages->push_back( pNewStage );
}
iBar += nCopyBar;
}
if( lstAudio ){
for( int i=1; i<g_aAudioTracks.size(); i++ ){
TAudioTrack* pAudio = CopyAudioTrack( i, iStartBar, iEndBar-iStartBar+1 );
lstAudio->push_back( pAudio );
}
}
}
// ---------------------------------------------------------------------------
/*
void TUseStylePanel::InsertStages( int iInsertBar, TOpusStageList lstStages )
{
int iDestStage = GetInsertStage( iInsertBar );
for( int i=lstStages.size()-1; i>=0; i-- ){
TOpusStage* pStage = lstStages[i];
g_lstOpusStages.insert( g_lstOpusStages.begin()+iDestStage, pStage );
}
}
// ---------------------------------------------------------------------------
*/
void TUseStylePanel::DeleteBars( int iStartBarP, int iEndBarP, bool bDelWave )
{
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
int iBar = iStartBarP,
iEndBar = iEndBarP;
while( iBar<=iEndBar ){
int iFirstBar, iSrcStage = FindStage( iBar, &iFirstBar ),
nOffsetBar = iBar-iFirstBar;
TSegmentItem* pSrcSeg = (TSegmentItem*)pStyItem->aItems->Items[iSrcStage];
TOpusStage* pOriStage = g_lstOpusStages[iSrcStage];
int nDelBar = pOriStage->aBars.size() - nOffsetBar;
if( nDelBar>iEndBar-iBar+1 )
nDelBar = iEndBar-iBar+1;
pOriStage->aBars.erase( pOriStage->aBars.begin() + nOffsetBar,
pOriStage->aBars.begin() + nOffsetBar + nDelBar );
iEndBar -= nDelBar;
g_Opus.ChangeStageBar( iSrcStage, -nDelBar, true );
if( pOriStage->aBars.empty() ){ //删除原段落
RemoveSegment( pSrcSeg, false );
}
else{
pSrcSeg->nBars -= nDelBar;
}
pStyItem->nBars -= nDelBar;
}
// g_Opus.CountBars();
if( bDelWave ){
for( int i=1; i<g_aAudioTracks.size(); i++ ){
RemoveWaveBars( i, iStartBarP, iEndBarP - iStartBarP + 1 );
// RemoveAudioEffects( g_aAudioTracks[i]->lstEffects, iStartBarP, iEndBarP+1 );
}
}
m_pContentPanel->SelectBars( -1, -1 );
}
// ---------------------------------------------------------------------------
void TUseStylePanel::Undo( bool bUndo )
{
if( m_VolTrackBar ){
delete m_VolTrackBar;
m_VolTrackBar = NULL;
}
int iMode=-1, iChangeStage = 0;
TUndoLite* pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo();
int iType = pLite->iType;
if( ( iType<UNDO_MIDI_ADD || iType>UNDO_MIDI_FONT )
&& ( iType<UNDO_TRKMID_ADD || iType>UNDO_TRKMID_DELALL )
&& VIEW_STYLE!=g_iViewMode )
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 );
if( iType!=UNDO_STAGE_VOL )
Stop();
if( iType>=UNDO_BAR_INSERT && iType<=UNDO_BAR_CHANGE ){
if( bUndo && pLite->iCode>0 ){ //处理AddWeakupBar
m_bAddWeakupBar = true;
//删除第一小节
for( int i=1; i<g_aAudioTracks.size(); i++ ){
TAudioTrack* pAT = g_aAudioTracks[i];
delete pAT->lstBars[0];
pAT->lstBars.erase( pAT->lstBars.begin() );
}
TOpusStage* pStage = g_lstOpusStages[0];
delete pStage->aBars[0];
pStage->aBars.erase( pStage->aBars.begin() );
g_Opus.CountBars();
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pSegment = (TSegmentItem*)pStyItem->aItems->Items[0];
pSegment->nBars--;
pStyItem->nBars--;
}
int iDelStart = pLite->iBegin,
iDelEnd = pLite->iEnd,
iInsStart = pLite->iBegin,
iInsEnd = pLite->iEnd,
nBars = pLite->iEnd - pLite->iBegin + 1;
TOpusStageList* lstStages = ( iType>=UNDO_BAR_CHANGE && !bUndo || iType==UNDO_BAR_INSERT )
? (TOpusStageList*)pLite->pAfter
: (TOpusStageList*)pLite->pBefore;
if( iType<UNDO_BAR_CHANGE || pLite->iExt1 )
f_MM_Undo( bUndo );
if( iType==UNDO_BAR_INSERT && bUndo
|| iType==UNDO_BAR_DELETE && !bUndo ){
iMode = MODE_DELETE;
}
else if( iType==UNDO_BAR_INSERT && !bUndo
|| iType==UNDO_BAR_DELETE && bUndo ){
iMode = MODE_INSERT;
}
else if( iType==UNDO_BAR_MOVE ){
iMode = MODE_MOVE;
if( bUndo ){
iDelStart = pLite->iExt1;
iDelEnd = iDelStart + nBars - 1;
}
else{
iInsStart = pLite->iExt1;
iInsEnd = iInsStart + nBars - 1;
}
}
else{
iMode = MODE_CHANGE;
if( bUndo )
iDelEnd += pLite->iExt1;
else
iInsEnd += pLite->iExt1;
}
iChangeStage = FindStage( min( iDelStart, iInsStart ), NULL );
int nMTCount = g_aMidiTracks.size();
if( iMode==MODE_DELETE || iMode==MODE_MOVE || iMode==MODE_CHANGE ){
DeleteBars( iDelStart, iDelEnd, iMode==MODE_CHANGE ? false : true );
}
if( iMode==MODE_INSERT || iMode==MODE_MOVE || iMode==MODE_CHANGE ){
//还原波形
if( iMode==MODE_INSERT || iMode==MODE_MOVE ){
TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
for( int i=1; i<g_aAudioTracks.size(); i++ ){
TAudioTrack* pAudio = lstAudio ? (*lstAudio)[i-1] : NULL;
InsertAudioTrack( i, iInsStart, nBars, pAudio );
}
}
if( iMode==MODE_CHANGE ){
if( iInsEnd > iDelEnd ){
TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
for( int i=1; i<g_aAudioTracks.size(); i++ ){
TAudioTrack* pAudio = lstAudio ? (*lstAudio)[i-1] : NULL;
InsertAudioTrack( i, iDelEnd+1, iInsEnd-iDelEnd, pAudio );
}
}
else if( iInsEnd<iDelEnd ){
for( int i=1; i<g_aAudioTracks.size(); i++ ){
RemoveWaveBars( i, iInsEnd+1, iDelEnd-iInsEnd );
}
}
}
//还原Segment和OpusStage
int iStage = GetInsertStage( iInsStart );
if( iStage<0 )
iStage = 0;
for( int s=0; s<(*lstStages).size(); s++ ){
TOpusStage* pStage = DuplicateStage( (*lstStages)[s] );
g_Opus.InsertStage( iStage, pStage );
g_Midi.InsertStage( iStage );
TSegmentItem* pSegment = new TSegmentItem;
pSegment->iSegType = pStage->iSegType;
pSegment->iSegNo = pStage->iSegNo;
pSegment->volume = pStage->nVol;
pSegment->nBars = pStage->aBars.size();
DWORD opts = OPT_DEL|OPT_VOL;
if( pStage->iSegType<SEGTYPE_INTRO )
opts |= OPT_TEXTURE;
//检查风格有效性
for( int i=0; i<pStage->aTracks.size(); i++ ){
TTrack* pTrack = pStage->aTracks[i];
TPROSTYLE* pStyle = GetStyleInfo( pTrack->iStyleLoc, pTrack->iStyleId );
if( pStyle ){
pSegment->AddTrack( pStyle, pTrack, opts, false );
TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iStage, pTrack->iFile, pTrack->iChanSpec,
pTrack->iBank, pTrack->iProg );
pTrack->iFile = pMT->file;
pTrack->iChanSpec = pMT->chno;
}
else{
DebugPrint( "风格文件已失效!\n" );
delete pTrack;
pStage->aTracks.erase( pStage->aTracks.begin() + i );
i--;
}
}
InsertSegment( iStage, pSegment, pStage->aBars.size() );
delete pSegment;
iStage++;
}
m_pContentPanel->SelectBars( iInsStart, iInsEnd );
}
IntegrateStages( iChangeStage, false );
ResetScrollBar();
Paint();
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
if( m_pContentPanel->IsVertical() && nBars==g_Opus.BarCount() ||
!m_pContentPanel->IsVertical() && ( bDeletedMT || nMTCount!=g_aMidiTracks.size()) ){
m_pContentPanel->InitialVars();
}
// if( !m_pContentPanel->IsVertical() )
// GenerateCompose();
}
else if( iType==UNDO_TRKMID_DELALL ){
if( m_pContentPanel->IsVertical() ){
if( pLite->iCode==ST_MIDI )
m_pContentPanel->SetScrollMode( false );
}
TOpusStageList* lstStages = bUndo ? (TOpusStageList*)pLite->pBefore
: (TOpusStageList*)pLite->pAfter;
TMidiTrackList *lstTracks = bUndo ? (TMidiTrackList*)pLite->pExt1 : NULL;
UINT idLoc = bUndo ? pLite->iExt1 : pLite->iExt2,
idStyle = bUndo ? pLite->iBegin : pLite->iEnd;
ClearAllItems();
g_Midi.ClearMidiTracks();
if( lstTracks ){
for( int i=0; i<lstTracks->size(); i++ ){
TMidiTrack* pMT = new TMidiTrack((*lstTracks)[i]);
g_Midi.AddMidiTrack( pMT );
}
}
g_Opus.Set( idLoc, idStyle, *lstStages );
g_Midi.SortMidiTracks();
g_Opus.BuildStyleItem();
TStylePanel::SetStyleItem( g_pUseStyle );
ResetScrollBar();
Paint();
if( !m_pContentPanel->IsVertical() ){
m_pContentPanel->InitialVars();
GenerateCompose();
}
else if( g_iSegColorMode==1 ){
m_pContentPanel->InvalidateBars( 0, g_Opus.BarCount()-1, BAR_DATA );
}
if( g_iPreStage==0 ){
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
g_lstOpusStages );
}
}
else if( iType>=UNDO_MIDI_ADD && iType<=UNDO_MIDI_FONT || iType==UNDO_TRKMID_ADD || iType==UNDO_TRKMID_DEL ){
if( m_pContentPanel->IsVertical() ){
if( pLite->iCode==ST_MIDI )
m_pContentPanel->SetScrollMode( false );
else if( VIEW_STYLE!=g_iViewMode )
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 );
}
vector<DWORD> *aAddStage = (vector<DWORD>*)( bUndo ? pLite->pExt1 : pLite->pExt2 ),
*aDelStage = (vector<DWORD>*)( bUndo ? pLite->pExt2 : pLite->pExt1 );
TTrack *aAddTrks = bUndo ? (TTrack*)pLite->pBefore : (TTrack*)pLite->pAfter;
int iSBar = pLite->iBegin,
iEBar = pLite->iEnd,
iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ),
infoAdd = bUndo ? pLite->iExt1 : pLite->iExt2,
infoDel = bUndo ? pLite->iExt2 : pLite->iExt1,
iAddMT = infoAdd==-1 ? -1 : (infoAdd & 0xFF),
iDelMT = infoDel==-1 ? -1 : (infoDel & 0xFF);
BYTE iAddMTState = infoAdd==-1 ? 0 : (infoAdd & 0xFF00)>>8,
iAddMTVol = infoAdd==-1 ? 0 : (infoAdd & 0xFF0000)>>16;
char iAddMTPan = infoAdd==-1 ? 0 : (infoAdd & 0xFF000000)>>24;
if( iEBar>=0 )
GetInsertStage( iEBar+1 );
TMidiTrack *pDelMT = NULL, *pAddMT = NULL;
if( iDelMT>=0 && iDelMT<g_aMidiTracks.size() )
pDelMT = g_aMidiTracks[iDelMT];
if( iAddMT>=0 && iAddMT<g_aMidiTracks.size() )
pAddMT = g_aMidiTracks[iAddMT];
vector<DWORD>::iterator itAdd = aAddStage->begin(),
itDel = aDelStage->begin();
int iAddStage(-1), iAddTrack(-1),
iDelStage(-1), iDelTrack(-1);
if( itAdd!=aAddStage->end() ){
int iFBar = (*itAdd) & 0xFFF,
iLBar = ((*itAdd) & 0xFFF000)>>12;
iAddTrack = ((*itAdd) & 0xFF000000)>>24;
iAddStage = GetInsertStage( iFBar );
GetInsertStage( iLBar+1 );
}
if( itDel!=aDelStage->end() ){
int iFBar = (*itDel) & 0xFFF,
iLBar = ((*itDel) & 0xFFF000)>>12;
iDelTrack = ((*itDel) & 0xFF000000)>>24;
iDelStage = GetInsertStage( iFBar );
GetInsertStage( iLBar+1 );
}
bool bAddedMT = false;
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
while( itAdd!=aAddStage->end() || itDel!=aDelStage->end() ){
if( iDelStage>=0 && (iAddStage<0 || iDelStage<iAddStage) ){
TOpusStage* pStage = g_lstOpusStages[iDelStage];
TTrack* pTrack = pStage->aTracks[iDelTrack];
if( !pDelMT || pDelMT->file!=pTrack->iFile || pDelMT->chno!=pTrack->iChanSpec ){
pDelMT = g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec );
}
delete pTrack;
pStage->aTracks.erase( pStage->aTracks.begin()+iDelTrack );
TSegmentItem* pSegment = (TSegmentItem*)pStyItem->aItems->Items[iDelStage];
TTrackItem* pTrkItem = (TTrackItem*)pSegment->aItems->Items[iDelTrack];
TStylePanel::DeleteItem( pTrkItem, -1 );
pDelMT->DelStage( iDelStage );
if( ++itDel!=aDelStage->end() ){
int iFBar = (*itDel) & 0xFFF,
iLBar = ((*itDel) & 0xFFF000)>>12;
iDelTrack = ((*itDel) & 0xFF000000)>>24;
iDelStage = GetInsertStage( iFBar );
GetInsertStage( iLBar+1 );
}
else{
iDelStage = -1;
iDelTrack = -1;
}
}
else if( iDelStage>=0 && iDelStage==iAddStage ){
TOpusStage* pStage = g_lstOpusStages[iDelStage];
TTrack *pTrack = pStage->aTracks[iDelTrack],
*pSubTrack = &aAddTrks[itAdd - aAddStage->begin()];
if( !pDelMT || pDelMT->file!=pTrack->iFile || pDelMT->chno!=pTrack->iChanSpec ){
pDelMT = g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec );
}
if( pSubTrack->iFile!=pDelMT->file || pSubTrack->iChanSpec!=pDelMT->chno ){
if( !pAddMT || pAddMT->file!=pSubTrack->iFile || pAddMT->chno!=pSubTrack->iChanSpec
|| pAddMT->prog!=pSubTrack->iProg
|| !( pAddMT=g_Midi.FindMidiTrack( pSubTrack->iFile, pSubTrack->iChanSpec )) ){
pAddMT = new TMidiTrack( pSubTrack->iBank, pSubTrack->iChanSpec, pSubTrack->iProg, pSubTrack->iFile );
pAddMT->state = iAddMTState;
pAddMT->volume = iAddMTVol;
pAddMT->pan = iAddMTPan;
g_Midi.AddMidiTrack( pAddMT, iAddMT );
bAddedMT = true;
}
pDelMT->DelStage( iDelStage );
pAddMT->AddStage( iAddStage );
}
else if( pAddMT==pDelMT && pSubTrack->iProg!=pAddMT->prog ){
pAddMT->prog = pSubTrack->iProg;
}
if( pTrack->iStyleLoc!=pSubTrack->iStyleLoc
|| pTrack->iStyleId!=pSubTrack->iStyleId ){
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[iDelStage];
TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];
pTrkItem->pStyle = GetStyleInfo( pSubTrack->iStyleLoc, pSubTrack->iStyleId );
}
memcpy( pTrack, pSubTrack, sizeof(TTrack) );
if( ++itAdd!=aAddStage->end() ){
int iFBar = (*itAdd) & 0xFFF,
iLBar = ((*itAdd) & 0xFFF000)>>12;
iAddTrack = ((*itAdd) & 0xFF000000)>>24;
iAddStage = GetInsertStage( iFBar );
GetInsertStage( iLBar+1 );
}
else{
iAddStage = -1,
iAddTrack = -1;
}
if( ++itDel!=aDelStage->end() ){
int iFBar = (*itDel) & 0xFFF,
iLBar = ((*itDel) & 0xFFF000)>>12;
iDelTrack = ((*itDel) & 0xFF000000)>>24;
iDelStage = GetInsertStage( iFBar );
GetInsertStage( iLBar+1 );
}
else{
iDelStage = -1;
iDelTrack = -1;
}
}
else if( iAddStage>=0 && ( iDelStage<0 || iDelStage>iAddStage ) ){
TTrack* pTrack = new TTrack( &aAddTrks[itAdd - aAddStage->begin()] );
if( !pAddMT || pAddMT->file!=pTrack->iFile || pAddMT->chno!=pTrack->iChanSpec
|| !( pAddMT=g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec )) ){
pAddMT = new TMidiTrack( pTrack->iBank, pTrack->iChanSpec, pTrack->iProg, pTrack->iFile );
pAddMT->state = iAddMTState;
pAddMT->volume = iAddMTVol;
pAddMT->pan = iAddMTPan;
g_Midi.AddMidiTrack( pAddMT, iAddMT );
bAddedMT = true;
}
TOpusStage* pStage = g_lstOpusStages[iAddStage];
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[iAddStage];
pStage->aTracks.insert( pStage->aTracks.begin()+iAddTrack, pTrack );
AddTrack( pSeg, pTrack, iAddTrack );
pAddMT->AddStage( iAddStage );
if( ++itAdd!=aAddStage->end() ){
int iFBar = (*itAdd) & 0xFFF,
iLBar = ((*itAdd) & 0xFFF000)>>12;
iAddTrack = ((*itAdd) & 0xFF000000)>>24;
iAddStage = GetInsertStage( iFBar );
GetInsertStage( iLBar+1 );
}
else{
iAddStage = -1,
iAddTrack = -1;
}
}
}
IntegrateStages( iBStage, false );
ResetScrollBar();
Paint();
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
if( !m_pContentPanel->IsVertical() ){
if( bDeletedMT || bAddedMT ){
m_pContentPanel->InitialVars();
}
else{
if( iDelMT>=0 ){
int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT );
if( iST>0 )
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST );
}
}
if( iAddMT>=0 && !aAddStage->empty() || iDelMT>=0 && !bDeletedMT ){
if( VIEW_TRACK!=g_iViewMode )
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 );
if( iAddMT==iDelMT )
m_pContentPanel->SelectTrack( -1, -1, -1, false );
int iMT = iAddMT>=0 && !aAddStage->empty() ? iAddMT : iDelMT,
iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT );
if( iST>0 ){
m_pContentPanel->SelectTrack( iST-1, -1, -1, false );
m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1, true );
}
}
GenerateCompose();
}
if( g_iSegColorMode==1 && iType!=UNDO_MIDI_FONT )
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_DATA );
}
else if( iType==UNDO_OPUS_STYLE ){ //全曲风格替换
iMode = MODE_INIT;
TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
TOpusStageList* lstStages = (TOpusStageList*)( bUndo ? pLite->pBefore
: pLite->pAfter );
if( lstAudio ){
f_MM_Undo( bUndo );
}
g_Audio.RestoreAudio( lstStages, lstAudio, bUndo );
g_Opus.Set( pLite->iBegin, pLite->iEnd, *lstStages );
g_Opus.BuildStyleItem();
g_Midi.ClearMidiTracks();
SetStyleItem( g_pUseStyle );
if( g_iPreStage==0 ){
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
g_lstOpusStages );
}
}
else if( iType==UNDO_STAGE_VOL || iType==UNDO_PROG_VOL ){
int iStage = GetInsertStage( pLite->iBegin ),
nStageLen = pLite->iEnd - pLite->iBegin;
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
TSegmentItem* pTempSeg = (TSegmentItem*)pStyItem->aItems->Items[iStage];
if( pTempSeg->iSegType<SEGTYPE_FILL && pTempSeg->nBars>nStageLen )
GetInsertStage( pLite->iEnd );
TSegmentItem* pSegItem = (TSegmentItem*)pStyItem->aItems->Items[iStage];
int iSet = (int)(bUndo ? pLite->pBefore : pLite->pAfter ),
iOther = (int)(!bUndo ? pLite->pBefore : pLite->pAfter );
TCommonItem* pSetItem = NULL;
if( iType==UNDO_STAGE_VOL ){
SetSelectStage( iStage );
pSetItem = pSegItem;
}
else{
TTrack* pExt = (TTrack*)pLite->pExt1;
for( int i=0; i<pSegItem->aItems->Count; i++ ){
TTrackItem* pTrkItem = (TTrackItem*)pSegItem->aItems->Items[i];
TTrack* pTrack = pTrkItem->pTrack;
if( pTrack->iStyleLoc==pExt->iStyleLoc && pTrack->iStyleId==pExt->iStyleId
&& pTrack->iSegNo==pExt->iSegNo && pTrack->iBank==pExt->iBank
&& pTrack->iProg==pExt->iProg && pTrack->nVol==iOther ){
pSetItem = pTrkItem;
SetSelectTrack( pTrkItem );
break;
}
}
}
ChangeVolume( iStage, pSetItem, iSet, false );
if( iSet>=0 && iOther<0 || iSet<0 && iOther>=0 ){ //静音操作
DrawItem( m_pSelItem, m_iSelLine, COL_FOLD );
}
else{
DrawItem( m_pSelItem, m_iSelLine, COL_TEXT );
DoAdjustVolume( NULL );
}
}
if( iMode>=0 )
m_pContentPanel->OnStageChanged( iChangeStage, iMode );
}
// ---------------------------------------------------------------------------
void TUseStylePanel::SetSelectTrack( TTrackItem* pTrack )
{
TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0];
TSegmentItem* pSeg = (TSegmentItem*)pTrack->up;
if( !pStyle->IsUnfold() ){
SetFold( pStyle, 0 );
}
TCommonItem* pItem = GetNextItem( pStyle );
int iLine = 1;
while( pItem!=pSeg ){
pItem = GetNextItem( pItem );
iLine++;
}
if( !pSeg->IsUnfold() ){
SetFold( pSeg, iLine );
}
while( pItem!=pTrack ){
pItem = GetNextItem( pItem );
iLine++;
}
SetSelect( pTrack, iLine - m_iTopLine );
ShowSelItem();
}
// ---------------------------------------------------------------------------
bool __fastcall TUseStylePanel::GetPrebeat( BYTE* pData, int& nSize )
{
if( m_aItems->Count==0 )
return false;
TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
TTrack* pDrumTrk = NULL;
for( int i=pStyItem->aItems->Count-1; !pDrumTrk && i>=0; i-- ){
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
int stype = pSeg->GetSegType();
if( stype!=SEGTYPE_ENDING ){
for( int j=0; j<pSeg->aItems->Count; j++ ){
TTrack* pTrk = ((TTrackItem*)pSeg->aItems->Items[j])->pTrack;
if( pTrk->iChanNo==9 ){
pDrumTrk = pTrk;
break;
}
}
}
}
if( pDrumTrk ){
int nStageNum = 1;
TStage* aStages = new TStage[nStageNum];
aStages[0].iSegType = SEGTYPE_VAR;
aStages[0].iSegKey = 0;
aStages[0].nBarNum = 4;
aStages[0].aChords = new TBarChords[aStages[0].nBarNum];
for( int j=0; j<4; j++ ){
aStages[0].aChords[j].iKey[0]
= aStages[0].aChords[j].iKey[1]
= aStages[0].aChords[j].iKey[2]
= aStages[0].aChords[j].iKey[3] = 0;
aStages[0].aChords[j].iType[0]
= aStages[0].aChords[j].iType[1]
= aStages[0].aChords[j].iType[2]
= aStages[0].aChords[j].iType[3] = 0;
}
//tracks
aStages[0].nTrkNum = 1;
aStages[0].aTracks = new TComposeTrack[aStages[0].nTrkNum];
aStages[0].aTracks[0].iStyleLoc = pDrumTrk->iStyleLoc;
aStages[0].aTracks[0].iStyleId = pDrumTrk->iStyleId;
aStages[0].aTracks[0].iSegNo = pDrumTrk->iSegNo;
aStages[0].aTracks[0].iChanNo = pDrumTrk->iChanNo;
aStages[0].aTracks[0].iChanSpec = pDrumTrk->iChanSpec;
aStages[0].aTracks[0].iProg = pDrumTrk->iProg;
aStages[0].aTracks[0].nVol = 110;
int ret = f_CM_Compose( &nSize, pData, g_iMelodyTimeSignature, g_nMelodyTempo,
nStageNum, aStages, false, NULL, NULL );
if( ret==0 ){
return true;
}
}
return false;
}
// ---------------------------------------------------------------------------
void TUseStylePanel::SetBarsUndo( int iMode, int iStartBar, int nBars, int iMoveTo )
{
int iEndBar = iStartBar + nBars - 1;
TOpusStageList* lstStages = new TOpusStageList;
TAudioTrackList* lstAudio = new TAudioTrackList;
CopyUndoBars( iStartBar, iEndBar, lstStages, lstAudio );
void *pBefore = iMode==UNDO_BAR_INSERT ? NULL : (void*)lstStages,
*pAfter = iMode==UNDO_BAR_INSERT ? (void*)lstStages : NULL;
g_Undo.AddUndo( iMode, 0, iStartBar, iEndBar, pBefore, pAfter );
if( iMode==UNDO_BAR_MOVE && iMoveTo > iStartBar )
iMoveTo -= nBars;
g_Undo.SetUndoExtra( iMoveTo, 0, 0, (void*)lstAudio, NULL );
}
//---------------------------------------------------------------------------