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

415 lines
11 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#include <Vcl.Imaging.pngimage.hpp>
#pragma hdrstop
#include "GlobalUnit.h"
#include "ChordPanel.h"
#define COL_HEIGHT 40
#define COL_GAP 10
#define MAINKEY_WIDTH 50
#define ADJKEY_WIDTH 40
#define CHORDTYPE_WIDTH 96
String u_strChordType[] = { "大三 Maj", "小三 Min", "大小七 7", "小七 Min7",
"挂二 Sus2", "挂四 Sus4", "挂六 Sus6", "大七 Maj7" };
//---------------------------------------------------------------------------
#pragma package(smart_init)
__fastcall TChordPanel::TChordPanel(TComponent* AOwner)
: TToolpalPanel(AOwner)
{
m_iType = TPTYPE_CHORD;
m_nTextHeight = 40;
m_iMelodyKey = 0;
m_iMainKey = m_iChordType = -1;
m_iAdjustKey = 0;
m_bEnable = false;
m_lblName = NULL;
m_lblType = NULL;
m_strTitle = "和弦设置";
AddToolBtn( 3, "imgAlphaChord", KeyModeClick, "显示英文和弦" );
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::CreateWnd(void)
{
TToolpalPanel::CreateWnd();
m_lblName = new TLabel(this);
m_lblName->Parent = this;
m_lblName->Alignment = taCenter;
m_lblName->Layout = tlCenter;
m_lblName->AutoSize = false;
m_lblName->SetBounds( LEFT_BOUND + COL_GAP,
m_nTitleHeight + COL_GAP,
MAINKEY_WIDTH + ADJKEY_WIDTH + COL_GAP,
m_nTextHeight - COL_GAP );
m_lblName->Font->Name = g_strTxtFontName;
// m_lblName->Font->Size = g_szFont9;
m_lblName->Font->Color = RGB(156, 170, 189);
m_lblName->Caption = g_bAlphaKey ? L"和弦调号" : L"和弦级数";
m_lblType = new TLabel(this);
m_lblType->Parent = this;
m_lblType->Alignment = taCenter;
m_lblType->Layout = tlCenter;
m_lblType->AutoSize = false;
m_lblType->SetBounds( m_lblName->Left + m_lblName->Width + 16,
m_nTitleHeight + COL_GAP,
CHORDTYPE_WIDTH,
m_nTextHeight - COL_GAP );
m_lblType->Font->Name = g_strTxtFontName;
// m_lblType->Font->Size = g_szFont9;
m_lblType->Font->Color = RGB(156, 170, 189);
m_lblType->Caption = L"和弦类型";
for( int i = 0; i < 7; i++ ){
m_aMainKeys[i] = new TTextButton(this);
m_aMainKeys[i]->Parent = this;
m_aMainKeys[i]->Enabled = false;
m_aMainKeys[i]->OnClick = MainKeyClick;
m_aMainKeys[i]->Tag = MainKeyTag( i );
m_aMainKeys[i]->Text = g_bAlphaKey ? g_strAlphaTable[i] : g_strTable[i];
m_aMainKeys[i]->FontName = g_strTxtFontName;
m_aMainKeys[i]->FontSize = g_szFont12;
m_aMainKeys[i]->SetBounds( LEFT_BOUND + COL_GAP,
m_nTitleHeight + m_nTextHeight + i*COL_HEIGHT,
MAINKEY_WIDTH, COL_HEIGHT );
}
for( int i=0; i<2; i++ ){
m_aAdjustKeys[i] = new TTextButton(this);
m_aAdjustKeys[i]->Parent = this;
m_aAdjustKeys[i]->Enabled = false;
m_aAdjustKeys[i]->OnClick = AdjustKeyClick;
m_aAdjustKeys[i]->Tag = i==0 ? 1 : -1;
m_aAdjustKeys[i]->Text = i==0 ? "#" : "b";
m_aAdjustKeys[i]->FontName = g_strTxtFontName;
m_aAdjustKeys[i]->FontSize = g_szFont12;
m_aAdjustKeys[i]->SetBounds( m_aMainKeys[0]->Left + m_aMainKeys[0]->Width + COL_GAP,
m_nTitleHeight + m_nTextHeight + i*COL_HEIGHT,
ADJKEY_WIDTH, COL_HEIGHT );
}
for( int i=0; i<c_Type_Num; i++ ){
m_aChordTypes[i] = new TTextButton(this);
m_aChordTypes[i]->Parent = this;
m_aChordTypes[i]->Enabled = false;
m_aChordTypes[i]->OnClick = ChordTypeClick;
m_aChordTypes[i]->Tag = i;
m_aChordTypes[i]->Text = u_strChordType[i];
m_aChordTypes[i]->FontName = g_strTxtFontName;
m_aChordTypes[i]->FontSize = g_szFont12;
int h = i;
if( i==7 ) h = 4;
else if( i>=4 ) h++;
m_aChordTypes[i]->SetBounds( m_aAdjustKeys[0]->Left + m_aAdjustKeys[0]->Width + 16,
m_nTitleHeight + m_nTextHeight + h*COL_HEIGHT,
CHORDTYPE_WIDTH, COL_HEIGHT );
}
m_lstBtnTools[0]->Down = g_bAlphaKey;
}
//---------------------------------------------------------------------------
__fastcall TChordPanel::~TChordPanel()
{
for( int i = 0; i < 7; i++ ){
SAFE_DELETE( m_aMainKeys[i] );
}
for( int i=0; i<2; i++ ){
SAFE_DELETE( m_aAdjustKeys[i] );
m_aAdjustKeys[i] = NULL;
}
for( int i=0; i<c_Type_Num; i++ ){
SAFE_DELETE( m_aChordTypes[i] );
}
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::WMSize(Winapi::Messages::TWMSize &Message)
{
TToolpalPanel::WMSize( Message );
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::SetChord( int iMainKey, int iAdjustKey, int iChordType )
{
if( m_iMainKey!=iMainKey ){
if( m_iMainKey>=0 )
m_aMainKeys[m_iMainKey]->SetDown( false );
if( iMainKey>=0 )
m_aMainKeys[iMainKey]->SetDown( true );
m_iMainKey = iMainKey;
}
EnableAdjustKey( iMainKey, iAdjustKey );
EnableChordType( iMainKey );
m_iAdjustKey = iAdjustKey;
if( m_iChordType!=iChordType ){
if( m_iChordType>=0 )
m_aChordTypes[m_iChordType]->SetDown(false);
if( iChordType>=0 )
m_aChordTypes[iChordType]->SetDown(true);
m_iChordType = iChordType;
}
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::MainKeyClick( TObject* Sender )
{
int iSeries = ((TTextButton*)Sender)->Tag,
iAdjustKey = 0,
iChordType = 0;
if( iSeries==1 || iSeries==2 || iSeries==5 )
iChordType = 1;
else if( iSeries==6 )
iAdjustKey = -1;
if( g_bAlphaKey ){
int iKey = (iSeries<3) ? (iSeries*2) : (iSeries*2 - 1);
iKey += m_iMelodyKey + iAdjustKey;
if( iKey<0 ) iKey += 12;
else if( iKey>11 ) iKey -= 12;
if( iKey==1 || iKey==3 || iKey==8 || iKey==10 ) iAdjustKey = -1;
else if( iKey==6 ) iAdjustKey = 1;
}
int iMainKey = -1;
for( int i=0; i<7; i++ ){
if( m_aMainKeys[i]==Sender ){
iMainKey = i;
break;
}
}
if( iMainKey!=m_iMainKey || iAdjustKey!=m_iAdjustKey || iChordType!=m_iChordType ){
SetChord( iMainKey, iAdjustKey, iChordType );
m_pContentPanel->SetSelectChord( GetChordKey(), iChordType );
}
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::AdjustKeyClick( TObject* Sender )
{
TTextButton* pAdjust = (TTextButton*)Sender;
int iAdjustKey = pAdjust->Down ? 0 : pAdjust->Tag;
if( iAdjustKey!=m_iAdjustKey ){
SetChord( m_iMainKey, iAdjustKey, m_iChordType );
m_pContentPanel->SetSelectChord( GetChordKey(), m_iChordType );
}
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::ChordTypeClick( TObject* Sender )
{
int iChordType = ((TTextButton*)Sender)->Tag;
if( iChordType!=m_iChordType ){
SetChord( m_iMainKey, m_iAdjustKey, iChordType );
m_pContentPanel->SetSelectChord( GetChordKey(), iChordType );
}
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::EnableChordModify( bool bEnable, int iBarKey, int iChordKey, int iChordType )
{
SetMelodyKey( iBarKey );
int iMainKey, iAdjustKey;
m_pContentPanel->GetChordDispalyKey( iChordKey, iBarKey, iMainKey, iAdjustKey );
if( bEnable!=m_bEnable ){
for( int i=0; i<7; i++ ){
TTextButton * pBtn = m_aMainKeys[i];
pBtn->Enabled = bEnable;
pBtn->SetDown( bEnable && i==iMainKey );
}
for( int i=0; i<c_Type_Num; i++ ){
TTextButton * pBtn = m_aChordTypes[i];
pBtn->Enabled = bEnable;
pBtn->SetDown( bEnable && i==iChordType );
}
EnableAdjustKey( bEnable ? iMainKey : 0, iAdjustKey );
EnableChordType( bEnable ? iMainKey : -1 );
m_bEnable = bEnable;
m_iMainKey = iMainKey;
m_iAdjustKey = iAdjustKey;
m_iChordType = iChordType;
}
else if( bEnable ){
SetChord( iMainKey, iAdjustKey, iChordType );
}
}
//---------------------------------------------------------------------------
void TChordPanel::EnableAdjustKey( int iMainKey, int iAdjustKey )
{
switch( iMainKey ){
case -1: case 0: case 4:
m_aAdjustKeys[0]->Enabled = false;
m_aAdjustKeys[1]->Enabled = false;
break;
case 3:
m_aAdjustKeys[0]->Enabled = true;
m_aAdjustKeys[1]->Enabled = false;
break;
default:
m_aAdjustKeys[0]->Enabled = false;
m_aAdjustKeys[1]->Enabled = true;
break;
}
m_aAdjustKeys[0]->SetDown( iAdjustKey>0 );
m_aAdjustKeys[1]->SetDown( iAdjustKey<0 );
}
//---------------------------------------------------------------------------
void TChordPanel::EnableChordType( int iMainKey )
{
for( int i=0; i<c_Type_Num; i++ ){
m_aChordTypes[i]->Enabled = iMainKey>=0;
}
}
//---------------------------------------------------------------------------
int TChordPanel::MainKeyTag( int index )
{
int iTag = index;
if( g_bAlphaKey && m_iMelodyKey>0 ){
int iOffset = 0;
switch( m_iMelodyKey ){
case 1: case 2: iOffset = 1; break;
case 3: case 4: iOffset = 2; break;
case 5: case 6: iOffset = 3; break;
case 7: iOffset = 4; break;
case 8: case 9: iOffset = 5; break;
case 10: case 11: iOffset = 6; break;
}
iTag -= iOffset;
if( iTag<0 )
iTag += 7;
}
return iTag;
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::SetMelodyKey( int iKey )
{
if( m_iMelodyKey!=iKey ){
m_iMelodyKey = iKey;
if( iKey>0 ){
for( int i=0; i<7; i++ ){
if( m_aMainKeys[i] )
m_aMainKeys[i]->Tag = MainKeyTag( i );
}
}
}
}
//---------------------------------------------------------------------------
int TChordPanel::GetChordKey()
{
int iKey = m_iMainKey;
switch( m_iMainKey ){
case 1: case 2:
iKey = m_iMainKey * 2;
if( m_iAdjustKey!=0 ) iKey += m_iAdjustKey;
break;
case 3:
iKey = 5;
if( m_iAdjustKey!=0 ) iKey += m_iAdjustKey;
break;
case 4:
iKey = 7;
break;
case 5: case 6:
iKey = m_iMainKey * 2 - 1;
if( m_iAdjustKey!=0 ) iKey += m_iAdjustKey;
break;
}
if( iKey>=0 && !g_bAlphaKey ){
iKey += m_iMelodyKey;
if( iKey>11 )
iKey -= 12;
}
return iKey;
}
//---------------------------------------------------------------------------
void __fastcall TChordPanel::KeyModeClick(TObject *Sender)
{
TPNGButton* pBtn = (TPNGButton*)Sender;
// pBtn->Down = !pBtn->Down;
SetKeyMode( !pBtn->Down );
}
//---------------------------------------------------------------------------
void TChordPanel::SetKeyMode( bool bAlpha )
{
if( g_bAlphaKey!= bAlpha ){
if( m_lblName ){
int iChordKey = GetChordKey();
g_bAlphaKey = bAlpha;
for( int i = 0; i < 7; i++ ){
m_aMainKeys[i]->Text = g_bAlphaKey ? g_strAlphaTable[i] : g_strTable[i];
m_aMainKeys[i]->Tag = MainKeyTag( i );
if( Visible )
m_aMainKeys[i]->Repaint();
}
if( Visible ){
int iMainKey, iAdjustKey;
m_pContentPanel->GetChordDispalyKey( iChordKey, m_iMelodyKey, iMainKey, iAdjustKey );
SetChord( iMainKey, iAdjustKey, m_iChordType );
}
m_lblName->Caption = g_bAlphaKey ? L"和弦调号" : L"和弦级数";
m_lstBtnTools[0]->Down = bAlpha;
}
else{
g_bAlphaKey = bAlpha;
}
m_pContentPanel->InvalidateShowBars( BAR_DATA );
}
}
//---------------------------------------------------------------------------