//--------------------------------------------------------------------------- #include #pragma hdrstop #include "GlobalUnit.h" #include "MessageDef.h" #include "ContentPanelUnit.h" #include "UseStylePanel.h" #include "ChordPanel.h" #include "TrackPanel.h" #include "MidiTrack.h" #include "SwitchTextureForm.h" #include "SwitchProgFormUnit.h" #include "AudioFxFormUnit.h" #include "VSTPluginFormUnit.h" #include "ProgressFormUnit.h" #include "Undo.h" //#define TRK_HDR_WIDTH 120 #define DOTIP_WIDTH 10 #define CUR_WIDTH 11 #define CUR_HEIGHT 8 #define ABS_POI_PLAY 6 #define ABS_POI_WAVE 4 #define SM_TOP 15 #define SM_SIZE 14 #define SOLO_LEFT -19//101 #define MUTE_LEFT -34//86 #define HOVER_MUTE 0x10000 #define HOVER_SOLO 0x20000 #define TRACK_M_HOVER 0x10 #define TRACK_S_HOVER 0x20 #define IDM_TRKSHOW 0x100 #define IDM_TRKAUD 0x200 #define IDM_TRKMID 0x300 //--------------------------------------------------------------------------- #pragma package(smart_init) extern TImage * w_imgDrag; //拖动图片 extern bool w_bDraging; extern int w_iDragMode, //拖动模式 w_xImgDrag, //透明图片位置 w_yImgDrag, w_xOldDrag, //透明图片上次位置 w_yOldDrag, w_xOffDrag, //图片左上角与鼠标距离 w_yOffDrag; extern TCursor crBrush, crBrushAdd, crBrushNo; const COLORREF clrBackground = RGB(52,56,62), //面板背景 clrBackboard = RGB( 29,31,35 ), //面板边框 clrBarTitle[17] = { RGB(22,24,27),RGB(64,69,76),RGB(44,48,55), RGB(42,46,53),RGB(41,44,51),RGB(39,42,48),RGB(37,40,46), RGB(35,38,43),RGB(33,35,40),RGB(31,32,37),RGB(28,30,34), RGB(26,28,32),RGB(24,25,29),RGB(23,24,26),RGB(21,22,24), RGB(19,20,22),RGB(22,24,27) }, //小节栏渐变色 clrBarTitleSel[17] = { RGB(152,152,152),RGB(145,144,144),RGB(135,134,134), RGB(125,123,123),RGB(112,111,111),RGB(99,98,98),RGB(86,84,84), RGB(73,71,71),RGB(62,60,60),RGB(50,49,49),RGB(39,37,38), RGB(32,29,30),RGB(30,28,29),RGB(29,27,28),RGB(29,26,27), RGB(28,25,26),RGB(27,24,25) }, //高亮小节栏渐变色 clrFocus = RGB(247,246,246), clrFocback = RGB(225,236,255), clrSelText = RGB(201,214,229), clrTitleFont = RGB(156,170,189), clrHeadFont = RGB(52,56,62), clrSelCell = RGB(83,109,165), //选中和弦 clrPlayLine = RGB(255,0,0), // 播放标示线 clrInsertLine = RGB(228,123,249),//255,0,255), //音频插入线 clrRecordMask = RGB(226,225,225), //屏蔽录音颜色 clrEffectBk = RGB(247,246,246), //音效区域背景 clrWaveBk[3] = {RGB(186,185,185), RGB(216,215,215), RGB(226,225,225)}, clrWave[2] = {RGB(15,229,226), RGB(75,148,147)}, clrSMState[4] = {RGB(186,185,185), RGB(216,215,215), RGB(248,235,159), RGB(250,244,213)}; //--------------------------------------------------------------------------- __fastcall TContentPanel::TContentPanel(TComponent* AOwner) : Vcl::Extctrls::TPanel(AOwner) { Visible = false; DoubleBuffered = true; m_rgnClip = NULL; m_pStylePanel = NULL; m_pItem = NULL; m_sbVert = m_sbHoriz = NULL; m_imgPlayCursor = m_imgMidiIcon = m_imgWaveIcon = NULL; m_pTimer = NULL; m_PopupMenu = NULL; m_bPlaying = m_bDragReady = m_bDraging = m_bBrush = false; m_iMode = VIEW_INIT; m_bVertical = true; m_nBarWidth = m_nDataWidth = POINTS_PER_BAR; m_nRowGapHeight = 14; m_nTitleHeight = 17; m_nChordHeight = 27; m_nTrackHeight = 31; m_nLeftOriBound = m_nLeftBound = 4;//20; m_nRightBound = 1;//15; m_nTopBound = 1; m_nBottomBound = 1; m_nTrkHdrWidth = MIN_HDR_WIDTH; m_nBarDrawHeight = m_nTitleHeight + m_nTrackHeight; m_nBarHeight = m_nRowGapHeight + m_nBarDrawHeight; m_nChordTxtHeight = 18; m_iPlayBar = m_iPlayPoint = 0; m_iDropBar = -1; m_iCopyAudio = m_iDragAudio = -1; m_iSelTrackBar = m_iSelTrackPoint = -1; m_iSelBarStart = m_iSelBarEnd = -1; m_iSelCellStart = m_iSelCellEnd = -1; m_iSelPointStart = m_iSelPointEnd = -1; m_iMouseDownBar = m_iMouseDownPoint = -1; m_iCopyBarStart = m_iCopyBarEnd = -1; m_iCopyCellStart = m_iCopyCellEnd = -1; m_iCopyPointStart = m_iCopyPointEnd = -1; m_iSelTrack = -1; m_bCut = false; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::CreateWnd(void) { Vcl::Extctrls::TPanel::CreateWnd(); if( m_ApplicationEvents==NULL ){ m_ApplicationEvents = new TApplicationEvents(NULL); m_ApplicationEvents->OnMessage = DoHandleMessage; } OnDblClick = DoubleClick; if( !m_imgPlayCursor ){ m_imgPlayCursor = new TBitmap(); m_imgPlayCursor->LoadFromResourceName(int(HInstance), L"imgPlayCursor"); } if( !m_imgMidiIcon ){ m_imgMidiIcon = new TBitmap(); m_imgMidiIcon->LoadFromResourceName(int(HInstance), L"imgMidiIcon"); } if( !m_imgWaveIcon ){ m_imgWaveIcon = new TBitmap(); m_imgWaveIcon->LoadFromResourceName(int(HInstance), L"imgWaveIcon"); } m_pngChordUp = new TPngImage(); m_pngChordUp->LoadFromResourceName(int(HInstance), "chordUp"); m_pngChordDown = new TPngImage(); m_pngChordDown->LoadFromResourceName(int(HInstance), "chordDown"); m_pngChord2 = new TPngImage(); m_pngChord2->LoadFromResourceName(int(HInstance), "chord2"); m_pngChord4 = new TPngImage(); m_pngChord4->LoadFromResourceName(int(HInstance), "chord4"); m_pngChord6 = new TPngImage(); m_pngChord6->LoadFromResourceName(int(HInstance), "chord6"); m_pngChord7 = new TPngImage(); m_pngChord7->LoadFromResourceName(int(HInstance), "chord7"); m_pngChordI = new TPngImage(); m_pngChordI->LoadFromResourceName(int(HInstance), "chordI"); m_pngChordV = new TPngImage(); m_pngChordV->LoadFromResourceName(int(HInstance), "chordV"); m_pngChordMaj = new TPngImage(); m_pngChordMaj->LoadFromResourceName(int(HInstance), "chordMaj"); m_pngChordMin = new TPngImage(); m_pngChordMin->LoadFromResourceName(int(HInstance), "chordMin"); m_pngChordSus = new TPngImage(); m_pngChordSus->LoadFromResourceName(int(HInstance), "chordSus"); m_sbVert = new TSkinScrollBar(this); m_sbVert->Parent = this; m_sbVert->m_pWndCtrl = this; m_sbVert->Visible = false; m_sbVert->Left = ClientWidth - m_sbVert->Width - 1; m_sbVert->Top = 1; m_sbVert->Height = ClientHeight - 2; m_sbHoriz = new TSkinScrollBar(this, false); m_sbHoriz->Parent = this; m_sbHoriz->m_pWndCtrl = this; m_sbHoriz->Visible = false; m_sbHoriz->Left = m_nTrkHdrWidth; m_sbHoriz->Top = ClientHeight - m_sbHoriz->Height - 1; m_sbHoriz->Width = ClientWidth - m_nTrkHdrWidth - 1; //录音提示 m_iBeatHint = -1; for( int i=0; i<4; i++ ){ m_imgBeatHint[i] = new TPngImage(); String strHintName = "imgBeatHint" + IntToStr( i+1 ); m_imgBeatHint[i]->LoadFromResourceName(int(HInstance), strHintName ); } m_wBeatHint = m_imgBeatHint[0]->Width; m_hBeatHint = m_imgBeatHint[0]->Height; m_lBeatHint = (ClientWidth - m_wBeatHint) / 2; m_tBeatHint = (ClientHeight - m_hBeatHint) / 2; Canvas->Font->Name = "SimHei"; Canvas->Font->Size = g_szFont8; InitialVars(); g_Midi.InitNoteColor(); } //--------------------------------------------------------------------------- __fastcall TContentPanel::~TContentPanel() { if( m_ApplicationEvents ) delete m_ApplicationEvents; if( m_rgnClip ) ::DeleteObject(m_rgnClip); if( m_sbVert ) delete m_sbVert; if( m_sbHoriz ) delete m_sbHoriz; // if( m_PopupMenu ) // delete m_PopupMenu; if( m_imgPlayCursor ) delete m_imgPlayCursor; if( m_imgMidiIcon ) delete m_imgMidiIcon; if( m_imgWaveIcon ) delete m_imgWaveIcon; for( int i=0; i<4; i++ ){ if( m_imgBeatHint[i] ) delete m_imgBeatHint[i]; } if( m_pngChordUp ) delete m_pngChordUp; if( m_pngChordDown ) delete m_pngChordDown; if( m_pngChord2 ) delete m_pngChord2; if( m_pngChord4 ) delete m_pngChord4; if( m_pngChord6 ) delete m_pngChord6; if( m_pngChord7 ) delete m_pngChord7; if( m_pngChordI ) delete m_pngChordI; if( m_pngChordV ) delete m_pngChordV; if( m_pngChordMaj ) delete m_pngChordMaj; if( m_pngChordMin ) delete m_pngChordMin; if( m_pngChordSus ) delete m_pngChordSus; ClearShowTracks(); } //--------------------------------------------------------------------------- void TContentPanel::ClearShowTracks() { SelectTrack( -1, -1, -1 ); while( !m_aTracks.empty() ){ delete m_aTracks.back(); m_aTracks.pop_back(); } } //--------------------------------------------------------------------------- void TContentPanel::SetMode( int iMode ) { if( m_iMode!=iMode ){ m_iMode = iMode; m_iDropBar = -1; m_iCopyAudio = m_iDragAudio = -1; m_iSelTrackBar = m_iSelTrackPoint = -1; SelectRange( -1, -1, -1, -1 ); SelectCopyPos( -1, -1, -1, -1 ); SelectCells( -1, -1, -1, -1 ); SelectCopyCells( -1, -1, -1, -1 ); m_iSelTrack = g_iSelAudio = iMode==MODE_INIT ? 0 : -1; g_iSelMidiTrack = -1; ((TChordPanel*)m_pChordPanel)->EnableChordModify( false, -1, -1, -1 ); ((TUseStylePanel*)m_pStylePanel)->SetSelectStage( -1 ); if( iMode==MODE_INIT && !m_bVertical ) SetScrollMode( true ); else InvalidateRgn( Handle, NULL, false ); } } //--------------------------------------------------------------------------- void TContentPanel::SetScrollMode( bool bVertical ) { if( m_bVertical!=bVertical ){ m_bVertical = bVertical; m_iDropBar = -1; m_iCopyAudio = m_iDragAudio = -1; m_iSelTrackBar = m_iSelTrackPoint = -1; SelectRange( -1, -1, -1, -1 ); SelectCopyPos( -1, -1, -1, -1 ); SelectCells( -1, -1, -1, -1 ); SelectCopyCells( -1, -1, -1, -1 ); g_iSelAudio = g_iSelMidiTrack = m_iSelTrack = -1; ((TChordPanel*)m_pChordPanel)->EnableChordModify( false, -1, -1, -1 ); ((TUseStylePanel*)m_pStylePanel)->SetSelectStage( -1 ); ((TTrackPanel*)m_pTrackPanel)->SetSelTrack( -1, -1 ); ClearShowTracks(); int nBarDrawHeight = m_nTitleHeight; if( g_lstOpusStages.size()>0 ){ nBarDrawHeight += m_nChordHeight; } if( m_iMode==VIEW_INIT ){ TShowTrack* pTrk = new TShowTrack( ST_AUDIO, 0, 0 ); m_aTracks.push_back( pTrk ); } else{ if( !m_bVertical ){ for( int i=0; iIsHide() ){ m_aTracks.push_back( new TShowTrack( ST_MIDI, i, g_aMidiTracks[i] ) ); } } } for( int i=0; iIsHide() && !g_aAudioTracks[i]->lstBars.empty() ){ m_aTracks.push_back( new TShowTrack( ST_AUDIO, i, g_aAudioTracks[i] ) ); } } } nBarDrawHeight += m_nTrackHeight * m_aTracks.size(); if( nBarDrawHeight!=m_nBarDrawHeight ){ m_nBarDrawHeight = nBarDrawHeight; m_nBarHeight = m_nRowGapHeight + m_nBarDrawHeight; } CalcViewArea(); if( bVertical ){ if( m_nRowNum>m_nRowShow ){ m_sbVert->SetRange( 0, m_nRowNum-1 ); m_sbVert->SetPageSize( m_nRowShow ); m_sbVert->SetPosition( 0 ); /* int iRowScroll = 0; if( m_iBeginShowBar>0 ){ iRowScroll = min( m_iBeginShowBar / m_nColumnNum, m_nRowNum-m_nRowShow ); if( iRowScroll<0 ){ iRowScroll = 0; } } ScrollView( iRowScroll ); */ } else{ m_sbVert->SetRange( 0, 0, false ); m_sbVert->SetPageSize( 0, false ); m_sbVert->SetPosition( 0, false ); } if( m_sbHoriz ){ m_sbHoriz->SetRange( 0, 0, false ); m_sbHoriz->SetPageSize( 0, false ); m_sbHoriz->SetPosition( 0, false ); } m_iBeginShowBar = 0; m_iBeginShowTrack = 0; m_nTrackShow = m_aTracks.size(); } else{ GenerateCompose(); int nRange = m_nBarNum; int nDrawWidth = ClientWidth - m_nLeftOriBound - m_nRightBound; if( nDrawWidth % m_nBarWidth > 0 ) nRange++; if( nRange>m_nColumnNum ){ m_sbHoriz->SetRange( 0, nRange - 1 ); m_sbHoriz->SetPageSize( m_nColumnNum ); m_sbHoriz->SetPosition( 0 ); /* if( m_iBeginShowBar>0 ){ ScrollView( m_iBeginShowBar, false ); } */ } else{ m_sbHoriz->SetRange( 0, 0, false ); m_sbHoriz->SetPageSize( 0, false ); m_sbHoriz->SetPosition( 0, false ); } nRange = m_aTracks.size(); int nDrawHeight = ClientHeight - m_nTopBound - m_nBottomBound - m_nRowGapHeight - m_nTitleHeight - m_nChordHeight; if( nDrawHeight % m_nTrackHeight > 0 ) nRange++; if( nRange > m_nTrackShow ){ m_sbVert->SetRange( 0, nRange-1 ); m_sbVert->SetPageSize( m_nTrackShow ); m_sbVert->SetPosition( 0 ); } else{ m_sbVert->SetRange( 0, 0, false ); m_sbVert->SetPageSize( 0, false ); m_sbVert->SetPosition( 0, false ); } m_nRowNum = m_nRowShow = 1; m_iBeginShowRow = 0; } InvalidateRgn( Handle, NULL, true ); } ShowPlayPoint(); } //--------------------------------------------------------------------------- void TContentPanel::InitialVars( bool bClear ) { ClearShowTracks(); int nBarNum = 0; if( bClear ){ m_iDropBar = -1; m_iCopyAudio = m_iDragAudio = -1; m_iSelBarStart = m_iSelBarEnd = -1; m_iSelCellStart = m_iSelCellEnd = -1; m_iSelPointStart = m_iSelPointEnd = -1; m_iCopyBarStart = m_iCopyBarEnd = -1; m_iCopyCellStart = m_iCopyCellEnd = -1; m_iCopyPointStart = m_iCopyPointEnd = -1; m_iSelTrackBar = m_iSelTrackPoint = -1; m_iPlayBar = m_iPlayPoint = 0; m_bCut = false; m_iBeginShowBar = m_iBeginShowTrack = 0; } else{ int nBarDrawHeight = m_nTitleHeight; if( g_lstOpusStages.size()>0 ){ nBarDrawHeight += m_nChordHeight; nBarNum = GetBarCount(); } if( m_iMode==VIEW_INIT && nBarNum==0 ){ TShowTrack* pTrk = new TShowTrack( ST_AUDIO, 0, 0 ); m_aTracks.push_back( pTrk ); } else{ if( !m_bVertical ){ for( int i=0; iIsHide() ){ m_aTracks.push_back( new TShowTrack( ST_MIDI, i, g_aMidiTracks[i] ) ); } } } for( int i=0; iIsHide() && !g_aAudioTracks[i]->lstBars.empty() ){ m_aTracks.push_back( new TShowTrack( ST_AUDIO, i, g_aAudioTracks[i] ) ); } } } nBarDrawHeight += m_nTrackHeight * m_aTracks.size(); if( nBarDrawHeight!=m_nBarDrawHeight ){ m_nBarDrawHeight = nBarDrawHeight; m_nBarHeight = m_nRowGapHeight + m_nBarDrawHeight; } } m_nBarNum = nBarNum; CalcViewArea(); m_nChordTxtWidth = m_nDataWidth/g_nChordNumPerBar; // m_iBeginShowRow = 0; // m_iBeginShowTrack = 0; SetScrollView( m_iBeginShowBar ); InvalidateRgn( Handle, NULL, false ); } //--------------------------------------------------------------------------- int TContentPanel::GetShowTrackId( int type, int index ) { for( int i=0; itype==type && m_aTracks[i]->index==index ) return i+1; } return 0; } //--------------------------------------------------------------------------- bool TContentPanel::SetScrollView( int iFirstShowBar ) { bool bScroll = false; m_iBeginShowBar = iFirstShowBar; m_iBeginShowTrack = 0; if( m_bVertical ){ if( m_nRowNum>m_nRowShow ){ //显示滚动条 m_sbVert->SetRange( 0, m_nRowNum-1 ); m_sbVert->SetPageSize( m_nRowShow ); m_sbVert->SetPosition( 0 ); int iRowScroll = 0; if( iFirstShowBar>0 ){ iRowScroll = min( iFirstShowBar / m_nColumnNum, m_nRowNum-m_nRowShow ); if( iRowScroll<0 ){ iRowScroll = 0; } } if( iRowScroll!=m_iBeginShowRow ) bScroll = true; ScrollView( iRowScroll ); } else { m_sbVert->SetRange( 0, 0, false ); m_sbVert->SetPageSize( 0, false ); m_sbVert->SetPosition( 0, false ); if( m_iBeginShowRow!=0 ){ m_iBeginShowRow = 0; m_iBeginShowBar = 0; bScroll = true; InvalidateRgn( Handle, NULL, false ); } } } else{ int nRange = m_nBarNum; int nDrawWidth = ClientWidth - m_nLeftOriBound - m_nRightBound; if( nDrawWidth % m_nBarWidth > 0 ) nRange++; if( nRange>m_nColumnNum ){ //显示滚动条 m_sbHoriz->SetRange( 0, nRange - 1 ); m_sbHoriz->SetPageSize( m_nColumnNum ); m_sbHoriz->SetPosition( 0 ); if( m_iBeginShowBar>0 ){ ScrollView( m_iBeginShowBar, false ); } } else { m_sbHoriz->SetRange( 0, 0, false ); m_sbHoriz->SetPageSize( 0, false ); m_sbHoriz->SetPosition( 0, false ); } nRange = m_aTracks.size(); int nDrawHeight = ClientHeight - m_nTopBound - m_nBottomBound - m_nRowGapHeight - m_nTitleHeight - m_nChordHeight; if( nDrawHeight % m_nTrackHeight > 0 ) nRange++; if( nRange > m_nTrackShow ){ m_sbVert->SetRange( 0, nRange-1 ); m_sbVert->SetPageSize( m_nTrackShow ); m_sbVert->SetPosition( 0 ); } else{ m_sbVert->SetRange( 0, 0, false ); m_sbVert->SetPageSize( 0, false ); m_sbVert->SetPosition( 0, false ); } } return bScroll; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoHandleMessage(MSG &Msg, bool &Handled) { if( !Visible ) return; if( Msg.message==WM_MOUSEMOVE && Msg.wParam==0 ){ TPoint pt( Msg.pt.x, Msg.pt.y ); pt = ScreenToClient( pt ); if( m_sbVert && m_sbVert->Visible && Msg.hwnd!=m_sbVert->Handle ) //竖直滚动条自动隐藏 m_sbVert->Visible = false; if( m_sbHoriz && m_sbHoriz->Visible && Msg.hwnd!=m_sbHoriz->Handle ) //水平滚动条自动隐藏 m_sbHoriz->Visible = false; if( pt.x>=0 && pt.x=0 && pt.yCursor = crHSplit; m_ApplicationEvents->CancelDispatch(); } } else if( !m_bVertical && m_nLeftBound>=MIN_HDR_WIDTH && pt.yTop && pt.x>m_nLeftBound-8 && pt.xCursor = crHSplit; m_ApplicationEvents->CancelDispatch(); } else{ if( Screen->Cursor==crHSplit ) Screen->Cursor = crDefault; if( m_sbVert->IsOperable() && pt.x >= m_sbVert->Left && pt.y >= m_sbVert->Top ){ //竖直滚动条自动显示 m_sbVert->Visible = true; m_ApplicationEvents->CancelDispatch(); } if( m_sbHoriz->IsOperable() && pt.x >= m_sbHoriz->Left && pt.y >= m_sbHoriz->Top ){ //水平滚动条自动显示 m_sbHoriz->Visible = true; m_ApplicationEvents->CancelDispatch(); } } } else if( Screen->Cursor==crHSplit && (pt.x<0 || pt.y<0 || pt.y>=Height) ){ Screen->Cursor = crDefault; } } else if( Msg.message==WM_KEYDOWN && Msg.hwnd==Handle && Msg.wParam>=VK_PRIOR && Msg.wParam<=VK_DOWN ){ OnDirectionKey( Msg.wParam ); } } //--------------------------------------------------------------------------- void TContentPanel::ShowBeatHint( int iBeat ) { if( m_iBeatHint==iBeat ) return; if( iBeat<0 || iBeat>3 ){ iBeat = -1; RECT rectHint; SetRect( &rectHint, m_lBeatHint, m_tBeatHint, m_lBeatHint + m_wBeatHint, m_tBeatHint + m_hBeatHint ); InvalidateRect( Handle, &rectHint, false ); } else{ Canvas->Draw( m_lBeatHint, m_tBeatHint, m_imgBeatHint[iBeat] ); } m_iBeatHint = iBeat; } // --------------------------------------------------------------------------- void TContentPanel::SetPlayPoint( int iBar, int iPoint ) { if( m_iPlayBar==iBar && m_iPlayPoint==iPoint ){ return; } if( m_nBarNum==0 ){ m_iPlayBar = m_iPlayPoint = 0; return; } int iRow = m_bVertical ? m_iPlayBar / m_nColumnNum - m_iBeginShowRow : 0; if( m_nBarNum>0 && iRow>=0 ){ RECT rect; int iCol = m_bVertical ? m_iPlayBar % m_nColumnNum : m_iPlayBar - m_iBeginShowBar, left = iCol * m_nBarWidth + m_iPlayPoint + m_nLeftBound, top = iRow * m_nBarHeight + m_nTopBound + m_nRowGapHeight; SetRect( &rect, left - 5, top - 8, left - 5 + m_imgPlayCursor->Width, top - 8 + m_imgPlayCursor->Height ); InvalidateRect( Handle, &rect, false ); int nH = m_nBarDrawHeight; if( top + m_nBarDrawHeight > ClientHeight - m_nBottomBound ) nH = ClientHeight - m_nBottomBound - top; SetRect( &rect, left, top, left + 1, top + nH ); InvalidateRect( Handle, &rect, false ); } m_iPlayBar = iBar; m_iPlayPoint = iPoint; ShowPlayPoint(); } //--------------------------------------------------------------------------- void TContentPanel::ShowPlayPoint() { int iRow = m_bVertical ? m_iPlayBar / m_nColumnNum - m_iBeginShowRow : 0, iCol = m_bVertical ? m_iPlayBar % m_nColumnNum : m_iPlayBar - m_iBeginShowBar; if( m_bVertical && iRow<0 ){ ScrollView( iRow + m_iBeginShowRow ); } else if( m_bVertical && ( iRow>=m_nRowShow || m_nRowShow>1 && iRow>=m_nRowShow-1 )){ //int nRowScroll = min( m_nRowShow+m_iBeginShowRow-1, m_nRowNum-iRow ); // 显示到第2行 int nRow1 = iRow+m_iBeginShowRow, nRow2 = m_nRowNum-m_nRowShow+1; if( m_nRowShow>2 ) nRow1--; if( nRow1>=0 && nRow2>=0 ){ int nRowScroll = min( nRow1, nRow2 ); // 显示到第2行 ScrollView( nRowScroll ); } } else if( !m_bVertical && iCol<0 ){ ScrollView( iCol + m_iBeginShowBar, false ); } else if( !m_bVertical && iCol>=m_nColumnNum-1 ){ //int nColScroll = min( m_iBeginShowBar+m_nColumnNum-2, m_nBarNum-m_nColumnNum+1 ); // 显示第2小节 int nColScroll = min( m_iPlayBar-2, m_nBarNum-m_nColumnNum+1 ); // 显示第2小节 ScrollView( nColScroll, false ); } else if( m_nBarNum>0 ){ RECT rect; int left = iCol * m_nBarWidth + m_iPlayPoint + m_nLeftBound, top = iRow * m_nBarHeight + m_nTopBound + m_nRowGapHeight; SetRect( &rect, left - 5, top - 8, left - 5 + m_imgPlayCursor->Width, top - 8 + m_imgPlayCursor->Height ); InvalidateRect( Handle, &rect, false ); int nH = m_nBarDrawHeight; if( top + m_nBarDrawHeight > ClientHeight - m_nBottomBound ) nH = ClientHeight - m_nBottomBound - top; SetRect( &rect, left, top, left + 1, top + nH ); InvalidateRect( Handle, &rect, false ); } } void TContentPanel::InvalidateBar( int iBar, int iBeginPoint, int iEndPoint, int iArea ) { if( iBar=m_nRowShow || iCol>=m_nColumnNum ) return; rectDraw.left = iCol * m_nBarWidth + m_nLeftBound + iBeginPoint - 1; rectDraw.right = iCol * m_nBarWidth + m_nLeftBound + iEndPoint + 1; if( rectDraw.right>ClientWidth-m_nRightBound ) rectDraw.right = ClientWidth-m_nRightBound; int nBarTop = iRow * m_nBarHeight + m_nTopBound, nDrawBottom = ClientHeight - m_nBottomBound; bool bData = g_lstOpusStages.size()>0; if( iArea & BAR_TITLE ){ rectDraw.top = nBarTop + m_nRowGapHeight; if( rectDraw.top < nDrawBottom ){ rectDraw.bottom = rectDraw.top + m_nTitleHeight; if( rectDraw.bottom > nDrawBottom ) rectDraw.bottom = nDrawBottom; InvalidateRect( Handle, &rectDraw, false ); } } if( ( iArea & BAR_DATA ) && bData ){ rectDraw.top = nBarTop + m_nRowGapHeight + m_nTitleHeight; if( rectDraw.top < nDrawBottom ){ rectDraw.bottom = rectDraw.top + m_nChordHeight; if( rectDraw.bottom > nDrawBottom ) rectDraw.bottom = nDrawBottom; else if( !( iArea & BAR_TRACK ) ) rectDraw.bottom++; InvalidateRect( Handle, &rectDraw, false ); } } if( iArea & BAR_TRACK ){ int iTrack = ( iArea & 0xFF ) - m_iBeginShowTrack; if( iTrack>=0 && iTrack<=m_nTrackShow ){ if( iTrack>0 ){ rectDraw.top = nBarTop + m_nRowGapHeight + m_nTitleHeight + (iTrack - 1) * m_nTrackHeight; if( bData ) rectDraw.top += m_nChordHeight; rectDraw.bottom = rectDraw.top + m_nTrackHeight + 1; } else{ rectDraw.top = nBarTop + m_nRowGapHeight + m_nTitleHeight; if( bData ) rectDraw.top += m_nChordHeight; rectDraw.bottom = rectDraw.top + (m_aTracks.size()-m_iBeginShowTrack) * m_nTrackHeight + 1; } if( rectDraw.top < nDrawBottom ){ if( rectDraw.bottom > nDrawBottom ) rectDraw.bottom = nDrawBottom; InvalidateRect( Handle, &rectDraw, false ); } } } } //--------------------------------------------------------------------------- void TContentPanel::InvalidateBars( int iBarStart, int iBarEnd, int iArea ) { for( int i=iBarStart; i<=iBarEnd; i++ ){ InvalidateBar( i, 0, m_nBarWidth, iArea ); } } //--------------------------------------------------------------------------- void TContentPanel::InvalidateStage( int iStage, int iArea ) { if( iStage<0 || iStage>=g_lstOpusStages.size() ) return; int iFirstBar = FirstBar( iStage ); TOpusStage * pStage = g_lstOpusStages[iStage]; InvalidateBars( iFirstBar, iFirstBar + pStage->aBars.size() - 1, iArea ); } //--------------------------------------------------------------------------- void TContentPanel::InvalidateShowBars( int iArea ) { int iBarS = m_iBeginShowBar, iBarE = iBarS + m_nRowNum * m_nColumnNum; if( iBarE>m_nBarNum ) iBarE = m_nBarNum-1; InvalidateBars( iBarS, iBarE, iArea ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::OnDirectionKey( WORD key ) { if( m_nBarNum==0 ) return; int nSBCode = -1; int nWMCode = -1; if( key>=VK_PRIOR && key<=VK_HOME ){ if( m_bVertical && m_sbVert && m_sbVert->IsOperable() ) nWMCode = WM_VSCROLL; else if( !m_bVertical && m_sbHoriz && m_sbHoriz->IsOperable() ) nWMCode = WM_HSCROLL; } else if( key==VK_UP || key==VK_DOWN ){ if( m_sbVert && m_sbVert->IsOperable() ) nWMCode = WM_VSCROLL; } else if( key==VK_LEFT || key==VK_RIGHT ){ if( m_sbHoriz && m_sbHoriz->IsOperable() ) nWMCode = WM_HSCROLL; } if( nWMCode>=0 ){ if( key==VK_UP || key==VK_LEFT ) nSBCode = SB_LINEUP; else if( key==VK_DOWN || key==VK_RIGHT ) nSBCode = SB_LINEDOWN; else if( key==VK_PRIOR ) nSBCode = SB_PAGEUP; else if( key==VK_NEXT ) nSBCode = SB_PAGEDOWN; else if( key==VK_HOME ) nSBCode = SB_TOP; else if( key==VK_END ) nSBCode = SB_BOTTOM; Perform( nWMCode, MAKELONG(nSBCode,0), NULL ); } } //--------------------------------------------------------------------------- void TContentPanel::ScrollView( int nPos, bool bVertical, bool bRedraw ) { if( bVertical ){ if( m_bVertical ){ m_iBeginShowBar = nPos * m_nColumnNum; if( m_iBeginShowRow!=nPos ){ m_iBeginShowRow = nPos; InvalidateRgn( Handle, NULL , false ); } } else{ if( m_iBeginShowTrack!=nPos ){ m_iBeginShowTrack = nPos; InvalidateRgn( Handle, NULL , false ); } } if( bRedraw ){ m_sbVert->SetPosition( nPos ); } } else{ if( m_iBeginShowBar!=nPos ){ m_iBeginShowBar = nPos; InvalidateRgn( Handle, NULL , false ); } if( bRedraw ){ m_sbHoriz->SetPosition( nPos ); } } } //--------------------------------------------------------------------------- void TContentPanel::CalcViewArea() { if( ClientWidth>0 && ClientHeight>0 ){ if( m_bVertical ){ m_nColumnNum = (ClientWidth - m_nLeftOriBound - m_nRightBound) / m_nBarWidth; m_nRowNum = m_nBarNum / m_nColumnNum; if( m_nBarNum % m_nColumnNum > 0 ){ m_nRowNum++; } int nDrawHeight = ClientHeight - m_nTopBound - m_nBottomBound; m_nRowShow = nDrawHeight / m_nBarHeight; if( nDrawHeight % m_nBarHeight > m_nRowGapHeight + m_nTitleHeight ){ m_nRowShow++; m_nRowNum++; } m_nLeftBound = m_nLeftOriBound + 3; m_nTrackShow = m_aTracks.size(); } else{ m_nLeftBound = m_aTracks.empty() ? m_nLeftOriBound + 3 : m_nTrkHdrWidth; int nDrawWidth = ClientWidth - m_nLeftBound - m_nRightBound; m_nColumnNum = nDrawWidth / m_nBarWidth; if( nDrawWidth % m_nBarWidth > 0 ) m_nColumnNum++; int nHeight = ClientHeight - m_nTopBound - m_nBottomBound - m_nRowGapHeight - m_nTitleHeight - m_nChordHeight; m_nTrackShow = nHeight / m_nTrackHeight; if( nHeight % m_nTrackHeight > 0 ) m_nTrackShow++; m_sbHoriz->Left = m_nLeftBound; m_sbHoriz->Width = ClientWidth - m_nLeftBound - 1; } } else{ DebugPrint( "no area" ); } } //--------------------------------------------------------------------------- void TContentPanel::DrawBars() { bool bData = !g_lstOpusStages.empty(); bool bTrack = !m_aTracks.empty(); if( !bData && !bTrack ) return; TRect rtInvalid = Canvas->ClipRect; int iBeginRow = m_bVertical ? (rtInvalid.top - m_nTopBound) / m_nBarHeight : 0, iEndRow = m_bVertical ? (rtInvalid.bottom - m_nTopBound) / m_nBarHeight : 1, iBeginCol = ( rtInvalid.left - m_nLeftBound ) / m_nBarWidth, iEndCol = ( rtInvalid.right - m_nLeftBound ) / m_nBarWidth; // if( !m_bVertical ){ if( iBeginCol<0 ) iBeginCol = 0; if( iEndCol<0 ) iEndCol = 0; // } if( iBeginRow<0 ) iBeginRow = 0; if( iEndCol 0 ) iEndCol++; if( m_bVertical && (rtInvalid.bottom - m_nTopBound) % m_nBarHeight > 2 ) iEndRow++; int rowTop = m_nTopBound + iBeginRow * m_nBarHeight; iBeginRow += m_iBeginShowRow; iEndRow += m_iBeginShowRow; int iSelBarStart = m_iSelBarStart, iSelBarEnd = m_iSelBarEnd, iSelPointStart = m_iSelPointStart, iSelPointEnd = m_iSelPointEnd; if( iSelBarEnd>=0 && iSelBarStart<0 ){ iSelBarStart = 0; iSelPointStart = 0; } else if( iSelBarStart>=0 && iSelBarEnd<0 ){ iSelBarEnd = m_nBarNum - 1; iSelPointEnd = m_nDataWidth - 1; } if( m_rgnClip ) SelectClipRgn( Canvas->Handle, m_rgnClip ); int iFirstBar(0), iStage(0), nBarCount(0), iLastKey(g_iMelodyKey); for( int i=iBeginRow; i0 || iEndCol>0 && iEndCol=m_nBarNum ) break; if( bData && nBarCount>0 && nBarCountiSegType>=SEGTYPE_INTRO ) iLastKey = pStage->iSegKey; else iLastKey = pStage->aBars[nBarCount-1-iFirstBar]->iBarKey; } } if( m_nBarNum - nBarCount >= m_nColumnNum ){ //显示整满行 right = m_nColumnNum * m_nBarWidth + m_nLeftBound; } else{ //显示非整行 right = (m_nBarNum - nBarCount) * m_nBarWidth + m_nLeftBound; } //绘制轨道 if( bTrack ){ int iBeginTrk = 0, iEndTrk = m_aTracks.size(); if( !m_bVertical ){ int iTrackTop = m_nTopBound + m_nRowGapHeight + m_nTitleHeight + m_nChordHeight; iBeginTrk = (rtInvalid.top - iTrackTop) / m_nTrackHeight; iEndTrk = (rtInvalid.bottom - iTrackTop) / m_nTrackHeight; if( iBeginTrk<0 ) iBeginTrk = 0; if( iEndTrk<0 ) iEndTrk = 0; else if( iEndTrk 0) ) iEndTrk++; iBeginTrk += m_iBeginShowTrack; iEndTrk += m_iBeginShowTrack; if( iBeginTrk>m_aTracks.size() ) iBeginTrk = m_aTracks.size(); if( iEndTrk>m_aTracks.size() ) iEndTrk = m_aTracks.size(); } bool bBreak = bData, bDrawHead = !m_bVertical && (rtInvalid.left < m_nLeftBound-4); int topTrack = barTop + m_nTitleHeight + ( bData ? m_nChordHeight : 0 ) + (iBeginTrk-m_iBeginShowTrack) * m_nTrackHeight, leftTrack = bDrawHead ? m_nLeftOriBound : iBarLeft, num = min( m_nBarNum - nBarCount, iEndCol - iBeginCol ); Canvas->Pen->Style = psSolid; for( int t=iBeginTrk; tPen->Color = clrBarTitle[0]; if( bDrawHead ){ Canvas->MoveTo( leftTrack, topTrack ); Canvas->LineTo( m_nLeftBound-4, topTrack ); } Canvas->MoveTo( iBarLeft+1, topTrack ); Canvas->LineTo( right, topTrack ); bBreak = false; } DrawTrack( nBarCount, num, leftTrack, topTrack+1, t ); topTrack += m_nTrackHeight; bBreak = true; } } Canvas->Font->Name = "SimHei"; Canvas->Font->Size = g_szFont8; Canvas->Font->Color = clrTitleFont; //绘制第一个小节线 Canvas->Pen->Color = clrBarTitle[0]; Canvas->MoveTo( m_nLeftBound, barTop ); Canvas->LineTo( m_nLeftBound, barBottom ); for( int j=iBeginCol; jPen->Style = psSolid; if( m_iMode==VIEW_STYLE && m_iSelTrack<0 && ( m_iSelBarStart==nBarCount || m_iCopyBarStart==nBarCount )){ Canvas->Pen->Color = clrFocus; if( m_iCopyBarStart==nBarCount ){ Canvas->Brush->Color = clBlack; Canvas->Pen->Style = psDot; } Canvas->MoveTo( iBarLeft, barTop ); Canvas->LineTo( iBarLeft, barBottom ); } if( ( iSelBarStart<=nBarCount && iSelBarEnd>=nBarCount || m_iCopyBarStart<=nBarCount && m_iCopyBarEnd>=nBarCount ) && m_iMode==VIEW_STYLE && m_iSelTrack<0 ){ int l=iBarLeft+1, r=iBarLeft+m_nBarWidth+1; //绘制高亮小节栏 DrawBarTitle( l, r, barTop, true ); if( m_iMode==VIEW_STYLE ){ Canvas->Pen->Color = clrFocus; if( m_iCopyBarStart<=nBarCount && m_iCopyBarEnd>=nBarCount ){ Canvas->Brush->Color = clBlack; Canvas->Pen->Style = psDot; } } else Canvas->Pen->Color = clrBarTitle[0]; } else{ //绘制小节栏 DrawBarTitle( iBarLeft+1, iBarLeft+m_nBarWidth+1, barTop, false ); Canvas->Pen->Color = clrBarTitle[0]; } // 绘制小节栏上框 Canvas->MoveTo( iBarLeft+1, barTop ); Canvas->LineTo( iBarLeft+m_nBarWidth, barTop ); //绘制小节序号或调号 bool bDrawKey = false; if( bData && nBarCountaBars.size() ){ iStage++; iFirstBar = nBarCount; } TOpusStage* pStage = g_lstOpusStages[iStage]; int iKey = -1; if( nBarCount==0 ){ iKey = iLastKey; bDrawKey = true; } else if( pStage->iSegType<=SEGTYPE_FILL ){ iKey = pStage->aBars[nBarCount-iFirstBar]->iBarKey; bDrawKey = iKey!=iLastKey; } else if( nBarCount==iFirstBar ){ iKey = pStage->iSegKey; bDrawKey = iKey!=iLastKey; } if( bDrawKey ){ strText = "1 = "; strText += g_strMelodyKey[iKey]; iLastKey = iKey; } } if( !bDrawKey ) strText = IntToStr(nBarCount+1); Canvas->Brush->Style = bsClear; Canvas->TextOut( iBarLeft + 8, barTop + 4, strText ); Canvas->Brush->Style = bsSolid; int iBarTop = barTop + m_nTitleHeight; if( bData && nBarCountPen->Style = psSolid; if( m_iMode==VIEW_STYLE && m_iSelTrack<0 && ( m_iSelBarEnd==nBarCount || m_iCopyBarEnd==nBarCount )){ Canvas->Pen->Color = clrFocus; if( m_iCopyBarEnd==nBarCount ){ Canvas->Brush->Color = clBlack; Canvas->Pen->Style = psDot; } } else{ Canvas->Pen->Color = clrBarTitle[0]; } //绘制小节线 Canvas->MoveTo( iBarLeft + m_nBarWidth, barTop ); Canvas->LineTo( iBarLeft + m_nBarWidth, barTop + m_nTitleHeight ); if( j==m_nColumnNum-1 || nBarCount==m_nBarNum-1 ){ Canvas->MoveTo( iBarLeft + m_nBarWidth, barTop + m_nTitleHeight ); Canvas->LineTo( iBarLeft + m_nBarWidth, barTop + m_nBarDrawHeight ); } else if( bData ){ Canvas->MoveTo( iBarLeft + m_nBarWidth, barTop + m_nTitleHeight ); Canvas->LineTo( iBarLeft + m_nBarWidth, barTop + m_nTitleHeight + m_nChordHeight ); } //绘制播放线 if( m_iPlayBar==nBarCount ){ int iPlayPoint = iBarLeft + m_iPlayPoint; if( iPlayPoint-5>=rtInvalid.left && iPlayPoint+5=rtInvalid.top ){ Canvas->Draw( iPlayPoint - 5, barTop - 8, m_imgPlayCursor ); } if( iPlayPoint>=rtInvalid.left && iPlayPointPen->Color; Canvas->Pen->Color = clrPlayLine; Canvas->Pen->Style = psSolid; Canvas->MoveTo( iPlayPoint, barTop+1 ); Canvas->LineTo( iPlayPoint, barBottom ); Canvas->Pen->Color = clrOld; } } //绘制音频插入线 if( g_iSelAudio>=0 && nBarCount==m_iSelTrackBar ){ int l = iBarLeft + m_iSelTrackPoint, t = iBarTop + ( GetShowTrackId(ST_AUDIO,g_iSelAudio) - 1 ) * m_nTrackHeight, b = t + m_nTrackHeight; if( l>=rtInvalid.left && lPen->Color = clrInsertLine; Canvas->MoveTo( l, t ); Canvas->LineTo( l, b ); } } // 绘制小节栏下框 if( barTop+m_nBarDrawHeight <= barBottom ){ Canvas->Pen->Color = clrBarTitle[0]; Canvas->MoveTo( iBarLeft, barTop + m_nBarDrawHeight ); Canvas->LineTo( iBarLeft+m_nBarWidth, barTop + m_nBarDrawHeight ); } if( w_bDraging ){ Canvas->Pen->Style = psSolid; TRect rcTip; rcTip.left = iBarLeft, rcTip.top = barTop, rcTip.right = iBarLeft+m_nBarWidth, rcTip.bottom = barTop + m_nBarDrawHeight - 1; if( rcTip.bottom > barBottom ){ rcTip.bottom = barBottom; } if( nBarCount==m_iDropBar ){ rcTip.right = rcTip.left + DOTIP_WIDTH; Canvas->Brush->Color = clrFocback; Canvas->FillRect( rcTip ); Canvas->Pen->Color = clrFocus; Canvas->MoveTo( rcTip.left, rcTip.top ); Canvas->LineTo( rcTip.right, rcTip.top ); Canvas->MoveTo( rcTip.left, rcTip.bottom ); Canvas->LineTo( rcTip.right, rcTip.bottom ); Canvas->MoveTo( rcTip.right, rcTip.top ); Canvas->LineTo( rcTip.right, rcTip.bottom ); } if( nBarCount==m_iDropBar-1 ){ rcTip.left = rcTip.right - DOTIP_WIDTH; Canvas->Brush->Color = clrFocback; Canvas->FillRect( rcTip ); Canvas->Pen->Color = clrFocus; Canvas->MoveTo( rcTip.left, rcTip.top ); Canvas->LineTo( rcTip.right, rcTip.top ); Canvas->MoveTo( rcTip.left, rcTip.bottom ); Canvas->LineTo( rcTip.right, rcTip.bottom ); Canvas->MoveTo( rcTip.left, rcTip.top ); Canvas->LineTo( rcTip.left, rcTip.bottom ); } } nBarCount++; iBarLeft += m_nBarWidth; } rowTop += m_nBarHeight; } } //--------------------------------------------------------------------------- void TContentPanel::DrawBarTitle( int l, int r, int t, bool bSel ) { Canvas->Pen->Style = psSolid; for( int i=0; iPen->Color = clrBarTitleSel[i]; else Canvas->Pen->Color = clrBarTitle[i]; Canvas->MoveTo( l, t+i ); Canvas->LineTo( r, t+i ); } } //--------------------------------------------------------------------------- void TContentPanel::DrawBarData( int iBar, int iStage, int iFirstBar, int leftBar, int topBar ) { TColor clrOld = Canvas->Brush->Color; //背景 TRect rectBar; rectBar.left = leftBar + 1; rectBar.right = leftBar + m_nDataWidth; rectBar.top = topBar; rectBar.bottom = rectBar.top + m_nChordHeight; COLORREF clrNormal; TOpusStage* pStage = g_lstOpusStages[iStage]; { int ty = pStage->iSegType, iNo = g_iSegColorMode==0 ? pStage->iSegNo : pStage->aTracks.size(); bool bInc = g_iSegColorMode==0 ? true : iNo>0 && pStage->aTracks[0]->iChanNo==9; Canvas->Brush->Color = GetSegmentColor( ty, iNo, bInc ); } Canvas->FillRect( rectBar ); //和弦选中框 if( m_iMode==VIEW_CHORD ){ if ( iBar>=m_iSelBarStart && iBar<=m_iSelBarEnd ){ //绘制选中和弦框 int l = leftBar, r = leftBar + m_nDataWidth, t = topBar, b = topBar + m_nChordHeight - 1; BYTE rF = 227, gF = 24, bF = 19, rD = 110, gD = 108, bD = 105, rL = 230, gL = 226, bL = 217; if( iBar==m_iSelBarStart ) //左框位置 l += m_iSelCellStart * m_nChordTxtWidth; if( iBar==m_iSelBarEnd ){ //右框位置 r = leftBar + (m_iSelCellEnd+1) * m_nChordTxtWidth; if( m_iSelCellEnd==g_nChordNumPerBar-1 ) r--; } for( int i=0; i<4; i++ ){ if( i==0 ) Canvas->Pen->Color = RGB(rF, gF, bF); if( i<2 ){ //绘制下框 if( i>0 ){ Canvas->Pen->Color = RGB(rL, gL, bL); rL -= 10, gL -= 10, bL -= 10; } Canvas->MoveTo( l+i, b-i ); Canvas->LineTo( r-i+1, b-i ); if( iBar==m_iSelBarEnd ){ //绘制右框 Canvas->MoveTo( r-i, t+i ); Canvas->LineTo( r-i, b-i+1 ); } } if( i>0 ){ Canvas->Pen->Color = RGB(rD, gD, bD); rD += 30, gD += 30, bD += 30; } //绘制上框 Canvas->MoveTo( l+i, t+i ); Canvas->LineTo( r-i+1, t+i ); if( iBar==m_iSelBarStart ){ //绘制左框 Canvas->MoveTo( l+i, t+i ); Canvas->LineTo( l+i, b-i+1 ); } } } if( iBar>=m_iCopyBarStart && iBar<=m_iCopyBarEnd ){ int l = leftBar, r = leftBar + m_nDataWidth, t = topBar, b = topBar + m_nChordHeight - 1; Canvas->Brush->Color = clWhite; Canvas->Pen->Style = psDot; Canvas->Pen->Color = clRed; if( iBar==m_iCopyBarStart ){ //绘制左框 l += m_iCopyCellStart * m_nChordTxtWidth; if( m_iCopyCellStart==0 ){ Canvas->Brush->Color = clBlack; } Canvas->MoveTo( l, t ); Canvas->LineTo( l, b ); if( m_iCopyCellStart==0 ){ Canvas->Brush->Color = clWhite; } } if( iBar==m_iCopyBarEnd ){ //绘制右框 r = leftBar + (m_iCopyCellEnd+1) * m_nChordTxtWidth; if( m_iCopyCellEnd==g_nChordNumPerBar-1 ) r--; Canvas->MoveTo( r, t ); Canvas->LineTo( r, b ); } //绘制上下框 Canvas->MoveTo( l, t ); Canvas->LineTo( r, t ); Canvas->MoveTo( l, b ); Canvas->LineTo( r, b ); } } //和弦 if( pStage->iSegType>=SEGTYPE_INTRO ) //前间尾奏无需绘制和弦 return; TBar * pBar = pStage->aBars[iBar-iFirstBar]; TRect rectDest; rectDest.top = topBar + ( m_nChordHeight - m_nChordTxtHeight ) / 2; rectDest.bottom = rectDest.top + m_nChordTxtHeight; int iPreKey = -1, iPreType = -1; for( int i=0; iaChords.iKey[i] != iPreKey || pBar->aChords.iType[i] != iPreType ){ rectDest.left = leftBar + i * m_nChordTxtWidth; rectDest.right = rectDest.left + m_nChordTxtWidth; DrawChord( rectDest, pBar->iBarKey, pBar->aChords.iKey[i], pBar->aChords.iType[i] ); iPreKey = pBar->aChords.iKey[i]; iPreType = pBar->aChords.iType[i]; } } //画笔还原 Canvas->Brush->Color = clrOld; } //--------------------------------------------------------------------------- void TContentPanel::DrawTrack( int iBarS, int nBarNum, int left, int top, int iTrack ) { bool bDrawHead = !m_bVertical && (left < m_nLeftBound-4); int leftBar = bDrawHead ? m_nLeftBound : left; TColor clrOld = Canvas->Brush->Color; TShowTrack* pST = m_aTracks[iTrack]; COLORREF clrUnselect = clrWaveBk[0], clrSelect = clrWaveBk[1], clrHigh = clWhite; Canvas->Font->Name = "Tohoma"; Canvas->Font->Size = g_szFont9; // Canvas->Font->Color = clrHeadFont; if( bDrawHead ){ TRect rectHead( m_nLeftOriBound, top, m_nLeftBound-4, top+m_nTrackHeight-1 ); if( m_iSelTrack==iTrack ) Canvas->Brush->Color = clrSelect; else Canvas->Brush->Color = clrUnselect; Canvas->FillRect( rectHead ); TBitmap* pImg = pST->type==ST_MIDI ? m_imgMidiIcon : m_imgWaveIcon; Canvas->Draw( m_nLeftOriBound + 2, top + 2, pImg ); String strText; if( pST->type==ST_MIDI ){ strText = IntToStr( pST->index + 1 ) + " "; TMidiTrack* pMT = (TMidiTrack*)pST->pTrack; strText += GetProgName( pMT->bank, pMT->chno, pMT->prog ); } else{ strText = "音轨 " + IntToStr( pST->index==0 ? 1 : pST->index ); } //----处理字符过长------ int nWidth = m_nLeftBound - m_nLeftOriBound - pImg->Width - 12 - 16; 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 = bsClear; Canvas->Font->Color = clrHeadFont; Canvas->TextOut( m_nLeftOriBound + pImg->Width + 4, top + 2, strText ); Canvas->Brush->Style = bsSolid; if( pST->iHover & TRACK_S_HOVER ){ if( pST->pTrack->IsSolo() ) Canvas->Brush->Color = clrSMState[3]; else Canvas->Brush->Color = clrSMState[1]; } else if( pST->pTrack->IsSolo() ) Canvas->Brush->Color = clrSMState[2]; else Canvas->Brush->Color = clrSMState[0]; TRect rtSM( m_nTrkHdrWidth+SOLO_LEFT, top+SM_TOP, m_nTrkHdrWidth+SOLO_LEFT+SM_SIZE, top+SM_TOP+SM_SIZE ); Canvas->FillRect( rtSM ); Canvas->Brush->Color = clrHeadFont; Canvas->FrameRect( rtSM ); Canvas->Font->Name = "SimHei"; Canvas->Font->Size = g_szFont8; Canvas->Brush->Style = bsClear; Canvas->TextOut( rtSM.left + 4, rtSM.top + 2, "S" ); Canvas->Brush->Style = bsSolid; rtSM.left = m_nTrkHdrWidth+MUTE_LEFT; rtSM.right = m_nTrkHdrWidth+MUTE_LEFT + SM_SIZE; if( pST->iHover & TRACK_M_HOVER ){ if( pST->pTrack->IsMute() ) Canvas->Brush->Color = clrSMState[3]; else Canvas->Brush->Color = clrSMState[1]; } else if( pST->pTrack->IsMute() ) Canvas->Brush->Color = clrSMState[2]; else Canvas->Brush->Color = clrSMState[0]; Canvas->FillRect( rtSM ); Canvas->Brush->Color = clrHeadFont; Canvas->FrameRect( rtSM ); Canvas->Brush->Style = bsClear; Canvas->TextOut( rtSM.left + 4, rtSM.top + 2, "M" ); Canvas->Brush->Style = bsSolid; } if( nBarNum==0 ) return; //背景 TRect rectBar; rectBar.left = leftBar; rectBar.right = rectBar.left + nBarNum * m_nDataWidth; rectBar.top = top; rectBar.bottom = rectBar.top + m_nTrackHeight - 1; if( rectBar.bottom > ClientHeight - m_nBottomBound ) rectBar.bottom = ClientHeight - m_nBottomBound; int iBarE = iBarS + nBarNum - 1; if( m_iMode==VIEW_INIT ){ if( iBarS==0 ){ TRect rtNor = rectBar; rtNor.right = rectBar.left + m_nDataWidth; Canvas->Brush->Color = clrSelect; Canvas->FillRect( rtNor ); rectBar.left += m_nDataWidth; } if( rectBar.right>rectBar.left ){ Canvas->Brush->Color = clrHigh; if( rectBar.right > ClientWidth - m_nRightBound ) rectBar.right = ClientWidth - m_nRightBound; Canvas->FillRect( rectBar ); } } else if( m_iMode==VIEW_CHORD || m_iSelBarStart<0 && m_iSelBarEnd<0 || iBarE=0 && iBarS>m_iSelBarEnd ) ){ if( m_iSelTrack==iTrack ) Canvas->Brush->Color = clrSelect; else Canvas->Brush->Color = clrUnselect; if( rectBar.right > ClientWidth - m_nRightBound ) rectBar.right = ClientWidth - m_nRightBound; Canvas->FillRect( rectBar ); } else{ if( m_iSelTrack==iTrack ) Canvas->Brush->Color = clrSelect; else Canvas->Brush->Color = clrUnselect; if( iBarS<=m_iSelBarStart ){ TRect rtNor = rectBar; rtNor.right = rectBar.left + ( m_iSelBarStart - iBarS ) * m_nDataWidth + m_iSelPointStart; if( rtNor.right>rtNor.left ){ if( rtNor.right > ClientWidth - m_nRightBound ) rtNor.right = ClientWidth - m_nRightBound; Canvas->FillRect( rtNor ); rectBar.left = rtNor.right; } } if( m_iSelBarEnd>=0 && iBarE>=m_iSelBarEnd ){ TRect rtNor = rectBar; rtNor.left = rectBar.right - ( iBarE - m_iSelBarEnd + 1 ) * m_nDataWidth + m_iSelPointEnd; if( rtNor.right>rtNor.left ){ if( rtNor.right > ClientWidth - m_nRightBound ) rtNor.right = ClientWidth - m_nRightBound; Canvas->FillRect( rtNor ); rectBar.right = rtNor.left; } } if( rectBar.right>rectBar.left ){ if( m_iDragAudio<0 && ( m_iSelTrack==iTrack || m_iSelTrack<0 ) || pST->type==ST_AUDIO && m_iDragAudio==pST->index ) Canvas->Brush->Color = clrHigh; if( rectBar.right > ClientWidth - m_nRightBound ) rectBar.right = ClientWidth - m_nRightBound; Canvas->FillRect( rectBar ); } } if( pST->type==ST_AUDIO ) DrawRowWave( iBarS, nBarNum, leftBar, top, pST->index ); else DrawRowMidi( iBarS, nBarNum, leftBar, top, pST->index ); //画笔还原 Canvas->Brush->Color = clrOld; } //--------------------------------------------------------------------------- void TContentPanel::DrawRowWave( int iBarS, int nBarNum, int left, int top, int iWave ) { //绘制波形 TAudioTrack* pTrack = g_aAudioTracks[iWave]; int iBarE = iBarS + nBarNum - 1, lWave = left, hE = 1; int mid = top + m_nTrackHeight/2 + 1; for( int i=0; ilstBars[iWvBar]; for( int k=0; kaVols[k]>0 && pBar->aVols[k]<=0x80008000 ){ DWORD wLeft = LOWORD(pBar->aVols[k]), wRight = HIWORD(pBar->aVols[k]); int yBottom = mid + ((14 * wRight )/0x8000), yTop = mid - ((14 * wLeft )/0x8000); if( yBottom>yTop ){ if( m_iMode==VIEW_INIT || m_iMode!=VIEW_CHORD &&( m_iDragAudio==iWave || m_iDragAudio<0 && ( g_iSelAudio==iWave || m_iSelTrack<0 ) && m_iSelBarStart>=0 && m_iSelBarEnd>=0 ) &&( iWvBar>m_iSelBarStart || iWvBar==m_iSelBarStart && k>=m_iSelPointStart ) && ( m_iSelBarStart>0 && m_iSelBarEnd<0 || iWvBarPen->Color = clrWave[0]; else Canvas->Pen->Color = clrWave[1]; Canvas->MoveTo( lWave+k, yTop ); Canvas->LineTo( lWave+k, yBottom ); } } } lWave += m_nDataWidth; } //绘制复制边框 if( m_iCopyAudio==iWave && iBarS<=m_iCopyBarEnd && iBarE>=m_iCopyBarStart ){ int l = left, r = left + nBarNum * m_nDataWidth, t = top, b = top + m_nTrackHeight - 2; Canvas->Pen->Style = psDot; Canvas->Pen->Color = clRed; if( iBarS<=m_iCopyBarStart ){ //绘制左框 l += ( m_iCopyBarStart - iBarS ) * m_nDataWidth + m_iCopyPointStart; Canvas->MoveTo( l, t ); Canvas->LineTo( l, b ); } if( iBarE>=m_iCopyBarEnd ){ //绘制右框 r -= ( iBarE - m_iCopyBarEnd + 1 ) * m_nDataWidth - m_iCopyPointEnd; Canvas->MoveTo( r, t ); Canvas->LineTo( r, b ); } //绘制上下框 Canvas->MoveTo( l, t ); Canvas->LineTo( r, t ); Canvas->MoveTo( l, b ); Canvas->LineTo( r, b ); Canvas->Pen->Style = psSolid; } } //--------------------------------------------------------------------------- void TContentPanel::DrawRowMidi( int iBarS, int nBarNum, int left, int top, int iTrack ) { //绘制MIDI TMidiTrack* pTrack = g_aMidiTracks[iTrack]; int iBarE = iBarS + nBarNum, iTickS = iBarS * POINTS_PER_BAR, iTickE = iBarE * POINTS_PER_BAR, iSelS = m_iSelBarStart>=iBarS ? (m_iSelBarStart-iBarS) * POINTS_PER_BAR : -1, iSelE = m_iSelBarEnd>=iBarS ? (m_iSelBarEnd-iBarS) * POINTS_PER_BAR + m_iSelPointEnd: -1; int bottom = top + m_nTrackHeight - 3; for( int i=0; iaNotes.size(); i++ ){ if( pTrack->ptMax < pTrack->ptMin ) continue; TMidiNote* pNote = pTrack->aNotes[i]; int range = pTrack->ptMax - pTrack->ptMin; if( range<26 ) range = 26; if( pNote->tkOn < pNote->tkOff && pNote->tkOn < iTickE && pNote->tkOff > iTickS ){ int iL = max( pNote->tkOn, iTickS ) - iTickS, iR = min( pNote->tkOff, iTickE ) - iTickS, iH = bottom - 26 * (pNote->pitch - pTrack->ptMin) / range; int vol = pNote->volume * pTrack->volume / 100; Canvas->Pen->Color = g_Midi.GetNoteColor( vol ); if( iLiL ){ Canvas->MoveTo( iL+left, iH ); Canvas->LineTo( iT+left, iH ); iL = iT; } } if( iSelE>0 && iR>iSelE ){ int iT = max( iSelE, iL ); if( iTMoveTo( iT+left, iH ); Canvas->LineTo( iR+left, iH ); iR = iT; } } if( iR > iL ){ if( m_iMode!=VIEW_CHORD && ( iSelS>=0 || iSelE>=0 ) && m_iDragAudio<0 && ( m_iSelTrack==iTrack || m_iSelTrack<0 ) ) Canvas->Pen->Color = clrWave[0]; Canvas->MoveTo( iL+left, iH ); Canvas->LineTo( iR+left, iH ); } } } } void __fastcall TContentPanel::Paint() { DrawBars(); if( w_bDraging ){ //绘制半透明图片 TBlendFunction Blend; Blend.BlendOp = AC_SRC_OVER; Blend.BlendFlags = 0; Blend.AlphaFormat = 0; Blend.SourceConstantAlpha =135; TPoint pt(w_xImgDrag, w_yImgDrag); pt = ScreenToClient( pt ); ::AlphaBlend (Canvas->Handle, pt.X, pt.Y, w_imgDrag->Width, w_imgDrag->Height, w_imgDrag->Canvas->Handle, 0, 0, w_imgDrag->Width, w_imgDrag->Height, Blend ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::WMEraseBkgnd(TWMEraseBkgnd &Message) { TRect rect = GetClientRect(); TCanvas* tempCanvas = new TCanvas; tempCanvas->Handle = Message.DC; //绘制底色 tempCanvas->Brush->Color = clrBackground; tempCanvas->FillRect( rect ); //绘制外边框 tempCanvas->Brush->Color = clrBackboard; tempCanvas->FrameRect(rect); if( !m_bVertical && m_nLeftBound==m_nTrkHdrWidth ){ //绘制轨道头区域 TRect rectHead = rect; rectHead.right = m_nTrkHdrWidth; // rectHead.bottom = m_nTopBound+m_nRowGapHeight+m_nTitleHeight+m_nChordHeight; tempCanvas->Brush->Color = RGB( 58, 62, 69 ); tempCanvas->FillRect( rectHead ); // rectHead.top = rectHead.bottom; // rectHead.bottom = rect.bottom; // rectHead.left = TRK_HDR_WIDTH-4; // tempCanvas->FillRect( rectHead ); tempCanvas->Brush->Color = clrBackboard; tempCanvas->FrameRect( rectHead ); // rectHead.top = rect.top; } delete tempCanvas; Message.Result = true; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::WMSize(TWMSize &Message) { DefaultHandler( &Message ); CalcViewArea(); if( m_rgnClip ){ ::DeleteObject( m_rgnClip ); } m_rgnClip = ::CreateRectRgn( 0, 0, ClientWidth - m_nRightBound, ClientHeight - m_nBottomBound ); m_lBeatHint = (ClientWidth - m_wBeatHint) / 2; m_tBeatHint = (ClientHeight - m_hBeatHint) / 2; if( !m_sbVert || !m_sbHoriz ) return; m_sbVert->Left = ClientWidth - m_sbVert->Width - 1; m_sbVert->Height = ClientHeight - 2; m_sbHoriz->Top = ClientHeight - m_sbHoriz->Height - 1; m_sbHoriz->Width = ClientWidth - m_nLeftBound - 1; if( m_bVertical ){ if( m_nRowNum>m_nRowShow ){ m_sbVert->SetRange( 0, m_nRowNum-1 ); m_sbVert->SetPageSize( m_nRowShow ); m_sbVert->SetPosition( 0 ); int iRowScroll = 0; if( m_iBeginShowBar>0 ){ iRowScroll = min( m_iBeginShowBar / m_nColumnNum, m_nRowNum-m_nRowShow ); if( iRowScroll<0 ){ iRowScroll = 0; } } ScrollView( iRowScroll ); } else{ m_sbVert->SetRange( 0, 0, false ); m_sbVert->SetPageSize( 0, false ); m_sbVert->SetPosition( 0, false ); if( m_iBeginShowBar>0 ) ScrollView( 0 ); } } else{ int nRange = m_aTracks.size(); int nDrawHeight = ClientHeight - m_nTopBound - m_nBottomBound - m_nRowGapHeight - m_nTitleHeight - m_nChordHeight; if( nDrawHeight % m_nTrackHeight > 0 ) nRange++; if( nRange > m_nTrackShow ){ m_sbVert->SetRange( 0, nRange-1 ); m_sbVert->SetPageSize( m_nTrackShow ); m_sbVert->SetPosition( 0 ); int iRowScroll = 0; if( m_iSelTrack-m_iBeginShowTrack>=m_nTrackShow ){ iRowScroll = m_iSelTrack - m_nTrackShow + 1; } else if( m_iBeginShowTrack>0 ){ iRowScroll = min( m_iBeginShowTrack, nRange-m_nTrackShow ); if( iRowScroll<0 ){ iRowScroll = 0; } } ScrollView( iRowScroll ); } else{ m_sbVert->SetRange( 0, 0, false ); m_sbVert->SetPageSize( 0, false ); m_sbVert->SetPosition( 0, false ); if( m_iBeginShowTrack>0 ) ScrollView( 0 ); } nRange = m_nBarNum; int nDrawWidth = ClientWidth - m_nLeftOriBound - m_nRightBound; if( nDrawWidth % m_nBarWidth > 0 ) nRange++; if( nRange>m_nColumnNum ){ m_sbHoriz->SetRange( 0, nRange - 1 ); m_sbHoriz->SetPageSize( m_nColumnNum ); m_sbHoriz->SetPosition( 0 ); int iRowScroll = 0; if( m_iBeginShowBar>0 ){ iRowScroll = min( m_iBeginShowBar, nRange-m_nColumnNum ); if( iRowScroll<0 ){ iRowScroll = 0; } } ScrollView( iRowScroll, false ); } else{ m_sbHoriz->SetRange( 0, 0, false ); m_sbHoriz->SetPageSize( 0, false ); m_sbHoriz->SetPosition( 0, false ); if( m_iBeginShowBar>0 ) ScrollView( 0, false ); } } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::WMVScroll(TWMScroll &Message) { if( m_sbVert && m_sbVert->IsOperable() ) OnWMScroll( Message, true ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::WMHScroll(TWMScroll &Message) { if( m_sbHoriz && m_sbHoriz->IsOperable() ) OnWMScroll( Message, false ); } //--------------------------------------------------------------------------- void TContentPanel::OnWMScroll(TWMScroll &Message, bool bVertical) { TSkinScrollBar* pSB = bVertical ? m_sbVert : m_sbHoriz; int minpos, maxpos, page, curpos; pSB->GetScrollRange(&minpos, &maxpos); page = pSB->GetPageSize(); // Get the current position of scroll box. curpos = pSB->GetScrollPos(); // Determine the new position of scroll box. switch (Message.ScrollCode) { case SB_TOP: // Scroll to far top. curpos = minpos; break; case SB_BOTTOM: // Scroll to far bottom. curpos = maxpos-page+1; break; case SB_ENDSCROLL: // End scroll. break; case SB_LINEUP: // Scroll left. if (curpos > minpos) curpos--; break; case SB_LINEDOWN: // Scroll right. if (curpos < maxpos-page+1) curpos++; break; case SB_PAGEUP: // Scroll one page left. if (curpos > minpos) curpos = max(minpos, curpos-page); break; case SB_PAGEDOWN: // Scroll one page right. if( curposHandle ) pSB->SetPosition(curpos); ScrollView(curpos, bVertical, FALSE); Message.Result = true; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::WMMouseWheel(TWMMouseWheel &Message) { if( m_sbVert && m_sbVert->IsOperable() ){ UINT nSBCode; if( Message.WheelDelta>0 ) nSBCode = SB_LINEUP; else nSBCode = SB_LINEDOWN; Perform( WM_VSCROLL, MAKELONG(nSBCode,0), NULL ); } else if( m_sbHoriz && m_sbHoriz->IsOperable() ){ UINT nSBCode; if( Message.WheelDelta>0 ) nSBCode = SB_LINEUP; else nSBCode = SB_LINEDOWN; Perform( WM_HSCROLL, MAKELONG(nSBCode,0), NULL ); } } //--------------------------------------------------------------------------- DWORD TContentPanel::HitTest( int X, int Y, int& iHitType, bool bHead ) { iHitType = -1; if( X<0 || X >= m_nColumnNum*m_nBarWidth+m_nLeftBound || Y <= m_nTopBound || Y >= ClientHeight - m_nBottomBound || Y >= (m_nRowNum-m_iBeginShowRow)*m_nBarHeight+m_nTopBound ){ return -1; } else if( X <= m_nLeftBound ){ if( bHead && Y > m_nTopBound+m_nRowGapHeight+m_nTitleHeight+m_nChordHeight ){ int nTop = m_nTopBound+m_nRowGapHeight+m_nTitleHeight+m_nChordHeight; for( int i=m_iBeginShowTrack; i=nTop && Y<=nBottom ){ int iBoxType=BAR_LEFT, nSMTop=nTop+SM_TOP, lBox = 0, tBox = nTop ; if( Y>=nSMTop && Y<=nSMTop+SM_SIZE ){ if( X>=m_nTrkHdrWidth+MUTE_LEFT && X<=m_nTrkHdrWidth+MUTE_LEFT+SM_SIZE ){ iBoxType = HOVER_MUTE; lBox = m_nTrkHdrWidth+MUTE_LEFT; tBox += SM_TOP; } else if( X>=m_nTrkHdrWidth+SOLO_LEFT && X<=m_nTrkHdrWidth+SOLO_LEFT+SM_SIZE ){ iBoxType = HOVER_SOLO; lBox = m_nTrkHdrWidth+SOLO_LEFT; tBox += SM_TOP; } } iHitType = i + iBoxType; return MAKELONG( lBox, tBox ); } else if( Y=0 ){ if( deltaY0 ){ //右下角标宽度 if( iType==1 ) //m wTKey = 7; else if( iType==2 ) //7 wTKey = 6; else if( iType==3 || iType==7 ) //m7 M7 wTKey = 11; else //s2 s4 s6 wTKey = 10; } if( !g_bAlphaKey ){ if( iMainKey==0 ){ wMKey = iType>0 ? 6 : 8; } else if( iMainKey==1 ){ wIKey = iType>2 ? 5 : 6; wMKey = iType>0 ? 11 : 14; } else if( iMainKey==2 ){ if( iType==0 ){ wIKey = 5; wMKey = 16; } else if( iType<=2 ){ wIKey = 5; wMKey = 14; } else{ wIKey = 4; wMKey = 12; } } else if( iMainKey==3 ){ wMKey = iType>0 ? 13 : 18; } else if( iMainKey==4 ){ wMKey = iType>0 ? 7 : 11; } else if( iMainKey==5 ){ if( iType==0 ){ wVKey = 8; wMKey = 17; } else if( iType<=2 ){ wVKey = 7; wMKey = 14; } else{ wVKey = 6; wMKey = 12; } } else if( iMainKey==6 ){ wIKey = 4; if( iType==0 ){ wVKey = 6; wMKey = 19; } else if( iType<=2 ){ wVKey = 5; wMKey = 15; } else{ wVKey = 4; wMKey = 14; } } } else{ if( iMainKey==5 ) //A升降号靠近 wAKey = 1; else if( iMainKey==1 || iMainKey==4) //D G宽度稍大 wMKey = 13; else if( iMainKey==3 && iType>0 ) //F下标靠近 wMKey = 9; } int wChord = wMKey + wAKey + wTKey; int iLeft = iOriLeft + ( rcDraw.Width() - wChord ) / 2; int iTop = iOriTop - 2; //绘制升降调 if( iAjustKey!=0 ){ if( iAjustKey==1 ) Canvas->Draw( iLeft, iOriTop, m_pngChordUp ); else Canvas->Draw( iLeft, iOriTop, m_pngChordDown ); iLeft += wAKey; if(iMainKey==2 && iType>=3) //bIIIm7可紧凑些 iLeft -= 1; } if( g_bAlphaKey ){ //英文字母 TFont *fntOld = new TFont; fntOld->Assign( Canvas->Font ); //保存原字体 Canvas->Brush->Style = bsClear; Canvas->Font->Name = "Times New Roman"; Canvas->Font->Quality = TFontQuality::fqClearTypeNatural; Canvas->Font->Color = RGB(60,43,23); Canvas->Font->Style = TFontStyles()<Font->Size = g_szFont16; //字母字体大小 Canvas->TextOut( iLeft, iTop, g_strAlphaTable[iMainKey] ); Canvas->Font->Assign( fntOld ); //恢复原字体 delete fntOld; } else{ int l = iLeft; iTop += 5; if( iMainKey<4 ){ Canvas->Draw( l, iTop, m_pngChordI ); //I l += wIKey; if( iMainKey==3 ){ Canvas->Draw( l, iTop, m_pngChordV ); //IV } else if( iMainKey>0 ){ Canvas->Draw( l, iTop, m_pngChordI ); //II l += wIKey; if( iMainKey==2 ){ Canvas->Draw( l, iTop, m_pngChordI ); //III } } } else{ l += 2; Canvas->Draw( l, iTop, m_pngChordV ); //V l += wVKey; if( iMainKey>4 ){ Canvas->Draw( l, iTop, m_pngChordI ); //VI l += wIKey; if( iMainKey==6 ){ Canvas->Draw( l, iTop, m_pngChordI ); //VII l += wIKey; } } } } if( iType>0 ){ iTop = iOriTop + 11; iLeft += wMKey; if(iMainKey!=3 || iType<3) //#IVm7可紧凑些 iLeft += 1; //绘制A if( iType==7 ){ //M Canvas->Draw( iLeft, iTop, m_pngChordMaj ); iLeft += 8; } else if( iType>=4 ){ //s Canvas->Draw( iLeft, iTop+1, m_pngChordSus ); iLeft += 6; } else if( iType==1 || iType==3 ){ //m Canvas->Draw( iLeft, iTop+2, m_pngChordMin ); iLeft += 8; } else if( iType==2 ){ iLeft += 2; } //绘制N if( iType==2 ){ //7 Canvas->Draw( iLeft, iTop, m_pngChord7 ); } else if( iType==3 || iType==7 ){ //7 if( iMainKey==6 && iAjustKey ) //保证bVII不出格 iLeft--; Canvas->Draw( iLeft, iTop, m_pngChord7 ); } else if( iType==4 ){ //2 Canvas->Draw( iLeft, iTop, m_pngChord2 ); } else if( iType==5 ){ //4 Canvas->Draw( iLeft, iTop, m_pngChord4 ); } else if( iType==6 ){ //6 Canvas->Draw( iLeft, iTop, m_pngChord6 ); } } } //----------------------------------------------------------------------------- void TContentPanel::SetSelectRange( int iStartBar, int iStartPoint, int iEndBar, int iEndPoint, bool bInvalid ) { SelectRange( iStartBar, iStartPoint, iEndBar, iEndPoint, bInvalid ); } //----------------------------------------------------------------------------- void TContentPanel::GetSelectRange( int& iStartBar, int& iStartPoint, int& iEndBar, int& iEndPoint ) { iStartBar = m_iSelBarStart; iStartPoint = m_iSelPointStart; iEndBar = m_iSelBarEnd; iEndPoint = m_iSelPointEnd; } //----------------------------------------------------------------------------- void TContentPanel::AddNewBar( int iBar ) { int iRow, iCol; m_nBarNum++; if( m_bVertical ){ m_nRowNum = m_nBarNum / m_nColumnNum; if( m_nBarNum % m_nColumnNum>0 ){ m_nRowNum++; } if( m_nRowNum>m_nRowShow ){ m_sbVert->SetRange( 0, m_nRowNum-1 ); //m_sbVert->SetPageSize( m_nRowShow ); } iRow = iBar / m_nColumnNum - m_iBeginShowRow; if( iRow>(m_nRowShow-1) ){ int nRowScroll = min( m_nRowShow+m_iBeginShowRow-1, m_nRowNum-iRow ); // 显示到第2行 ScrollView( nRowScroll ); } else{ iCol = iBar % m_nColumnNum; TRect rectNew(0,0,0,0); rectNew.left = iCol * m_nBarWidth + m_nLeftBound - 1; rectNew.right = rectNew.left + m_nBarWidth + 2; //包含左右边框 rectNew.top = iRow * m_nBarHeight + m_nTopBound; rectNew.bottom = rectNew.top + m_nBarHeight + 2; //包含上下边框 InvalidateRect( Handle, &rectNew, FALSE ); } } else{ if( m_nBarNum > m_nColumnNum ){ int nRange = m_nBarNum; int nDrawWidth = ClientWidth - m_nLeftOriBound - m_nRightBound; if( nDrawWidth % m_nBarWidth > 0 ) nRange++; m_sbHoriz->SetRange( 0, nRange-1 ); if( iBar >= m_iBeginShowBar + m_nColumnNum ){ } else{ TRect rectNew(0,0,0,0); rectNew.left = (iBar-m_iBeginShowBar) * m_nBarWidth + m_nLeftBound - 1; rectNew.right = rectNew.left + m_nBarWidth + 2; //包含左右边框 rectNew.top = m_nTopBound; rectNew.bottom = rectNew.top + m_nBarHeight + 2; //包含上下边框 InvalidateRect( Handle, &rectNew, FALSE ); } } } } //----------------------------------------------------------------------------- void TContentPanel::DrawDragImg( int mode ) { w_imgDrag = new TImage(this); if( mode==DM_ADJUSTWIDTH || mode==DM_ADJUSTHEADER ){ COLORREF clrPixel[2] = { clWhite, clBlack }; w_imgDrag->Width = 4; w_imgDrag->Height = Height-2; TRect rcDraw( 0, 0, w_imgDrag->Width, w_imgDrag->Height ); for( int i=0; iWidth; i++ ){ for( int j=0; jHeight; j++ ){ w_imgDrag->Canvas->Pixels[i][j] = clrPixel[(i+j)%2]; } } } else if( mode==DM_ADJUSTSTAGE ){ w_imgDrag->Width = m_iSelBarEnd > m_iSelBarStart ? 160 : 120; w_imgDrag->Height = 24; TRect rcDraw( 0, 0, w_imgDrag->Width, w_imgDrag->Height ); //绘制底色 w_imgDrag->Canvas->Brush->Color = clrBackboard; w_imgDrag->Canvas->FillRect( rcDraw ); //绘制列表项文字 w_imgDrag->Canvas->Font->Name = g_strTxtFontName; w_imgDrag->Canvas->Font->Quality = TFontQuality::fqClearTypeNatural; w_imgDrag->Canvas->Font->Size = g_szFont9; w_imgDrag->Canvas->Font->Style = TFontStyles()<Canvas->Font->Color = clrSelText; char str[256]; if( m_iSelBarEnd>m_iSelBarStart ) sprintf( str, "第 %d - %d 小节", m_iSelBarStart+1, m_iSelBarEnd+1 ); else sprintf( str, "第 %d 小节", m_iSelBarStart+1 ); String strCaption = str; int Y = rcDraw.Top + ( w_imgDrag->Height - Canvas->TextHeight(strCaption) )/2; rcDraw.Left += (w_imgDrag->Width - Canvas->TextWidth(strCaption))/2; w_imgDrag->Canvas->Brush->Style = bsSolid; w_imgDrag->Canvas->TextRect( rcDraw, rcDraw.Left, Y, strCaption ); } else if( mode==DM_ADJUSTAUDIO ){ int iBarStart = m_iSelBarStart<0 ? 0 : m_iSelBarStart, iBarEnd = m_iSelBarEnd<0 ? m_nBarNum-1 : m_iSelBarEnd, iPointStart = m_iSelPointStart<0 ? 0 : m_iSelPointStart, iPointEnd = m_iSelPointEnd<0 ? 119 : m_iSelPointEnd, nWidth = ( iBarEnd - iBarStart ) * POINTS_PER_BAR + iPointEnd - iPointStart; w_imgDrag->Width = nWidth > POINTS_PER_BAR ? POINTS_PER_BAR : nWidth; w_imgDrag->Height = 25; TRect rcDraw( 0, 0, w_imgDrag->Width, w_imgDrag->Height ); //绘制底色 w_imgDrag->Canvas->Brush->Color = clrBackboard; w_imgDrag->Canvas->FillRect( rcDraw ); //绘制波形 int mid = w_imgDrag->Height/2 + 1, gap = nWidth / 120; if( gap<1 ) gap = 1; w_imgDrag->Canvas->Pen->Color = clrWave[0]; int iPos = 0, p = iPointStart; for( int i=iBarStart; i<=iBarEnd && iPos<120; i++ ){ TWaveBar *pBar = g_aAudioTracks[g_iSelAudio]->lstBars[i]; while( paVols[p]>0 && pBar->aVols[p]<0x80000000 ){ DWORD wLeft = LOWORD(pBar->aVols[p]), wRight = HIWORD(pBar->aVols[p]), yBottom = mid + (12 * wRight )/0x8000, yTop = mid - (12 * wLeft )/0x8000; if( yBottom>yTop ){ w_imgDrag->Canvas->MoveTo( iPos, yTop ); w_imgDrag->Canvas->LineTo( iPos, yBottom ); } } iPos++; p += gap; } if( iPos<120 ) p -= POINTS_PER_BAR; } m_iDragAudio = g_iSelAudio; } w_bDraging = true; w_iDragMode = mode; } //--------------------------------------------------------------------------- bool TContentPanel::ShowDragImg( bool bShow, int iState ) { bool bCanDrop = false; int w = w_imgDrag->Width, h = w_imgDrag->Height; TPoint ptOld( w_xOldDrag, w_yOldDrag ), ptNew( w_xImgDrag, w_yImgDrag ); RECT rtInvalid; ptOld = ScreenToClient( ptOld ); ptNew = ScreenToClient( ptNew ); if( w_iDragMode==DM_ADJUSTWIDTH || w_iDragMode==DM_ADJUSTHEADER ){ rtInvalid.left = 0; rtInvalid.right = 0; rtInvalid.top = 1; rtInvalid.bottom = Height-1; if( ptOld.X>0 && ptOld.X0 && ptOld.X+w0 && ptNew.X0 && ptNew.X+wWidth ) rtInvalid.right = Width; if( rtInvalid.right>rtInvalid.left ){ InvalidateRect( Handle, &rtInvalid, false ); } if( !bShow && w_iDragMode==DM_ADJUSTHEADER ){ m_nTrkHdrWidth = ptNew.x; CalcViewArea(); InvalidateRgn( Handle, NULL, true ); } } else if( w_iDragMode==DM_ADJUSTSTYLE || w_iDragMode==DM_ADJUSTSTAGE || w_iDragMode==DM_ADJUSTAUDIO ){ TPoint ptMouse( ptNew.X + w_xOffDrag, ptNew.Y + w_yOffDrag ); rtInvalid.left = Width; rtInvalid.right = 0; rtInvalid.top = Height; rtInvalid.bottom = 0; if( ptOld.Y>0 && ptOld.Y0 && ptOld.Y+h0 && ptOld.X0 && ptOld.X+w0 && ptNew.Y0 && ptNew.Y+h0 && ptNew.X0 && ptNew.X+w=0 || m_iDropBar>=0 ) && ( !m_pItem || (m_pItem->iType!=SEGTYPE_STYLE && m_pItem->iType!=SEGTYPE_TRACK ))){ //处理Drop事件 int iHitType = -1; DWORD dwHit = HitTest( ptMouse.X, ptMouse.Y, iHitType ); if( iHitType>=BAR_TITLE ){ HandleDropEvent( iState ); SetFocus(); } } else if( w_iDragMode==DM_ADJUSTAUDIO ){ HandleDropEvent( iState ); } if( m_pTimer ){ delete m_pTimer; m_pTimer = NULL; } SetDropBar( -1 ); m_pItem = NULL; m_bDraging = false; } if( rtInvalid.top<0 ) rtInvalid.top = 0; if( rtInvalid.bottom>Height ) rtInvalid.bottom = Height; if( rtInvalid.left<0 ) rtInvalid.left = 0; if( rtInvalid.right>Width ) rtInvalid.right = Width; if( rtInvalid.bottom>rtInvalid.top && rtInvalid.right>rtInvalid.left ){ InvalidateRect( Handle, &rtInvalid, false ); } if( bShow ){ SetScrollTimer( ptMouse ); } } return bCanDrop; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::WMMouseDown(TWMMouse &Message) { ptDown.x = ptDown.y = 0; m_iMouseDownBar = m_iMouseDownPoint = -1; if( Message.Keys & MK_RBUTTON ){ if( m_bBrush ){ m_bBrush = false; Screen->Cursor = crDefault; } if( m_bDraging ){ m_bDraging = false; if( m_iMode==VIEW_TRACK ){ SelectRange( -1, -1, -1, -1 ); } else{ SelectBars( -1, -1 ); } } ReleaseCapture(); m_iMouseDownBar = m_iMouseDownPoint = -1; m_pItem = NULL; m_PopupMenu->ClearItems(); if( m_iMode==VIEW_INIT || m_nBarNum==0 ) return; CMenuItem* pMenuItem = NULL; int iHitType = -1; DWORD dwHit = HitTest( Message.XPos, Message.YPos, iHitType, true ); if( iHitType<=BAR_CURSOR ){ if( !m_bVertical ){ pMenuItem = m_PopupMenu->CreateMenu( "新增音频轨道", "", DoTrackAdd, ST_AUDIO ); pMenuItem->Enabled = g_aAudioTracks.size()CreateMenu( "新增MIDI轨道...","",DoTrackAdd, ST_MIDI ); } else return; } else{ int iView = VIEW_TRACK; if( iHitTypeMainForm->Perform( UM_SETVIEWMODE, iView, 0 ); } int iHitBar = LOWORD(dwHit); if( iHitType>=BAR_LEFT ){ int iHitTrack = -1; if( iHitType>=HOVER_SOLO ) iHitTrack = iHitType - HOVER_SOLO; else if( iHitType>=HOVER_MUTE ) iHitTrack = iHitType - HOVER_MUTE; else iHitTrack = iHitType - BAR_LEFT; SelectTrack( iHitTrack, -1, -1 ); bool bMute = m_aTracks[iHitTrack]->pTrack->IsMute(), bSolo = m_aTracks[iHitTrack]->pTrack->IsSolo(); m_PopupMenu->CreateMenu( bMute ? "取消静音" : "静音", "", DoTrackMute ); m_PopupMenu->CreateMenu( bSolo ? "取消独奏" : "独奏", "",DoTrackSolo ); m_PopupMenu->CreateMenu( "删除该轨道", "", DoTrackDel, IDM_TRKSHOW+iHitTrack ); m_PopupMenu->CreateMenu( "隐藏该轨道", "", DoTrackHide, IDM_TRKSHOW+iHitTrack ); m_PopupMenu->CreateMenu( "轨道导出为...","",DoTrackSave ); m_PopupMenu->CreateMenu( "-" ); pMenuItem = m_PopupMenu->CreateMenu( "新增音频轨道", "", DoTrackAdd, ST_AUDIO ); pMenuItem->Enabled = g_aAudioTracks.size()CreateMenu( "新增MIDI轨道...","",DoTrackAdd, ST_MIDI ); } else if( iHitType>=BAR_TRACK ){ int iHitTrack = iHitType & 0xFF, iHitPoint = HIWORD(dwHit); if( iHitTrack!=m_iSelTrack || m_iSelBarStart<0 && m_iSelBarEnd<0 || iHitBar=0 && iHitBar>m_iSelBarEnd || iHitBar==m_iSelBarStart && iHitPointm_iSelPointEnd ){ SelectTrack( iHitTrack, iHitBar, iHitPoint ); } ptDown.X = Message.XPos; ptDown.Y = Message.YPos; bool bMute = m_aTracks[iHitTrack]->pTrack->IsMute(), bSolo = m_aTracks[iHitTrack]->pTrack->IsSolo(); m_PopupMenu->CreateMenu( bMute ? "取消静音" : "静音", "", DoTrackMute ); m_PopupMenu->CreateMenu( bSolo ? "取消独奏" : "独奏", "",DoTrackSolo ); m_PopupMenu->CreateMenu( "删除该轨道", "", DoTrackDel, IDM_TRKSHOW+iHitTrack ); m_PopupMenu->CreateMenu( "隐藏该轨道", "", DoTrackHide, IDM_TRKSHOW+iHitTrack ); m_PopupMenu->CreateMenu( "轨道导出为...","",DoTrackSave ); m_PopupMenu->CreateMenu( "-" ); m_PopupMenu->CreateMenu( "全选", "Ctrl+A", DoSelectAll ); if( m_aTracks[iHitTrack]->type==ST_AUDIO ){ pMenuItem = m_PopupMenu->CreateMenu( "复制所选音频", "Ctrl+C", DoAudioCopy ); pMenuItem->Enabled = m_iSelBarStart>=0 || m_iSelBarEnd>=0; pMenuItem = m_PopupMenu->CreateMenu( "剪切所选音频", "Ctrl+X", DoAudioCut ); pMenuItem->Enabled = m_iSelBarStart>=0 || m_iSelBarEnd>=0; pMenuItem = m_PopupMenu->CreateMenu( "删除所选音频", "Ctrl+Del", DoAudioDelete ); pMenuItem->Enabled = m_iSelBarStart>=0 || m_iSelBarEnd>=0; if( m_iCopyBarStart>=0 ){ m_PopupMenu->CreateMenu( "-" ); String strText = "粘贴"; strText += m_bCut ? "剪切的音频" : "复制的音频"; pMenuItem = m_PopupMenu->CreateMenu( strText, "Ctrl+V", DoAudioPaste ); pMenuItem->Enabled = m_iCopyBarStart>=0; } m_PopupMenu->CreateMenu( "-" ); m_PopupMenu->CreateMenu( "设为录音起点", "", DoSetSelPosStart ); m_PopupMenu->CreateMenu( "设为录音终点", "", DoSetSelPosEnd ); pMenuItem = m_PopupMenu->CreateMenu( "取消录音起点", "", DoDelSelPosStart ); pMenuItem->Enabled = m_iSelBarStart>=0; pMenuItem = m_PopupMenu->CreateMenu( "取消录音终点", "", DoDelSelPosEnd ); pMenuItem->Enabled = m_iSelBarEnd>=0; m_PopupMenu->CreateMenu( "-" ); m_PopupMenu->CreateMenu( "插入音频片段...","Ctrl+Ins",DoAudioLoad ); bool bSP = m_iSelBarStart>=0 || m_iSelBarEnd>=0; CMenuItem *pMSPFx = NULL, *pMSPVst = NULL, *pMSP = m_PopupMenu->CreateMenu( "局部音效处理" ), *pMAdd = m_PopupMenu->CreateMenu( "添加轨道音效" ), *pMAddFx = pMAdd->AppendMenu( "Fx音效" ), *pMAddVst = pMAdd->AppendMenu( "VST音效" ); pMSP->Enabled = bSP; pMAddVst->Enabled = !g_lstVSTFx.empty(); if( bSP ){ pMSPFx = pMSP->AppendMenu( "Fx音效" ); pMSPVst = pMSP->AppendMenu( "VST音效" ); pMSPVst->Enabled = !g_lstVSTFx.empty(); } for( int i=0; iAppendMenu( g_strEffect[i], "", DoAudioFxProcess, i ); if( iAppendMenu( g_strEffect[i], "", DoAudioAddFx, i ); } if( !g_lstVSTFx.empty() ){ for( int i=0; istrFileName, '\\' )+1, *ext = strrchr( pVST->strFileName, '.' ); if( ext>name ){ strncpy( fname, name, ext-name ); fname[ext-name] = '\0'; } else strcpy(fname, name ); if( !pVST->aPlugins.empty() ) strcat( fname, " ..." ); if( pMSPVst ) pMSPVst->AppendMenu( fname, "", DoAudioVstProcess, i ); pMAddVst->AppendMenu( fname, "", DoAudioAddVst, i ); } } } else{ bool bContent=false, bSwitch=false, bInsert=true; if( m_iSelBarStart>=0 && m_iSelBarEnd>0 ){ TMidiTrack* pMT = (TMidiTrack*)m_aTracks[iHitTrack]->pTrack; int iBStage = FindStage( m_iSelBarStart, NULL ), iEStage = FindStage( m_iSelBarEnd, NULL ); for( int i=iBStage; i<=iEStage; i++ ){ TOpusStage* pStage = g_lstOpusStages[i]; if( !bSwitch && pStage->iSegType<=SEGTYPE_FILL ) bSwitch = true; if( bInsert && pMT->IsDrum() && pStage->aTracks[0]->iChanNo==9 ) bInsert = false; } for( int i=0; iaStages.size(); i++ ){ int s = pMT->aStages[i]; if( s>=iBStage && s<=iEStage ){ bContent = true; break; } else if( s>iEStage ){ break; } } } pMenuItem = m_PopupMenu->CreateMenu( "插入织体...", "Ctrl+Ins", DoInsertTexture ); pMenuItem->Enabled = !bContent && bSwitch && bInsert; pMenuItem = m_PopupMenu->CreateMenu( "删除所选织体", "Ctrl+Del", DoDeleteTexture ); pMenuItem->Enabled = bContent; pMenuItem = m_PopupMenu->CreateMenu( "更换所选织体...", "", DoSwitchTexture ); pMenuItem->Enabled = bContent && bSwitch; pMenuItem = m_PopupMenu->CreateMenu( "更换所选乐器/音色...", "", DoSwitchFontProg ); pMenuItem->Enabled = bContent; m_PopupMenu->CreateMenu( "更换轨道织体...", "", DoTrackSwitchTexture ); m_PopupMenu->CreateMenu( "更换轨道乐器/音色...", "", DoTrackSwitchFontProg ); } } else if( iHitType==BAR_DATA ){ int iCell = GetCell( HIWORD(dwHit) ); bool bCanCopy = false; if( m_iSelBarStart<0 || iHitBarm_iSelBarEnd || iHitBar==m_iSelBarStart && iCellm_iSelCellEnd ){ int iFirstBar, iHitStage = FindStage( iHitBar, &iFirstBar ); TOpusStage *pHitStage = g_lstOpusStages[iHitStage]; if( pHitStage->iSegType<=SEGTYPE_FILL ){ int iEndBar = iHitBar, iEndCell = iCell; if( m_iCopyBarStart>=0 ){ //计算已复制和弦个数 int nChordRemain = (m_iCopyBarEnd - m_iCopyBarStart) * g_nChordNumPerBar - m_iCopyCellStart + m_iCopyCellEnd + 1 ; int iStage = iHitStage, iStartBar = iHitBar, iStartCell = iCell, iLastBar = iFirstBar + pHitStage->aBars.size() - 1; TOpusStage * pStage = pHitStage; while( true ){ int nCellCount = ( iLastBar - iStartBar + 1 ) * g_nChordNumPerBar - iStartCell; if( nCellCount >= nChordRemain ){ iEndBar = iStartBar + nChordRemain / g_nChordNumPerBar; iEndCell = iStartCell + nChordRemain % g_nChordNumPerBar - 1; if( iEndCell>=g_nChordNumPerBar ){ iEndBar++; iEndCell -= g_nChordNumPerBar; } else if( iEndCell<0 ){ iEndBar--; iEndCell = g_nChordNumPerBar - 1; } break; } else{ iEndBar = iLastBar; iEndCell = g_nChordNumPerBar - 1; nChordRemain -= nCellCount; iStage++; if( iStageiSegType<=SEGTYPE_FILL ){ iStartBar = iLastBar + 1; iStartCell = 0; iLastBar = iStartBar + pStage->aBars.size() - 1; } else break; } else break; } } } SelectCells( iHitBar, iCell, iEndBar, iEndCell ); bCanCopy = true; } } else if( ( iHitBar>m_iSelBarStart || iHitBar==m_iSelBarStart && iCell>=m_iSelCellStart ) && ( iHitBarCreateMenu( "复制和弦","Ctrl+C",DoChordCopy ); pMenuItem->Enabled = bCanCopy && m_iSelBarStart>=0; pMenuItem = m_PopupMenu->CreateMenu( "粘贴和弦","Ctrl+V",DoChordPaste ); pMenuItem->Enabled = bCanCopy && m_iCopyBarStart>=0; m_PopupMenu->CreateMenu( "-" ); m_PopupMenu->CreateMenu( "与前一和弦相同","Ctrl+Del",DoChordDelete ); bool bCanDelete = false; if( bCanCopy ){ if( m_iSelCellStart>0 ){ bCanDelete = true; } else{ int iFirstBar, iSelStage = FindStage( m_iSelBarStart, &iFirstBar ); if( m_iSelBarStart!=iFirstBar ){ bCanDelete = true; } else if( iSelStage>0 ){ TOpusStage *pPreStage = g_lstOpusStages[iSelStage-1]; if( pPreStage->iSegType<=SEGTYPE_FILL ){ bCanDelete = true; } } } } pMenuItem->Enabled = bCanDelete; m_PopupMenu->CreateMenu( "-" ); m_PopupMenu->CreateMenu( "导出伴奏...","",DoTrackSave ); } else if( iHitType==BAR_TITLE ){ bool bCanInsert = m_iCopyBarStart!=-1; if( iHitBar>=m_iCopyBarStart && iHitBar<=m_iCopyBarEnd ){ SelectBars( m_iCopyBarStart, m_iCopyBarEnd ); } else if( m_iSelBarStart<0 || iHitBarm_iSelBarEnd ){ int iFirstBar, iStage = FindStage( iHitBar, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; if( pStage->iSegType>=SEGTYPE_INTRO ){ SelectBars( iFirstBar, iFirstBar+pStage->aBars.size()-1 ); } else{ SelectBars( iHitBar, iHitBar ); } } bool bSel = m_iSelBarStart>=0; bool bCanCopy = bSel; if( m_iSelBarEnd>=0 ){ int iStage = FindStage( m_iSelBarEnd, NULL ); if( g_lstOpusStages[iStage]->iSegType==SEGTYPE_ENDING ) bCanCopy = false; } pMenuItem = m_PopupMenu->CreateMenu( "复制小节","Ctrl+C",DoBarsCopy ); pMenuItem->Enabled = bCanCopy; pMenuItem = m_PopupMenu->CreateMenu( "剪切小节","Ctrl+X",DoBarsCut ); pMenuItem->Enabled = bCanCopy; m_PopupMenu->CreateMenu( "-" ); pMenuItem = m_PopupMenu->CreateMenu( "插入空小节","Ctrl+Ins",DoInsertBlankBar ); pMenuItem->Enabled = bSel; String strText = "插入"; if( m_iCopyBarStart>=0 ){ strText += m_bCut ? "剪切的小节" : "复制的小节"; pMenuItem = m_PopupMenu->CreateMenu( strText,"Ctrl+V",DoBarsInsert ); pMenuItem->Enabled = bSel && m_iCopyBarStart>=0; } pMenuItem = m_PopupMenu->CreateMenu( "删除所选小节","Ctrl+Del",DoBarsDelete ); pMenuItem->Enabled = bSel; m_PopupMenu->CreateMenu( "-" ); pMenuItem = m_PopupMenu->CreateMenu( "改变所选小节调号" ); pMenuItem->Enabled = bSel; if( bSel ){ for( int i=0; iAppendMenu( g_strMelodyKey[i], "", DoBarsChangeKey, i ); } } pMenuItem = m_PopupMenu->CreateMenu( "添加乐器织体...", "", DoInsertTexture ); bool bTexture = false; if( /*!m_bVertical &&*/ bSel ){ int iBS = FindStage( m_iSelBarStart, NULL ), iES = FindStage( m_iSelBarEnd, NULL ); for( int i=iBS; i<=iES; i++ ){ if( g_lstOpusStages[i]->iSegTypeEnabled = bTexture; m_PopupMenu->CreateMenu( "-" ); m_PopupMenu->CreateMenu( "全选", "Ctrl+A", DoSelectAll ); } } m_PopupMenu->Parent = this; m_PopupMenu->Show(Message.XPos,Message.YPos); return; } if( !(Message.Keys & MK_LBUTTON) ) return; if( Screen->Cursor==crHSplit ){ //调整宽度 int iMode = Message.XPos0 ){ int iHitType = -1; DWORD dwHit = HitTest( Message.XPos, Message.YPos, iHitType, !m_bBrush ); int iHitBar = LOWORD(dwHit), iHitPoint = HIWORD(dwHit); if( m_bBrush ){ if( Screen->Cursor!=crBrushNo && iHitType>BAR_CURSOR && iHitTypeMainForm->Perform( UM_SHOWPLAYTIME, iHitBar, iHitPoint ); return; } //符合条件准备拖动 if( iHitType>=BAR_TITLE ){ //左键点中 int iView = VIEW_TRACK; if( iHitTypeMainForm->Perform( UM_SETVIEWMODE, iView, 0 ); } } if( iHitType<0 || iHitBar<0 ){ if( m_iMode==VIEW_STYLE ){ //风格模式 SelectBars( -1, -1 ); SelectCopyBars( -1, -1 ); } else if( m_iMode==VIEW_CHORD ){ //和弦模式 SelectCells( -1, -1, -1, -1 ); SelectCopyCells( -1, -1, -1, -1 ); ((TChordPanel*)m_pChordPanel)->EnableChordModify( false, -1, -1, -1 ); } else{ //轨道模式 SelectTrack( -1, -1, -1 ); SelectRange( -1, -1, -1, -1 ); SelectCopyPos( -1, -1, -1, -1 ); } } else if( iHitType>=HOVER_MUTE ){ int iHitTrack = -1, iState = -1; if( iHitType>=HOVER_SOLO ){ iHitTrack = iHitType - HOVER_SOLO; iState = TRACK_SOLO; } else{ iHitTrack = iHitType - HOVER_MUTE; iState = TRACK_MUTE; } SelectTrack( iHitTrack , -1, -1 ); ((TTrackPanel*)m_pTrackPanel)->OnTrackStateChanged( iState ); return; } else if( iHitType>=BAR_LEFT ){ int iHitTrack = iHitType & 0xFF; SelectTrack( iHitTrack , -1, -1 ); return; } else if( iHitType>=BAR_TRACK ){ int iHitTrack = iHitType & 0xFF; if( iHitTrack!=m_iSelTrack || m_iSelBarStart<0 && m_iSelBarEnd<0 || iHitBar=0 && iHitBar>m_iSelBarEnd || iHitBar==m_iSelBarStart && iHitPointm_iSelPointEnd ){ SelectTrack( iHitTrack , iHitBar, iHitPoint ); //SelectRange( -1, -1, -1, -1 ); } m_bDragReady = true; } else if( iHitType==BAR_TITLE ){ if( m_iSelBarStart<0 && m_iSelBarEnd<0 || iHitBar=0 && iHitBar>m_iSelBarEnd ){ SelectBars( iHitBar, iHitBar ); m_bDraging = true; } else{ m_bDragReady = true; } } else if( iHitType==BAR_DATA ){ int iHitCell = GetCell( iHitPoint ); int iFirstBar, iStage = FindStage( iHitBar, &iFirstBar ); TOpusStage *pStage = g_lstOpusStages[iStage]; if( pStage->iSegType<=SEGTYPE_FILL ){ SelectCells( iHitBar, iHitCell, iHitBar, iHitCell ); m_iMinSelBar = iFirstBar; m_iMaxSelBar = iFirstBar + pStage->aBars.size() - 1; for( int i=iStage-1; i>=0; i-- ){ pStage = g_lstOpusStages[i]; if( pStage->iSegType<=SEGTYPE_FILL ) m_iMinSelBar -= pStage->aBars.size(); else break; } for( int i=iStage+1; iiSegType<=SEGTYPE_FILL ) m_iMaxSelBar += pStage->aBars.size(); else break; } m_bDraging = true; } else{ SelectCells( -1, -1, -1, -1 ); } } if( m_bDragReady || m_bDraging ){ ptDown.X = Message.XPos; ptDown.Y = Message.YPos; m_iMouseDownBar = iHitBar; m_iMouseDownPoint = iHitPoint; SetCapture( Handle ); } } } } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::UMMouseMove(TWMMouseMove &Message) { if( m_bDragReady ){ if( abs(Message.XPos-ptDown.X)>=4 || abs(Message.YPos-ptDown.Y)>=4 ){ //开始拖动 m_bDragReady = false; if( m_iMode==VIEW_TRACK ){ int iHitType = -1; DWORD dwHit = HitTest( Message.XPos, Message.YPos, iHitType ); int iHitBar = LOWORD(dwHit), iHitPoint = HIWORD(dwHit); if( iHitTypetype==ST_AUDIO ){ if( m_iSelBarStart>=0 || m_iSelBarEnd>=0 ){ //移动音频 DrawDragImg( DM_ADJUSTAUDIO ); int left = ptDown.X, top = ptDown.Y - 10; TPoint pt( left, top ); pt = ClientToScreen( pt ); w_xOldDrag = w_xImgDrag = pt.X; w_yOldDrag = w_yImgDrag = pt.Y; w_xOffDrag = -1; w_yOffDrag = 10; SelectCopyPos( -1, -1, -1, -1 ); } else{ if( iHitBar>m_iMouseDownBar || iHitBar==m_iMouseDownBar && iHitPoint>m_iMouseDownPoint ) SelectRange( m_iMouseDownBar, m_iMouseDownPoint, iHitBar, iHitPoint ); else SelectRange( iHitBar, iHitPoint, m_iMouseDownBar, m_iMouseDownPoint ); } } else{ int iStartBar = min( m_iMouseDownBar, iHitBar ), iEndBar = max( m_iMouseDownBar, iHitBar ); if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd ) SelectRange( iStartBar, 0, iEndBar, m_nBarWidth-1 ); } m_bDraging = true; } else if( m_iMode==VIEW_STYLE ){ if( m_iSelBarStart>=0 ){ //调整段落 int iLSBar, iStage = FindStage( m_iSelBarEnd, &iLSBar ); if( g_lstOpusStages[iStage]->iSegType==SEGTYPE_ENDING ){ int iFirstStage = FindStage( m_iSelBarStart, NULL ); if( iFirstStage!=iStage ){ if( m_iMouseDownBar < iLSBar ){ SelectBars( m_iSelBarStart, iLSBar-1 ); } else{ SelectBars( iLSBar, m_iSelBarEnd ); } } } DrawDragImg( DM_ADJUSTSTAGE ); int left = ptDown.X - 100, top = ptDown.Y - 20; TPoint pt( left, top ); pt = ClientToScreen( pt ); w_xOldDrag = w_xImgDrag = pt.X; w_yOldDrag = w_yImgDrag = pt.Y; w_xOffDrag = 100; w_yOffDrag = 20; m_bDraging = true; } } } } else if( m_bDraging ){ int iHitType = -1; DWORD dwHit = HitTest( Message.XPos, Message.YPos, iHitType ); if( iHitType>=0 ){ int iHitBar = LOWORD(dwHit); int iStartBar = min( m_iMouseDownBar, iHitBar ), iEndBar = max( m_iMouseDownBar, iHitBar ); if( m_iMode==VIEW_STYLE ){ if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd ) SelectBars( iStartBar, iEndBar ); } else if( m_iMode==VIEW_CHORD ){ int iStartCell = GetCell( m_iMouseDownPoint ), iEndCell = iStartCell; if( iHitBar>m_iMaxSelBar ){ iStartBar = m_iMouseDownBar; iEndBar = m_iMaxSelBar; iEndCell = g_nChordNumPerBar - 1; } else if( iHitBartype==ST_AUDIO ){ int iHitPoint = HIWORD(dwHit); int iStartPoint = m_iMouseDownPoint, iEndPoint = m_iMouseDownPoint; if( iHitBar==m_iMouseDownBar ){ iStartPoint = min( iStartPoint, iHitPoint ); iEndPoint = max( iEndPoint, iHitPoint ); } else if( iHitBar0/* g_lstOpusStages.size()>0*/ ){ if( !Focused() ) SetFocus(); if( m_bBrush ){ int iCursor = crBrushNo, iHitType = -1, iBrushType = m_pItem->iType, iBrushSegType = m_pItem->GetSegType(); DWORD dwHit = HitTest( Message.XPos, Message.YPos, iHitType, false ); if( iHitType>BAR_CURSOR && iHitTypeiSegType; if( iHitSegType<=SEGTYPE_FILL ){ if( iBrushType==SEGTYPE_SEGMENT && iHitTypepTrack; if( pTrack->iChanNo==9 ){ for( int i=0; iIsDrum() ){ bAdd = false; break; } } } if( bAdd ) iCursor = crBrushAdd; else iCursor = crBrush; } else{ int iTrack = iHitType & 0xFF; TShowTrack* pTrk = m_aTracks[iTrack]; if( pTrk->type==ST_MIDI ){ TMidiTrack* pMT = (TMidiTrack*)pTrk->pTrack; TTrack* pTrack = ((TTrackItem*)m_pItem)->pTrack; if( pMT->IsDrum() && pTrack->iChanNo==9 || !pMT->IsDrum() && pTrack->iChanNo!=9 ) iCursor = crBrush; } } } } } Screen->Cursor = iCursor; } else if( !m_bVertical && Message.Keys==0 ){ int iHitType = -1, iTrack = -1, iHover = -1; DWORD dwHit = HitTest( Message.XPos, Message.YPos, iHitType, true ); if( iHitType>=HOVER_SOLO ){ iTrack = iHitType - HOVER_SOLO; iHover = TRACK_S_HOVER; if( Hint.IsEmpty() ){ ShowHint = true; Hint = "独奏开关"; } else if( Hint.Compare("独奏开关") ){ ShowHint = false; Hint = ""; } } else if( iHitType>=HOVER_MUTE ){ iTrack = iHitType - HOVER_MUTE; iHover = TRACK_M_HOVER; if( Hint.IsEmpty() ){ ShowHint = true; Hint = "静音开关"; } else if( Hint.Compare("静音开关") ){ ShowHint = false; Hint = ""; } } else{ ShowHint = false; Hint = ""; } int nSMTop = m_nTopBound+m_nRowGapHeight+m_nTitleHeight+m_nChordHeight+SM_TOP; for( int i=m_iBeginShowTrack; iiHover & iHover) ){ int lBox = LOWORD( dwHit ), tBox = HIWORD( dwHit ); pTrk->iHover |= iHover; SetRect( &rect, lBox, tBox, lBox+SM_SIZE, tBox+SM_SIZE ); InvalidateRect( Handle, &rect, false ); } if( (pTrk->iHover & TRACK_S_HOVER) && (iTrack!=i || iHover!=TRACK_S_HOVER) ){ pTrk->iHover -= TRACK_S_HOVER; SetRect( &rect, m_nTrkHdrWidth+SOLO_LEFT, nSMTop, m_nTrkHdrWidth+SOLO_LEFT+SM_SIZE, nSMTop+SM_SIZE ); InvalidateRect( Handle, &rect, false ); } if( (pTrk->iHover & TRACK_M_HOVER) && (iTrack!=i || iHover!=TRACK_M_HOVER) ){ pTrk->iHover -= TRACK_M_HOVER; SetRect( &rect, m_nTrkHdrWidth+MUTE_LEFT, nSMTop, m_nTrkHdrWidth+MUTE_LEFT+SM_SIZE, nSMTop+SM_SIZE ); InvalidateRect( Handle, &rect, false ); } nSMTop += m_nTrackHeight; } } } } //----------------------------------------------------------------------------- void __fastcall TContentPanel::UMMouseUp(TWMMouse &Message) { TShiftState Shift(Message.Keys); if( !Shift.Contains(ssLeft) ) return; if( m_bDragReady || m_bDraging ){ if( m_bDragReady ){ //选中小节或前尾奏段 if( m_iMode==VIEW_STYLE ){ if( m_iSelBarStart<0 || m_iMouseDownBarm_iSelBarEnd ){ int iFirstBar, iStage = FindStage( m_iMouseDownBar, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; if( pStage->iSegType>=SEGTYPE_INTRO ){ SelectBars( iFirstBar, iFirstBar+pStage->aBars.size()-1 ); } else SelectBars( m_iMouseDownBar, m_iMouseDownBar ); } } else if( m_iMode==VIEW_CHORD ){ int iCell = GetCell( m_iMouseDownPoint ); if( m_iSelBarStart<0 || m_iMouseDownBarm_iSelBarEnd || m_iMouseDownBar==m_iSelBarStart && iCellm_iSelCellEnd ){ int iFirstBar, iDownStage = FindStage( m_iMouseDownBar, &iFirstBar ); TOpusStage *pDownStage = g_lstOpusStages[iDownStage]; if( pDownStage->iSegType<=SEGTYPE_FILL ){ int iEndBar = m_iMouseDownBar, iEndCell = iCell; if( m_iCopyBarStart>=0 ){ //计算已复制和弦个数 int nChordRemain = (m_iCopyBarEnd - m_iCopyBarStart) * g_nChordNumPerBar - m_iCopyCellStart + m_iCopyCellEnd + 1 ; int iStage = iDownStage, iStartBar = m_iMouseDownBar, iStartCell = iCell, iLastBar = iFirstBar + pDownStage->aBars.size() - 1; TOpusStage * pStage = pDownStage; while( true ){ int nCellCount = ( iLastBar - iStartBar + 1 ) * g_nChordNumPerBar - iStartCell; if( nCellCount >= nChordRemain ){ iEndBar = iStartBar + nChordRemain / g_nChordNumPerBar; iEndCell = iStartCell + nChordRemain % g_nChordNumPerBar - 1; if( iEndCell>=g_nChordNumPerBar ){ iEndBar++; iEndCell -= g_nChordNumPerBar; } else if( iEndCell<0 ){ iEndBar--; iEndCell = g_nChordNumPerBar - 1; } break; } else{ iEndBar = iLastBar; iEndCell = g_nChordNumPerBar - 1; nChordRemain -= nCellCount; iStage++; if( iStageiSegType<=SEGTYPE_FILL ){ iStartBar = iLastBar + 1; iStartCell = 0; iLastBar = iStartBar + pStage->aBars.size() - 1; } else break; } else break; } } } SelectCells( m_iMouseDownBar, iCell, iEndBar, iEndCell ); } } } else{ if( m_iSelBarStart<0 || m_iMouseDownBarm_iSelBarEnd || m_iMouseDownBar==m_iSelBarStart && m_iMouseDownPointm_iSelPointEnd ){ SelectRange( -1, -1, -1, -1 ); } } } else if( m_bDraging && m_iSelBarStart>=0 && m_iSelBarEnd>=0 ){ if( m_bBrush ){ if( Message.XPos<0 || Message.XPos>Width || Message.YPos<0 || Message.YPos>Height ){ if( m_iMode==VIEW_STYLE ) SelectBars( -1, -1 ); } else HandleBrush(); } else if( m_iMode==VIEW_STYLE || m_iMode==VIEW_TRACK && m_aTracks[m_iSelTrack]->type==ST_MIDI ){ int iStartBar = m_iSelBarStart, iEndBar = m_iSelBarEnd; int iFirstBar, iStage = FindStage( iStartBar, &iFirstBar ); TOpusStage* pStage1 = g_lstOpusStages[iStage]; if( pStage1->iSegType>=SEGTYPE_INTRO ) iStartBar = iFirstBar; iStage = FindStage( iEndBar, &iFirstBar ); TOpusStage* pStage2 = g_lstOpusStages[iStage]; if( pStage1->iSegType>=SEGTYPE_INTRO && pStage1==pStage2 || pStage2->iSegType>=SEGTYPE_INTRO ) iEndBar = iFirstBar+pStage2->aBars.size()-1; if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd ){ if( m_iMode==VIEW_STYLE ) SelectBars( iStartBar, iEndBar ); else SelectRange( iStartBar, 0, iEndBar, m_nBarWidth-1, true ); } } else if( m_iMode==VIEW_TRACK ){ int iStartPoint = m_iSelBarStart * m_nDataWidth + m_iSelPointStart, iEndPoint = m_iSelBarEnd * m_nDataWidth + m_iSelPointEnd, deltaPoint = iEndPoint - iStartPoint; int minArea = max( 10, (int)(g_nPPB / 4.0 + 0.5) ); if( deltaPoint=0 ){ GetSelectChord( iBarKey, iKey, iType ); bEnable = iKey!=-1; } ((TChordPanel*)m_pChordPanel)->EnableChordModify( bEnable, iBarKey, iKey, iType ); } ReleaseCapture(); m_bDragReady = false; m_bDraging = false; m_bBrush = false; m_iMouseDownBar = m_iMouseDownPoint = -1; m_pItem = NULL; } else if( m_bBrush ){ SetCapture( Handle ); } } //----------------------------------------------------------------------------- bool TContentPanel::HandleHoverEvent(TPoint ptMouse) { if( g_lstOpusStages.size()==0 || !m_bDraging && !m_pItem || (w_iDragMode==DM_ADJUSTSTYLE || w_iDragMode==DM_ADJUSTSTAGE) && m_pItem && ( m_pItem->iType==SEGTYPE_STYLE || m_pItem->iType==SEGTYPE_TRACK ) ){ return false; } bool bCanDrop = false; int X = ptMouse.X, Y = ptMouse.Y; int iHitType = -1; DWORD dwHit = HitTest( X, Y, iHitType ); if( iHitType>=BAR_TITLE ){ int iHitBar = LOWORD(dwHit), iHitPoint = HIWORD(dwHit); if( (w_iDragMode==DM_ADJUSTSTYLE || w_iDragMode==DM_ADJUSTSTAGE) && iHitTypeaBars.size() - 1; int iHitType = pHitStage->iSegType; if( iHitType==SEGTYPE_FILL ) iHitType = SEGTYPE_VAR; bool bCanInsert = false; if( m_pItem ){ int iDropType = m_pItem->GetSegType(); TOpusStage* pLastStage = g_lstOpusStages.back(); if( iDropType==SEGTYPE_FILL ) iDropType = SEGTYPE_VAR; if( iDropType==iHitType ){ // SelectBars( iFirstBar, iLastBar ); bCanDrop = true; } if( iHitBar==m_nBarNum-1 && iHitPoint>90 ){ if( pLastStage->iSegType!=SEGTYPE_ENDING && iDropType>=SEGTYPE_INTRO ){ bCanInsert = true; } } else if( iDropType==SEGTYPE_INTRO ){ bCanInsert = true; } } else{ int iStage = FindStage( m_iSelBarStart, NULL ); TOpusStage* pHoverStage = g_lstOpusStages[iStage]; if( pHoverStage->iSegTypem_iSelBarEnd && iHitType90 ) || iHitType>=SEGTYPE_INTRO && ( iHitBar==iFirstBar && iHitPoint<30 || iHitBar==iLastBar && iHitPoint>90 ))){ if( m_pItem ) SelectBars( -1, -1 ); SetDropBar( iHitBar + (iHitPoint>90 ? 1 : 0) ); bCanDrop = true; } else{ SetDropBar( -1 ); if( bCanDrop ){ SelectBars( iFirstBar, iLastBar ); } } } else if( w_iDragMode==DM_ADJUSTAUDIO && iHitType>=BAR_TRACK && iHitTypetype==ST_AUDIO ){ SelectTrack( iHitTrack, iHitBar, iHitPoint, false ); bCanDrop = true; } else{ SelectTrack( -1, -1, -1, false ); } } } if( !bCanDrop ){ if( w_iDragMode==DM_ADJUSTSTYLE || w_iDragMode==DM_ADJUSTSTAGE ){ if( m_pItem ) SelectBars( -1, -1 ); SetDropBar( -1 ); } else if( w_iDragMode==DM_ADJUSTAUDIO ){ SelectTrack( -1, -1, -1, false ); } } return bCanDrop; } //----------------------------------------------------------------------------- void TContentPanel::AudioMove( int iSrcTrack, int iSrcBarStart, int iSrcPointStart, int iSrcBarEnd, int iSrcPointEnd, bool bCut ) { if( m_bPlaying ) Parent->Perform( UM_STOP, STOP_CONTENT, 0 ); int nTotalBars = m_nBarNum; if( iSrcBarStart<0 ){ iSrcBarStart = 0; iSrcPointStart = 0; } if( iSrcBarEnd<0 ){ iSrcBarEnd = nTotalBars; iSrcPointEnd = 0; } int iDestBarStart = m_iSelTrackBar, iDestPointStart = m_iSelTrackPoint, iDestBarEnd, iDestPointEnd, nSrcLen = ( iSrcBarEnd * POINTS_PER_BAR + iSrcPointEnd ) - ( iSrcBarStart * POINTS_PER_BAR + iSrcPointStart ); if( m_iDragAudio<0 && m_iSelBarEnd>=0 ){ iDestBarEnd = m_iSelBarEnd; iDestPointEnd = m_iSelPointEnd; } else{ int nPointsEnd = ( iDestBarStart * POINTS_PER_BAR + iDestPointStart ) + nSrcLen; iDestBarEnd = nPointsEnd / POINTS_PER_BAR; if( iDestBarEnd>=nTotalBars ){ iDestBarEnd = nTotalBars; iDestPointEnd = 0; } else{ iDestPointEnd = nPointsEnd % POINTS_PER_BAR; } } int nDestLen = ( iDestBarEnd - iDestBarStart ) * POINTS_PER_BAR + (iDestPointEnd - iDestPointStart ); double dblSrcStart = iSrcBarStart + (double)iSrcPointStart / POINTS_PER_BAR, dblSrcEnd = iSrcBarEnd + (double)iSrcPointEnd / POINTS_PER_BAR, dblDestStart = iDestBarStart + (double)iDestPointStart / POINTS_PER_BAR, dblDestEnd = iDestBarEnd + (double)iDestPointEnd / POINTS_PER_BAR; //Set Undo DWORD *aBefore=NULL, *aAfter=NULL, *aExtra=NULL; int iSrcBarBreak = iSrcBarEnd, iSrcPointBreak = iSrcPointEnd; int nAT = 1, *aTrks = &g_iSelAudio; //int iTracks = g_iSelAudio; if( bCut && iSrcTrack!=g_iSelAudio ){ // iTracks =-1;//+= ( 1<0 ){ if( nSrcLen > nDestLen ){ //超出总长度 double dblDelStart = dblSrcStart + ( dblDestEnd - dblDestStart ); if( bCut ){ //单独删除不复制的部分 int nDelLen = nSrcLen - nDestLen, nPointsEnd = ( iSrcBarStart * POINTS_PER_BAR + iSrcPointStart ) + nDelLen; iSrcBarBreak = nPointsEnd / POINTS_PER_BAR; iSrcPointBreak = nPointsEnd % POINTS_PER_BAR; // Set Undo CopyWave( iSrcTrack, iSrcBarBreak, iSrcPointBreak, iSrcBarEnd, iSrcPointEnd, &aExtra ); MoveAudio( iSrcTrack, dblDelStart, dblSrcEnd, -1, 0, MODE_ERASE ); } dblSrcEnd = dblDelStart; } // Set Undo CopyWave( g_iSelAudio, iDestBarStart, iDestPointStart, iDestBarEnd, iDestPointEnd, &aBefore ); } else{ TAudioTrack* pAudio = CopyAudioTrack( g_iSelAudio, 0, m_nBarNum ); g_Undo.AddUndo( bCut ? UNDO_AUDIO_MOVE : UNDO_AUDIO_COPY, g_iSelAudio, g_iMelodyKey, -1, (void*)pAudio, NULL ); } MoveAudio( iSrcTrack, dblSrcStart, dblSrcEnd, g_iSelAudio, dblDestStart, bCut ? MODE_MOVE : MODE_COPY ); if( g_iSelAudio>0 ){ f_MM_AddUndoAfter( nAT, aTrks ); // Set Undo CopyWave( g_iSelAudio, iDestBarStart, iDestPointStart, iDestBarEnd, iDestPointEnd, &aAfter ); int iBegin = MAKELONG( iDestPointStart, iDestBarStart ), iEnd = MAKELONG( iDestPointEnd, iDestBarEnd ), iType = bCut ? UNDO_AUDIO_MOVE : UNDO_AUDIO_COPY; g_Undo.AddUndo( iType, g_iSelAudio, iBegin, iEnd, (void*)aBefore, (void*)aAfter ); if( bCut ){ int iSrcBegin = MAKELONG( iSrcPointStart, iSrcBarStart ), iSrcEnd = MAKELONG( iSrcPointEnd, iSrcBarEnd ); g_Undo.SetUndoExtra( iSrcTrack, iSrcBegin, iSrcEnd, (void*)aExtra, NULL ); } //显示 if( iSrcTrack!=g_iSelAudio ) InvalidateBars( m_iSelBarStart, m_iSelBarEnd, BAR_TRACK | GetShowTrackId( ST_AUDIO, iSrcTrack ) ); if( m_iDragAudio>0 || m_iSelBarStart<0 ){ /* if( m_iSelBarStart==iDestBarStart && m_iSelBarEnd==iDestBarEnd && iDestBarEnd - iDestBarStart > 1 ) InvalidateBars( iDestBarStart+1, iDestBarEnd-1, BAR_TRACK | GetShowTrackId( ST_AUDIO, g_iSelAudio ) ); */ SelectRange( iDestBarStart, iDestPointStart, iDestBarEnd, iDestPointEnd, true ); } else InvalidateBars( iDestBarStart, iDestBarEnd, BAR_TRACK | GetShowTrackId( ST_AUDIO, g_iSelAudio ) ); } if( nAT>1 ) delete[] aTrks; } //----------------------------------------------------------------------------- void TContentPanel::HandleDropEvent( int iState ) { TUseStylePanel* pStylePanel = (TUseStylePanel*)m_pStylePanel; if( w_iDragMode==DM_ADJUSTAUDIO ){ if( g_iSelAudio>=0 && m_iSelTrackBar>=0 ){ if( m_iDragAudio!=g_iSelAudio || m_iSelTrackBar!=m_iSelBarStart || m_iSelTrackPoint!=m_iSelPointStart ){ TShiftState Shift( iState ); bool bCtrl = Shift.Contains( ssCtrl ); AudioMove( m_iDragAudio, m_iSelBarStart, m_iSelPointStart, m_iSelBarEnd, m_iSelPointEnd, !bCtrl ); } } else{ int iTrack = GetShowTrackId( ST_AUDIO, m_iDragAudio ) - 1; SelectTrack( iTrack, m_iSelBarStart, m_iSelPointStart, false ); } m_iDragAudio = -1; } else if( m_iSelBarStart>=0 && m_pItem ){ //应用风格到段 int iFirstBar, iStage = FindStage( m_iSelBarStart, &iFirstBar ); TSegmentItem* pSegItem = (TSegmentItem*)m_pItem; TOpusStage* pStage = g_lstOpusStages[iStage]; int nBar = pStage->aBars.size(); if( pSegItem->iSegType>=SEGTYPE_INTRO ) nBar = pSegItem->nBars; if( pStage->aBars.size()!=nBar ){ //段落长度调整 SetPlayPoint( 0, 0 ); Application->MainForm->Perform( UM_SHOWPLAYTIME, 0, 0 ); } pStylePanel->ReformStage( iStage, pSegItem ); iStage = FindStage( m_iSelBarStart, NULL ); SelectStage( iStage ); } else if( m_iDropBar>=0 ){ if( m_pItem ){ //插入前尾奏 TSegmentItem* pSegItem = (TSegmentItem*)m_pItem; int nBarNum = 0; if( pSegItem->iSegType>=SEGTYPE_INTRO ) nBarNum = pSegItem->nBars; int iStage = FindStage( m_iDropBar, NULL ); int iPSFirstBar, iPlayStage = FindStage( m_iPlayBar, &iPSFirstBar ); if( iStage>=0 && iPlayStage>=iStage ){ SetPlayPoint( 0, 0 ); Application->MainForm->Perform( UM_SHOWPLAYTIME, 0, 0 ); } bool bPreChange = g_iPreStage==0; if( bPreChange ){ DuplicateRawBars(); SendMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); } f_MM_AddUndoBefore( -1, NULL ); pStylePanel->InsertStage( m_iDropBar, pSegItem ); iStage = FindStage( m_iDropBar, NULL ); SelectBars( m_iDropBar, m_iDropBar+nBarNum-1 ); if( bPreChange ) InitialVars(); f_MM_AddUndoAfter( -1, NULL ); pStylePanel->SetBarsUndo( UNDO_BAR_INSERT, m_iDropBar, nBarNum ); } else if( m_iSelBarStart>=0 ){ TShiftState Shift( iState ); bool bCtrl = Shift.Contains( ssCtrl ); pStylePanel->MoveBars( m_iSelBarStart, m_iSelBarEnd, m_iDropBar, bCtrl ? MODE_COPY : MODE_MOVE ); } } } //----------------------------------------------------------------------------- void TContentPanel::SelectBars( int iStartBar, int iEndBar ) { int iStart = m_iSelBarStart, iEnd = m_iSelBarEnd; if( iStart==iStartBar ){ if( iEnd==iEndBar ) return; else{ iStart = min( iEndBar, iEnd ); iEnd = max( iEndBar, iEnd ); } } else if( iEndBar==iEnd ){ iEnd = max( iStartBar, iStart ); iStart = min( iStartBar, iStart ); } else{ if( iStart<0 || iStartBar=0 ) iStart = iStartBar; if( iEndBar>iEnd ) iEnd = iEndBar; } m_iSelBarStart = iStartBar; m_iSelBarEnd = iEndBar; if( iStartBar<0 && iEndBar<0 ){ m_iSelCellStart = m_iSelCellEnd = -1; m_iSelPointStart = m_iSelPointEnd = -1; //DebugPrint( "Select -1, -1" ); } else{ if( iStartBar>=0 && m_iSelPointStart<0 ){ m_iSelPointStart = 0; } if( iEndBar>=0 && m_iSelPointEnd<0 ){ m_iSelPointEnd = m_nBarWidth-1; } } int iArea = 0; if( m_iMode==VIEW_STYLE ){ iArea = BAR_TITLE|BAR_DATA|BAR_TRACK; } else if( m_iMode==VIEW_CHORD ){ iArea = BAR_DATA; } else{ iArea = BAR_TRACK; } InvalidateBars( iStart, iEnd, iArea ); } //----------------------------------------------------------------------------- void TContentPanel::GetSelectBars( int& iStartBar, int& iEndBar ) { iStartBar = m_iSelBarStart; iEndBar = m_iSelBarEnd; } //----------------------------------------------------------------------------- void TContentPanel::SelectCells( int iBarStart, int iCellStart, int iBarEnd, int iCellEnd ) { if( iBarStart==m_iSelBarStart && iCellStart==m_iSelCellStart && iBarEnd==m_iSelBarEnd && iCellEnd==m_iSelCellEnd ) return; if( iBarStart!=m_iSelBarStart || iBarEnd!=m_iSelBarEnd ){ m_iSelCellStart = iCellStart; m_iSelCellEnd = iCellEnd; if( iBarStart==m_iSelBarStart ) InvalidateBar( iBarStart, 0, m_nBarWidth, BAR_DATA ); if( iBarEnd==m_iSelBarEnd ) InvalidateBar( iBarEnd, 0, m_nBarWidth, BAR_DATA ); SelectBars( iBarStart, iBarEnd ); } else if( iBarStart==iBarEnd ){ m_iSelCellStart = iCellStart; m_iSelCellEnd = iCellEnd; InvalidateBar( iBarStart, 0, m_nBarWidth, BAR_DATA ); } else{ if( iCellStart!=m_iSelCellStart ){ int l = min( m_iSelCellStart, iCellStart ) * m_nChordTxtWidth, r = ( max( m_iSelCellStart, iCellStart ) + 1 ) * m_nChordTxtWidth; m_iSelCellStart = iCellStart; InvalidateBar( iBarStart, l, r, BAR_DATA ); } if( iCellEnd!=m_iSelCellEnd ){ int l = min( m_iSelCellEnd, iCellEnd ) * m_nChordTxtWidth, r = ( max( m_iSelCellEnd, iCellEnd ) + 1 ) * m_nChordTxtWidth; m_iSelCellEnd = iCellEnd; InvalidateBar( iBarEnd, l, r, BAR_DATA ); } } } //--------------------------------------------------------------------------- void TContentPanel::SelectCopyCells( int iBarStart, int iCellStart, int iBarEnd, int iCellEnd ) { if( m_iCopyBarStart==iBarStart && m_iCopyCellStart==iCellStart && m_iCopyBarEnd==iBarEnd && m_iCopyCellEnd==iCellEnd ) return; int iOldBarStart = m_iCopyBarStart, iOldBarEnd = m_iCopyBarEnd; //iOldCellSetart = m_iCopyCellStart, //iOldCellEnd = m_iCopyCellEnd; m_iCopyBarStart = iBarStart; m_iCopyBarEnd = iBarEnd; m_iCopyCellStart = iCellStart; m_iCopyCellEnd = iCellEnd; if( iOldBarStart>=0 ){ if( iBarStart>=0 ){ if( iBarStart<=iOldBarEnd || iBarEnd>=iOldBarStart ){ int iStart = min( iBarStart, iOldBarStart ), iEnd = max( iBarEnd, iOldBarEnd ); InvalidateBars( iStart, iEnd ); } else{ InvalidateBars( iOldBarStart, iOldBarEnd ); InvalidateBars( iBarStart, iBarEnd ); } } else{ InvalidateBars( iOldBarStart, iOldBarEnd ); } } else if( iBarStart>=0 ){ InvalidateBars( iBarStart, iBarEnd ); } } //--------------------------------------------------------------------------- void TContentPanel::SelectCopyPos( int iBarStart, int iPointStart, int iBarEnd, int iPointEnd ) { if( m_iCopyBarStart==iBarStart && m_iCopyPointStart==iPointStart && m_iCopyBarEnd==iBarEnd && m_iCopyPointEnd==iPointEnd ) return; if( iBarStart<0 ){ iBarStart = 0; iPointStart = 0; } if( iBarEnd<0 ){ iBarEnd = g_Opus.BarCount(); iPointEnd = 0; } int iOldBarStart = m_iCopyBarStart, iOldBarEnd = m_iCopyBarEnd; //iOldPointStart = m_iCopyPointStart, //iOldPointEnd = m_iCopyPointEnd; m_iCopyBarStart = iBarStart; m_iCopyBarEnd = iBarEnd; m_iCopyPointStart = iPointStart; m_iCopyPointEnd = iPointEnd; if( iOldBarStart>=0 ){ int iWave = GetShowTrackId( ST_AUDIO, m_iCopyAudio ); if( m_iCopyAudio==g_iSelAudio && iBarStart>=0 ){ if( iBarStart<=iOldBarEnd || iBarEnd>=iOldBarStart ){ int iStart = min( iBarStart, iOldBarStart ), iEnd = max( iBarEnd, iOldBarEnd ); InvalidateBars( iStart, iEnd, BAR_TRACK | iWave ); } else{ InvalidateBars( iOldBarStart, iOldBarEnd, BAR_TRACK | iWave ); InvalidateBars( iBarStart, iBarEnd, BAR_TRACK | iWave ); } } else{ InvalidateBars( iOldBarStart, iOldBarEnd, BAR_TRACK | iWave ); } } if( iBarStart>=0 ){ m_iCopyAudio = g_iSelAudio; int iWave = GetShowTrackId( ST_AUDIO, g_iSelAudio ); InvalidateBars( iBarStart, iBarEnd, BAR_TRACK | iWave ); } else{ m_iCopyAudio = -1; m_bCut = false; } } //--------------------------------------------------------------------------- void TContentPanel::SetDropBar( int iBar ) { int iDropOld = m_iDropBar; if( iBar!=iDropOld ){ m_iDropBar = iBar; for( int i=1; i>=0; i-- ){ if( iDropOld>=0 ) InvalidateBar( iDropOld - i, 0, m_nBarWidth, BAR_TITLE|BAR_DATA|BAR_TRACK ); if( iBar>=0 ) InvalidateBar( iBar - i, 0, m_nBarWidth, BAR_TITLE|BAR_DATA|BAR_TRACK ); } } } //----------------------------------------------------------------------------- void TContentPanel::SelectStage( int iStage ) { if( iStage>=0 && iStageaBars.size() - 1; SelectBars( iFirstBar, iEndBar ); } } //----------------------------------------------------------------------------- void TContentPanel::SetScrollTimer(TPoint ptMouse, bool bVertical) { int X = ptMouse.X, Y = ptMouse.Y; //判断是否滚动 if( m_bVertical ){ if( m_nRowNum>m_nRowShow && X>m_nLeftBound && XHeight-m_nRowGapHeight && m_iBeginShowRow0 ) iDirect = -1; if( iDirect!=0 ){ if( !m_pTimer ){ m_pTimer = new TTimer(this); m_pTimer->OnTimer = TimerProc; m_pTimer->Tag = MAKELONG( iDirect, 0 ); m_pTimer->Interval = 500; m_pTimer->Enabled = true; } } else if( m_pTimer ){ delete m_pTimer; m_pTimer = NULL; } } } else{ if( m_aTracks.size()>m_nTrackShow && X>m_nLeftBound && XHeight-m_nRowGapHeight && m_iBeginShowTrack<(int)(m_aTracks.size()-m_nTrackShow) ) iDirect = 1; else if( Y0 ) iDirect = -1; if( iDirect!=0 ){ if( !m_pTimer ){ m_pTimer = new TTimer(this); m_pTimer->OnTimer = TimerProc; m_pTimer->Tag = MAKELONG( iDirect, 0 ); m_pTimer->Interval = 500; m_pTimer->Enabled = true; } } else if( m_pTimer ){ delete m_pTimer; m_pTimer = NULL; } } else if( m_nBarNum>m_nColumnNum && Y>m_nTopBound && YWidth-m_nRightBound && ( g_iToolPanelShow!=0 || m_bBrush && X-120 || w_bDraging && X>-12 ) && m_iBeginShowBar>0 ) iDirect = -1; if( iDirect!=0 ){ if( !m_pTimer ){ m_pTimer = new TTimer(this); m_pTimer->OnTimer = TimerProc; m_pTimer->Tag = MAKELONG( iDirect, 1 ); m_pTimer->Interval = 500; m_pTimer->Enabled = true; } } else if( m_pTimer ){ delete m_pTimer; m_pTimer = NULL; } } } } //----------------------------------------------------------------------------- void __fastcall TContentPanel::TimerProc(TObject* Sender) { if( w_bDraging || m_bDraging ){ DebugPrint( "On timer." ); if( m_pTimer->Tag!=0 ){ bool bVertical = HIWORD( m_pTimer->Tag )==0; short iDirect = (short)(LOWORD( m_pTimer->Tag )); int &iCurPos = bVertical ? (m_bVertical ? m_iBeginShowRow : m_iBeginShowTrack) : m_iBeginShowBar, iMaxPos = bVertical ? (m_bVertical ? m_nRowNum-m_nRowShow : m_aTracks.size()-m_nTrackShow) : m_nBarNum-m_nColumnNum; ScrollView( iCurPos + iDirect, bVertical ); if( iCurPos<=0 || iCurPos>=iMaxPos ){ delete m_pTimer; m_pTimer = NULL; } else if( m_pTimer->Interval>200 ){ m_pTimer->Interval = 200; } } } else if( m_pTimer && m_pTimer->Tag!=0 ){ delete m_pTimer; m_pTimer = NULL; } } //----------------------------------------------------------------------------- void __fastcall TContentPanel::OnStageChanged( int iStage, int iMode ) { if( m_bPlaying ) Parent->Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 ); int nBarCount = GetBarCount(); if( m_iPlayBar>=nBarCount ){ SetPlayPoint( 0, 0 ); Application->MainForm->Perform( UM_SHOWPLAYTIME, 0, 0 ); } if( iMode==MODE_DELETE || m_iSelBarEnd>=nBarCount ) SelectBars( -1, -1 ); if( m_iCopyBarStart>=0 && iMode!=MODE_COPY && iMode!=MODE_MOVE ){ SelectCopyBars( -1, -1 ); } if( iMode==MODE_INIT ){ InitialVars(); //SelectBars( -1, -1 ); SelectRange( -1, -1, -1, -1 ); SelectCopyPos( -1, -1, -1, -1 ); SelectCells( -1, -1, -1, -1 ); SelectCopyCells( -1, -1, -1, -1 ); } else{ if( iStage>0 ) iStage--; if( nBarCount!=m_nBarNum ){ if( nBarCount==0 ){ InvalidateRgn( Handle, NULL, false ); } else if( nBarCount 0 ){ m_nRowNum++; } int nDrawHeight = ClientHeight - m_nTopBound - m_nBottomBound; if( nDrawHeight % m_nBarHeight > m_nRowGapHeight + m_nTitleHeight ){ m_nRowNum++; } if( !SetScrollView( iFirstShowBar ) ){ for( int i=iStage; ipStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); PostMessage( Parent->Handle, UM_STAGECHANGED, 0, 0 ); } else{ PostMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); } } if( !m_bVertical ) GenerateCompose(); } //----------------------------------------------------------------------------- void __fastcall TContentPanel::OnChangeMelodyKey( int Index ) { g_Undo.AddUndo( UNDO_KEY_MELODY, 0, g_iMelodyKey, Index, NULL, NULL ); ChangeBarsKey( 0, g_Opus.BarCount()-1, Index, NULL ); // ChangeMelodyKey( Index ); } //--------------------------------------------------------------------------- /* void TContentPanel::ChangeMelodyKey( int iKey ) { g_Opus.ChangeKey( -1, -1, iKey, NULL ); g_iMelodyKey = iKey; InvalidateShowBars(); if( g_iViewMode==VIEW_CHORD ){ SelectCells( -1, -1, -1, -1 ); ((TChordPanel*)m_pChordPanel)->EnableChordModify( false, -1, -1, -1 ); } } //--------------------------------------------------------------------------- */ void TContentPanel::ChangeBarsKey( int iBarStart, int iBarEnd, int iKey, int keys[] ) { g_Opus.ChangeKey( iBarStart, iBarEnd, iKey, keys ); if( iBarStart==0 ){ g_iMelodyKey = keys ? keys[0] : iKey;; Application->MainForm->Perform( UM_CHANGEKEY, 0, 0 ); } if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } if( !m_bVertical ) GenerateCompose(); int opt = BAR_TITLE | BAR_DATA; if( !m_bVertical ) opt |= BAR_TRACK; InvalidateBars( iBarStart, iBarEnd+1, opt ); if( g_iViewMode==VIEW_CHORD ){ SelectCells( -1, -1, -1, -1 ); ((TChordPanel*)m_pChordPanel)->EnableChordModify( false, -1, -1, -1 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoubleClick(TObject* sender) { if( m_iMode==VIEW_TRACK ){ int iHitType = -1; DWORD dwHit = HitTest( ptDown.X, ptDown.Y, iHitType ); int iHitBar = LOWORD(dwHit), iHitPoint = HIWORD(dwHit); if( iHitType>=BAR_TRACK && iHitTypetype==ST_AUDIO ) /* if( iHitType & 0xFF00 ) SelectRangeByEffect( iHitBar, iHitPoint, ( iHitType & 0xFF00 )>>8 ); else */ SelectRangeByWave( iHitBar, iHitPoint ); } } else if( m_iSelBarStart>=0 ){ if( m_iMode==VIEW_STYLE ){ int iFirstBar, iStage = FindStage( m_iSelBarStart, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; int iEndBar = iFirstBar + pStage->aBars.size()-1; SelectBars( iFirstBar ,iEndBar ); ((TUseStylePanel*)m_pStylePanel)->SetSelectStage( iStage ); } else if( m_iMode==VIEW_CHORD ){ int iFirstBar, iStage = FindStage( m_iSelBarStart, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; TBar * pBar = pStage->aBars[m_iSelBarStart-iFirstBar]; int iCellStart = m_iSelCellStart, iCellEnd = iCellStart; int key = pBar->aChords.iKey[iCellStart], type = pBar->aChords.iType[iCellStart]; for( int i=m_iSelCellStart-1; i>=0; i-- ){ if( pBar->aChords.iKey[i]==key && pBar->aChords.iType[i]==type ) iCellStart = i; else break; } for( int i=m_iSelCellStart+1; iaChords.iKey[i]==key && pBar->aChords.iType[i]==type ) iCellEnd = i; else break; } SelectCells( m_iSelBarStart, iCellStart, m_iSelBarStart, iCellEnd ); } } } //----------------------------------------------------------------------------- void TContentPanel::SelectRangeByWave( int iHitBar, int iHitPoint ) { TWaveBarList& list = g_aAudioTracks[g_iSelAudio]->lstBars; int nMiss = 0; //前向查找波形起点 int iBarS = iHitBar, iPtS = iHitPoint; while( iBarS>=0 ){ for( ; iPtS>=0; iPtS-- ){ DWORD dwValue = list[iBarS]->aVols[iPtS]; WORD wVol = max( LOWORD( dwValue ), HIWORD(dwValue) ); if( wVol<1024 ){ nMiss++; if( nMiss>4 ) break; } else nMiss = 0; } if( nMiss>4 || iBarS==0 ) break; else{ iPtS = POINTS_PER_BAR - 1; iBarS--; } } //后向查找波形终点 nMiss = 0; int iBarE = iHitBar, iPtE = iHitPoint; while( iBarEaVols[iPtE]; WORD wVol = max( LOWORD( dwValue ), HIWORD(dwValue) ); if( wVol<1024 ){ nMiss++; if( nMiss>4 ) break; } else nMiss = 0; } if( nMiss>4 || iBarE==m_nBarNum-1 ) break; else{ iPtE = 0; iBarE++; } } int ptStart = iBarS * POINTS_PER_BAR + iPtS + nMiss, ptEnd = iBarE * POINTS_PER_BAR + iPtE - nMiss; if( ptEnd - ptStart > 4 ){ iBarS = ptStart / POINTS_PER_BAR; iPtS = ptStart % POINTS_PER_BAR; iBarE = ptEnd / POINTS_PER_BAR; iPtE = ptEnd % POINTS_PER_BAR; SelectRange( iBarS, iPtS, iBarE, iPtE ); } } //----------------------------------------------------------------------------- /* void TContentPanel::SelectRangeByEffect( int iHitBar, int iHitPoint , int delta ) { TAudioTrack* pTrack = g_aAudioTracks[g_iSelAudio]; int nEffects = 0, hE = 1; if( pTrack->iEffectShow>0 ){ for( int i=0; ilstEffects[i] ){ nEffects++; } } if( nEffects>0 ){ hE = 14 / nEffects; if( hE>4 ) hE = 4; } } int hEffects = nEffects * hE; if( delta >= hEffects ) return; if( pTrack->iEffectShow==1 ){ delta = hEffects - delta; } int y = 0; for( int j=0; jlstEffects[j] ){ y += hE; } if( delta < y ){ TEffect* pAE = pTrack->lstEffects[j]; while( pAE ){ if( pAE->iBarEnd>iHitBar || pAE->iBarEnd==iHitBar && pAE->iPointEnd>=iHitPoint ){ if( pAE->iBarStartiBarStart==iHitBar && pAE->iPointStart<=iHitPoint ){ SelectRange( pAE->iBarStart, pAE->iPointStart, pAE->iBarEnd, pAE->iPointEnd ); } break; } pAE = pAE->pNext; } break; } } } //----------------------------------------------------------------------------- */ void TContentPanel::BeginBrush( TCommonItem* pBrushItem ) { if( m_iMode==VIEW_STYLE ){ m_pItem = pBrushItem; SelectTrack( -1, -1, -1 ); if( m_bVertical ) SelectBars( -1, -1 ); else SelectRange( -1, -1, -1, -1 ); } m_bBrush = true; SetCapture( Handle ); } //----------------------------------------------------------------------------- void TContentPanel::CancelBrush() { m_bBrush = false; m_pItem = NULL; } //----------------------------------------------------------------------------- void TContentPanel::HandleBrush() { if( m_iMode==VIEW_STYLE ){ if( !m_pItem ) return; if( m_bPlaying ) Parent->Perform( UM_STOP, STOP_CONTENT, 0 ); // 计算实际有效的起止位置 int iStartBar = m_iSelBarStart, iEndBar = m_iSelBarEnd, iFStage = g_Opus.FindStage( iStartBar, NULL ), iLStage = g_Opus.FindStage( iEndBar, NULL ); iStartBar = -1; iEndBar = -1; for( int i=iFStage; i<=iLStage; i++ ){ if( m_pItem->iType==SEGTYPE_TRACK && g_lstOpusStages[i]->iSegType==((TTrackItem*)m_pItem)->GetSegType() || m_pItem->iType==SEGTYPE_SEGMENT && g_lstOpusStages[i]->iSegType<=SEGTYPE_FILL ){ int iFBar = g_Opus.StageFirstBar( i ); if( iFBar > m_iSelBarStart ) iStartBar = iFBar; else iStartBar = m_iSelBarStart; break; } } if( iStartBar>=0 ){ for( int i=iLStage; i>=iFStage; i-- ){ if( m_pItem->iType==SEGTYPE_TRACK && g_lstOpusStages[i]->iSegType==((TTrackItem*)m_pItem)->GetSegType() || m_pItem->iType==SEGTYPE_SEGMENT && g_lstOpusStages[i]->iSegType<=SEGTYPE_FILL ){ int iLBar = g_Opus.StageLastBar( i ); if( iLBar > m_iSelBarEnd ) iEndBar = m_iSelBarEnd; else iEndBar = iLBar; break; } } } if( iStartBar<0 || iEndBar<0 || iStartBar>iEndBar ){ SelectBars( -1, -1 ); return; } if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd ) SelectBars( iStartBar, iEndBar ); if( m_pItem->iType==SEGTYPE_TRACK ){ int iTrack = -1; TTrackItem* pTrkItem = (TTrackItem*)m_pItem; TTrack subTrk( pTrkItem->pTrack ); if( m_iSelTrack<0 ){ bool bAdd = true; if( subTrk.iChanNo==9 ){ for( int i=0; iIsDrum() ){ subTrk.iFile = pMT->file; subTrk.iBank = pMT->bank; subTrk.iChanSpec = pMT->chno; subTrk.iProg = pMT->prog; iTrack = i; bAdd = false; break; } } } if( bAdd ){ subTrk.iFile = 0xFF; subTrk.iChanSpec = subTrk.iChanNo; } } else if( m_aTracks[m_iSelTrack]->type==ST_MIDI ){ TMidiTrack* pMT = (TMidiTrack*)m_aTracks[m_iSelTrack]->pTrack; subTrk.iFile = pMT->file; subTrk.iBank = pMT->bank; subTrk.iChanSpec = pMT->chno; subTrk.iProg = pMT->prog; iTrack = m_aTracks[m_iSelTrack]->index; } ((TUseStylePanel*)m_pStylePanel)->ChangeTexture( iStartBar, iEndBar, pTrkItem->GetSegType(), iTrack, &subTrk, SEGTYPE_TRACK ); } else ((TUseStylePanel*)m_pStylePanel)->ReformBars( m_iSelBarStart, m_iSelBarEnd, (TSegmentItem*)m_pItem ); } } //----------------------------------------------------------------------------- void TContentPanel::GetSelectChord( int& iBarKey, int& iChordKey, int& iChordType ) { int key=-1, type=-1, barKey=-1; if( m_iSelBarStart>=0 && m_iSelCellStart>=0 ){ int iFirstBar, iStage = FindStage( m_iSelBarStart, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; TBar* pBar = pStage->aBars[m_iSelBarStart-iFirstBar]; type = pBar->aChords.iType[m_iSelCellStart]; key = pBar->aChords.iKey[m_iSelCellStart]; barKey = pBar->iBarKey; if( m_iSelBarEnd>m_iSelBarStart || m_iSelCellEnd>m_iSelCellStart ){ int iBar = m_iSelBarStart, iCell = m_iSelCellStart; while( iBar=g_nChordNumPerBar ){ iCell = 0; iBar++; if( iBar>=iFirstBar+pStage->aBars.size() ){ iStage = FindStage( iBar, &iFirstBar ); pStage = g_lstOpusStages[iStage]; } pBar = pStage->aBars[iBar-iFirstBar]; if( barKey!=pBar->iBarKey ){ barKey = key = type = -1; break; } } if( key!=pBar->aChords.iKey[iCell] || type!=pBar->aChords.iType[iCell] ){ barKey = key = type = -1; break; } } } } iChordKey = key; iChordType = type; iBarKey = barKey; } //--------------------------------------------------------------------------- bool TContentPanel::SetSelectChord( int iKey, int iChordType ) { if( m_iSelBarStart>=0 && m_iSelCellStart>=0 && ( m_iSelBarEnd>m_iSelBarStart || m_iSelBarEnd==m_iSelBarStart && m_iSelCellEnd>=m_iSelCellStart )){ int iFirstBar, iStage = FindStage( m_iSelBarStart, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; int iBar = m_iSelBarStart, iCell = m_iSelCellStart, iEndBar = m_iSelBarEnd, iCellEnd = m_iSelCellEnd; if( iBar==m_iSelBarEnd && iCell==m_iSelCellEnd //仅选中1拍 && iCellaBars[iBar-iFirstBar]->aChords.iKey[iCell], iOriType = pStage->aBars[iBar-iFirstBar]->aChords.iType[iCell]; if( pStage->aBars[iBar-iFirstBar]->aChords.iKey[i]==iOriKey && pStage->aBars[iBar-iFirstBar]->aChords.iType[i]==iOriType ) iCellEnd++; else break; } } int iUndo = 0, iSelChordNum = (iEndBar - iBar - 1) * g_nChordNumPerBar + (g_nChordNumPerBar - iCell) + (iCellEnd + 1); BYTE *pBefore = new BYTE[iSelChordNum], *pAfter = new BYTE[iSelChordNum]; while( iBaraBars[iSBar]->aChords.iKey[iCell]<<4) + pStage->aBars[iSBar]->aChords.iType[iCell]; pAfter[iUndo] = (iKey<<4) + iChordType; iUndo++; pStage->aBars[iSBar]->aChords.iKey[iCell] = iKey; pStage->aBars[iSBar]->aChords.iType[iCell] = iChordType; if( g_iPreStage==0 ){ //初始化模式时须修改原始和弦 TOpusStage* pRawStage = g_Theme.StageList()[iStage]; pRawStage->aBars[iSBar]->aChords.iKey[iCell] = iKey; pRawStage->aBars[iSBar]->aChords.iType[iCell] = iChordType; } iCell++; if( iCell>=g_nChordNumPerBar ){ InvalidateBar( iBar, 0, m_nBarWidth, BAR_DATA ); iCell = 0; iBar++; iStage = FindStage( iBar, &iFirstBar ); pStage = g_lstOpusStages[iStage]; } } if( iBar==iEndBar && iCell=0 ){ pTrack = m_aTracks[iTrack]; if( pTrack->type==ST_AUDIO && iBar<0 ){ iBar = 0; iPoint = 0; } } if( m_iSelTrack==iTrack && m_iSelTrackBar==iBar && m_iSelTrackPoint==iPoint ) return; int iAudio = pTrack && pTrack->type==ST_AUDIO ? pTrack->index : -1, iMidi = pTrack && pTrack->type==ST_MIDI ? pTrack->index : -1; if( m_iSelTrack!=iTrack ){ if( m_iSelTrack>=m_iBeginShowTrack && m_iSelTrack-m_iBeginShowTrack ClientHeight - m_nBottomBound ) nH = ClientHeight - m_nBottomBound - top; RECT rectOld; SetRect( &rectOld, m_nLeftOriBound, top, m_nLeftBound-4, top + nH ); InvalidateRect( Handle, &rectOld, false ); } } m_iSelTrack = iTrack; g_iSelAudio = iAudio; g_iSelMidiTrack = iMidi; if( iTrack>=0 ){ if( iTrack=m_nTrackShow ){ if( !m_bVertical ){ int nPos = iTrack ClientHeight - m_nBottomBound ) nH = ClientHeight - m_nBottomBound - top; RECT rectNew; SetRect( &rectNew, m_nLeftOriBound, top, m_nLeftBound-4, top + nH ); InvalidateRect( Handle, &rectNew, false ); } } } if( ( !w_bDraging || m_iDragAudio>=0 ) && m_pTrackPanel && m_pTrackPanel->Visible ){ ((TTrackPanel*)m_pTrackPanel)->SetSelTrack( pTrack ? pTrack->type : -1, pTrack ? pTrack->index : -1 ); } } else if( pTrack && pTrack->type==ST_AUDIO ){ if( m_iSelTrackBar>=0 ){ int iRow = m_bVertical ? m_iSelTrackBar / m_nColumnNum - m_iBeginShowRow : 0, iCol = m_bVertical ? m_iSelTrackBar % m_nColumnNum : m_iSelTrackBar - m_iBeginShowBar; if( iRow>=0 && iRow=0 && iCol ClientHeight - m_nBottomBound ) nH = ClientHeight - m_nBottomBound - top; RECT rectOld; SetRect( &rectOld, left, top, left + 1, top + nH ); InvalidateRect( Handle, &rectOld, false ); } } if( iBar>=0 ){ int iRow = m_bVertical ? iBar / m_nColumnNum - m_iBeginShowRow : 0, iCol = m_bVertical ? iBar % m_nColumnNum : iBar - m_iBeginShowBar; if( iRow>=0 && iRow=0 && iCol ClientHeight - m_nBottomBound ) nH = ClientHeight - m_nBottomBound - top; for( int i=0; iPixels[left][top + i] = clrInsertLine; } } } } m_iSelTrackBar = iBar; m_iSelTrackPoint = iPoint; } //--------------------------------------------------------------------------- void TContentPanel::SelectRange( int iBarStart, int iPointStart, int iBarEnd, int iPointEnd, bool bInvalid ) { if( iBarStart==0 && iPointStart<5 ){ iPointStart = 0; } if( (m_iDragAudio<0 || g_iSelAudio==m_iDragAudio) && m_iSelBarStart==iBarStart && m_iSelPointStart==iPointStart && m_iSelBarEnd==iBarEnd && m_iSelPointEnd==iPointEnd){ if( bInvalid && m_iSelTrack>=0 ){ InvalidateBars( iBarStart, iBarEnd, BAR_TRACK | (m_iSelTrack+1) ); } return; } if( m_iSelTrack<0 ){ m_iSelTrackBar = m_iSelTrackPoint = -1; return; } int iTrack = m_iSelTrack + 1;// GetShowTrackId( ST_AUDIO, g_iSelAudio )<<8; if( iBarStart>=0 ){ m_iSelTrackBar = iBarStart; m_iSelTrackPoint = iPointStart; } else if( iBarEnd>=0 ){ m_iSelTrackBar = m_iSelTrackPoint = 0; } if( m_iDragAudio>0 && g_iSelAudio!=m_iDragAudio || bInvalid ){ m_iSelPointStart = iPointStart; m_iSelPointEnd = iPointEnd; SelectBars( iBarStart, iBarEnd ); InvalidateBars( iBarStart, iBarEnd, BAR_TRACK | iTrack ); } else if( iBarStart!=m_iSelBarStart || iBarEnd!=m_iSelBarEnd ){ int iOldBarStart = m_iSelBarStart, iOldBarEnd = m_iSelBarEnd; m_iSelPointStart = iPointStart; m_iSelPointEnd = iPointEnd; SelectBars( iBarStart, iBarEnd ); int iInvBarEnd = min( iOldBarStart, iBarStart ); if( iInvBarEnd<0 ) iInvBarEnd = max( iOldBarStart, iBarStart ); if( iInvBarEnd>=0 ) InvalidateBars( 0, iInvBarEnd, BAR_TRACK | iTrack ); int iInvBarStart = max( iOldBarEnd, iBarEnd ); if( iInvBarStart<0 ) iInvBarStart = iInvBarEnd; if( iInvBarStart>=0 ) InvalidateBars( iInvBarStart, m_nBarNum-1, BAR_TRACK | iTrack ); } else if( iBarStart==iBarEnd ){ m_iSelPointStart = iPointStart; m_iSelPointEnd = iPointEnd; InvalidateBar( iBarStart, 0, m_nBarWidth, BAR_TRACK | iTrack ); } else{ if( iPointStart!=m_iSelPointStart ){ int l = min( m_iSelPointStart, iPointStart ), r = max( m_iSelPointStart, iPointStart ); m_iSelPointStart = iPointStart; InvalidateBar( iBarStart, l, r, BAR_TRACK | iTrack ); } if( iPointEnd!=m_iSelPointEnd ){ int l = min( m_iSelPointEnd, iPointEnd ), r = max( m_iSelPointEnd, iPointEnd ); m_iSelPointEnd = iPointEnd; InvalidateBar( iBarEnd, l, r, BAR_TRACK | iTrack ); } } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoSelectAll(System::TObject* Sender) { if( m_nBarNum==0 ) return; if( m_iMode==VIEW_TRACK ){ SelectRange( 0, 0, m_nBarNum-1, m_nDataWidth-1 ); } else if( m_iMode==VIEW_STYLE ){ SelectBars( 0, m_nBarNum-1 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoCancelAll(System::TObject* Sender) { if( m_iMode==VIEW_CHORD ){ SelectCells( -1, -1, -1, -1 ); SelectCopyCells( -1, -1, -1, -1 ); } else if( m_iMode==VIEW_TRACK ){ SelectRange( -1, -1, -1, -1 ); SelectCopyPos( -1, -1, -1, -1 ); } else if( m_iMode==VIEW_STYLE ){ SelectBars( -1, -1 ); SelectCopyBars( -1, -1 ); } ReleaseCapture(); m_bDragReady = false; m_bDraging = false; m_bBrush = false; m_iMouseDownBar = m_iMouseDownPoint = -1; m_pItem = NULL; } //--------------------------------------------------------------------------- // 复制 void __fastcall TContentPanel::DoBarsCopy(System::TObject* Sender) { if( !m_bDraging && m_iSelBarEnd>=0 ){ bool bSetCopy = false; int iLSBar, iStage = FindStage( m_iSelBarEnd, &iLSBar ); if( g_lstOpusStages[iStage]->iSegType==SEGTYPE_ENDING ){ int iFirstStage = FindStage( m_iSelBarStart, NULL ); if( iFirstStage!=iStage ){ SelectBars( m_iSelBarStart, iLSBar-1 ); bSetCopy = true; } } else{ bSetCopy = true; } if( bSetCopy ) SelectCopyBars( m_iSelBarStart, m_iSelBarEnd, false ); } } //--------------------------------------------------------------------------- // 剪切 void __fastcall TContentPanel::DoBarsCut(System::TObject* Sender) { if( !m_bDraging && m_iSelBarEnd>=0 ){ bool bSetCopy = false; int iLSBar, iStage = FindStage( m_iSelBarEnd, &iLSBar ); if( g_lstOpusStages[iStage]->iSegType==SEGTYPE_ENDING ){ int iFirstStage = FindStage( m_iSelBarStart, NULL ); if( iFirstStage!=iStage ){ SelectBars( m_iSelBarStart, iLSBar-1 ); bSetCopy = true; } } else{ bSetCopy = true; } if( bSetCopy ) SelectCopyBars( m_iSelBarStart, m_iSelBarEnd, true ); } } //--------------------------------------------------------------------------- // 插入 void __fastcall TContentPanel::DoBarsInsert(System::TObject* Sender) { if( !m_bDraging && m_iSelBarStart>=0 && m_iCopyBarStart>=0 ){ int iSelStart = m_iSelBarStart, //iSelEnd = m_iSelBarEnd, iCopyStart = m_iCopyBarStart, iCopyEnd = m_iCopyBarEnd; ((TUseStylePanel*)m_pStylePanel)->MoveBars( iCopyStart, iCopyEnd, iSelStart, m_bCut ? MODE_MOVE : MODE_COPY ); SelectCopyBars( m_iSelBarStart, m_iSelBarEnd ); } } //--------------------------------------------------------------------------- // 删除 void __fastcall TContentPanel::DoBarsDelete(System::TObject* Sender) { if( !m_bDraging && m_iSelBarStart>=0 ){ ((TUseStylePanel*)m_pStylePanel)->MoveBars( m_iSelBarStart, m_iSelBarEnd, -1, MODE_DELETE ); } } //--------------------------------------------------------------------------- // 变调 void __fastcall TContentPanel::DoBarsChangeKey(System::TObject* Sender) { if( !m_bDraging ){ int iKey = (int)Sender; if( iKey<0 ) return; int* arrKeys = new int[m_iSelBarEnd-m_iSelBarStart+1]; GetBarKeys( m_iSelBarStart, m_iSelBarEnd, arrKeys ); g_Undo.AddUndo( UNDO_KEY_BARS, 0, m_iSelBarStart, m_iSelBarEnd, arrKeys, (void*)iKey ); ChangeBarsKey( m_iSelBarStart, m_iSelBarEnd, iKey, NULL ); } } //--------------------------------------------------------------------------- void TContentPanel::GetBarKeys( int iBarStart, int iBarEnd, int arrKeys[] ) { /* if( g_iPreStage==0 ){ for( int i=iBarStart; i<=iBarEnd; i++ ){ arrKeys[i] = g_lstRawBars[i]->iBarKey; } } else{ */ int iBar = iBarStart; while( iBar<=iBarEnd ){ int iFirstBar, iStage = FindStage( iBar, &iFirstBar ); TOpusStage* pStage = g_lstOpusStages[iStage]; int iStart = max( iBar, iFirstBar ), iEnd = min( iBarEnd, (int)(iFirstBar + pStage->aBars.size() - 1) ); for( int i = iStart; i<=iEnd; i++ ){ arrKeys[iBar-iBarStart] = pStage->iSegType>=SEGTYPE_INTRO ? pStage->iSegKey : pStage->aBars[i-iFirstBar]->iBarKey; } iBar = iEnd + 1; } // } } //--------------------------------------------------------------------------- void TContentPanel::SelectCopyBars( int iBarStart, int iBarEnd, bool bCut ) { m_bCut = bCut; if( m_iCopyBarStart==iBarStart && m_iCopyBarEnd==iBarEnd ) return; int iOldBarStart = m_iCopyBarStart, iOldBarEnd = m_iCopyBarEnd; m_iCopyBarStart = iBarStart; m_iCopyBarEnd = iBarEnd; if( iBarStart<0 && iBarEnd<0 ){ m_iCopyCellStart = m_iCopyCellEnd = -1; m_iCopyPointStart = m_iCopyPointEnd = -1; } if( iOldBarStart>=0 ){ if( iBarStart>=0 ){ if( iBarStart<=iOldBarEnd || iBarEnd>=iOldBarStart ){ int iStart = min( iBarStart, iOldBarStart ), iEnd = max( iBarEnd, iOldBarEnd ); InvalidateBars( iStart, iEnd, BAR_TITLE|BAR_DATA|BAR_TRACK ); } else{ InvalidateBars( iOldBarStart, iOldBarEnd, BAR_TITLE|BAR_DATA|BAR_TRACK ); InvalidateBars( iBarStart, iBarEnd, BAR_TITLE|BAR_DATA|BAR_TRACK ); } } else{ InvalidateBars( iOldBarStart, iOldBarEnd, BAR_TITLE|BAR_DATA|BAR_TRACK ); } } else if( iBarStart>=0 ){ InvalidateBars( iBarStart, iBarEnd, BAR_TITLE|BAR_DATA|BAR_TRACK ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoChordCopy(System::TObject* Sender) { if( !m_bDraging && m_iSelBarStart>=0 ){ SelectCopyCells( m_iSelBarStart, m_iSelCellStart, m_iSelBarEnd, m_iSelCellEnd ); } } //--------------------------------------------------------------------------- void TContentPanel::ChordPaste( int key[], int type[], int len, bool bAddUndo ) { BYTE *pBefore=NULL, *pAfter=NULL; int iSelChordNum = (m_iSelBarEnd - m_iSelBarStart - 1) * g_nChordNumPerBar + (g_nChordNumPerBar - m_iSelCellStart) + (m_iSelCellEnd + 1); int iCell, iStage, iBarCount, iBar, iBarFirst, index = 0, iUndo=0; iCell = m_iSelCellStart; iBar = m_iSelBarStart; iStage = FindStage(iBar, &iBarFirst); TOpusStage *pStage = g_lstOpusStages[iStage]; iBarCount = pStage->aBars.size(); int iSBar = iBar - iBarFirst; TBar *pBar = pStage->aBars[iSBar]; if( bAddUndo ){ pBefore = new BYTE[iSelChordNum]; pAfter = new BYTE[iSelChordNum]; } while(iSelChordNum--){ if( pBefore && pAfter ){ pBefore[iUndo] = ( pBar->aChords.iKey[iCell]<<4 ) + pBar->aChords.iType[iCell]; pAfter[iUndo] = ( key[index]<<4 ) + type[index]; iUndo++; } pBar->aChords.iKey[iCell] = key[index]; pBar->aChords.iType[iCell] = type[index]; if( g_iPreStage==0 ){ //初始化模式时须修改原始和弦 TOpusStage* pRawStage = g_Theme.StageList()[iStage]; pRawStage->aBars[iSBar]->aChords.iKey[iCell] = key[index]; pRawStage->aBars[iSBar]->aChords.iType[iCell] = type[index]; } index++; if(index == len) index = 0; // 重复粘贴 iCell++; if(iCell >= g_nChordNumPerBar){ iCell = 0; iBar++; if((iBar - iBarFirst) >= iBarCount){ if( ++iStage>=g_lstOpusStages.size() ) break; iBarFirst = FirstBar(iStage); pStage = g_lstOpusStages[iStage]; iBarCount = pStage->aBars.size(); } iSBar = iBar - iBarFirst; pBar = pStage->aBars[iSBar]; } } if( bAddUndo ){ int iBegin = MAKELONG( m_iSelCellStart, m_iSelBarStart ), iEnd = MAKELONG( m_iSelCellEnd, m_iSelBarEnd ); g_Undo.AddUndo( UNDO_CHORD, 0, iBegin, iEnd, (void*)pBefore, (void*)pAfter ); } InvalidateBars( m_iSelBarStart, m_iSelBarEnd ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoChordPaste(System::TObject* Sender) { if( m_bDraging || m_iSelBarStart<0 || m_iCopyBarStart<0 ) return; else if( m_iCopyBarStart==m_iSelBarStart && m_iCopyCellStart==m_iSelCellStart )// 不粘贴 return; int iChordNum = (m_iCopyBarEnd - m_iCopyBarStart - 1) * g_nChordNumPerBar + (g_nChordNumPerBar - m_iCopyCellStart) + (m_iCopyCellEnd + 1); int *iKey = new int[iChordNum]; int *iType = new int[iChordNum]; int iCell, iStage, iBarCount, iBar, iBarFirst; TOpusStage *pStage = NULL; TBar *pBar = NULL; iCell = m_iCopyCellStart; iBar = m_iCopyBarStart; iStage = FindStage(iBar, &iBarFirst); pStage = g_lstOpusStages[iStage]; iBarCount = pStage->aBars.size(); pBar = pStage->aBars[iBar - iBarFirst]; for(int i = 0; i < iChordNum; i++) { iKey[i] = pBar->aChords.iKey[iCell]; iType[i] = pBar->aChords.iType[iCell]; iCell++; if(iCell >= g_nChordNumPerBar){ iCell = 0; iBar++; if((iBar - iBarFirst) >= iBarCount){ if( ++iStage>=g_lstOpusStages.size() ) break; iBarFirst = FirstBar(iStage); pStage = g_lstOpusStages[iStage]; iBarCount = pStage->aBars.size(); } pBar = pStage->aBars[iBar - iBarFirst]; } } ChordPaste(iKey, iType, iChordNum); delete[] iKey; delete[] iType; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoChordDelete(System::TObject* Sender) { if( m_bDraging || m_iSelBarStart<0 ) return; int iBar = -1, iCell = -1; TOpusStage *pStage = NULL; TBar *pBar = NULL; if(m_iSelCellStart > 0) { iBar = m_iSelBarStart; iCell = m_iSelCellStart - 1; } else { iBar = m_iSelBarStart - 1; iCell = g_nChordNumPerBar - 1; } if( iBar>=0 ){ int iBarFirst, iStage = FindStage(iBar, &iBarFirst); if( iStage>=0 ){ pStage = g_lstOpusStages[iStage]; if( pStage->iSegType<=SEGTYPE_FILL ){ pBar = pStage->aBars[iBar - iBarFirst]; int iKey = pBar->aChords.iKey[iCell], iType = pBar->aChords.iType[iCell]; SetSelectChord( iKey, iType ); } } } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::CreateEditMenu(TMenuPanel *Menu, bool bEnabled) { if( g_Opus.BarCount()==0 || !bEnabled ) return; if(m_iMode == VIEW_CHORD){ Menu->CreateMenu("-"); CMenuItem* pMenuItem = Menu->CreateMenu( "复制和弦", "Ctrl+C", DoChordCopy ); pMenuItem->Enabled = m_iSelBarStart>=0; pMenuItem = Menu->CreateMenu( "粘贴和弦", "Ctrl+V", DoChordPaste ); pMenuItem->Enabled = m_iSelBarStart>=0 && m_iCopyBarStart>=0; Menu->CreateMenu("-"); pMenuItem = Menu->CreateMenu( "与前一和弦相同", "Ctrl+Del", DoChordDelete ); bool bCanDelete = false; if( m_iSelCellStart != -1 ){ int iFirstBar, iSelStage = FindStage( m_iSelBarStart, &iFirstBar ); if( m_iSelBarStart!=iFirstBar ){ bCanDelete = true; } else if(m_iSelBarStart==iFirstBar && m_iSelCellStart > 0){ bCanDelete = true; } else if(iSelStage > 0){ TOpusStage *pPreStage = g_lstOpusStages[iSelStage-1]; if( pPreStage->iSegType<=SEGTYPE_FILL ){ bCanDelete = true; } } } pMenuItem->Enabled = bCanDelete; } else if(m_iMode == VIEW_STYLE){ Menu->CreateMenu("-"); bool bSel = m_iSelBarStart>=0; bool bCanCopy = bSel; if( m_iSelBarEnd>=0 ){ int iStage = FindStage( m_iSelBarEnd, NULL ); if( g_lstOpusStages[iStage]->iSegType==SEGTYPE_ENDING ) bCanCopy = false; } CMenuItem* pMenuItem = Menu->CreateMenu( "复制小节", "Ctrl+C", DoBarsCopy ); pMenuItem->Enabled = bSel && bCanCopy; pMenuItem = Menu->CreateMenu( "剪切小节", "Ctrl+X", DoBarsCut ); pMenuItem->Enabled = bSel && bCanCopy; Menu->CreateMenu( "-" ); pMenuItem = Menu->CreateMenu( "插入空小节","Ctrl+Ins",DoInsertBlankBar ); pMenuItem->Enabled = bSel; if( m_iCopyBarStart>=0 ){ String strText = "插入"; strText += m_bCut ? "剪切的小节" : "复制的小节"; pMenuItem = Menu->CreateMenu( strText,"Ctrl+V",DoBarsInsert ); pMenuItem->Enabled = bSel && m_iCopyBarStart>=0; } pMenuItem = Menu->CreateMenu( "删除所选小节", "Ctrl+Del", DoBarsDelete ); pMenuItem->Enabled = bSel; Menu->CreateMenu("-"); pMenuItem = Menu->CreateMenu( "改变所选小节调号" ); pMenuItem->Enabled = bSel; if( bSel ){ for( int i=0; iAppendMenu( g_strMelodyKey[i], "", DoBarsChangeKey, i ); } } Menu->CreateMenu("-"); pMenuItem = Menu->CreateMenu( "全选", "Ctrl+A", DoSelectAll ); pMenuItem->Enabled = m_nBarNum>0; } else{ Menu->CreateMenu("-"); String strMute = "所选轨道静音", strSolo = "所选轨道独奏"; if( m_iSelTrack>=0 ){ bool bMute = m_aTracks[m_iSelTrack]->pTrack->IsMute(), bSolo = m_aTracks[m_iSelTrack]->pTrack->IsSolo(); if( bMute ) strMute = "取消" + strMute; if( bSolo ) strSolo = "取消" + strSolo; } CMenuItem* pMenuItem = Menu->CreateMenu( strMute, "", DoTrackMute ); pMenuItem->Enabled = m_iSelTrack>=0; pMenuItem = Menu->CreateMenu( strSolo, "",DoTrackSolo ); pMenuItem->Enabled = m_iSelTrack>=0; pMenuItem = Menu->CreateMenu( "删除所选轨道", "", DoTrackDel, IDM_TRKSHOW+m_iSelTrack ); pMenuItem->Enabled = m_iSelTrack>=0; pMenuItem = Menu->CreateMenu( "隐藏所选轨道", "", DoTrackHide, IDM_TRKSHOW+m_iSelTrack ); pMenuItem->Enabled = m_iSelTrack>=0; Menu->CreateMenu("-"); pMenuItem = Menu->CreateMenu( "全选", "Ctrl+A", DoSelectAll ); pMenuItem->Enabled = m_iSelTrack>=0; if( m_iSelTrack>=0 ){ if( m_aTracks[m_iSelTrack]->type==ST_AUDIO ){ pMenuItem = Menu->CreateMenu( "复制所选音频", "Ctrl+C", DoAudioCopy ); pMenuItem->Enabled = m_iSelBarStart>=0 || m_iSelBarEnd>=0; pMenuItem = Menu->CreateMenu( "剪切所选音频", "Ctrl+X", DoAudioCut ); pMenuItem->Enabled = m_iSelBarStart>=0 || m_iSelBarEnd>=0; pMenuItem = Menu->CreateMenu( "删除所选音频", "Ctrl+Del", DoAudioDelete ); pMenuItem->Enabled = m_iSelBarStart>=0 || m_iSelBarEnd>=0; if( m_iCopyBarStart>=0 ){ Menu->CreateMenu("-"); String strText = "粘贴"; strText += m_bCut ? "剪切的音频" : "复制的音频"; pMenuItem = Menu->CreateMenu( strText, "Ctrl+V", DoAudioPaste ); } Menu->CreateMenu("-"); Menu->CreateMenu( "设为录音起点", "", DoSetSelPosStart ); Menu->CreateMenu( "设为录音终点", "", DoSetSelPosEnd ); pMenuItem = Menu->CreateMenu( "取消录音起点", "", DoDelSelPosStart ); pMenuItem->Enabled = m_iSelBarStart>=0; pMenuItem = Menu->CreateMenu( "取消录音终点", "", DoDelSelPosEnd ); pMenuItem->Enabled = m_iSelBarEnd>=0; Menu->CreateMenu("-"); Menu->CreateMenu( "插入音频片段...", "Ctrl+Ins", DoAudioLoad ); bool bSP = m_iSelBarStart>=0 || m_iSelBarEnd>=0; CMenuItem *pMSPFx = NULL, *pMSPVst = NULL, *pMSP = Menu->CreateMenu( "局部音效处理" ), *pMAdd = Menu->CreateMenu( "添加轨道音效" ), *pMAddFx = pMAdd->AppendMenu( "Fx音效" ), *pMAddVst = pMAdd->AppendMenu( "VST音效" ); pMSP->Enabled = bSP; pMAddVst->Enabled = !g_lstVSTFx.empty(); if( bSP ){ pMSPFx = pMSP->AppendMenu( "Fx音效" ); pMSPVst = pMSP->AppendMenu( "VST音效" ); pMSPVst->Enabled = !g_lstVSTFx.empty(); } for( int i=0; iAppendMenu( g_strEffect[i], "", DoAudioFxProcess, i ); if( iAppendMenu( g_strEffect[i], "", DoAudioAddFx, i ); } if( !g_lstVSTFx.empty() ){ for( int i=0; istrFileName, '\\' )+1, *ext = strrchr( pVST->strFileName, '.' ); if( ext>name ){ strncpy( fname, name, ext-name ); fname[ext-name] = '\0'; } else strcpy(fname, name ); if( !pVST->aPlugins.empty() ) strcat( fname, " ..." ); if( pMSPVst ) pMSPVst->AppendMenu( fname, "", DoAudioVstProcess, i ); pMAddVst->AppendMenu( fname, "", DoAudioAddVst, i ); } } } else{ bool bContent=false, bSwitch=false, bInsert=true; if( m_iSelBarStart>=0 && m_iSelBarEnd>0 ){ TMidiTrack* pMT = (TMidiTrack*)m_aTracks[m_iSelTrack]->pTrack; int iBStage = FindStage( m_iSelBarStart, NULL ), iEStage = FindStage( m_iSelBarEnd, NULL ); for( int i=iBStage; i<=iEStage; i++ ){ TOpusStage* pStage = g_lstOpusStages[i]; if( !bSwitch && pStage->iSegType<=SEGTYPE_FILL ) bSwitch = true; if( bInsert && pMT->IsDrum() && pStage->aTracks[0]->iChanNo==9 ) bInsert = false; } for( int i=0; iaStages.size(); i++ ){ int s = pMT->aStages[i]; if( s>=iBStage && s<=iEStage ){ bContent = true; break; } else if( s>iEStage ){ break; } } } pMenuItem = Menu->CreateMenu( "插入织体...", "Ctrl+Ins", DoInsertTexture ); pMenuItem->Enabled = !bContent && bSwitch && bInsert; pMenuItem = Menu->CreateMenu( "删除所选织体", "Ctrl+Del", DoDeleteTexture ); pMenuItem->Enabled = bContent; pMenuItem = Menu->CreateMenu( "更换所选织体...", "", DoSwitchTexture ); pMenuItem->Enabled = bContent && bSwitch; pMenuItem = Menu->CreateMenu( "更换所选乐器/音色...", "", DoSwitchFontProg ); pMenuItem->Enabled = bContent; pMenuItem = Menu->CreateMenu( "更换轨道织体...", "", DoTrackSwitchTexture ); pMenuItem->Enabled = bContent && bSwitch; pMenuItem = Menu->CreateMenu( "更换轨道乐器/音色...", "", DoTrackSwitchFontProg ); } } } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::CreateTrackMenu(TMenuPanel *pMenu, bool bEnabled) { CMenuItem* pMenuItem = pMenu->CreateMenu( "新增" ); pMenuItem->Enabled = bEnabled && m_nBarNum; if( pMenuItem->Enabled ){ CMenuItem* pSubMenu = pMenuItem->AppendMenu( "音频轨道", "", DoTrackAdd, ST_AUDIO ); pSubMenu->Enabled = g_aAudioTracks.size()AppendMenu( "MIDI轨道...", "", DoTrackAdd, ST_MIDI ); pSubMenu->Enabled = !m_bVertical; } pMenuItem = pMenu->CreateMenu( "删除" ); pMenuItem->Enabled = bEnabled && m_nBarNum; if( pMenuItem->Enabled ){ CMenuItem* pSubMenu = pMenuItem->AppendMenu( "全部音频轨道", "", DoTrackDel, ST_AUDIO ); pSubMenu->Enabled = g_iPreStage==0 && !g_aAudioTracks[0]->lstBars.empty() || g_iPreStage!=0 && g_aAudioTracks.size()>1; pSubMenu = pMenuItem->AppendMenu( "全部MIDI轨道", "", DoTrackDel, ST_MIDI ); pSubMenu->Enabled = !m_bVertical && !g_Midi.IsEmpty(); } pMenuItem = pMenu->CreateMenu( "隐藏" ); pMenuItem->Enabled = bEnabled && m_nBarNum; if( pMenuItem->Enabled ){ CMenuItem* pSubMenu = pMenuItem->AppendMenu( "全部音频轨道", "", DoTrackHide, ST_AUDIO ); bool bCanDo = false; if( g_iPreStage==0 ){ if( !g_aAudioTracks[0]->lstBars.empty() && !g_aAudioTracks[0]->IsHide() ) bCanDo = true; } else{ for( int i=1; iIsHide() ){ bCanDo = true; break; } } } pSubMenu->Enabled = bCanDo; pSubMenu = pMenuItem->AppendMenu( "全部MIDI轨道", "", DoTrackHide, ST_MIDI ); bCanDo = false; if( !m_bVertical ){ for( int i=0; iIsHide() ){ bCanDo = true; break; } } } pSubMenu->Enabled = bCanDo; } pMenuItem = pMenu->CreateMenu( "显示" ); pMenuItem->Enabled = bEnabled && m_nBarNum; if( pMenuItem->Enabled ){ bool bHasSubAudio = false, bHasSubMidi = false; String strText; CMenuItem *pAudioMenu = pMenuItem->AppendMenu( "全部音频轨道", "", DoTrackShow, ST_AUDIO ), *pMidiMenu = pMenuItem->AppendMenu( "全部MIDI轨道", "", DoTrackShow, ST_MIDI ); /*////////////////////////////////////////////////// // test code pMenuItem->AppendMenu( "-" ); for( int i=0; i<25; i++ ){ strText = "测试音频轨道 " + IntToStr( i ); pMenuItem->AppendMenu( strText ); } pMenuItem->AppendMenu( "-" ); for( int i=0; i<25; i++ ){ strText = "测试MIDI轨道 " + IntToStr( i ); pMenuItem->AppendMenu( strText ); } pMenuItem->AppendMenu( "-" ); for( int i=0; i<25; i++ ){ strText = "测试Other轨道 " + IntToStr( i ); pMenuItem->AppendMenu( strText ); } // /*/////////////////////////////////////////////////// /* for( int i=0; ipTrack->IsHide() ){ if( pST->type==ST_AUDIO ){ if( !bHasSubAudio ){ pMenuItem->AppendMenu( "-" ); bHasSubAudio = true; } int iTrk = pST->index==0 ? 1 : pST->index; strText = "音频轨道 " + IntToStr( iTrk ); pMenuItem->AppendMenu( strText, "", DoTrackShow, IDM_TRKSHOW+i ); } else{ if( !bHasSubMidi ){ pMenuItem->AppendMenu( "-" ); bHasSubMidi = true; } strText = "MIDI轨道 " + IntToStr( pST->index+1 ); pMenuItem->AppendMenu( strText, "", DoTrackShow, IDM_TRKMID+i ); } } } */ if( g_iPreStage!=0 && g_aAudioTracks.size()>1 ){ for (int i = 1; i < g_aAudioTracks.size(); i++) { if( g_aAudioTracks[i]->IsHide() ){ if( !bHasSubAudio ){ pMenuItem->AppendMenu( "-" ); bHasSubAudio = true; } strText = "音频轨道 " + IntToStr( i ); pMenuItem->AppendMenu( strText, "", DoTrackShow, IDM_TRKAUD+i ); } } } else if( g_iPreStage==0 && g_aAudioTracks[0]->IsHide() && !g_aAudioTracks[0]->lstBars.empty() ){ pMenuItem->AppendMenu( "-" ); bHasSubAudio = true; strText = "音频轨道 " + IntToStr( 1 ); pMenuItem->AppendMenu( strText, "", DoTrackShow, IDM_TRKAUD ); } if( !m_bVertical ){ for (int i = 0; i < g_aMidiTracks.size(); i++) { if( g_aMidiTracks[i]->IsHide() ){ if( !bHasSubMidi ){ pMenuItem->AppendMenu( "-" ); bHasSubMidi = true; } strText = "MIDI轨道 " + IntToStr( i+1 ); pMenuItem->AppendMenu( strText, "", DoTrackShow, IDM_TRKMID+i ); } } } pAudioMenu->Enabled = bHasSubAudio; pMidiMenu->Enabled = bHasSubMidi; } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoSetSelPosStart(System::TObject* Sender) { int iHitType = -1; DWORD dwHit = HitTest( ptDown.X, ptDown.Y, iHitType ); int iBarStart = LOWORD(dwHit), iPointStart = HIWORD(dwHit), iBarEnd = m_iSelBarEnd, iPointEnd = m_iSelPointEnd; int iMaxPoint = m_nBarNum * m_nDataWidth - 1, iStartPoint = iBarStart * m_nDataWidth + iPointStart; int minArea = max( 10, (int)( g_nPPB / 4.0 + 0.5 )); if( iStartPoint > iMaxPoint - minArea ){ iStartPoint = iMaxPoint - minArea; iBarStart = iStartPoint / m_nDataWidth; iPointStart = iStartPoint % m_nDataWidth; } if( iBarEnd>=0 ){ int iEndPoint = iBarEnd * m_nDataWidth + iPointEnd; if( iEndPoint > iStartPoint ){ if( iEndPoint < iStartPoint + minArea ){ iEndPoint = iStartPoint + minArea; iBarEnd = iEndPoint / m_nDataWidth; iPointEnd = iEndPoint % m_nDataWidth; } } else{ iBarEnd = -1; iPointEnd = -1; } } SelectRange( iBarStart, iPointStart, iBarEnd, iPointEnd ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoSetSelPosEnd(System::TObject* Sender) { int iHitType = -1; DWORD dwHit = HitTest( ptDown.X, ptDown.Y, iHitType ); int iBarStart = m_iSelBarStart, iPointStart = m_iSelPointStart, iBarEnd = LOWORD(dwHit), iPointEnd = HIWORD(dwHit); int iMinPoint = 0, iEndPoint = iBarEnd * m_nDataWidth + iPointEnd; int minArea = max( 10, (int)( g_nPPB / 4.0 + 0.5 )); if( iEndPoint < iMinPoint + minArea ){ iEndPoint = iMinPoint + minArea; iBarEnd = iEndPoint / m_nDataWidth; iPointEnd = iEndPoint % m_nDataWidth; } if( iBarStart>=0 ){ int iStartPoint = iBarStart * m_nDataWidth + iPointStart; if( iEndPoint > iStartPoint ){ if( iEndPoint < iStartPoint + minArea ){ iStartPoint = iEndPoint - minArea; iBarStart = iStartPoint / m_nDataWidth; iPointStart = iStartPoint % m_nDataWidth; } } else{ iBarStart = -1; iPointStart = -1; } } SelectRange( iBarStart, iPointStart, iBarEnd, iPointEnd ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoDelSelPosStart(System::TObject* Sender) { if( m_iSelBarStart>=0 ){ SelectRange( -1, -1, m_iSelBarEnd, m_iSelPointEnd ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoDelSelPosEnd(System::TObject* Sender) { if( m_iSelBarEnd>=0 ){ SelectRange( m_iSelBarStart, m_iSelPointStart, -1, -1 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoInsertBlankBar(System::TObject* Sender) { if( !m_bDraging && m_iSelBarStart>=0 ){ bool bPreChange = g_iPreStage==0; if( bPreChange ){ DuplicateRawBars(); PostMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); } f_MM_AddUndoBefore( -1, NULL ); ((TUseStylePanel*)m_pStylePanel)->InsertBlankBar( m_iSelBarStart ); if( bPreChange ) InitialVars(); SelectBars( m_iSelBarStart, m_iSelBarStart ); f_MM_AddUndoAfter( -1, NULL ); ((TUseStylePanel*)m_pStylePanel)->SetBarsUndo( UNDO_BAR_INSERT, m_iSelBarStart, 1 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackAdd(System::TObject* Sender) { Parent->Perform( UM_STOP, STOP_CONTENT, 0 ); if( (int)Sender==ST_AUDIO ){ if( g_iPreStage==0 ){ DuplicateRawBars(); PostMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); } TAudioTrack* pTrack = NewAudioTrack( g_Opus.BarCount() ); if( pTrack ){ if( VIEW_TRACK!=m_iMode ) Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 ); InitialVars(); SelectTrack( m_aTracks.size()-1, -1, -1 ); ShowPlayPoint(); } } else{ Parent->Perform( UM_STOP, STOP_USESTYLE, 0 ); ChangeMidiTrack(); ShowPlayPoint(); } } //--------------------------------------------------------------------------- /* void __fastcall TContentPanel::DoTrackAddAudio(System::TObject* Sender) { Parent->Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 ); if( g_iPreStage==0 ){ DuplicateRawBars(); PostMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); // Parent->Perform( UM_STAGECHANGED, 3, 0 ); } TAudioTrack* pTrack = NewAudioTrack( g_Opus.BarCount() ); if( pTrack ){ if( VIEW_TRACK!=m_iMode ) Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 ); InitialVars(); SelectTrack( m_aTracks.size()-1, -1, -1 ); ShowPlayPoint(); // Application->MainForm->Perform( UM_ENABLERECORD, 0, 0 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackAddMidi(System::TObject* Sender) { ChangeMidiTrack(); ShowPlayPoint(); } //--------------------------------------------------------------------------- */ void __fastcall TContentPanel::DoTrackDel(System::TObject* Sender) { if( m_nBarNum==0 ) return; Parent->Perform( UM_STOP, STOP_CONTENT, 0 ); int iType = (int)Sender, index = iTypelstBars.empty() ){ if( g_aAudioTracks[0]->IsSolo() ) bSolo = true; } else if( g_aAudioTracks.size()>1 ){ for (int i = 1; i < g_aAudioTracks.size(); i++) { if( g_aAudioTracks[i]->IsSolo() ) bSolo = true; } } DeleteAudioTrack(-1); InitialVars(); } } else{ Parent->Perform( UM_STOP, STOP_USESTYLE, 0 ); if( !m_bVertical && g_aMidiTracks.size()>0 ){ ((TUseStylePanel*)m_pStylePanel)->DeleteAllTexture(); } } } else{ TShowTrack* pST = m_aTracks[index]; bSolo = pST->pTrack->IsSolo(); if( pST->type==ST_AUDIO ){ DeleteAudioTrack( pST->index ); InitialVars(); } else{ Parent->Perform( UM_STOP, STOP_USESTYLE, 0 ); ((TUseStylePanel*)m_pStylePanel)->ChangeTexture( -1, -1, -1, pST->index, NULL, ST_MIDI ); } } if( bSolo ) SetTrackParams(); SelectTrack( -1, -1, -1 ); ShowPlayPoint(); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackShow(System::TObject* Sender) { int iType = (int)Sender, index = -1; vector* arrIndex = new vector; if( iType>=IDM_TRKMID ){ index = iType - IDM_TRKMID; iType = ST_MIDI; } else if( iType>=IDM_TRKAUD ){ index = iType - IDM_TRKAUD; iType = ST_AUDIO; } if( iType==ST_AUDIO ){ if( g_iPreStage!=0 && g_aAudioTracks.size()>1 ){ for (int i = 1; i < g_aAudioTracks.size(); i++) { if( (index<0 || index==i) && g_aAudioTracks[i]->IsHide() ){ g_aAudioTracks[i]->Hide( false ); arrIndex->push_back( (BYTE)i ); } } } else if( g_iPreStage==0 && index<=0 && g_aAudioTracks[0]->IsHide() && !g_aAudioTracks[0]->lstBars.empty() ){ g_aAudioTracks[0]->Hide( false ); arrIndex->push_back( (BYTE)0 ); } } else{ for (int i = 0; i < g_aMidiTracks.size(); i++) { if( ( index<0 || index==i ) && g_aMidiTracks[i]->IsHide() ){ g_aMidiTracks[i]->Hide( false ); arrIndex->push_back( (BYTE)i ); } } } if( arrIndex->empty() ){ delete arrIndex; } else{ if( index<0 ){ if( iType==ST_AUDIO ) g_Undo.AddUndo( UNDO_TRKAUD_SHOWALL, 0, -1, -1, (void*)arrIndex, NULL ); else g_Undo.AddUndo( UNDO_TRKMID_SHOWALL, 0, -1, -1, (void*)arrIndex, NULL ); } else{ if( iType==ST_AUDIO ) g_Undo.AddUndo( UNDO_TRKAUD_SHOW, 0, -1, -1, (void*)arrIndex, NULL ); else g_Undo.AddUndo( UNDO_TRKMID_SHOW, 0, -1, -1, (void*)arrIndex, NULL ); } InitialVars(); ShowPlayPoint(); if( arrIndex->size()==1 ){ int iShowTrk = (*arrIndex)[0], id = GetShowTrackId( iType, iShowTrk ) - 1; SelectTrack( id, -1, -1 ); } else{ SelectTrack( -1, -1, -1 ); } if( iType==ST_AUDIO ) Application->MainForm->Perform( UM_ENABLERECORD, 0, 0 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackHide(System::TObject* Sender) { int iType = (int)Sender, index = iType* arrIndex = new vector; bool bUnselect = false; if( index<0 ){ for( int i=0; itype==iType && !pST->pTrack->IsHide() ){ pST->pTrack->Hide(true); arrIndex->push_back( pST->index ); if( m_iSelTrack==i ) bUnselect = true; } } } else{ TShowTrack* pST = m_aTracks[index]; iType = pST->type; if( !pST->pTrack->IsHide() ){ pST->pTrack->Hide(true); arrIndex->push_back( pST->index ); if( m_iSelTrack==index ) bUnselect = true; } } if( arrIndex->empty() ){ delete arrIndex; } else{ if( index<0 ){ if( iType==ST_AUDIO ) g_Undo.AddUndo( UNDO_TRKAUD_HIDEALL, 0, -1, -1, (void*)arrIndex, NULL ); else g_Undo.AddUndo( UNDO_TRKMID_HIDEALL, 0, -1, -1, (void*)arrIndex, NULL ); } else{ if( iType==ST_AUDIO ) g_Undo.AddUndo( UNDO_TRKAUD_HIDE, 0, -1, -1, (void*)arrIndex, NULL ); else g_Undo.AddUndo( UNDO_TRKMID_HIDE, 0, -1, -1, (void*)arrIndex, NULL ); } if( bUnselect ) SelectTrack( -1, -1, -1 ); InitialVars(); ShowPlayPoint(); if( iType==ST_AUDIO ) Application->MainForm->Perform( UM_ENABLERECORD, 0, 0 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackMute(System::TObject* Sender) { ((TTrackPanel*)m_pTrackPanel)->OnTrackStateChanged( TRACK_MUTE ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackSolo(System::TObject* Sender) { ((TTrackPanel*)m_pTrackPanel)->OnTrackStateChanged( TRACK_SOLO ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioDelete(System::TObject* Sender) { if( m_bDraging || m_iSelBarStart<0 && m_iSelBarEnd<0 ) return; if( m_bPlaying ) Parent->Perform( UM_STOP, STOP_CONTENT, 0 ); if( m_iSelBarStart<0 ){ m_iSelBarStart = 0; m_iSelPointStart = 0; } if( m_iSelBarEnd<0 ){ m_iSelBarEnd = m_nBarNum-1; m_iSelPointEnd = m_nDataWidth-1; } double dblStartPoint = m_iSelBarStart + (double)m_iSelPointStart / POINTS_PER_BAR, dblEndPoint = m_iSelBarEnd + (double)m_iSelPointEnd / POINTS_PER_BAR; // TAudioTrack* pTrack = g_aAudioTracks[g_iSelAudio]; //Set Undo DWORD* aWave = NULL; if( g_iSelAudio>0 ){ CopyWave( g_iSelAudio, m_iSelBarStart, m_iSelPointStart, m_iSelBarEnd, m_iSelPointEnd, &aWave ); g_Undo.AddUndo( UNDO_AUDIO_ERASE, g_iSelAudio, MAKELONG( m_iSelPointStart, m_iSelBarStart ), MAKELONG( m_iSelPointEnd, m_iSelBarEnd ), (void*)aWave, NULL ); } else{ TAudioTrack* pAudio = CopyAudioTrack( g_iSelAudio, 0, m_nBarNum ); g_Undo.AddUndo( UNDO_AUDIO_ERASE, g_iSelAudio, g_iMelodyKey, -1, (void*)pAudio, NULL ); } f_MM_AddUndoBefore( 1, &g_iSelAudio ); MoveAudio( g_iSelAudio, dblStartPoint, dblEndPoint, -1, -1, MODE_ERASE ); if( g_iSelAudio>0 ){ f_MM_AddUndoAfter( 1, &g_iSelAudio ); InvalidateBars( m_iSelBarStart, m_iSelBarEnd, BAR_TRACK | GetShowTrackId(ST_AUDIO,g_iSelAudio) ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioCopy(System::TObject* Sender) { if( m_bDraging || m_iSelBarStart<0 && m_iSelBarEnd<0 ) return; SelectCopyPos( m_iSelBarStart, m_iSelPointStart, m_iSelBarEnd, m_iSelPointEnd ); m_bCut = false; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioCut(System::TObject* Sender) { if( m_bDraging || m_iSelBarStart<0 && m_iSelBarEnd<0 ) return; SelectCopyPos( m_iSelBarStart, m_iSelPointStart, m_iSelBarEnd, m_iSelPointEnd ); m_bCut = true; } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioPaste(System::TObject* Sender) { if( m_bDraging || g_iSelAudio<0 || m_iSelTrackBar<0 || m_iCopyAudio<0 || m_iCopyBarStart<0 ) return; else if( m_iCopyAudio==g_iSelAudio && m_iCopyBarStart==m_iSelTrackBar && m_iCopyPointStart==m_iSelTrackPoint )// 不粘贴 return; AudioMove( m_iCopyAudio, m_iCopyBarStart, m_iCopyPointStart, m_iCopyBarEnd, m_iCopyPointEnd, m_bCut ); if( m_bCut ){ SelectCopyPos( -1, -1, -1, -1 ); // m_bCut = false; } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioLoad(System::TObject* Sender) { PostMessage( Application->MainForm->Handle, UM_AUDIOLOAD, m_iSelTrackBar, m_iSelTrackPoint ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackSave(System::TObject* Sender) { if( g_iSelAudio>=0 ){ //导出音轨 PostMessage( Application->MainForm->Handle, UM_SAVEPROJECT, SAVE_AUDIO, g_iSelAudio+1 ); } else{ //导出伴奏 PostMessage( Application->MainForm->Handle, UM_SAVEPROJECT, SAVE_COMPOSE, g_iSelMidiTrack+1 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioFxProcess(System::TObject* Sender) { int ind = (int)Sender; OnAudioEffectProcess( g_aAudioEffectTypes[ind] ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioVstProcess(System::TObject* Sender) { int ind = (int)Sender; OnAudioEffectProcess( FX_VST + ind ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioAddFx(System::TObject* Sender) { int ind = (int)Sender; PostMessage( m_pTrackPanel->Handle, UM_AUDIOFX, 0, g_aAudioEffectTypes[ind] ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoAudioAddVst(System::TObject* Sender) { int ind = (int)Sender; PostMessage( m_pTrackPanel->Handle, UM_AUDIOFX, 0, FX_VST+ind ); } //--------------------------------------------------------------------------- void TContentPanel::OnAudioEffectProcess( int iFxType ) { Parent->Perform( UM_STOP, STOP_ALL, 0 ); double dblEditStartBar = 0, dblEditEndBar = m_nBarNum; int iModifyBeginBar = m_iSelBarStart, iModifyBeginPoint = m_iSelPointStart, iModifyEndBar = m_iSelBarEnd, iModifyEndPoint = m_iSelPointEnd; if( iModifyBeginBar>=0 ){ dblEditStartBar = iModifyBeginBar + (double)iModifyBeginPoint/POINTS_PER_BAR; } else{ iModifyBeginBar = 0; iModifyBeginPoint = 0; } if( iModifyEndBar>=0 ){ dblEditEndBar = iModifyEndBar + (double)iModifyEndPoint/POINTS_PER_BAR; } else{ iModifyEndBar = g_Opus.BarCount(); iModifyEndPoint = 0; } int iPlugin = -1; UINT pluginID = 0; char* strVSTFile = NULL; if( iFxType>=FX_VST ){ VSTINFO* pVST = g_lstVSTFx[iFxType-FX_VST]; strVSTFile = pVST->strFileName; if( !pVST->aPlugins.empty() ){ TVSTPluginForm* pPlugForm = new TVSTPluginForm( NULL, pVST ); if( pPlugForm->ShowModal()==mrOk ){ iPlugin = pPlugForm->m_iSel; pluginID = pVST->aPlugins[iPlugin]->id; } delete pPlugForm; if( iPlugin<0 ) return; } } HRESULT hr = f_MM_AudioAddFx( g_iSelAudio, iFxType, strVSTFile, pluginID, true ); if( hr!=S_OK ){ return; } GenerateCompose(); TAudioFxForm * pForm = new TAudioFxForm(NULL, g_iSelAudio, dblEditStartBar, dblEditEndBar, -1, iFxType, iPlugin ); if( pForm->ShowModal()==mrOk ){ // 保存处理前波形 DWORD *aBefore = NULL; CopyWave( g_iSelAudio, iModifyBeginBar, iModifyBeginPoint, iModifyEndBar, iModifyEndPoint, &aBefore ); f_MM_AddUndoBefore( 1, &g_iSelAudio ); TProgressForm * frmProgress = new TProgressForm(NULL); int ret = frmProgress->MM_AudioFxApply( dblEditStartBar, dblEditEndBar ); int eExtra = frmProgress->GetOpertaionResult(); if( ret==mrOk ){ delete frmProgress; f_MM_AddUndoAfter( 1, &g_iSelAudio ); // 获取处理后波形 int iVolBar = iModifyBeginBar, iVolPoint = iModifyBeginPoint, nPoints = ( iModifyEndBar * POINTS_PER_BAR + iModifyEndPoint ) - ( iModifyBeginBar * POINTS_PER_BAR + iModifyBeginPoint ), iPoint = 0; DWORD *aAfter = new DWORD[nPoints]; while( iPoint0 ){ iSP = iVolPoint; if( iSP + nPoints - iPoint < POINTS_PER_BAR ) iEP = iSP + nPoints - iPoint; } else if( nPoints-iPoint < POINTS_PER_BAR ){ iEP = nPoints - iPoint; } if( iEP > iSP ){ TWaveBar* pBar = g_aAudioTracks[g_iSelAudio]->lstBars[iVolBar]; for( int i=iSP; iaVols[i] = f_MM_GetAudioVolume( g_iSelAudio, iVolBar + i/(double)POINTS_PER_BAR ); } if( aAfter ){ memcpy( aAfter + iPoint, pBar->aVols + iSP, sizeof(DWORD)*(iEP-iSP) ); } iVolPoint = 0; iVolBar++; iPoint += iEP - iSP; } else{ break; } } g_Undo.AddUndo( UNDO_AUDIO_FX, g_iSelAudio, MAKELONG( iModifyBeginPoint, iModifyBeginBar ), MAKELONG( iModifyEndPoint, iModifyEndBar ), (void*)aBefore, (void*)aAfter ); InvalidateBars( iModifyBeginBar, iModifyEndBar, BAR_TRACK | (m_iSelTrack+1) ); } else{ f_MM_CancelAddUndo(); if( eExtra!=e_UserCanceled ){ MessageForm->ShowMessage( "局部音效处理未成功!", MB_ICONERROR|MB_OK ); } } } delete pForm; f_MM_AudioMoveFx( g_iSelAudio, -1, -1 ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::OnTrackStateChanged( int iType, int iIndex, BYTE iState, bool bUnset ) { if( m_bVertical || m_aTracks.empty() ) return; int iShowTrack = GetShowTrackId( iType, iIndex ); if( iShowTrack>0 ){ RECT rect; int lBox = iState==TRACK_MUTE ? m_nTrkHdrWidth+MUTE_LEFT : m_nTrkHdrWidth+SOLO_LEFT, tBox = m_nTopBound + m_nRowGapHeight + m_nTitleHeight + m_nChordHeight + SM_TOP + ( iShowTrack - m_iBeginShowTrack - 1 ) * m_nTrackHeight; SetRect( &rect, lBox, tBox, lBox + SM_SIZE, tBox + SM_SIZE ); if( bUnset ){ if( iState==TRACK_MUTE ) rect.right = m_nTrkHdrWidth+SOLO_LEFT + SM_SIZE; else rect.left = m_nTrkHdrWidth+MUTE_LEFT; } InvalidateRect( Handle, &rect, false ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoInsertTexture(TObject* Sender) { if( !Sender ){ bool bContent=false, bSwitch=false, bInsert=true; if( m_iSelTrack>=0 && m_iSelBarStart>=0 && m_iSelBarEnd>0 ){ TMidiTrack* pMT = (TMidiTrack*)m_aTracks[m_iSelTrack]->pTrack; int iBStage = FindStage( m_iSelBarStart, NULL ), iEStage = FindStage( m_iSelBarEnd, NULL ); for( int i=iBStage; i<=iEStage; i++ ){ TOpusStage* pStage = g_lstOpusStages[i]; if( !bSwitch && pStage->iSegType<=SEGTYPE_FILL ) bSwitch = true; if( bInsert && pMT->IsDrum() && pStage->aTracks[0]->iChanNo==9 ) bInsert = false; } for( int i=0; iaStages.size(); i++ ){ int s = pMT->aStages[i]; if( s>=iBStage && s<=iEStage ){ bContent = true; break; } else if( s>iEStage ){ break; } } } if( bContent || !bSwitch || !bInsert ) return; } ChangeMidiTrack( m_iSelTrack>=0 ? m_aTracks[m_iSelTrack]->index : -1, m_iSelBarStart, m_iSelBarEnd ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoDeleteTexture(TObject* Sender) { if( m_iSelTrack>=0 && m_aTracks[m_iSelTrack]->type==ST_MIDI ){ if( !Sender ){ bool bContent=false; if( m_iSelBarStart>=0 && m_iSelBarEnd>0 ){ TMidiTrack* pMT = (TMidiTrack*)m_aTracks[m_iSelTrack]->pTrack; int iBStage = FindStage( m_iSelBarStart, NULL ), iEStage = FindStage( m_iSelBarEnd, NULL ); for( int i=0; iaStages.size(); i++ ){ int s = pMT->aStages[i]; if( s>=iBStage && s<=iEStage ){ bContent = true; break; } else if( s>iEStage ){ break; } } } if( !bContent ) return; } Parent->Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 ); ((TUseStylePanel*)m_pStylePanel)->ChangeTexture( m_iSelBarStart, m_iSelBarEnd, -1, m_aTracks[m_iSelTrack]->index, NULL, ST_MIDI ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoSwitchTexture(TObject* Sender) { if( m_iSelTrack>=0 && m_aTracks[m_iSelTrack]->type==ST_MIDI ){ int iSBar = Sender==NULL ? -1 : m_iSelBarStart, iEBar = Sender==NULL ? -1 : m_iSelBarEnd; ChangeMidiTrack( m_aTracks[m_iSelTrack]->index, iSBar, iEBar ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackSwitchTexture(TObject* Sender) { DoSwitchTexture( NULL ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoSwitchFontProg(TObject* Sender) { if( m_iSelTrack>=0 && m_aTracks[m_iSelTrack]->type==ST_MIDI ){ Parent->Perform( UM_STOP, STOP_ALL, 0 ); TShowTrack* pST = m_aTracks[m_iSelTrack]; TMidiTrack* pMT = g_aMidiTracks[pST->index]; TSwitchProgForm *sPf = new TSwitchProgForm( NULL, pMT->bank, pMT->prog, pMT->chno ); BYTE data[100000]; int len = 100000; int iSBar = Sender==NULL ? -1 : m_iSelBarStart, iEBar = Sender==NULL ? -1 : m_iSelBarEnd; GetMidiTrackData( len, data, pST->index, iSBar, iEBar, &sPf->m_iStartBar, &sPf->m_lenBar ); f_MM_LoadDemo( data, len ); if( sPf->ShowModal() == mrOk ){ BYTE iBank = sPf->m_iFont==g_idFont ? 0xFF : sPf->m_iFont; char iProg = sPf->m_iProg, iChno = sPf->m_iChno; if( iBank!=pMT->bank || iProg!=pMT->prog || iChno!=pMT->chno ){ ((TUseStylePanel*)m_pStylePanel)->ChangeFont( iSBar, iEBar, pST->index, iBank, iProg, iChno, ST_MIDI ); } } delete sPf; f_MM_LoadDemo( NULL, 0 ); } } //--------------------------------------------------------------------------- void __fastcall TContentPanel::DoTrackSwitchFontProg(TObject* Sender) { DoSwitchFontProg( NULL ); } //--------------------------------------------------------------------------- void __fastcall TContentPanel::OnMidiSwitch(TMessage &msg) { if( msg.WParam==0 ) DoSwitchFontProg( NULL ); else if( msg.WParam==1 ) DoSwitchTexture( NULL ); } //--------------------------------------------------------------------------- void TContentPanel::ChangeMidiTrack( int iMT, int iSBar, int iEBar ) { Parent->Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 ); TMidiTrack* pMT = iMT<0 ? NULL : g_aMidiTracks[iMT]; TStageList lstStages; char progOri(-1), chanOri(-1), segNoOri(-1); TPROSTYLE *pStyleOri = NULL; bool bOriSet = iMT>=0, bHasDrum = bOriSet && !pMT->IsDrum(); if( pMT ){ progOri = pMT->prog; if( pMT->IsDrum() ) chanOri = 9; } int iEndBar = iEBar<0 ? g_Opus.BarCount()-1 : m_iSelBarEnd, iStartBar = iSBar<0 ? 0 : m_iSelBarStart, // lenBar = iEndBar - iStartBar + 1, iDropMask = 0; int iFBar, iStage = FindStage( iStartBar, &iFBar ), iLBar = iFBar; while( iStageiSegType = pStage->iSegType; pDemoStage->iSegKey = pStage->iSegKey; pDemoStage->nBarNum = pStage->aBars.size(); if( pStage->iSegType<=SEGTYPE_FILL ){ pDemoStage->aChords = new TBarChords[pDemoStage->nBarNum]; for( int j=0; jnBarNum; j++ ){ memcpy( &pDemoStage->aChords[j], &pStage->aBars[j]->aChords, sizeof(TBarChords) ); } if( bOriSet ){ for( int i=0; iaTracks.size(); i++ ){ TTrack* pTrack = pStage->aTracks[i]; if( pTrack->iFile==pMT->file && pTrack->iChanSpec==pMT->chno ){ char st = pDemoStage->iSegType, sn = pTrack->iSegNo, cn = pTrack->iChanNo, pg = pTrack->iProgOrig;// -1; TPROSTYLE* pStyTemp = GetStyleInfo( pTrack->iStyleLoc, pTrack->iStyleId ); /* if( pTrack->iStyleLoc==0 ){ for( int t=0; t<16; t++ ){ if( pStyTemp->pOrigin->detail.tracks[st][sn][t].no==cn ){ pg = pStyTemp->pOrigin->detail.tracks[st][sn][t].prog; break; } } } else if( pTrack->iStyleLoc!=1 ){ for( int t=0; t<16; t++ ){ if( pStyTemp->pLocal->trkRef[st][sn][t].chan==cn ){ pg = pStyTemp->pLocal->trkRef[st][sn][t].prog; break; } } } */ if( !pStyleOri ){ pStyleOri = pStyTemp; segNoOri = sn; chanOri = cn; progOri = pg; } else{ if( pStyleOri!=pStyTemp || segNoOri!=sn || chanOri!=cn || progOri!=pg ){ pStyleOri = NULL; segNoOri = -1; progOri = -1; if( chanOri!=9 ) chanOri = -1; bOriSet = false; } } break; } } } else if( !bHasDrum && !pStage->aTracks.empty() ){ if( pStage->aTracks[0]->iChanNo==9 ) bHasDrum = true; } DWORD iT = ( 1 << pStage->iSegType ); if( !(iDropMask & iT ) ) iDropMask |= iT; } iLBar += pStage->aBars.size(); if( iLBar>iEndBar ){ pDemoStage->nBarNum -= iLBar - iEndBar - 1; break; } else{ iStage++; } } if( !bHasDrum ) iDropMask |= 0x80; TSwitchTextureForm *pProgPar = new TSwitchTextureForm(NULL, iDropMask, progOri, pMT ? pMT->bank : -1, pMT ? pMT->prog : -1, pStyleOri, chanOri, segNoOri, &lstStages, iStartBar-iFBar); 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.nVol = pProgPar->m_cSetVol; subTrk.nVolOrig = pProgPar->m_cSetVolOri; subTrk.iProgOrig = pProgPar->m_cSetProgOri; if( !pProgPar->m_bSetCur || pMT && pMT->bank==0xFF && pProgPar->m_cSetProg==pMT->prog ){ subTrk.iFile = pMT->file; subTrk.iBank = pMT->bank; subTrk.iChanSpec = pMT->chno; subTrk.iProg = pMT->prog; } else{ subTrk.iFile = 0xFF; subTrk.iBank = 0xFF; subTrk.iChanSpec =subTrk.iChanNo; subTrk.iProg = pProgPar->m_cSetProg; } int iSegType = pProgPar->m_cSetSegType, op = m_bVertical ? SEGTYPE_TRACK : ST_MIDI; ((TUseStylePanel*)m_pStylePanel)->ChangeTexture( iSBar, iEBar, iSegType, iMT, &subTrk, op ); } delete pProgPar; for( int i=0; iiType; if( iType<=UNDO_TRKAUD_DELALL ) Parent->Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 ); if( iType==UNDO_KEY_MELODY ){ TOpusStageList* lstStages = (TOpusStageList*)(bUndo ? pLite->pBefore : pLite->pAfter); int iKey = bUndo ? pLite->iBegin : pLite->iEnd; if( !lstStages ){ ChangeBarsKey( 0, g_Opus.BarCount()-1, iKey, NULL ); } else{ g_Theme.Set( *lstStages ); g_iMelodyKey = iKey; ((TUseStylePanel*)m_pStylePanel)->InitOpus( g_pPreStyle, g_iPreStage ); } Parent->Perform( UM_CHANGEKEY, 0, 0 ); } else if( iType==UNDO_KEY_BARS ){ if( VIEW_STYLE!=m_iMode ) Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 ); int iKey = bUndo ? -1 : (int)pLite->pAfter, *aKey = bUndo ? (int*)pLite->pBefore : NULL; ChangeBarsKey( pLite->iBegin, pLite->iEnd, iKey, aKey ); SelectBars( pLite->iBegin, pLite->iEnd ); } else if(iType==UNDO_CHORD ){ if( VIEW_CHORD!=m_iMode ){ Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_CHORD, 0 ); } BYTE* aParam = (BYTE*)( bUndo ? pLite->pBefore : pLite->pAfter ); int iBarStart = HIWORD(pLite->iBegin), iCellStart = LOWORD(pLite->iBegin), iBarEnd = HIWORD(pLite->iEnd), iCellEnd = LOWORD(pLite->iEnd), nCellNum = (iBarEnd - iBarStart - 1) * g_nChordNumPerBar + (g_nChordNumPerBar - iCellStart) + (iCellEnd + 1), *keys = new int[nCellNum], *types = new int[nCellNum]; for( int i=0; i>4; types[i] = aParam[i] & 0x0F; } SelectCells( iBarStart, iCellStart, iBarEnd, iCellEnd ); ChordPaste( keys, types, nCellNum, false ); int iKey = -1, iType = -1, iBarKey = -1; bool bEnable = false; if( m_iSelBarStart>=0 ){ GetSelectChord( iBarKey, iKey, iType ); bEnable = iKey!=-1; } ((TChordPanel*)m_pChordPanel)->EnableChordModify( bEnable, iBarKey, iKey, iType ); } else if( iType>=UNDO_TRKAUD_ADD && iType<=UNDO_TRKAUD_HIDEALL || iType>=UNDO_TRKMID_SHOW && iType<=UNDO_TRKMID_HIDEALL ){ short iShowTrk = -1, iTrkType = ST_AUDIO; bool bSolo = false; bool bInit = true; if( iType<=UNDO_TRKAUD_DELALL ){ f_MM_Undo( bUndo ); short iTrk = pLite->iCode; if( iType==UNDO_TRKAUD_ADD ){ if( bUndo ){ if( g_aAudioTracks[iTrk]->IsSolo() ) bSolo = true; DeleteAudioTrack( iTrk, false ); if( iTrkMainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 ); if( g_iPreStage==0 ){ DuplicateRawBars(); PostMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); } NewAudioTrack( g_Opus.BarCount(), false ); iShowTrk = g_aAudioTracks.size()-1; } } else if( iType<=UNDO_TRKAUD_DELALL ){ TAudioTrackList* aTracks = (TAudioTrackList*)pLite->pBefore; int num = aTracks->size(); bInit = false; int iTrack = iTrk<0 ? 1 : iTrk; iShowTrk = bUndo ? iTrk : -1; if( bUndo ){ for( int i=0; iIsSolo() ) bSolo = true; if( !pTrack->IsHide() ) bInit = true; iTrack++; } } else{ for( int i=0; iIsSolo() ) bSolo = true; if( !g_aAudioTracks[iTrack]->IsHide() ) bInit = true; DeleteAudioTrack( iTrack, false ); } if( iTrk<0 || iTrk==g_iSelAudio ) SelectTrack( -1, -1 ,-1 ); else if( iTrk=UNDO_TRKAUD_SHOW && iType<=UNDO_TRKAUD_HIDEALL ) ? ST_AUDIO : ST_MIDI; vector* arrIndex = (vector*)pLite->pBefore; for( int i=0; isize(); i++ ){ int iTrk = (*arrIndex)[i]; TBaseTrack* pBT = NULL; if( iTrkType==ST_AUDIO ) pBT = g_aAudioTracks[iTrk]; else pBT = g_aMidiTracks[iTrk]; pBT->Hide( bUndo && ( iType==UNDO_TRKAUD_SHOW || iType==UNDO_TRKAUD_SHOWALL || iType==UNDO_TRKMID_SHOW || iType==UNDO_TRKMID_SHOWALL ) || !bUndo && ( iType==UNDO_TRKAUD_HIDE || iType==UNDO_TRKAUD_HIDEALL || iType==UNDO_TRKMID_HIDE || iType==UNDO_TRKMID_HIDEALL )); if( arrIndex->size()==1 && !pBT->IsHide() ) iShowTrk = iTrk; } } if( bInit ) InitialVars(); if( bSolo ) SetTrackParams(); if( iShowTrk>=0 ){ int id = GetShowTrackId( iTrkType, iShowTrk ) - 1; SelectTrack( id, -1, -1 ); } else{ SelectTrack( -1, -1, -1 ); } Application->MainForm->Perform( UM_ENABLERECORD, 0, 0 ); } else if( iType>=UNDO_AUDIO_ERASE && iType<=UNDO_AUDIO_FX ){ int iTrack = pLite->iCode; int iBarStart = HIWORD( pLite->iBegin ), iPointStart = LOWORD( pLite->iBegin ), iBarEnd = HIWORD( pLite->iEnd ), iPointEnd = LOWORD( pLite->iEnd ), iSelAudio = iTrack, iSelBarStart = iBarStart, iSelPointStart = iPointStart, iSelBarEnd = iBarEnd, iSelPointEnd = iPointEnd; if( g_aAudioTracks[iTrack]->IsHide() ){ g_aAudioTracks[iTrack]->Hide(false); InitialVars(); } if( VIEW_TRACK!=m_iMode ){ Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 ); } else{ SelectCopyPos( -1, -1, -1, -1 ); } f_MM_Undo( bUndo ); if( bUndo ){ DWORD* aWave = (DWORD*)pLite->pBefore; CopyWave( iTrack, iBarStart, iPointStart, iBarEnd, iPointEnd, &aWave ); if( iType==UNDO_AUDIO_MOVE ){ int iDelTrack = pLite->iExt1; int iDelBarStart = HIWORD( pLite->iExt2 ), iDelPointStart = LOWORD( pLite->iExt2 ), iDelBarEnd = HIWORD( pLite->iExt3 ), iDelPointEnd = LOWORD( pLite->iExt3 ), iDelBarBreak = iDelBarEnd, iDelPointBreak = iDelPointEnd; if( g_aAudioTracks[iDelTrack]->IsHide() ){ g_aAudioTracks[iDelTrack]->Hide(false); InitialVars(); } if( pLite->pExt1 ){ int len = ( iBarEnd * POINTS_PER_BAR + iPointEnd ) - ( iBarStart * POINTS_PER_BAR + iPointStart ), nPointsBreak = iDelBarStart * POINTS_PER_BAR + iDelPointStart + len; iDelBarBreak = nPointsBreak / POINTS_PER_BAR; iDelPointBreak = nPointsBreak % POINTS_PER_BAR; aWave = (DWORD*)pLite->pExt1; CopyWave( iDelTrack, iDelBarBreak, iDelPointBreak, iDelBarEnd, iDelPointEnd, &aWave ); } aWave = (DWORD*)pLite->pAfter; CopyWave( iDelTrack, iDelBarStart, iDelPointStart, iDelBarBreak, iDelPointBreak, &aWave ); iSelAudio = iDelTrack; iSelBarStart = iDelBarStart; iSelPointStart = iDelPointStart; iSelBarEnd = iDelBarEnd; iSelPointEnd = iDelPointEnd; InvalidateBars( iBarStart, iBarEnd, BAR_TRACK | GetShowTrackId(ST_AUDIO,iTrack) ); } } else{ int iDelBarStart, iDelPointStart, iDelBarEnd, iDelPointEnd, iDelTrack = -1; if( iType==UNDO_AUDIO_ERASE ){ iDelTrack = iTrack; iDelBarStart = iBarStart; iDelPointStart = iPointStart; iDelBarEnd = iBarEnd; iDelPointEnd = iPointEnd; } else if( iType==UNDO_AUDIO_MOVE ){ iDelTrack = pLite->iExt1; iDelBarStart = HIWORD( pLite->iExt2 ); iDelPointStart = LOWORD( pLite->iExt2 ); iDelBarEnd = HIWORD( pLite->iExt3 ); iDelPointEnd = LOWORD( pLite->iExt3 ); } if( iDelTrack>0 ){ double dblStart = iDelBarStart + (double)iDelPointStart / POINTS_PER_BAR, dblEnd = iDelBarEnd + (double)iDelPointEnd / POINTS_PER_BAR; MoveAudio( iDelTrack, dblStart, dblEnd, -1, -1, MODE_ERASE ); } if( iType>UNDO_AUDIO_ERASE ){ DWORD* aWave = (DWORD*)pLite->pAfter; CopyWave( iTrack, iBarStart, iPointStart, iBarEnd, iPointEnd, &aWave ); } } int iSelTrack = GetShowTrackId( ST_AUDIO, iSelAudio ); if( iSelTrack>0 ) SelectTrack( iSelTrack-1, iSelBarStart, iSelPointStart ); //SelectTrack( iSelAudio, iSelBarStart, iSelPointStart ); SelectRange( iSelBarStart, iSelPointStart, iSelBarEnd, iSelPointEnd, true ); // InvalidateBars( iSelBarStart, iSelBarEnd, BAR_TRACK | GetShowTrackId(ST_AUDIO,iSelAudio) ); } } //---------------------------------------------------------------------------