7457 lines
199 KiB
C++
7457 lines
199 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#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; i<g_aMidiTracks.size(); i++ ){
|
|
if( !g_aMidiTracks[i]->IsHide() ){
|
|
m_aTracks.push_back( new TShowTrack( ST_MIDI, i, g_aMidiTracks[i] ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
for( int i=0; i<g_aAudioTracks.size(); i++ ){
|
|
if( !g_aAudioTracks[i]->IsHide() && !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; i<g_aMidiTracks.size(); i++ ){
|
|
if( !g_aMidiTracks[i]->IsHide() ){
|
|
m_aTracks.push_back( new TShowTrack( ST_MIDI, i, g_aMidiTracks[i] ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
for( int i=0; i<g_aAudioTracks.size(); i++ ){
|
|
if( !g_aAudioTracks[i]->IsHide() && !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; i<m_aTracks.size(); i++ ){
|
|
if( m_aTracks[i]->type==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<Width && pt.y>=0 && pt.y<Height && Msg.hwnd==Handle
|
|
&& !m_bBrush ){
|
|
if( pt.x<m_nLeftOriBound ){
|
|
if( g_iToolPanelShow==0x01 ){
|
|
Screen->Cursor = crHSplit;
|
|
m_ApplicationEvents->CancelDispatch();
|
|
}
|
|
}
|
|
else if( !m_bVertical && m_nLeftBound>=MIN_HDR_WIDTH && pt.y<m_sbHoriz->Top
|
|
&& pt.x>m_nLeftBound-8 && pt.x<m_nLeftBound+2 ){
|
|
Screen->Cursor = 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_iBeginShowBar )
|
|
return;
|
|
|
|
int iRow, iCol;
|
|
TRect rectDraw;
|
|
|
|
iRow = m_bVertical ? iBar / m_nColumnNum - m_iBeginShowRow : 0;
|
|
iCol = m_bVertical ? iBar % m_nColumnNum : iBar - m_iBeginShowBar;
|
|
|
|
if( iRow>=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<m_nColumnNum && (rtInvalid.right - m_nLeftBound ) % m_nBarWidth > 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; i<m_nRowNum && i<iEndRow; i++ ){
|
|
int right, barTop = rowTop + m_nRowGapHeight,
|
|
barBottom = min( barTop + m_nBarDrawHeight - m_iBeginShowTrack*m_nTrackHeight,
|
|
ClientHeight - m_nBottomBound ),
|
|
iBarLeft = m_nLeftBound + iBeginCol * m_nBarWidth;
|
|
|
|
if( i==iBeginRow || iBeginCol>0 || iEndCol>0 && iEndCol<m_nColumnNum ){
|
|
if( m_bVertical )
|
|
nBarCount = i * m_nColumnNum + iBeginCol;
|
|
else
|
|
nBarCount = m_iBeginShowBar + iBeginCol;
|
|
|
|
if( nBarCount>=m_nBarNum )
|
|
break;
|
|
|
|
if( bData && nBarCount>0 && nBarCount<g_Opus.BarCount() ){
|
|
iStage = FindStage( nBarCount-1, &iFirstBar );
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
|
|
if( pStage->iSegType>=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<m_nTrackShow && ((rtInvalid.bottom-iTrackTop)%m_nTrackHeight > 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; t<iEndTrk && topTrack<rtInvalid.bottom; t++ ){
|
|
if( bBreak ){
|
|
// 绘制隔离线
|
|
Canvas->Pen->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; j<iEndCol && nBarCount<m_nBarNum; j++ ){
|
|
String strText;
|
|
|
|
Canvas->Pen->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 && nBarCount<g_Opus.BarCount() ){
|
|
if( nBarCount-iFirstBar==g_lstOpusStages[iStage]->aBars.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 && nBarCount<g_Opus.BarCount() ){
|
|
DrawBarData( nBarCount, iStage, iFirstBar, iBarLeft, iBarTop );
|
|
iBarTop += m_nChordHeight;
|
|
}
|
|
|
|
Canvas->Pen->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.right
|
|
&& barTop-8>=rtInvalid.top ){
|
|
Canvas->Draw( iPlayPoint - 5, barTop - 8, m_imgPlayCursor );
|
|
}
|
|
|
|
if( iPlayPoint>=rtInvalid.left && iPlayPoint<rtInvalid.right ){
|
|
TColor clrOld = Canvas->Pen->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 && l<rtInvalid.right ){
|
|
Canvas->Pen->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; i<m_nTitleHeight; i++ ){
|
|
if( bSel )
|
|
Canvas->Pen->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; i<g_nChordNumPerBar; i++ ){
|
|
if( iBar==m_iSelBarStart && i==m_iSelCellStart
|
|
|| iBar==m_iCopyBarStart && i==m_iCopyCellStart
|
|
|| pBar->aChords.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<m_iSelBarStart
|
|
|| ( m_iSelBarEnd>=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; i<nBarNum; i++ ){
|
|
int iWvBar = iBarS + i;
|
|
TWaveBar *pBar = pTrack->lstBars[iWvBar];
|
|
|
|
for( int k=0; k<POINTS_PER_BAR; k++ ){
|
|
if( pBar->aVols[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
|
|
|| iWvBar<m_iSelBarEnd
|
|
|| iWvBar==m_iSelBarEnd && k<m_iSelPointEnd ) )
|
|
Canvas->Pen->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; i<pTrack->aNotes.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( iL<iSelS ){
|
|
int iT = min( iSelS, iR );
|
|
|
|
if( iT>iL ){
|
|
Canvas->MoveTo( iL+left, iH );
|
|
Canvas->LineTo( iT+left, iH );
|
|
|
|
iL = iT;
|
|
}
|
|
}
|
|
|
|
if( iSelE>0 && iR>iSelE ){
|
|
int iT = max( iSelE, iL );
|
|
|
|
if( iT<iR ){
|
|
Canvas->MoveTo( 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( curpos<maxpos )
|
|
curpos = min(maxpos-page+1, curpos+page);
|
|
break;
|
|
|
|
case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
|
|
curpos = Message.Pos; // of the scroll box at the end of the drag operation.
|
|
break;
|
|
|
|
case SB_THUMBTRACK: // Drag scroll box to specified position. nPos is the
|
|
curpos = Message.Pos; // position that the scroll box has been dragged to.
|
|
break;
|
|
}
|
|
|
|
// Set the new position of the thumb (scroll box).
|
|
if( Message.ScrollBar!=pSB->Handle )
|
|
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<m_aTracks.size(); i++ ){
|
|
int nBottom = nTop+m_nTrackHeight;
|
|
if( Y>=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<nTop )
|
|
break;
|
|
|
|
nTop = nBottom;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
else{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int iRow = ( Y - m_nTopBound ) / m_nBarHeight + m_iBeginShowRow;
|
|
int iCol = ( X - m_nLeftBound ) / m_nBarWidth;
|
|
int deltaY = ( Y - m_nTopBound ) % m_nBarHeight;
|
|
int deltaX = ( X - m_nLeftBound ) % m_nBarWidth;
|
|
int iBar = m_bVertical ? iRow * m_nColumnNum + iCol
|
|
: iRow==0 ? m_iBeginShowBar + iCol : -1;
|
|
|
|
if( iBar<m_nBarNum && iBar>=0 ){
|
|
if( deltaY<m_nRowGapHeight ){
|
|
iHitType = BAR_CURSOR;
|
|
}
|
|
else if( deltaY<m_nRowGapHeight+m_nTitleHeight ){
|
|
iHitType = BAR_TITLE;
|
|
}
|
|
else if( deltaY<m_nRowGapHeight+m_nTitleHeight+m_nChordHeight ){
|
|
iHitType = BAR_DATA;
|
|
}
|
|
else{
|
|
int nWaveBottom = m_nRowGapHeight + m_nTitleHeight + m_nChordHeight;
|
|
for( int i=0; i<m_aTracks.size()-m_iBeginShowTrack; i++ ){
|
|
nWaveBottom += m_nTrackHeight;
|
|
|
|
if( deltaY<nWaveBottom ){
|
|
iHitType = i + m_iBeginShowTrack + BAR_TRACK;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( iHitType==BAR_CURSOR ){
|
|
if( m_nBarWidth-deltaX<ABS_POI_PLAY && iBar<m_nBarNum-1 ){ // 小节线左侧
|
|
return MAKELONG( iBar+1, 0 );
|
|
}
|
|
else if( deltaX<ABS_POI_PLAY && iCol<m_nColumnNum ){ // 小节线右侧
|
|
return MAKELONG( iBar, 0 );
|
|
}
|
|
}
|
|
else if( iHitType==BAR_TRACK ){
|
|
if( m_nBarWidth-deltaX<ABS_POI_WAVE && iBar<m_nBarNum-1 ){ // 小节线左侧
|
|
return MAKELONG( iBar+1, 0 );
|
|
}
|
|
else if( deltaX<ABS_POI_WAVE && iCol<m_nColumnNum ){ // 小节线右侧
|
|
return MAKELONG( iBar, 0 );
|
|
}
|
|
}
|
|
|
|
return MAKELONG( iBar, deltaX );
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
int TContentPanel::GetCell( int iPoint )
|
|
{
|
|
int iCell = g_nChordNumPerBar-1;
|
|
for( int i=0; i<g_nChordNumPerBar; i++ ){
|
|
if( iPoint < i * m_nChordTxtWidth ){
|
|
iCell = i-1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return iCell;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void TContentPanel::DrawChord( TRect& rcDraw, int iBarKey, int iKey, int iType )
|
|
{
|
|
int iOriLeft = rcDraw.left,
|
|
iOriTop = rcDraw.top;
|
|
|
|
int iMainKey, iAjustKey;
|
|
GetChordDispalyKey( iKey, iBarKey, iMainKey, iAjustKey );
|
|
|
|
int wMKey(12), wAKey(0), wTKey(0), wVKey(13), wIKey(8);
|
|
|
|
if( iAjustKey!=0 ) //左上角标宽度
|
|
wAKey = 3;
|
|
|
|
if( iType>0 ){ //右下角标宽度
|
|
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()<<fsItalic<<fsBold;
|
|
Canvas->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; i<w_imgDrag->Width; i++ ){
|
|
for( int j=0; j<w_imgDrag->Height; 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()<<fsBold;
|
|
w_imgDrag->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( p<POINTS_PER_BAR && iPos<120 ){
|
|
if( pBar->aVols[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.X<Width
|
|
|| ptOld.X+w>0 && ptOld.X+w<Width ){
|
|
rtInvalid.left = min( ptOld.X, rtInvalid.left );
|
|
rtInvalid.right = max( ptOld.X+w, rtInvalid.right );
|
|
}
|
|
|
|
if( bShow && (ptNew.X>0 && ptNew.X<Width
|
|
|| ptNew.X+w>0 && ptNew.X+w<Width )){
|
|
rtInvalid.left = min( ptNew.X, rtInvalid.left );
|
|
rtInvalid.right = max( ptNew.X+w, rtInvalid.right );
|
|
}
|
|
|
|
if( rtInvalid.left<0 ) rtInvalid.left = 0;
|
|
if( rtInvalid.right>Width ) 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.Y<Height
|
|
|| ptOld.Y+h>0 && ptOld.Y+h<Height ){
|
|
rtInvalid.top = min( ptOld.Y, rtInvalid.top );
|
|
rtInvalid.bottom = max( ptOld.Y+h, rtInvalid.bottom );
|
|
}
|
|
if( ptOld.X>0 && ptOld.X<Width
|
|
|| ptOld.X+w>0 && ptOld.X+w<Width ){
|
|
rtInvalid.left = min( ptOld.X, rtInvalid.left );
|
|
rtInvalid.right = max( ptOld.X+w, rtInvalid.right );
|
|
}
|
|
|
|
if( bShow ){
|
|
if( ptNew.Y>0 && ptNew.Y<Height
|
|
|| ptNew.Y+h>0 && ptNew.Y+h<Height ){
|
|
rtInvalid.top = min( ptNew.Y, rtInvalid.top );
|
|
rtInvalid.bottom = max( ptNew.Y+h, rtInvalid.bottom );
|
|
}
|
|
|
|
if( ptNew.X>0 && ptNew.X<Width
|
|
|| ptNew.X+w>0 && ptNew.X+w<Width ){
|
|
rtInvalid.left = min( ptNew.X, rtInvalid.left );
|
|
rtInvalid.right = max( ptNew.X+w, rtInvalid.right );
|
|
}
|
|
|
|
bCanDrop = HandleHoverEvent( ptMouse );
|
|
}
|
|
else{
|
|
if( ( w_iDragMode==DM_ADJUSTSTYLE || w_iDragMode==DM_ADJUSTSTAGE )
|
|
&& ( m_iSelBarStart>=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()<MAX_AUDIOTRACK;
|
|
m_PopupMenu->CreateMenu( "新增MIDI轨道...","",DoTrackAdd, ST_MIDI );
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
else{
|
|
int iView = VIEW_TRACK;
|
|
|
|
if( iHitType<BAR_TRACK ){
|
|
SelectTrack( -1, -1, -1 );
|
|
|
|
if( iHitType==BAR_TITLE )
|
|
iView = VIEW_STYLE;
|
|
else if( iHitType==BAR_DATA )
|
|
iView = VIEW_CHORD;
|
|
}
|
|
|
|
if( iView!=m_iMode ){
|
|
Application->MainForm->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()<MAX_AUDIOTRACK;
|
|
m_PopupMenu->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<m_iSelBarStart
|
|
|| m_iSelBarEnd>=0 && iHitBar>m_iSelBarEnd
|
|
|| iHitBar==m_iSelBarStart && iHitPoint<m_iSelPointStart
|
|
|| iHitBar==m_iSelBarEnd && iHitPoint>m_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; i<MAX_FX_NUM; i++ ){
|
|
if( pMSPFx )
|
|
pMSPFx->AppendMenu( g_strEffect[i], "", DoAudioFxProcess, i );
|
|
|
|
if( i<MAX_FX_NUM-1 )
|
|
pMAddFx->AppendMenu( g_strEffect[i], "", DoAudioAddFx, i );
|
|
}
|
|
|
|
if( !g_lstVSTFx.empty() ){
|
|
for( int i=0; i<g_lstVSTFx.size(); i++ ){
|
|
VSTINFO* pVST = g_lstVSTFx[i];
|
|
|
|
char fname[128],
|
|
*name = strrchr( pVST->strFileName, '\\' )+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; i<pMT->aStages.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 || iHitBar<m_iSelBarStart
|
|
|| iHitBar>m_iSelBarEnd
|
|
|| iHitBar==m_iSelBarStart && iCell<m_iSelCellStart
|
|
|| iHitBar==m_iSelBarEnd && iCell>m_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( iStage<g_lstOpusStages.size() ){
|
|
pStage = g_lstOpusStages[iStage];
|
|
if( pStage->iSegType<=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 )
|
|
&& ( iHitBar<m_iSelBarEnd || iHitBar==m_iSelBarEnd
|
|
&& iCell<=m_iSelCellEnd ) ){
|
|
bCanCopy = true;
|
|
}
|
|
|
|
pMenuItem = m_PopupMenu->CreateMenu( "复制和弦","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 || iHitBar<m_iSelBarStart || iHitBar>m_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; i<KEY_NUM; i++ ){
|
|
pMenuItem->AppendMenu( 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]->iSegType<SEGTYPE_INTRO ){
|
|
bTexture = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pMenuItem->Enabled = 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.XPos<m_nLeftOriBound ? DM_ADJUSTWIDTH : DM_ADJUSTHEADER;
|
|
DrawDragImg( iMode );
|
|
|
|
TPoint pt( 0, 1 );
|
|
if( iMode==DM_ADJUSTHEADER )
|
|
pt.x = m_nLeftBound;
|
|
|
|
w_xOffDrag = Message.XPos - pt.X;
|
|
w_yOffDrag = Message.YPos;
|
|
|
|
pt = ClientToScreen( pt );
|
|
|
|
w_xOldDrag = w_xImgDrag = pt.X;
|
|
w_yOldDrag = w_yImgDrag = pt.Y;
|
|
|
|
SetCapture( Handle );
|
|
}
|
|
else{
|
|
SetFocus();
|
|
|
|
if( m_nBarNum>0 ){
|
|
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 && iHitType<BAR_LEFT ){
|
|
if( iHitType<BAR_TRACK )
|
|
SelectBars( iHitBar, iHitBar );
|
|
else{
|
|
int iHitTrack = iHitType & 0xFF;
|
|
SelectTrack( iHitTrack , -1, -1 );
|
|
SelectRange( iHitBar, 0, iHitBar, m_nBarWidth-1 );
|
|
}
|
|
|
|
m_iMouseDownBar = iHitBar;
|
|
m_iMouseDownPoint = iHitPoint;
|
|
|
|
m_bDraging = true;
|
|
}
|
|
else{
|
|
m_bBrush = false;
|
|
}
|
|
}
|
|
else{
|
|
if( iHitType==BAR_CURSOR ){ //设置播放位置
|
|
SetPlayPoint( iHitBar, iHitPoint );
|
|
Application->MainForm->Perform( UM_SHOWPLAYTIME, iHitBar, iHitPoint );
|
|
|
|
return;
|
|
}
|
|
|
|
//符合条件准备拖动
|
|
if( iHitType>=BAR_TITLE ){ //左键点中
|
|
int iView = VIEW_TRACK;
|
|
if( iHitType<BAR_TRACK ){
|
|
SelectTrack( -1, -1, -1 );
|
|
|
|
if( iHitType==BAR_TITLE )
|
|
iView = VIEW_STYLE;
|
|
else if( iHitType==BAR_DATA )
|
|
iView = VIEW_CHORD;
|
|
}
|
|
|
|
if( iView!=m_iMode ){
|
|
Application->MainForm->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<m_iSelBarStart
|
|
|| m_iSelBarEnd>=0 && iHitBar>m_iSelBarEnd
|
|
|| iHitBar==m_iSelBarStart && iHitPoint<m_iSelPointStart
|
|
|| iHitBar==m_iSelBarEnd && iHitPoint>m_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<m_iSelBarStart
|
|
|| m_iSelBarEnd>=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; i<g_lstOpusStages.size(); i++ ){
|
|
pStage = g_lstOpusStages[i];
|
|
if( pStage->iSegType<=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( iHitType<BAR_TRACK )
|
|
return;
|
|
|
|
if( m_aTracks[m_iSelTrack]->type==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( iHitBar<m_iMinSelBar ){
|
|
iStartBar = m_iMinSelBar;
|
|
iEndBar = m_iMouseDownBar;
|
|
iStartCell = 0;
|
|
}
|
|
else{
|
|
int iHitCell = GetCell( HIWORD(dwHit) );
|
|
|
|
if( iHitBar==m_iMouseDownBar ){
|
|
iStartCell = min( iStartCell, iHitCell );
|
|
iEndCell = max( iEndCell, iHitCell );
|
|
}
|
|
else if( iHitBar<m_iMouseDownBar )
|
|
iStartCell = iHitCell;
|
|
else
|
|
iEndCell = iHitCell;
|
|
}
|
|
|
|
if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd
|
|
|| iStartCell!=m_iSelCellStart
|
|
|| iEndCell!=m_iSelCellEnd )
|
|
SelectCells( iStartBar, iStartCell, iEndBar, iEndCell );
|
|
}
|
|
else if( m_aTracks[m_iSelTrack]->type==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( iHitBar<m_iMouseDownBar )
|
|
iStartPoint = iHitPoint;
|
|
else
|
|
iEndPoint = iHitPoint;
|
|
|
|
if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd
|
|
|| iStartPoint!=m_iSelPointStart
|
|
|| iEndPoint!=m_iSelPointEnd )
|
|
SelectRange( iStartBar, iStartPoint, iEndBar, iEndPoint );
|
|
}
|
|
else{
|
|
if( iStartBar!=m_iSelBarStart || iEndBar!=m_iSelBarEnd-1 )
|
|
SelectRange( iStartBar, 0, iEndBar, m_nBarWidth-1 );
|
|
}
|
|
}
|
|
|
|
TPoint ptMouse( Message.XPos, Message.YPos );
|
|
SetScrollTimer( ptMouse );
|
|
}
|
|
else if( m_nBarNum>0/* 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 && iHitType<BAR_LEFT ){
|
|
int iHitBar = LOWORD(dwHit),
|
|
iHitStage = FindStage( iHitBar, NULL );
|
|
TOpusStage * pHitStage = g_lstOpusStages[iHitStage];
|
|
int iHitSegType = pHitStage->iSegType;
|
|
|
|
if( iHitSegType<=SEGTYPE_FILL ){
|
|
if( iBrushType==SEGTYPE_SEGMENT && iHitType<BAR_TRACK ){
|
|
iCursor = crBrush;
|
|
}
|
|
else if( iBrushType==SEGTYPE_TRACK && iHitSegType==iBrushSegType ){
|
|
if( iHitType<BAR_TRACK ){
|
|
bool bAdd = true;
|
|
TTrack* pTrack = ((TTrackItem*)m_pItem)->pTrack;
|
|
|
|
if( pTrack->iChanNo==9 ){
|
|
for( int i=0; i<g_aMidiTracks.size(); i++ ){
|
|
if( g_aMidiTracks[i]->IsDrum() ){
|
|
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; i<m_aTracks.size(); i++ ){
|
|
RECT rect;
|
|
TShowTrack* pTrk = m_aTracks[i];
|
|
|
|
if( iTrack==i && !(pTrk->iHover & 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_iMouseDownBar<m_iSelBarStart
|
|
|| m_iMouseDownBar>m_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_iMouseDownBar<m_iSelBarStart
|
|
|| m_iMouseDownBar>m_iSelBarEnd
|
|
|| m_iMouseDownBar==m_iSelBarStart && iCell<m_iSelCellStart
|
|
|| m_iMouseDownBar==m_iSelBarEnd && iCell>m_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( iStage<g_lstOpusStages.size() ){
|
|
pStage = g_lstOpusStages[iStage];
|
|
if( pStage->iSegType<=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_iMouseDownBar<m_iSelBarStart
|
|
|| m_iMouseDownBar>m_iSelBarEnd
|
|
|| m_iMouseDownBar==m_iSelBarStart
|
|
&& m_iMouseDownPoint<m_iSelPointStart
|
|
|| m_iMouseDownBar==m_iSelBarEnd
|
|
&& m_iMouseDownPoint>m_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<minArea ){
|
|
if( m_iSelBarStart==m_iMouseDownBar
|
|
&& m_iSelPointStart==m_iMouseDownPoint )
|
|
SelectRange( m_iSelBarStart, m_iSelPointStart, -1, -1 );
|
|
else
|
|
SelectRange( -1, -1, m_iSelBarEnd, m_iSelPointEnd );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( m_iMode==VIEW_CHORD ){
|
|
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 );
|
|
}
|
|
|
|
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) && iHitType<BAR_TRACK ){
|
|
int iFirstBar,
|
|
iHitStage = FindStage( iHitBar, &iFirstBar );
|
|
TOpusStage * pHitStage = g_lstOpusStages[iHitStage];
|
|
int iLastBar = iFirstBar + pHitStage->aBars.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->iSegType<SEGTYPE_ENDING && ( iHitBar<m_iSelBarStart
|
|
|| iHitBar>m_iSelBarEnd && iHitType<SEGTYPE_ENDING )){
|
|
bCanInsert = true;
|
|
}
|
|
}
|
|
|
|
if( bCanInsert && ( iHitType<SEGTYPE_INTRO && ( iHitPoint<30 || iHitPoint>90 )
|
|
|| 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 && iHitType<BAR_LEFT ){
|
|
int iHitTrack = iHitType & 0xFF;
|
|
|
|
if( m_aTracks[iHitTrack]->type==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<<iSrcTrack );
|
|
nAT = 2;
|
|
aTrks = new int[2];
|
|
aTrks[0] = g_iSelAudio;
|
|
aTrks[1] = iSrcTrack;
|
|
}
|
|
|
|
f_MM_AddUndoBefore( nAT, aTrks );
|
|
|
|
if( g_iSelAudio>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<iStart && 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 && iStage<g_lstOpusStages.size() ){
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
int iFirstBar = FirstBar( iStage ),
|
|
iEndBar = iFirstBar + pStage->aBars.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 && X<Width-m_nRightBound ){
|
|
short iDirect = 0;
|
|
if( Y>Height-m_nRowGapHeight && m_iBeginShowRow<m_nRowNum-m_nRowShow )
|
|
iDirect = 1;
|
|
else if( Y<m_nTopBound+m_nRowGapHeight && m_iBeginShowRow>0 )
|
|
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 && X<Width-m_nRightBound ){
|
|
short iDirect = 0;
|
|
if( Y>Height-m_nRowGapHeight
|
|
&& m_iBeginShowTrack<(int)(m_aTracks.size()-m_nTrackShow) )
|
|
iDirect = 1;
|
|
else if( Y<m_nTopBound+m_nRowGapHeight && m_iBeginShowTrack>0 )
|
|
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 && Y<Height-m_nBottomBound ){
|
|
short iDirect = 0;
|
|
|
|
if( X>Width-m_nRightBound && ( g_iToolPanelShow!=0 || m_bBrush && X<Width+120
|
|
|| w_bDraging && X<Width+12 )
|
|
&& m_iBeginShowBar<=m_nBarNum-m_nColumnNum )
|
|
iDirect = 1;
|
|
else if( X<m_nLeftBound && ( g_iToolPanelShow!=1 || 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<m_nBarNum ){
|
|
InvalidateBars( nBarCount, m_nBarNum-1, BAR_TITLE|BAR_DATA|BAR_TRACK );
|
|
}
|
|
|
|
m_nBarNum = nBarCount;
|
|
|
|
if( m_bVertical ){
|
|
int iFirstShowBar = m_iBeginShowRow * m_nColumnNum;
|
|
m_nRowNum = m_nBarNum / m_nColumnNum;
|
|
if( m_nBarNum % m_nColumnNum > 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; i<g_lstOpusStages.size(); i++ ){
|
|
InvalidateStage( i, BAR_CURSOR|BAR_TITLE|BAR_DATA|BAR_TRACK );
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
for( int i=iStage; i<g_Opus.StageCount(); i++ )
|
|
InvalidateStage( i, BAR_DATA|BAR_TITLE|BAR_TRACK );
|
|
}
|
|
}
|
|
else if( iMode==MODE_CHANGE ){ //修改
|
|
for( int i=iStage; i<g_Opus.StageCount(); i++ ) //可能出现3小节合并
|
|
InvalidateStage( i, BAR_DATA|BAR_TRACK );
|
|
}
|
|
else if( iMode==MODE_MOVE ){
|
|
for( int i=iStage; i<g_Opus.StageCount(); i++ ){
|
|
InvalidateStage( i, BAR_CURSOR|BAR_TITLE|BAR_DATA|BAR_TRACK );
|
|
}
|
|
}
|
|
|
|
if( iMode==MODE_CHANGE && g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->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 && iHitType<BAR_LEFT){
|
|
int iHitTrack = iHitType & 0xFF;
|
|
|
|
if( m_aTracks[iHitTrack]->type==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; i<g_nChordNumPerBar; i++ ){
|
|
if( pBar->aChords.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( iBarE<m_nBarNum ){
|
|
for( ; iPtE<POINTS_PER_BAR; iPtE++ ){
|
|
DWORD dwValue = list[iBarE]->aVols[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; i<MAX_FX_NUM; i++ ){
|
|
if( pTrack->lstEffects[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; j<MAX_FX_NUM; j++ ){
|
|
if( pTrack->lstEffects[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->iBarStart<iHitBar || pAE->iBarStart==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; i<g_aMidiTracks.size(); i++ ){
|
|
TMidiTrack* pMT = g_aMidiTracks[i];
|
|
|
|
if( pMT->IsDrum() ){
|
|
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<m_iSelBarEnd || iBar==m_iSelBarEnd && iCell<m_iSelCellEnd ){
|
|
iCell++;
|
|
|
|
if( iCell>=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拍
|
|
&& iCell<g_nChordNumPerBar-1){ //且不是小节最后1拍
|
|
for( int i=iCell+1; i<g_nChordNumPerBar; i++ ){
|
|
int iOriKey = pStage->aBars[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( iBar<iEndBar || iBar==iEndBar && iCell<=iCellEnd ){
|
|
int iSBar = iBar-iFirstBar;
|
|
|
|
pBefore[iUndo] = (pStage->aBars[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<g_nChordNumPerBar ){
|
|
InvalidateBar( iBar, 0, m_nBarWidth, BAR_DATA );
|
|
}
|
|
|
|
int iBegin = MAKELONG( m_iSelCellStart, m_iSelBarStart ),
|
|
iEnd = MAKELONG( iCellEnd, iEndBar );
|
|
|
|
g_Undo.AddUndo( UNDO_CHORD, 0, iBegin, iEnd, pBefore, pAfter );
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TContentPanel::GetChordDispalyKey( int iKey, int iBarKey, int& iMainKey, int& iAjustKey )
|
|
{
|
|
iMainKey = -1;
|
|
iAjustKey = 0;
|
|
|
|
if( iKey<0 )
|
|
return;
|
|
|
|
if( !g_bAlphaKey ){
|
|
iKey -= iBarKey;
|
|
if( iKey<0 ) iKey += 12;
|
|
}
|
|
|
|
switch( iKey ){
|
|
case 0: iMainKey = 0;
|
|
break;
|
|
case 1: iAjustKey = -1;
|
|
case 2: iMainKey = 1;
|
|
break;
|
|
case 3: iAjustKey = -1;
|
|
case 4: iMainKey = 2;
|
|
break;
|
|
case 6: iAjustKey = 1;
|
|
case 5: iMainKey = 3;
|
|
break;
|
|
case 7: iMainKey = 4;
|
|
break;
|
|
case 8: iAjustKey = -1;
|
|
case 9: iMainKey = 5;
|
|
break;
|
|
case 10: iAjustKey = -1;
|
|
case 11: iMainKey = 6;
|
|
break;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TContentPanel::SelectTrack( int iTrack, int iBar, int iPoint, bool bClear )
|
|
{
|
|
if( bClear ){
|
|
SelectRange( -1, -1, -1, -1 );
|
|
}
|
|
|
|
if( iBar==0 && iPoint<5 ){
|
|
iPoint = 0;
|
|
}
|
|
|
|
TShowTrack* pTrack = NULL;
|
|
if( iTrack>=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<m_nTrackShow ){
|
|
InvalidateShowBars( BAR_TRACK | (m_iSelTrack+1) );
|
|
|
|
if( !m_bVertical ){
|
|
int top = m_nTopBound + m_nRowGapHeight + m_nTitleHeight + m_nChordHeight
|
|
+ ( m_iSelTrack - m_iBeginShowTrack ) * m_nTrackHeight;
|
|
|
|
int nH = m_nTrackHeight;
|
|
if( top + m_nTrackHeight > 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_iBeginShowTrack || iTrack-m_iBeginShowTrack>=m_nTrackShow ){
|
|
if( !m_bVertical ){
|
|
int nPos = iTrack<m_iBeginShowTrack ? iTrack : iTrack - m_nTrackShow + 1;
|
|
ScrollView( nPos );
|
|
}
|
|
}
|
|
else{
|
|
InvalidateShowBars( BAR_TRACK | (iTrack+1) );
|
|
|
|
if( !m_bVertical ){
|
|
int top = m_nTopBound + m_nRowGapHeight + m_nTitleHeight + m_nChordHeight
|
|
+ ( iTrack - m_iBeginShowTrack ) * m_nTrackHeight;
|
|
|
|
int nH = m_nTrackHeight;
|
|
if( top + m_nTrackHeight > 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<m_nRowShow && iCol>=0 && iCol<m_nColumnNum ){
|
|
int left = iCol * m_nBarWidth + m_iSelTrackPoint + m_nLeftBound,
|
|
top = iRow * m_nBarHeight + m_nTopBound + m_nRowGapHeight
|
|
+ m_nTitleHeight + m_nChordHeight
|
|
+ iTrack * m_nTrackHeight;
|
|
|
|
int nH = m_nTrackHeight;
|
|
if( top + m_nTrackHeight > 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<m_nRowShow && iCol>=0 && iCol<m_nColumnNum ){
|
|
int left = iCol * m_nBarWidth + iPoint + m_nLeftBound,
|
|
top = iRow * m_nBarHeight + m_nTopBound + m_nRowGapHeight
|
|
+ m_nTitleHeight + m_nChordHeight
|
|
+ iTrack * m_nTrackHeight;
|
|
|
|
int nH = m_nTrackHeight;
|
|
if( top + m_nTrackHeight > ClientHeight - m_nBottomBound )
|
|
nH = ClientHeight - m_nBottomBound - top;
|
|
|
|
for( int i=0; i<nH; i++ ){
|
|
Canvas->Pixels[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; i<KEY_NUM; i++ ){
|
|
pMenuItem->AppendMenu( 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; i<MAX_FX_NUM; i++ ){
|
|
if( pMSPFx )
|
|
pMSPFx->AppendMenu( g_strEffect[i], "", DoAudioFxProcess, i );
|
|
|
|
if( i<MAX_FX_NUM-1 )
|
|
pMAddFx->AppendMenu( g_strEffect[i], "", DoAudioAddFx, i );
|
|
}
|
|
|
|
if( !g_lstVSTFx.empty() ){
|
|
for( int i=0; i<g_lstVSTFx.size(); i++ ){
|
|
VSTINFO* pVST = g_lstVSTFx[i];
|
|
|
|
char fname[128],
|
|
*name = strrchr( pVST->strFileName, '\\' )+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; i<pMT->aStages.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()<MAX_AUDIOTRACK;
|
|
|
|
pSubMenu = pMenuItem->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; i<g_aAudioTracks.size(); i++ ){
|
|
if( !g_aAudioTracks[i]->IsHide() ){
|
|
bCanDo = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pSubMenu->Enabled = bCanDo;
|
|
|
|
pSubMenu = pMenuItem->AppendMenu( "全部MIDI轨道", "", DoTrackHide, ST_MIDI );
|
|
bCanDo = false;
|
|
if( !m_bVertical ){
|
|
for( int i=0; i<g_aMidiTracks.size(); i++ ){
|
|
if( !g_aMidiTracks[i]->IsHide() ){
|
|
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; i<m_aTracks.size(); i++ ){
|
|
TShowTrack* pST = m_aTracks[i];
|
|
|
|
if( pST->pTrack->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 = iType<IDM_TRKSHOW ? -1 : iType - IDM_TRKSHOW;
|
|
bool bSolo = false;
|
|
|
|
if( index<0 ){
|
|
if( iType==ST_AUDIO ){
|
|
if( !g_aAudioTracks.empty() ){
|
|
if( g_iPreStage==0 && !g_aAudioTracks[0]->lstBars.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<BYTE>* arrIndex = new vector<BYTE>;
|
|
|
|
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<IDM_TRKSHOW ? -1 : iType - IDM_TRKSHOW;
|
|
vector<BYTE>* arrIndex = new vector<BYTE>;
|
|
bool bUnselect = false;
|
|
|
|
if( index<0 ){
|
|
for( int i=0; i<m_aTracks.size(); i++ ){
|
|
TShowTrack* pST = m_aTracks[i];
|
|
if( pST->type==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( iPoint<nPoints ){
|
|
int iSP = 0, iEP = POINTS_PER_BAR;
|
|
|
|
if( iVolPoint>0 ){
|
|
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; i<iEP; i++ ){
|
|
pBar->aVols[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; i<pMT->aStages.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; i<pMT->aStages.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( iStage<g_Opus.StageCount() ){
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
TStage* pDemoStage = new TStage;
|
|
lstStages.push_back( pDemoStage );
|
|
|
|
pDemoStage->iSegType = 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; j<pDemoStage->nBarNum; j++ ){
|
|
memcpy( &pDemoStage->aChords[j], &pStage->aBars[j]->aChords,
|
|
sizeof(TBarChords) );
|
|
}
|
|
|
|
if( bOriSet ){
|
|
for( int i=0; i<pStage->aTracks.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; i<lstStages.size(); i++ ){
|
|
delete lstStages[i];
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TContentPanel::Undo( bool bUndo )
|
|
{
|
|
if( m_bDraging )
|
|
return;
|
|
|
|
TUndoLite* pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo();
|
|
int iType = pLite->iType;
|
|
|
|
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<nCellNum; i++ ){
|
|
keys[i] = aParam[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( iTrk<g_iSelAudio )
|
|
g_iSelAudio--;
|
|
else if( iTrk==g_iSelAudio ){
|
|
SelectTrack( -1, -1, -1 );
|
|
}
|
|
}
|
|
else{
|
|
if( g_iViewMode!=VIEW_TRACK )
|
|
Application->MainForm->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; i<num; i++ ){
|
|
TAudioTrack* pTrack = DuplicateAudioTrack( (*aTracks)[i] );
|
|
|
|
if( iTrack==0 ){
|
|
delete g_aAudioTracks[0];
|
|
g_aAudioTracks.clear();
|
|
}
|
|
|
|
g_aAudioTracks.insert( g_aAudioTracks.begin()+iTrack, pTrack );
|
|
|
|
AudioEffectsSet( iTrack );
|
|
|
|
if( pTrack->IsSolo() )
|
|
bSolo = true;
|
|
|
|
if( !pTrack->IsHide() )
|
|
bInit = true;
|
|
|
|
iTrack++;
|
|
}
|
|
}
|
|
else{
|
|
for( int i=0; i<num; i++ ){
|
|
if( g_aAudioTracks[iTrack]->IsSolo() )
|
|
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<g_iSelAudio )
|
|
g_iSelAudio--;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
iTrkType = ( iType>=UNDO_TRKAUD_SHOW && iType<=UNDO_TRKAUD_HIDEALL ) ? ST_AUDIO : ST_MIDI;
|
|
vector<BYTE>* arrIndex = (vector<BYTE>*)pLite->pBefore;
|
|
|
|
for( int i=0; i<arrIndex->size(); 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) );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|