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

1510 lines
33 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#include <Vcl.Imaging.pngimage.hpp>
#pragma hdrstop
#include "GlobalUnit.h"
#include "StyleItem.h"
#include "FavorTextureUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TPngImage *u_imgFold = NULL,
*u_imgUnfold = NULL,
*u_imgTrackOn = NULL,
*u_imgTrackOff = NULL,
*u_imgDelete = NULL,
*u_imgDownload = NULL,
*u_imgDownloading = NULL,
*u_imgProg = NULL,
*u_imgTexture = NULL,
*u_imgVolume = NULL,
*u_imgBrush = NULL,
*u_imgCollect = NULL,
*u_imgUnCollect = NULL,
*u_imgScore = NULL,
*u_imgSave = NULL,
*u_imgImport = NULL,
*u_imgUpload = NULL,
*u_imgCharge = NULL;
COLORREF clrTextStyle = RGB(201, 214, 229), //Style文字
clrTextHot = RGB( 225, 236, 255 ), //高亮文字
clrTextDirty = RGB( 226, 232, 187 ),
clrTextDisable = RGB( 126, 131, 137 ), //未下载文字
clrTextLoading = RGB( 105, 197, 235 ), //正在下载
clrBackground = RGB(47, 50, 57), //面板背景
clrFocback = RGB( 67, 73, 80 ), //焦点背景
clrSelback = RGB( 29, 31, 35 ); //选中背景
TStyleItem *g_pPreStyle = NULL,
*g_pUseStyle = NULL;
/////////////////////////////////////////////////////////////////////////////
// TCommonItem
__fastcall TCommonItem::TCommonItem()
{
iType = 0;
dwState = 0;
iFocusCol = 0;
aOptions = new System::Classes::TList();
aItems = new System::Classes::TList();
prev = next = up = NULL;
}
__fastcall TCommonItem::TCommonItem( char type, DWORD opts )
{
iType = type;
dwState = 0;
iFocusCol = 0;
aOptions = new System::Classes::TList();
aItems = new System::Classes::TList();
prev = next = up = NULL;
if( opts!=0 ){
for( int i=0; i<OPT_NUM; i++ ){
if( opts & (1<<i) )
aOptions->Add( (void*)(1<<i) );
}
}
}
__fastcall TCommonItem::~TCommonItem()
{
ClearSubItems();
delete aOptions;
delete aItems;
}
void TCommonItem::ClearSubItems()
{
for( int i=0; i<aItems->Count; i++ ){
delete aItems->Items[i];
}
aItems->Clear();
}
void TCommonItem::RemoveSubItem( TCommonItem* pSub )
{
if( pSub->prev )
pSub->prev->next = pSub->next;
if( pSub->next )
pSub->next->prev = pSub->prev;
aItems->Remove( pSub );
delete pSub;
}
short __fastcall TCommonItem::GetColume( int X )
{
return 0;
}
bool TCommonItem::IsUnfold()
{
return dwState & STATE_UNFOLD;
}
bool TCommonItem::IsSelected()
{
return dwState & STATE_SELECTED;
}
/*
void __fastcall TCommonItem::SetCollect( bool bSet )
{
if( bSet )
dwState |= STATE_COLLECTED;
else
dwState &= ~STATE_COLLECTED;
}
*/
void __fastcall TCommonItem::SetFocus( WORD iCol )
{
iFocusCol = iCol;
}
void __fastcall TCommonItem::SetUnfold( bool bSet )
{
if( bSet )
dwState |= STATE_UNFOLD;
else
dwState &= ~STATE_UNFOLD;
}
void __fastcall TCommonItem::Select( bool bSet )
{
if( bSet )
dwState |= STATE_SELECTED;
else
dwState &= ~STATE_SELECTED;
}
void __fastcall TCommonItem::SetHover( bool bSet )
{
if( bSet )
dwState |= STATE_HOVER;
else
dwState &= ~STATE_HOVER;
}
DWORD TCommonItem::GetOption( int iCol )
{
for( int i=0; i<OPT_COL_NUM; i++ ){
if( iCol==(COL_OPT<<i) && aOptions->Count>i ){
return (DWORD)aOptions->Items[i];
}
}
return 0;
}
int TCommonItem::GetOnlineState()
{
TStyleItem* pStyItem = GetStyleItem();
if( pStyItem && pStyItem->pStyle ){
if( pStyItem->pStyle->idLoc==0 )
return pStyItem->pStyle->pOrigin->state;
else if( pStyItem->pStyle->idLoc==1 ){
if( iType==SEGTYPE_STYLE ){
int iStyDlState = e_Downloaded;
for( int i=0; i<aItems->Count; i++ ){
TSegmentItem* pSeg = (TSegmentItem*)aItems->Items[i];
int iState = pSeg->GetOnlineState();
if( iState==e_UnDownload )
return e_UnDownload;
else if( iState==e_Downloading )
iStyDlState = iState;
}
return iStyDlState;
}
else if( iType==SEGTYPE_TRACK ){
TTrackItem* pTrk = (TTrackItem*)this;
if( pTrk->pStyle->idLoc==0 )
return pTrk->pStyle->pOrigin->state;
else
return e_Downloaded;
}
else{
int iSegDlState = e_Downloaded;
for( int i=0; i<aItems->Count; i++ ){
TTrackItem* pTrk = (TTrackItem*)aItems->Items[i];
int iState = pTrk->GetOnlineState();
if( iState==e_UnDownload )
return e_UnDownload;
else if( iState==e_Downloading )
iSegDlState = iState;
}
return iSegDlState;
}
}
}
return e_Downloaded;
}
TStyleItem* TCommonItem::GetStyleItem()
{
if( iType==SEGTYPE_STYLE ){
return (TStyleItem*)this;
}
else if( iType==SEGTYPE_TRACK ){
return (TStyleItem*)up->up;
}
else{
return (TStyleItem*)up;
}
}
void TCommonItem::SetOnlineState( int iState )
{
TStyleItem* pStyItem = GetStyleItem();
if( pStyItem && pStyItem->pStyle ){
if( pStyItem->pStyle->idLoc==0 )
pStyItem->pStyle->pOrigin->state = iState;
else if( pStyItem->pStyle->idLoc==1 && iType==SEGTYPE_TRACK ){
TTrackItem* pTrk = (TTrackItem*)this;
if( pTrk->pStyle->idLoc==0 )
pTrk->pStyle->pOrigin->state = iState;
}
}
}
COLORREF TCommonItem::TextColor()
{
return clrTextStyle;
}
void __fastcall TCommonItem::DrawItem( TCanvas* Canvas, TRect Rect, WORD iCol )
{
int X, Y;
if( iType!=SEGTYPE_STYLE ){
Rect.Left += OPTION_WIDTH;
if( iType==SEGTYPE_TRACK ){
Rect.Left += OPTION_WIDTH;
}
}
Canvas->Brush->Color = clrBackground;
if( iCol==WORD(-1) ){
//刷新左边
TRect rtFresh( 0, Rect.Top, Rect.Left+OPTION_WIDTH, Rect.Bottom );
Canvas->FillRect( rtFresh );
}
if( dwState & STATE_SELECTED ) //绘制选中背景
Canvas->Brush->Color = clrSelback;
else if( dwState & STATE_HOVER || iFocusCol>COL_FOLD )
Canvas->Brush->Color = clrFocback;
if( iCol & COL_FOLD ){
TPngImage *pImg = NULL;
if( aItems->Count>0 ){ //输出fold
pImg = (dwState & STATE_UNFOLD) ? u_imgUnfold : u_imgFold;
}
else if( iType==SEGTYPE_TRACK ){ //输出mute
pImg = IsMute() ? u_imgTrackOff : u_imgTrackOn;
}
if( pImg ){
RECT rt;
GetClipBox( Canvas->Handle, &rt );
int w = pImg->Width/2,
h = pImg->Height,
l = ( iFocusCol==COL_FOLD ) ? w : 0;
X = Rect.Left + (OPTION_WIDTH - w)/2;
Y = Rect.Top + ( OPTION_HEIGHT - h) / 2;
int x = X-rt.left,
y = Y-rt.top,
b = y+h;
if( b > Rect.Bottom - rt.top )
b = Rect.Bottom - rt.top;
HRGN rgnClip = CreateRectRgn( x, y, x+w, b );
SelectClipRgn( Canvas->Handle, rgnClip );
Canvas->Draw( X-l, Y, pImg );
SelectClipRgn( Canvas->Handle, NULL );
DeleteObject(rgnClip);
}
}
int iOnline = GetOnlineState();
if( iCol >= COL_TEXT ){
//输出文字
if( iFocusCol>=COL_TEXT ){
Canvas->Font->Color = clrTextHot;
}
else if( iOnline==e_UnDownload ){
Canvas->Font->Color = clrTextDisable;
}
else if( iOnline==e_Downloading ){
if( iType==SEGTYPE_STYLE )
Canvas->Font->Color = clrTextLoading;
else
Canvas->Font->Color = clrTextDisable;
}
else{
Canvas->Font->Color = TextColor();
}
String strText = GetCaption();
Rect.Left += OPTION_WIDTH;
Y = Rect.Top + ( OPTION_HEIGHT - Canvas->TextHeight(strText) )/2;
//----处理字符过长------
int nWidth = Rect.Width() - 4 - 8;
if( iFocusCol > COL_FOLD || dwState & STATE_SELECTED )
nWidth -= aOptions->Count*OPTION_WIDTH + 2;
if( Canvas->TextWidth( strText )>nWidth ){
UnicodeString strShorty = strText;
while( Canvas->TextWidth( strShorty )>nWidth ){
strShorty = strShorty.SubString( 1, strShorty.Length()-2 );
}
strText = strShorty;
strText+="...";
}
//-----------
Canvas->Brush->Style = bsSolid;
Canvas->TextRect( Rect, Rect.Left+4, Y, strText );
}
for( int i=0; i<aOptions->Count; i++ ){
DWORD iOpt = (DWORD)aOptions->Items[i];
TPngImage* pImg = NULL;
if( iOpt==OPT_DEL ){
pImg = u_imgDelete;
}
else if( iOpt==OPT_DOWNLOAD ){
if( iOnline==e_Downloading )
pImg = u_imgDownloading;
else
pImg = u_imgDownload;
}
else if( iOpt==OPT_BRUSH )
pImg = u_imgBrush;
else if( iOpt==OPT_TEXTURE )
pImg = u_imgTexture;
else if( iOpt==OPT_FONTPROG )
pImg = u_imgProg;
else if( iOpt==OPT_VOL )
pImg = u_imgVolume;
else if( iOpt==OPT_COLLECT ){
if( IsCollected() )
pImg = u_imgCollect;
else
pImg = u_imgUnCollect;
}
else if( iOpt==OPT_SCORE )
pImg = u_imgScore;
else if( iOpt==OPT_SAVE )
pImg = u_imgSave;
else if( iOpt==OPT_IMPORT )
pImg = u_imgImport;
else if( iOpt==OPT_UPLOAD )
pImg = u_imgUpload;
else if( iOpt==OPT_CHARGE )
pImg = u_imgCharge;
if( iFocusCol>COL_FOLD || (dwState & STATE_SELECTED) ){
Rect.Right -= OPTION_WIDTH;
if( pImg ){
RECT rt;
GetClipBox( Canvas->Handle, &rt );
int w = pImg->Width/3,
h = pImg->Height,
l = ( iFocusCol==(1<<(i+2)) ) ? w : 0;
X = Rect.Right + (OPTION_WIDTH - w)/2;
Y = Rect.Top + ( OPTION_HEIGHT - h) / 2;
int x = X-rt.left,
y = Y-rt.top,
b = y+h;
if( b > Rect.Bottom - rt.top )
b = Rect.Bottom - rt.top;
HRGN rgnClip = CreateRectRgn( x, y, x+w, b );
SelectClipRgn( Canvas->Handle, rgnClip );
Canvas->Draw( X-l, Y, pImg );
SelectClipRgn( Canvas->Handle, NULL );
DeleteObject(rgnClip);
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// TTrackItem
__fastcall TTrackItem::TTrackItem()
: TCommonItem(SEGTYPE_TRACK, 0 )
{
bOwnTrack = false;
pTrack = NULL;
}
__fastcall TTrackItem::TTrackItem( TCommonItem* pUpItem, TPROSTYLE* info,
char stype, char sno, char ch,
char prog, char vol, DWORD opts )
: TCommonItem( SEGTYPE_TRACK, opts )
{
pStyle = info;
up = pUpItem;
}
__fastcall TTrackItem::TTrackItem( TCommonItem* pUpItem, TPROSTYLE* info, TTrack* pTrk,
DWORD opts, bool bOwn )
: TCommonItem( SEGTYPE_TRACK, opts )
{
up = pUpItem;
pStyle = info;
bOwnTrack = bOwn;
pTrack = pTrk;
}
__fastcall TTrackItem::~TTrackItem()
{
if( bOwnTrack && pTrack )
delete pTrack;
}
void TTrackItem::SetMute( bool bSet )
{
if( pTrack ){
if( bSet )
pTrack->nVol |= 0x80;
else
pTrack->nVol &= ~0x80;
}
}
bool TTrackItem::IsCollected()
{
return IsFavorTexture( pStyle->idLoc, pStyle->idStyle, GetSegType(),
pTrack->iSegNo, pTrack->iChanNo );
}
void TTrackItem::StyleId2Str( String& strText )
{
char strNo[20];
if( pStyle->idLoc==0 ){
sprintf( strNo, "[%d] ", pStyle->idStyle );
}
else if( pStyle->idLoc==1 ){
sprintf( strNo, "[S%d] ", pStyle->idStyle );
}
else if( pStyle->idLoc==(UINT)-1 ){
sprintf( strNo, "[T%d] ", LOWORD(pStyle->idStyle) );
}
else{
sprintf( strNo, "[L%d] ", LOWORD(pStyle->idStyle) );
}
strText += strNo;
}
char TTrackItem::GetSegType()
{
return ((TSegmentItem*)up)->iSegType;
}
char TTrackItem::GetSegNo()
{
if( pTrack )
return pTrack->iSegNo;
}
bool TTrackItem::IsMute()
{
return pTrack ? pTrack->nVol < 0 : false;
}
void TTrackItem::AddStyleId( String& strText )
{
TStyleItem* pStyItem = GetStyleItem();
if( pStyItem->pStyle!=pStyle ){
strText += " ";
StyleId2Str( strText );
}
}
String TTrackItem::GetCaption()
{
String strText;
if( pTrack->iBank!=0xFF || pTrack->iProg!=pTrack->iProgOrig
|| (pTrack->nVolOrig & 0x7F) != (pTrack->nVol & 0x7F) ){
strText += "* ";
}
if( (pTrack->iBank==0xFF || pTrack->iBank<0x80) && pTrack->iChanNo==9 )
strText += "GM鼓";
else
strText += GetProgName( pTrack->iBank, pTrack->iChanNo, pTrack->iProg );
AddStyleId( strText );
return strText;
}
COLORREF TTrackItem::TextColor()
{
if( pTrack->iBank!=0xFF ){
return clrTextDirty;
}
return GetSegmentColor( GetSegType(), 0, false );
}
String TTrackItem::HintText()
{
String strText = "织体:";
StyleId2Str( strText );
char strType_No[8];
sprintf( strType_No, "%s - %d", NAME_SEG[GetSegType()], pTrack->iSegNo+1 );
strText += strType_No;
strText += "\n\n音源:";
int iFont = pTrack->iBank==0xFF && !g_bExtFont ? g_idFont: pTrack->iBank;
if( iFont==0xFF ){
strText += "扩展音色库";
}
else if( iFont<0x80 ){
FONTINFO* pFI = g_lstFonts[iFont];
strText += pFI->strFontName;
}
else{
VSTINFO* pFI = g_lstVSTi[iFont-0x80];
strText += pFI->strVSTName;
}
strText += "\n";
if( pTrack->iProg!=pTrack->iProgOrig )
strText += "当前";
strText += "乐器:";
strText += GetProgName( pTrack->iBank, pTrack->iChanNo, pTrack->iProg );
if( pTrack->iProg!=pTrack->iProgOrig ){
strText += "\n原始乐器:";
strText += GetProgName( 0xFF, pTrack->iChanNo, pTrack->iProgOrig );
}
strText += "\n\n";
if( pTrack->nVol!=pTrack->nVolOrig )
strText += "当前";
strText += "音量:";
if( pTrack->nVol<0 )
strText += "静音";
else
strText += IntToStr( pTrack->nVol );
if( pTrack->nVol!=pTrack->nVolOrig ){
strText += "\n原始音量:";
strText += IntToStr( pTrack->nVolOrig );
}
return strText;
}
/////////////////////////////////////////////////////////////////////////////
// TSegmentItem
__fastcall TSegmentItem::TSegmentItem()
: TCommonItem(SEGTYPE_SEGMENT, 0)
{
iSegType = 0;
iSegNo = 0;
iInd = 0;
volume = 0;
nBars = 0;
bAutoSpec = false;
memset( aChanUsed, 0, sizeof(aChanUsed) );
}
__fastcall TSegmentItem::TSegmentItem( TCommonItem* pUpItem, char stype, char sno, DWORD opts,
int bars, char ind, char vol, bool bSpec )
: TCommonItem( SEGTYPE_SEGMENT, opts )
{
up = pUpItem;
iSegType = stype;
iSegNo = sno;
iInd = ind;
volume = vol;
nBars = bars;
bAutoSpec = bSpec;
memset( aChanUsed, 0, sizeof(aChanUsed) );
}
void TSegmentItem::ClearSubItems()
{
TCommonItem::ClearSubItems();
memset( aChanUsed, 0, sizeof(aChanUsed) );
}
TTrackItem* __fastcall TSegmentItem::AddTrack( TPROSTYLE* info, TTrack* pTrack, DWORD opts, bool bOwn, int iInd )
{
if( !info && !(info = GetStyleInfo( pTrack->iStyleLoc, pTrack->iStyleId )))
return NULL;
TTrackItem *pItem = NULL;
if( iInd>=0 ){
pItem = new TTrackItem( this, info, pTrack, opts, bOwn );
if( iSegType==SEGTYPE_VAR || iSegType==SEGTYPE_FILL )
pItem->aOptions->Add((void*)OPT_BRUSH);
if( aItems->Count==0 ){
aItems->Add( pItem );
}
else if( iInd<aItems->Count ){
TCommonItem *pNext = (TCommonItem*)aItems->Items[iInd];
if( pNext->prev )
pNext->prev->next = pItem;
pItem->prev = pNext->prev;
pNext->prev = pItem;
pItem->next = pNext;
aItems->Insert( iInd, pItem );
}
else{
TCommonItem *pLast = (TCommonItem*)aItems->Last();
pLast->next = pItem;
pItem->prev = pLast;
aItems->Add( pItem );
}
}
else{
for( int i=0; i<aItems->Count; i++ ){
TTrackItem* pTmp = (TTrackItem*)aItems->Items[i];
if( pTrack->iChanNo==9 && pTmp->pTrack->iChanNo==9 ){
pItem = pTmp;
break;
}
}
if( pItem ){
pItem->pStyle = info;
pTrack->iBank = pItem->pTrack->iBank;
pTrack->iChanSpec = pItem->pTrack->iChanSpec;
pTrack->iFile = pItem->pTrack->iFile;
if( bOwn )
delete pItem->pTrack;
pItem->pTrack = pTrack;
}
else{
pItem = new TTrackItem( this, info, pTrack, opts, bOwn );
if( iSegType==SEGTYPE_VAR || iSegType==SEGTYPE_FILL )
pItem->aOptions->Add((void*)OPT_BRUSH);
char ch = pTrack->iChanNo,
chSpec = pTrack->iChanSpec;
if( ch==9 ){
aChanUsed[9] = true;
}
else if( bAutoSpec ){
if( !aChanUsed[chSpec] ){
aChanUsed[chSpec] = true;
}
else if( ch!=9 ){
for( int i=0; i<16; i++ ){
if( !aChanUsed[i] ){
pTrack->iChanSpec = i;
aChanUsed[i] = true;
break;
}
}
}
}
bool bInserted = false;
if( aItems->Count>0 ){
if( ch==9 ){ //只能一个打击乐轨,且总在第一个
TTrackItem *pFirst = (TTrackItem*)aItems->First();
pItem->next = pFirst;
pFirst->prev = pItem;
aItems->Insert( 0, pItem );
bInserted = true;
}
else{
TCommonItem *pLast = (TCommonItem*)aItems->Last();
pLast->next = pItem;
pItem->prev = pLast;
}
}
if( !bInserted )
aItems->Add( pItem );
}
}
return pItem;
}
TTrackItem* __fastcall TSegmentItem::AddTrack( TPROSTYLE* info, char sno, char ch,
char prog, char vol, DWORD opts )
{
TTrack* pTrack = new TTrack;
pTrack->iStyleLoc = info->idLoc;
pTrack->iStyleId = info->idStyle;
pTrack->iSegNo = sno;
pTrack->iChanNo = pTrack->iChanSpec = ch;
pTrack->iProg = pTrack->iProgOrig = prog;
pTrack->nVol = pTrack->nVolOrig = vol;
return AddTrack( info, pTrack, opts, true );
}
TTrackItem* __fastcall TSegmentItem::AddTrack( TPROSTYLE* info, char sn, char tn,
DWORD opts, bool bAddLocal )
{
TTrackItem *pItem = NULL;
char st = iSegType;
if( info->idLoc==0 ){
TSTYLEORIGIN* pOrigin = info->pOrigin;
if( pOrigin->detail.tracks[st][sn][tn].no>=0 ){
pItem = AddTrack( info, sn,
pOrigin->detail.tracks[st][sn][tn].no,
pOrigin->detail.tracks[st][sn][tn].prog,
pOrigin->detail.tracks[st][sn][tn].vol,
opts );
}
}
else if( info->idLoc==1 ){
TSTYLESHARE* pShare = info->pShare;
TSHARETRACKREF& trkRef = pShare->trkRef[st][sn][tn];
UINT idStyle = trkRef.idStyle;
TPROSTYLE* pTrkInfo = NULL;
if( idStyle>0 )
pTrkInfo = GetStyleInfo( 0, idStyle );
if( pTrkInfo ){
int osn = trkRef.segNo;
char chan = trkRef.chan,
prog = trkRef.prog,
vol = trkRef.vol;// & 0x7F;
if( pTrkInfo!=info ){
for( int t=0; t<16; t++ ){
if( pTrkInfo->pOrigin->detail.tracks[st][osn][t].no==chan ){
prog = pTrkInfo->pOrigin->detail.tracks[st][osn][t].prog;
vol = pTrkInfo->pOrigin->detail.tracks[st][osn][t].vol;
break;
}
}
}
pItem = AddTrack( pTrkInfo, osn, chan, prog, vol, opts );
pItem->pTrack->iProg = trkRef.prog;
pItem->pTrack->nVol = trkRef.vol;
}
}
else{
TSTYLELOCAL* pLocal = info->pLocal;
TTRACKREF& trkRef = pLocal->trkRef[st][sn][tn];
UINT idLoc = trkRef.idLoc,
idStyle = trkRef.idStyle;
TPROSTYLE* pTrkInfo = NULL;
if( idStyle>0 && ( bAddLocal || idLoc==0 ) ){
pTrkInfo = GetStyleInfo( idLoc, idStyle );
}
if( pTrkInfo ){
int osn = trkRef.segNo;
char chan = trkRef.chan,
prog = trkRef.prog,
vol = trkRef.vol;// & 0x7F;
if( pTrkInfo!=info ){
for( int t=0; t<16; t++ ){
if( pTrkInfo->idLoc==0 ){
if( pTrkInfo->pOrigin->detail.tracks[st][osn][t].no==chan ){
prog = pTrkInfo->pOrigin->detail.tracks[st][osn][t].prog;
vol = pTrkInfo->pOrigin->detail.tracks[st][osn][t].vol;
break;
}
}
else{
int nSegNum = info->pLocal->nSegNum[st];
int iStart = ( st<SEGTYPE_INTRO || sn<4 ) ? 0 : 4,
iEnd = iStart + ( iStart==0 ? ( nSegNum & 0x0F ) : ( nSegNum>>4 ));
bool bFind = false;
for( int i=iStart; !bFind && i<iEnd; i++ ){
for( int j=0; j<16; j++ ){
if( pTrkInfo->pLocal->trkRef[st][i][j].idLoc==idLoc
&& pTrkInfo->pLocal->trkRef[st][i][j].idStyle==idStyle
&& pTrkInfo->pLocal->trkRef[st][i][j].segNo==osn
&& pTrkInfo->pLocal->trkRef[st][i][j].chan==chan ){
prog = pTrkInfo->pLocal->trkRef[st][i][j].prog;
vol = pTrkInfo->pLocal->trkRef[st][i][j].vol;
bFind = true;
break;
}
else if( pTrkInfo->pLocal->trkRef[st][i][j].idLoc==0
&& pTrkInfo->pLocal->trkRef[st][i][j].idStyle==0 ){
break;
}
}
}
}
}
}
pItem = AddTrack( pTrkInfo, osn, chan, prog, vol, opts );
pItem->pTrack->iProg = trkRef.prog;
pItem->pTrack->nVol = trkRef.vol;
}
}
return pItem;
}
/*
TTrackItem* __fastcall TSegmentItem::AddTrack( TPROSTYLE* info, char st, char sn, char tn,
DWORD opts, bool bAddLocal )
{
TTrackItem *pItem = NULL;
if( info->idLoc==0 ){
TSTYLEORIGIN* pOrigin = info->pOrigin;
if( pOrigin->detail.tracks[st][sn][tn].no>=0 ){
pItem = AddTrack( info, st, sn,
pOrigin->detail.tracks[st][sn][tn].no,
pOrigin->detail.tracks[st][sn][tn].no,
pOrigin->detail.tracks[st][sn][tn].prog,
pOrigin->detail.tracks[st][sn][tn].vol,
opts );
}
}
else if( info->idLoc==1 ){
TSTYLESHARE* pShare = info->pShare;
TSHARETRACKREF& trkRef = pShare->trkRef[st][sn][tn];
UINT idStyle = trkRef.idStyle;
TPROSTYLE* pTrkInfo = NULL;
if( idStyle>0 )
pTrkInfo = GetStyleInfo( 0, idStyle );
if( pTrkInfo ){
int osn = trkRef.segNo;
char chan = trkRef.chan,
prog = trkRef.prog,
vol = trkRef.vol;// & 0x7F;
if( pTrkInfo!=info ){
for( int t=0; t<16; t++ ){
if( pTrkInfo->pOrigin->detail.tracks[st][osn][t].no==chan ){
prog = pTrkInfo->pOrigin->detail.tracks[st][osn][t].prog;
vol = pTrkInfo->pOrigin->detail.tracks[st][osn][t].vol;
break;
}
}
}
pItem = AddTrack( pTrkInfo, st, osn, chan, chan, prog, vol, opts );
pItem->progCurr = trkRef.prog;
pItem->volCurr = trkRef.vol;
}
}
else{
TSTYLELOCAL* pLocal = info->pLocal;
TTRACKREF& trkRef = pLocal->trkRef[st][sn][tn];
UINT idLoc = trkRef.idLoc,
idStyle = trkRef.idStyle;
TPROSTYLE* pTrkInfo = NULL;
if( idStyle>0 && ( bAddLocal || idLoc==0 ) ){
pTrkInfo = GetStyleInfo( idLoc, idStyle );
}
if( pTrkInfo ){
int osn = trkRef.segNo;
char chan = trkRef.chan,
prog = trkRef.prog,
vol = trkRef.vol;// & 0x7F;
if( pTrkInfo!=info ){
for( int t=0; t<16; t++ ){
if( pTrkInfo->idLoc==0 ){
if( pTrkInfo->pOrigin->detail.tracks[st][osn][t].no==chan ){
prog = pTrkInfo->pOrigin->detail.tracks[st][osn][t].prog;
vol = pTrkInfo->pOrigin->detail.tracks[st][osn][t].vol;
break;
}
}
else{
int nSegNum = info->pLocal->nSegNum[st];
int iStart = ( st<SEGTYPE_INTRO || sn<4 ) ? 0 : 4,
iEnd = iStart + ( iStart==0 ? ( nSegNum & 0x0F ) : ( nSegNum>>4 ));
bool bFind = false;
for( int i=iStart; !bFind && i<iEnd; i++ ){
for( int j=0; j<16; j++ ){
if( pTrkInfo->pLocal->trkRef[st][i][j].idLoc==idLoc
&& pTrkInfo->pLocal->trkRef[st][i][j].idStyle==idStyle
&& pTrkInfo->pLocal->trkRef[st][i][j].segNo==osn
&& pTrkInfo->pLocal->trkRef[st][i][j].chan==chan ){
prog = pTrkInfo->pLocal->trkRef[st][i][j].prog;
vol = pTrkInfo->pLocal->trkRef[st][i][j].vol;
bFind = true;
break;
}
else if( pTrkInfo->pLocal->trkRef[st][i][j].idLoc==0
&& pTrkInfo->pLocal->trkRef[st][i][j].idStyle==0 ){
break;
}
}
}
}
}
}
pItem = AddTrack( pTrkInfo, st, osn, chan, chan, prog, vol, opts );
pItem->progCurr = trkRef.prog;
pItem->volCurr = trkRef.vol;
}
}
return pItem;
}
*/
void TSegmentItem::DeleteTrack( TCommonItem* pItem )
{
if( ((TTrackItem*)pItem)->pTrack->iChanNo==9 )
aChanUsed[9] = false;
else if( bAutoSpec )
aChanUsed[((TTrackItem*)pItem)->pTrack->iChanSpec] = false;
aItems->Remove( pItem );
delete pItem;
}
char TSegmentItem::GetIndType()
{
char type = iSegType;
if( ((TStyleItem*)up)->nBars>0 && type==SEGTYPE_FILL )
type = SEGTYPE_VAR;
return type;
}
String TSegmentItem::GetCaption()
{
String strText;
if( ((TStyleItem*)up)->nBars>0 ){
if( iSegType<=SEGTYPE_FILL ){
strText += "旋律";
strText += String("-") + (int)(iInd+1);
strText += " ";
strText += g_strSegment[iSegType];
}
else{
if( iSegType==SEGTYPE_INTRO ){
int index = iInd;
if( ((TCommonItem*)up->aItems->First())->GetSegType()!=SEGTYPE_INTRO )
index++;
if( index==0 ){
strText += "前奏";
}
else{
strText += "间奏";
strText += String("-") + index;
}
}
else{
strText += "尾奏";
}
}
}
else{
strText += g_strSegment[iSegType];
strText += String("-") + (int)(iInd+1);
}
if( iSegType>=SEGTYPE_INTRO ){
if( iSegNo<4 )
strText += " 大调" ;
else
strText += " 小调" ;
}
if( nBars>0 ){
char strNum[20];
sprintf( strNum, " (%d小节)", nBars );
strText += strNum;
}
return strText;
}
COLORREF TSegmentItem::TextColor()
{
int ty = GetSegType(),
iNo = g_iSegColorMode==0 ? GetSegNo() : aItems->Count;
bool bInc = g_iSegColorMode==0 ? true
: iNo>0 && ((TTrackItem*)aItems->Items[0])->pTrack->iChanNo==9;
return GetSegmentColor( ty, iNo, bInc );
}
/////////////////////////////////////////////////////////////////////////////
// TStyleItem
__fastcall TStyleItem::TStyleItem()
: TCommonItem(SEGTYPE_STYLE, 0)
{
pStyle = NULL;
nBars = 0;
// nVarNum = nFillNum = nIntroMajNum = nIntroMinNum = nEndingMajNum = nEndingMinNum = 0;
memset( nSegNum, 0, sizeof(int)*4 );
}
__fastcall TStyleItem::TStyleItem( TPROSTYLE* info, DWORD opts )
: TCommonItem( SEGTYPE_STYLE, opts )
{
pStyle = info;
nBars = 0;
memset( nSegNum, 0, sizeof(int)*4 );
// idLoc = info->idLoc;
// idStyle = info->idStyle;
}
bool TStyleItem::IsCollected()
{
return IsCollectedStyle( pStyle->idLoc, pStyle->idStyle );
}
TSegmentItem* __fastcall TStyleItem::AddSegment( char stype, char sno, DWORD opts,
int bars, char ind, char vol, bool bAutoSpec )
{
int index = ind;
if( ind<0 )
index = sno;//nSegNum[stype];
TSegmentItem *pItem = new TSegmentItem( this, stype, sno, opts, bars, index, vol, bAutoSpec );
bool bInserted = false;
if( aItems->Count>0 ){
if( ind<0 ){
ind = 0;
for( int i=0; i<=stype; i++ ){
ind += nSegNum[i];
}
}
if( bars==0 && ind>=0 && aItems->Count>ind ){
TCommonItem *pNext = (TCommonItem*)aItems->Items[ind];
if( pNext->prev ){
pItem->prev = pNext->prev;
pNext->prev->next = pItem;
}
pItem->next = pNext;
pNext->prev = pItem;
aItems->Insert( ind, pItem );
bInserted = true;
}
else{
TCommonItem* pLast = (TCommonItem*)aItems->Last();
pLast->next = pItem;
pItem->prev = pLast;
}
}
if( !bInserted ){
aItems->Add( pItem );
}
nSegNum[stype]++;
nBars += bars;
return pItem;
}
void TStyleItem::InsertSegment( int ind, TSegmentItem* pItem, int bars )
{
if( ind<0 || ind > aItems->Count )
ind = aItems->Count;
if( aItems->Count > ind ){
TCommonItem *pNext = (TCommonItem*)aItems->Items[ind];
if( pNext->prev ){
pItem->prev = pNext->prev;
pNext->prev->next = pItem;
}
pItem->next = pNext;
pNext->prev = pItem;
aItems->Insert( ind, pItem );
}
else{
if( aItems->Count>0 ){
TCommonItem* pLast = (TCommonItem*)aItems->Last();
pLast->next = pItem;
pItem->prev = pLast;
}
aItems->Add( pItem );
}
// pItem->iInd = ind;
nSegNum[pItem->iSegType]++;
nBars += bars;
}
void TStyleItem::DeleteSegment( TCommonItem* pSeg )
{
nSegNum[pSeg->GetSegType()]--;
if( pSeg->next ){
int stype = ((TSegmentItem*)pSeg)->GetIndType();
TSegmentItem* pNext = (TSegmentItem*)pSeg->next;
while( pNext ){
if( pNext->GetIndType()==stype )
pNext->iInd--;
pNext = (TSegmentItem*)pNext->next;
}
}
aItems->Remove( pSeg );
delete pSeg;
}
void TStyleItem::SetDownload()
{
if( pStyle ){
if( pStyle->idLoc==0 ){
// pStyle->pOrigin->state = e_Downloaded;
for( int i=0; i<aOptions->Count; i++ ){
DWORD iOpt = (DWORD)aOptions->Items[i];
if( iOpt==OPT_DOWNLOAD ){
aOptions->Items[i] = (void*)OPT_COLLECT;
break;
}
}
}
else if( pStyle->idLoc==1 ){
bool bFull = true;
for( int i=0; i<aItems->Count; i++ ){
TSegmentItem* pSeg = (TSegmentItem*)aItems->Items[i];
for( int j=0; j<pSeg->aItems->Count; j++ ){
TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
if( pTrk->pStyle->idLoc==0 && pTrk->pStyle->pOrigin->state!=e_Downloaded ){
bFull = false;
break;
}
}
if( !bFull )
break;
}
if( bFull ){
for( int i=0; i<aOptions->Count; i++ ){
DWORD iOpt = (DWORD)aOptions->Items[i];
if( iOpt==OPT_DOWNLOAD ){
aOptions->Items[i] = (void*)OPT_COLLECT;
break;
}
}
}
}
}
}
void TStyleItem::SetImport()
{
bool bSet = false;
for( int i=0; i<4; i++ ){
if( nSegNum[i]<8 ){
bSet = true;
break;
}
}
int iImport = -1;
for( int i=0; i<aOptions->Count; i++ ){
DWORD iOpt = (DWORD)aOptions->Items[i];
if( iOpt==OPT_IMPORT ){
iImport = i;
break;
}
}
if( iImport<0 && bSet ){
aOptions->Add((void*)OPT_IMPORT);
}
else if( iImport>=0 && !bSet ){
aOptions->Delete( iImport );
}
}
void TStyleItem::SetCharge( bool bSet )
{
int iCharge = -1;
for( int i=0; i<aOptions->Count; i++ ){
DWORD iOpt = (DWORD)aOptions->Items[i];
if( iOpt==OPT_CHARGE ){
iCharge = i;
break;
}
}
if( iCharge<0 && bSet ){
aOptions->Add((void*)OPT_CHARGE);
}
else if( iCharge>=0 && !bSet ){
aOptions->Delete( iCharge );
}
}
void TStyleItem::AddStyleId( String& strText )
{
char strNo[20] = "";
if( pStyle ){
if( pStyle->idLoc==0 ){
if( pStyle->idStyle>0 ){
sprintf( strNo, "[%d] ", pStyle->idStyle );
}
else{
strNo[0] = '\0';
}
}
else if( pStyle->idLoc==1 ){
sprintf( strNo, "[S%d] ", pStyle->idStyle );
}
else if( pStyle->idLoc!=(UINT)-1 ){
sprintf( strNo, "[L%d] ", LOWORD(pStyle->idStyle) );
}
}
strText += strNo;
}
String TStyleItem::GetCaption()
{
String strText;
AddStyleId( strText );
if( pStyle ){
if( pStyle->idLoc==0 )
strText += UTF8ToMBCS(pStyle->pOrigin->detail.strStyleName).c_str();
else if( pStyle->idLoc==1 )
strText += UTF8ToMBCS(pStyle->pShare->strStyleName).c_str();
else if( pStyle->idLoc!=(UINT)-1 )
strText += UTF8ToMBCS(pStyle->pLocal->strStyleName).c_str();
else
strText += "未知风格";
}
else{
if( this==g_pPreStyle )
strText += "新建自定义风格";
else if( this==g_pUseStyle )
strText += "无";
}
if( nBars>0 ){
char strNum[20];
sprintf( strNum, " (%d段 %d小节)", aItems->Count, nBars );
strText += strNum;
}
return strText;
}
String TStyleItem::HintText()
{
String HintStr;
if( !pStyle ){
HintStr = "新建自定义风格\n";
}
else if( pStyle->idLoc==0 ){
TSTYLEORIGIN* pOrig = pStyle->pOrigin;
HintStr = "发布风格\n\n";
HintStr += "名称:";
HintStr += UTF8ToMBCS(pOrig->detail.strStyleName).c_str();
HintStr += "\n作者:";
HintStr += UTF8ToMBCS(pOrig->detail.strAuthor).c_str();
HintStr += "\n简介:";
HintStr += UTF8ToMBCS(pOrig->detail.strDescription).c_str();
HintStr += "\n类型:";
String strType;
for( int i=0; i<4; i++ ){
int type = pOrig->detail.type[i];
if( type<0 )
break;
else{
if( type<24 ){
strType += (String)LSZ_STYLTYPES[type] + " ";
}
}
}
if (strType == L"") {
strType = L"未知类型";
}
HintStr += strType;
char buf[20];
HintStr += "\n原速:";
sprintf( buf, "%d", pOrig->detail.iTempo );
HintStr += buf;
HintStr += "\n价格:";
if( pOrig->cost==0 )
strcpy( buf, "免费" );
else
sprintf(buf, "%d个唱作音符", pOrig->cost);
HintStr += buf;
int score10 = (int)(pOrig->score/10.0 + 0.5);
sprintf( buf, "%.1f", score10 / 10.0 );
HintStr += "\n评分:";
HintStr += buf;
HintStr += "\n状态:";
if( pOrig->state==e_UnDownload )
HintStr += "未下载";
else if( pOrig->state==e_Downloading )
HintStr += "正在下载";
else
HintStr += "已下载";
}
else if( pStyle->idLoc==1 ){
TSTYLESHARE* pShare = pStyle->pShare;
HintStr = "分享风格\n\n";
HintStr += "名称:";
HintStr += UTF8ToMBCS(pShare->strStyleName).c_str();
HintStr += "\n作者:";
HintStr += UTF8ToMBCS(pShare->strAuthor).c_str();
HintStr += "\n简介:";
HintStr += UTF8ToMBCS(pShare->strDescription).c_str();
HintStr += "\n类型:";
String strType;
for( int i=0; i<2; i++ ){
int type = pShare->type[i];
if( type<0 )
break;
else{
if( type<24 ){
strType += (String)LSZ_STYLTYPES[type] + " ";
}
}
}
if (strType == L"") {
strType = L"未知类型";
}
HintStr += strType;
char buf[20];
HintStr += "\n原速:";
sprintf( buf, "%d", pShare->iTempo );
HintStr += buf;
int score10 = (int)(pShare->score/10.0 + 0.5);
sprintf( buf, "%.1f", score10 / 10.0 );
HintStr += "\n评分:";
HintStr += buf;
}
else if( pStyle->pLocal ){
TSTYLELOCAL* pLocal = pStyle->pLocal;
HintStr = "本地风格\n\n";
HintStr += "名称:";
HintStr += UTF8ToMBCS(pLocal->strStyleName).c_str();
char buf[20];
HintStr += "\n原速:";
sprintf( buf, "%d", pLocal->iTempo );
HintStr += buf;
}
return HintStr;
}
/////////////////////////////////////////////////////////////////////////
String GetProgName( BYTE iBank, BYTE iChan, BYTE iProg )
{
String strText;
if( iBank!=0xFF && iBank>=0x80 ){
VSTINFO* pVst = g_lstVSTi[iBank-0x80];
bool bSet = false;
for( int i=0; i<pVst->aPlugins.size(); i++ ){
if( iChan==pVst->aPlugins[i]->id ){
return pVst->aPlugins[i]->name;
}
}
if( !bSet ){
strText += "ch " + IntToStr( iChan+1 ) + ": ";
strText += pVst->strVSTName;
}
}
else{
FONTINFO* pFI = NULL;
if( iBank==0xFF ){
if( g_bExtFont ){
if(iChan==9)
pFI = g_lstCZFonts[16];
else
pFI = g_lstCZFonts[iProg/16];
}
else
pFI = g_lstFonts[g_idFont];
}
else
pFI = g_lstFonts[iBank];
int num = iChan==9 ? pFI->nDrumCount : pFI->nInstCount;
FONTPRESET* pSet = ( iChan==9 ? pFI->aDrums : pFI->aInsts );
char** strInst = NULL;
if( iChan==9 ){
for( int i=0; i<num; i++) {
if( pSet[i].id==iProg ){
return pSet[i].text;
}
}
}
else{
if( iBank==0xFF || g_bExtFontUsable && iBank<16
|| !strcmp( pFI->strFontName, g_strDefaultSoundSet )
|| !strcmp( pFI->strFontName, "Pop default" ) )
strInst = GM_INSTRUMENT;
if( strInst )
return strInst[iProg];
else{
for( int i=0; i<num; i++ ){
if( pSet[i].id==iProg ){
return pSet[i].text;
}
}
}
}
}
return strText;
}