Initial commit

This commit is contained in:
2026-06-13 00:10:11 +08:00
commit 2191c1aed4
535 changed files with 184587 additions and 0 deletions
+595
View File
@@ -0,0 +1,595 @@
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "GlobalUnit.h"
#include "ShowBarsPanelUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//String u_strTable[7] = { L"", L"Ⅱ", L"Ⅲ", L"Ⅳ", L"", L"Ⅵ", L"Ⅶ" };
//String u_strEnglishTable[7] = { L"C", L"D", L"E", L"F", L"G", L"A", L"B" };
short u_Adjust[12][12] = {
0, -1, 0 , -1, 0 , 0 , 1 , 0 , -1 ,0, -1, 0,
-1, 0, -1, 0, 0, 1, 0, -1, 0, -1, 0, 0,
0, -1, 0, 0, 1, 0, -1, 0, -1, 0, 0, -1,
-1, 0, 0, 1, 0, -1, 0, -1, 0, 0, -1, 0,
0, 0 , 1, 0 , -1, 0, -1, 0, 0, -1, 0, -1,
0, 1, 0 , -1, 0 , -1, 0 , 0, -1, 0, -1, 0,
1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, 0,
0 , -1, 0, -1, 0, 0, -1, 0, -1, 0, 0, 1,
-1, 0, -1, 0, 0, -1, 0, -1, 0, 0, 1, 0,
0, -1, 0, 0, -1, 0, -1, 0 , 0 , 1, 0 , -1,
-1, 0, 0, -1, 0, -1, 0, 0, 1, 0, -1, 0,
0, 0 , -1, 0 , -1, 0, 0, 1, 0, -1, 0 , -1
};
BYTE u_MainChord[12][12] ={
0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6,
1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 0,
1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 0, 1,
2, 2, 3, 3, 4, 5, 5, 6, 6, 0, 1, 1,
2, 3, 3, 4, 5, 5, 6, 6, 0, 1, 1, 2,
3, 3, 4, 5, 5, 6, 6, 0, 1, 1, 2, 2,
3, 4, 5, 5, 6, 6, 0, 1, 1, 2, 2, 3,
4, 5, 5, 6, 6, 0, 1, 1, 2, 2, 3, 3,
5, 5, 6, 6, 0, 1, 1, 2, 2, 3, 3, 4,
5, 6, 6, 0, 1, 1, 2, 2, 3, 3, 4, 5,
6, 6, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5,
6, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6
};
//---------------------------------------------------------------------------
__fastcall TShowBarsPanel::TShowBarsPanel(TComponent* AOwner)
: Vcl::Extctrls::TPanel(AOwner)
{
m_nBarWidth = m_nDataWidth = POINTS_PER_BAR;
m_nBarHeight = 55;
m_nDataHeight = 30;
m_nLeftOriBound = m_nLeftBound = 15;
m_nRightBound = 20;
m_nTopBound = 1;
// m_sFont7 = int(7 * 96.0 / g_yDpi + 0.5),
// m_sFont8 = int(8 * 96.0 / g_yDpi + 0.5),
// m_sFont9 = int(9 * 96.0 / g_yDpi + 0.5),
// m_sFont14 = int(14 * 96.0 / g_yDpi + 0.5),
// m_sFont16 = int(16 * 96.0 / g_yDpi + 0.5);
m_bPlaying = false;
}
//---------------------------------------------------------------------------
void __fastcall TShowBarsPanel::CreateWnd(void)
{
Vcl::Extctrls::TPanel::CreateWnd();
if( !ParentBackground ){
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_imgBackground = new TBitmap();
m_imgBackground->LoadFromResourceName(int(HInstance), L"CustomPanelBackground");
m_imgBarTitle = new TBitmap();
m_imgBarTitle->LoadFromResourceName(int(HInstance), L"BarTitle");
m_nTitleHeight = m_imgBarTitle->Height;
m_nBarDrawHeight = m_nTitleHeight + m_nDataHeight;
m_nRowGapHeight = m_nBarHeight - m_nBarDrawHeight;
Canvas->Font->Name = "黑体";
Canvas->Font->Size = g_szFont8;
Canvas->Font->Color = RGB(60,43,23);
InitialVars(0);
}
else{
m_imgBackground = NULL;
m_imgBarTitle = NULL;
}
}
//---------------------------------------------------------------------------
__fastcall TShowBarsPanel::~TShowBarsPanel()
{
if( m_imgBackground )
delete m_imgBackground;
if( m_imgBarTitle )
delete m_imgBarTitle;
if( m_sbVert )
delete m_sbVert;
}
//---------------------------------------------------------------------------
void TShowBarsPanel::InitialVars(int nBarNum)
{
if( m_nColumnNum==0 )
CalcViewArea();
m_nBeginShowRow = 0;
m_nBarNum = nBarNum;
m_nRowNum = m_nBarNum / m_nColumnNum;
if( m_nBarNum % m_nColumnNum>0 ){
m_nRowNum++;
}
if( m_nRowNum>m_nRowShow ){
if( !m_sbVert->Visible ){
m_sbVert->Visible = true;
}
m_sbVert->SetRange( 0, m_nRowNum-1 );
m_sbVert->SetPageSize( m_nRowShow );
m_sbVert->SetPosition( 0 );
}
else {
m_sbVert->Visible = false;
m_sbVert->SetRange( 0, 0, false );
m_sbVert->SetPageSize( 0, false );
m_sbVert->SetPosition( 0, false );
}
Invalidate();
}
//---------------------------------------------------------------------------
void TShowBarsPanel::SetPlayPoint( int iBar, int iPoint )
{
int iRow, iCol;
TRect rectOld(0,0,0,0), rectNew(0,0,0,0);
iRow = m_iPlayBar / m_nColumnNum - m_nBeginShowRow;
iCol = m_iPlayBar % m_nColumnNum;
if( iRow>=0 ){
rectOld.left = iCol * m_nBarWidth + m_iPlayPoint + m_nLeftBound;
rectOld.right = rectOld.left + 1;
rectOld.top = iRow * m_nBarHeight + m_nTopBound + m_nRowGapHeight;
rectOld.bottom = rectOld.top + m_nBarDrawHeight;
}
m_iPlayBar = iBar;
m_iPlayPoint = iPoint;
iRow = m_iPlayBar / m_nColumnNum - m_nBeginShowRow;
iCol = m_iPlayBar % m_nColumnNum;
rectNew.left = iCol * m_nBarWidth + m_iPlayPoint + m_nLeftBound;
rectNew.right = rectNew.left + 1;
rectNew.top = iRow * m_nBarHeight + m_nTopBound + m_nRowGapHeight;
rectNew.bottom = rectNew.top + m_nBarDrawHeight;
if( iRow<0 ){
ScrollView( iRow + m_nBeginShowRow );
}
else if( iRow>(m_nRowShow-1) ){
int nRowScroll = min( m_nRowShow+m_nBeginShowRow-1, m_nRowNum-iRow ); // 显示到第2行
ScrollView( nRowScroll );
}
else{
InvalidateRect( Handle, &rectOld, false );
InvalidateRect( Handle, &rectNew, false );
}
}
//---------------------------------------------------------------------------
void TShowBarsPanel::InvalidateBar( int iBar, int iBeginPoint, int iEndPoint, int iArea )
{
int iRow, iCol;
TRect rectDraw;
iRow = iBar / m_nColumnNum - m_nBeginShowRow;
iCol = iBar % m_nColumnNum;
rectDraw.left = iCol * m_nBarWidth + m_nLeftBound + iBeginPoint;
rectDraw.right = iCol * m_nBarWidth + m_nLeftBound + iEndPoint+1;
int nBarTop = iRow * m_nBarHeight + m_nTopBound;
rectDraw.bottom = nBarTop + m_nRowGapHeight;
rectDraw.top = rectDraw.bottom + m_nTitleHeight;
if( iArea & BAR_HEADER ){
rectDraw.top = nBarTop;
}
else if( iArea & BAR_TITLE ){
rectDraw.top = nBarTop + m_nRowGapHeight;
}
if( iArea & BAR_DATA ){
rectDraw.bottom = nBarTop + m_nBarHeight;
}
else if( iArea & BAR_TITLE ){
rectDraw.bottom = nBarTop + m_nRowGapHeight + m_nTitleHeight;
}
InvalidateRect( Handle, &rectDraw, false );
}
//---------------------------------------------------------------------------
void TShowBarsPanel::ScrollView( int nPos, bool bRedraw )
{
if( m_nBeginShowRow!=nPos ){
m_nBeginShowRow = nPos;
BarPosChanged();
Invalidate();
}
if( bRedraw ){
m_sbVert->SetPosition( nPos );
}
}
//---------------------------------------------------------------------------
void TShowBarsPanel::CalcViewArea()
{
if( ClientWidth>0 && ClientHeight>0 ){
m_nColumnNum = (ClientWidth - m_nLeftOriBound - m_nRightBound) / m_nBarWidth;
m_nRowShow = (ClientHeight - m_nTopBound - 1) / m_nBarHeight;
m_nLeftBound = (( ClientWidth - m_nRightBound ) % m_nBarWidth)/2 ;
}
}
//---------------------------------------------------------------------------
void TShowBarsPanel::DrawBars()
{
int rowTop = m_nTopBound, nBarCount = 0;
Canvas->Pen->Color = COLOR_BORDER;
if( m_nBeginShowRow>0 ){
nBarCount = m_nBeginShowRow * m_nColumnNum;
}
for( int i=m_nBeginShowRow; i<m_nRowNum && i<m_nBeginShowRow+m_nRowShow; i++ ){
int right, barTop = rowTop + m_nRowGapHeight;
if( m_nBarNum - nBarCount >= m_nColumnNum ){ //显示整满行
right = m_nColumnNum * m_nBarWidth + m_nLeftBound;
}
else{ //显示非整行
right = (m_nBarNum - nBarCount) * m_nBarWidth + m_nLeftBound;
}
//绘制第一个小节线
Canvas->MoveTo( m_nLeftBound, barTop );
Canvas->LineTo( m_nLeftBound, barTop + m_nBarDrawHeight );
for( int j=0; j<m_nColumnNum && nBarCount<m_nBarNum; j++ ){
String strText;
int iBarLeft = j*m_nBarWidth + m_nLeftBound;
//绘制小节栏
Canvas->Draw( iBarLeft+1, barTop, m_imgBarTitle );
//绘制小节序号
strText = IntToStr(nBarCount+1);
SetBarTitle( nBarCount, strText );
Canvas->Brush->Style = bsClear;
Canvas->TextOut( iBarLeft + 8, barTop + 1, strText );
DrawBarBkgnd( nBarCount, iBarLeft+1, barTop+m_nTitleHeight );
//绘制小节线
Canvas->MoveTo( iBarLeft + m_nBarWidth, barTop );
Canvas->LineTo( iBarLeft + m_nBarWidth, barTop + m_nBarDrawHeight );
DrawBarContext( nBarCount, iBarLeft, barTop+m_nTitleHeight );
//绘制播放线
if( m_iPlayBar==nBarCount ){
TColor clrOld = Canvas->Pen->Color;
Canvas->Pen->Color = g_clrPlayLine;
Canvas->MoveTo( iBarLeft + m_iPlayPoint, barTop );
Canvas->LineTo( iBarLeft + m_iPlayPoint, barTop + m_nBarDrawHeight );
Canvas->Pen->Color = clrOld;
}
DrawBarOperation( nBarCount, iBarLeft, rowTop );
nBarCount++;
}
// 绘制音频栏下框
Canvas->MoveTo( m_nLeftBound, rowTop + m_nBarHeight );
Canvas->LineTo( right+1, rowTop + m_nBarHeight );
rowTop += m_nBarHeight;
}
}
//---------------------------------------------------------------------------
void __fastcall TShowBarsPanel::Paint()
{
if( !ParentBackground ){
DrawBars();
}
}
//---------------------------------------------------------------------------
void __fastcall TShowBarsPanel::WMEraseBkgnd(Winapi::Messages::TWMEraseBkgnd &Message)
{
if( m_imgBackground ){
TCanvas* tempCanvas = new TCanvas;
tempCanvas->Handle = Message.DC;
//绘制底图
int cx = ClientWidth/m_imgBackground->Width + 1;
int cy = ClientHeight/m_imgBackground->Height + 1;
for (int i=0; i<cx; i++)
for (int j=0; j<cy; j++)
tempCanvas->Draw(i*m_imgBackground->Width,
j*m_imgBackground->Height,
m_imgBackground);
//绘制外边框
tempCanvas->Brush->Color = COLOR_BORDER;
TRect rect = GetClientRect();
tempCanvas->FrameRect(rect);
delete tempCanvas;
Message.Result = true;
}
else{
DefaultHandler( &Message );
}
}
//---------------------------------------------------------------------------
void __fastcall TShowBarsPanel::WMSize(Winapi::Messages::TWMSize &Message)
{
DefaultHandler( &Message );
if( ParentBackground )
return;
int nOriBeginShowRow = m_nBeginShowRow,
nOriRowNum = m_nRowNum,
nOriColumnNum = m_nColumnNum;
int iFirstShowBar = 0;
if( m_nBarNum>0 && m_nBeginShowRow>0 ){ //保存原显示的第一个小节
iFirstShowBar = m_nBeginShowRow * m_nColumnNum;
}
CalcViewArea();
if( m_sbVert ){
m_sbVert->Left = ClientWidth - m_sbVert->Width - 1;
m_sbVert->Top = 1;
m_sbVert->Height = ClientHeight - 2;
}
if( m_iPlayBar>=0 && m_bPlaying ){
iFirstShowBar = m_iPlayBar - m_nColumnNum; //显示到第2行
}
if( iFirstShowBar<0 ){
iFirstShowBar = 0;
}
if( m_nBarNum>0 ){
m_nRowNum = m_nBarNum / m_nColumnNum + 1;
if( m_nBarNum % m_nColumnNum==0 ){
m_nRowNum--;
}
if( m_nRowNum>m_nRowShow ){ //显示滚动条
m_sbVert->Visible = true;
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;
}
}
ScrollView( iRowScroll );
}
else{
m_nBeginShowRow = 0;
m_sbVert->Visible = false;
}
}
if( m_nRowNum!=nOriRowNum || m_nColumnNum!=nOriRowNum || m_nBeginShowRow!=nOriBeginShowRow ){
BarPosChanged();
Invalidate();
}
}
//---------------------------------------------------------------------------
void __fastcall TShowBarsPanel::WMVScroll(Winapi::Messages::TWMScroll &Message)
{
int minpos, maxpos, page, curpos;
m_sbVert->GetScrollRange(&minpos, &maxpos);
page = m_sbVert->GetPageSize();
// Get the current position of scroll box.
curpos = m_sbVert->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!=m_sbVert->Handle )
m_sbVert->SetPosition(curpos);
ScrollView(curpos, FALSE);
Message.Result = true;
}
//---------------------------------------------------------------------------
void __fastcall TShowBarsPanel::WMMouseWheel(TWMMouseWheel &Message)
{
if( m_sbVert->Visible ){
UINT nSBCode;
if( Message.WheelDelta>0 ) nSBCode = SB_LINEUP;
else nSBCode = SB_LINEDOWN;
Perform( WM_VSCROLL, MAKELONG(nSBCode,0), NULL );
}
}
//---------------------------------------------------------------------------
DWORD TShowBarsPanel::HitTest( int X, int Y, int& iHitType, bool bAbsorb, bool bIgnoreBound )
{
if( bIgnoreBound ){
if( X <= m_nLeftBound )
X = m_nLeftBound + 1;
if( X >= m_nColumnNum*m_nBarWidth+m_nLeftBound )
X = m_nColumnNum*m_nBarWidth+m_nLeftBound - 1;
if( Y <= m_nTopBound )
Y = m_nTopBound + 1;
if( Y >= (m_nRowNum-m_nBeginShowRow)*m_nBarHeight+m_nTopBound )
Y = (m_nRowNum-m_nBeginShowRow)*m_nBarHeight+m_nTopBound - 1;
}
else if( X <= m_nLeftBound || X >= m_nColumnNum*m_nBarWidth+m_nLeftBound ||
Y <= m_nTopBound || Y >= (m_nRowNum-m_nBeginShowRow)*m_nBarHeight+m_nTopBound ){
iHitType = -1;
return -1;
}
int iRow = ( Y - m_nTopBound ) / m_nBarHeight + m_nBeginShowRow;
int iCol = ( X - m_nLeftBound ) / m_nBarWidth;
int iBar = iRow * m_nColumnNum + iCol;
int deltaY = ( Y - m_nTopBound ) % m_nBarHeight;
int deltaX = ( X - m_nLeftBound ) % m_nBarWidth;
int nAbsorbWidth = bAbsorb ? CELL_ABSORB_WIDTH : 0;
if( iBar<m_nBarNum && iBar>=0 ){
if( deltaY<m_nRowGapHeight ){
iHitType = 0;
}
else if( deltaY<m_nBarHeight-m_nDataHeight ){
iHitType = 1;
}
else{
iHitType = 2;
}
if( m_nBarWidth-deltaX<nAbsorbWidth && iBar<m_nBarNum-1 ){ // 小节线左侧
return MAKELONG( iBar+1, 0 );
}
else if( deltaX<nAbsorbWidth ){ // 小节线右侧
return MAKELONG( iBar, 0 );
}
else{
return MAKELONG( iBar, deltaX );
}
}
else if( bIgnoreBound && iBar>=m_nBarNum ){
iHitType = 2;
return MAKELONG( m_nBarNum-1, deltaX );
}
else{
iHitType = -1;
}
return -1;
}
//-----------------------------------------------------------------------------
void __fastcall TShowBarsPanel::DrawChord( TRect& rcDraw, int iChord )
{
int iMainKey, iAjustKey, iType; //调级数、升降、大小
GetChordKey( iChord, iMainKey, iAjustKey, iType );
UniDrawChord(Canvas, rcDraw, iMainKey, iAjustKey, iType);
}
//-----------------------------------------------------------------------------
void TShowBarsPanel::GetChordKey( int iChord, int& iMainKey, int& iAjustKey, int& iType )
{
int iKey = ( iChord / CHORD_TYPE_NUM ) % KEY_NUM;
iType = iChord % CHORD_TYPE_NUM;
if( g_iShowType ){
iMainKey = u_MainChord[g_iMelodyKey][iKey];
iAjustKey = u_Adjust[g_iMelodyKey][iKey];
}
else{
iAjustKey = 0;
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;
}
}
}
//-----------------------------------------------------------------------------