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

642 lines
17 KiB
C++

//---------------------------------------------------------------------------
#pragma hdrstop
#include "StyleSelPanel.h"
#include "GlobalUnit.h"
#include <math.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define MAX_WIDTH 400
#define MIN_WIDTH 200
#define FRAME_TOP 20
#define FRAME_LEFT 14
#define FRAME_BOTTOM 12
#define SEL_LINE 40 //分页符的线条
#define SEL_HEIGH 15
#define SEL_RIGHT 20
#define BTN_TOP 5
#define BTN_LEFT 0
#define BTN_WIDTH 70
#define BTN_HEIGHT 16
#define MAX_EDIT_W 250
__fastcall SearchItem::SearchItem( System::Classes::TComponent* AOwner )
: TCKBox(AOwner)
{
count = 0;
}
__fastcall SearchItem::~SearchItem(void)
{
}
__fastcall TStyleSelPanel::TStyleSelPanel(System::Classes::TComponent* AOwner)
: Vcl::Extctrls::TPanel(AOwner)
{
Color = RGB(47,50,57);
m_ListStyle = new TList();
m_ListInstrBtn = new TList();
//添加风格
AddStyleButton("流行",0);
AddStyleButton("民谣",1);
AddStyleButton("摇滚",2);
AddStyleButton("舞曲",3);
AddStyleButton("爵士",4);
AddStyleButton("蓝调",5);
AddStyleButton("桑巴",6);
AddStyleButton("古典",7);
AddStyleButton("圆舞曲",8);
AddStyleButton("其他",-2); //修改为 >9
AddStyleButton("全选",-3,false);
AddStyleButton("全不选",-3,false);
//添加乐器
AddInstrButton("钢琴",2,0,1);
AddInstrButton("电钢琴",4,2,3,4,5);
AddInstrButton("风琴",8,16,17,18,19,20,21,22,23);
AddInstrButton("木吉他",2,24,25);
AddInstrButton("电吉他",3,25,26,27);
AddInstrButton("失真吉他",2,29,30);
AddInstrButton("小提琴",1,40);
AddInstrButton("竖琴",1,46);
AddInstrButton("弦乐",4,48,49,50,51);
AddInstrButton("小号",1,56);
AddInstrButton("铜管",3,61,62,63);
AddInstrButton("萨克斯",4,64,65,66,67);
AddInstrButton("长笛",1,73);
AddInstrButton("合成主音",8,80,81,82,83,84,85,86,87);
AddInstrButton("合成背景",8,88,89,90,91,92,93,94,95);
//排序选项
for( int i=0; i<2; i++ ){
m_lblSort[i] = new TLabel(this);
m_lblSort[i]->Visible = false;
m_lblSort[i]->Parent = this;
m_lblSort[i]->ControlStyle>>csOpaque;
m_lblSort[i]->Layout = tlCenter;
m_lblSort[i]->Font->Name = g_strTxtFontName;
m_lblSort[i]->Font->Size = g_szFont9;
m_lblSort[i]->Font->Color = RGB( 156, 170, 189 );
m_lblSort[i]->Height = BTN_HEIGHT;
m_lblSort[i]->Width = 30;
m_cbSort[i] = new TComboBoxComponent(NULL);
m_cbSort[i]->Visible = false;
m_cbSort[i]->Parent = this;
m_cbSort[i]->Width = 60;
m_cbSort[i]->Height = BTN_HEIGHT;
m_cbSort[i]->SetFont(g_strTxtFontName, g_szFont9);
m_cbSort[i]->OnChange = SortChanged;
}
m_lblSort[0]->Caption = "比较:";
m_cbSort[0]->AddItem("序号");
m_cbSort[0]->AddItem("价格");
m_cbSort[0]->AddItem("评分");
m_cbSort[0]->AddItem("速度");
m_lblSort[1]->Caption = "排列:";
m_cbSort[1]->AddItem("递减");
m_cbSort[1]->AddItem("递增");
m_LineEit = new TLineEdit(this);
m_LineEit->Visible = false;
m_LineEit->Parent = this;
m_LineEit->Color =RGB( 58,63,69 );
m_LineEit->Font->Name = g_strTxtFontName;
m_LineEit->Font->Size = g_szFont9;
m_LineEit->Font->Color = RGB( 161,170,179 );
m_LineEit->HintColor = RGB(161,170,179);
m_LineEit->HintText = "(查找)";
OnMouseMove = CMMouseMove;
OnMouseDown = CMMouseDown;
iSelect = SORT;
iMouse = -1;
oldX = 0;
oldY = 0;
oldAddLeft = 0;
iSortType = 0;
iSortMode = 1;
m_img = new TPngImage();
m_img->LoadFromResourceName(int(HInstance), L"imgPylon");
}
__fastcall TStyleSelPanel::~TStyleSelPanel(void)
{
for( int i=0; i<m_ListStyle->Count; i++ )
delete (SearchItem*)m_ListStyle->Items[i];
m_ListStyle->Clear();
delete m_ListStyle;
m_ListStyle = NULL;
for( int i=0; i<m_ListInstrBtn->Count; i++ )
delete (SearchItem*)m_ListInstrBtn->Items[i];
m_ListInstrBtn->Clear();
delete m_ListStyle;
m_ListStyle = NULL;
if(m_LineEit){
delete m_LineEit;
m_LineEit = NULL;
}
for( int i=0; i<2; i++ ){
delete m_lblSort[i];
m_lblSort[i] = NULL;
delete m_cbSort[i];
m_cbSort[i] = NULL;
}
if(m_img){
delete m_img;
m_img = NULL;
}
}
void __fastcall TStyleSelPanel::CreateWnd(void)
{
Vcl::Extctrls::TPanel::CreateWnd();
Canvas->Font->Name = g_strTxtFontName;
Canvas->Font->Quality = TFontQuality::fqClearTypeNatural;
Canvas->Font->Size = g_szFont9;
}
void __fastcall TStyleSelPanel::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
TRect rect = GetClientRect();
TCanvas* tempCanvas = new TCanvas;
tempCanvas->Handle = Message.DC;
tempCanvas->Brush->Color = RGB(58,63,69); //外背景
tempCanvas->FillRect(rect);
tempCanvas->Brush->Color = RGB(47,50,57); //内背景
tempCanvas->FillRect(framRet);
//上边线
tempCanvas->Pen->Color = RGB(47,50,57);
tempCanvas->MoveTo(rect.Left, rect.Top);
tempCanvas->LineTo(rect.Right,rect.Top);
tempCanvas->Pen->Color = RGB(30,31,36); //线条
tempCanvas->MoveTo(framRet.Left,framRet.Top); //左
tempCanvas->LineTo(framRet.Left,framRet.Bottom);
tempCanvas->MoveTo(framRet.Left,framRet.Bottom); //下
tempCanvas->LineTo(framRet.Right,framRet.Bottom);
tempCanvas->MoveTo(framRet.Right,framRet.Bottom); //右
tempCanvas->LineTo(framRet.Right,framRet.Top);
tempCanvas->MoveTo(framRet.Left,framRet.Top); //上
tempCanvas->LineTo(framRet.Right -SEL_RIGHT - 2*SEL_LINE +5,framRet.Top );
tempCanvas->MoveTo(framRet.Right -SEL_RIGHT,framRet.Top);
tempCanvas->LineTo(framRet.Right,framRet.Top);
tempCanvas->MoveTo( 0,Height -1 );
tempCanvas->LineTo( Width,Height -1 );
delete tempCanvas;
tempCanvas = NULL;
}
void __fastcall TStyleSelPanel::Paint(void)
{
for( int i=0; i<3; i++ ){
if( iSelect!=i )
DrawTab( i );
}
DrawTab( iSelect );
}
void TStyleSelPanel::DrawTab( int index )
{
TPoint *P = new TPoint[4];
String strText;
int l;
if( index==INSTR ){
strText = L"乐器";
P[0].X = framRet.Right - SEL_RIGHT -2*SEL_LINE +5;
P[0].Y = framRet.Top;
P[1].X = framRet.Right - SEL_RIGHT - SEL_LINE + 5;
P[1].Y = framRet.Top;
P[2].X = framRet.Right - SEL_RIGHT - SEL_LINE;
P[2].Y = framRet.Top - SEL_HEIGH;
P[3].X = framRet.Right - SEL_RIGHT - 2*SEL_LINE + 10;
P[3].Y = framRet.Top - SEL_HEIGH;
l = framRet.Right - SEL_RIGHT -2*SEL_LINE+5;
}
else if( index==STYLE ){
strText = L"分类";
P[0].X = framRet.Right - SEL_RIGHT -3*SEL_LINE +10;
P[0].Y = framRet.Top;
P[1].X = framRet.Right - SEL_RIGHT - 2*SEL_LINE + 10;
P[1].Y = framRet.Top;
P[2].X = framRet.Right - SEL_RIGHT - 2*SEL_LINE + 5;
P[2].Y = framRet.Top - SEL_HEIGH;
P[3].X = framRet.Right - SEL_RIGHT -3*SEL_LINE +15;
P[3].Y = framRet.Top - SEL_HEIGH;
l = framRet.Right - SEL_RIGHT -3*SEL_LINE+10;
}
else{
strText = L"排序";
P[0].X = framRet.Right - SEL_RIGHT -SEL_LINE;
P[0].Y = framRet.Top;
P[1].X = framRet.Right - SEL_RIGHT;
P[1].Y = framRet.Top;
P[2].X = framRet.Right - SEL_RIGHT -5;
P[2].Y = framRet.Top - SEL_HEIGH;
P[3].X = framRet.Right - SEL_RIGHT -SEL_LINE +5;
P[3].Y = framRet.Top - SEL_HEIGH;
l = framRet.Right - SEL_RIGHT -SEL_LINE;
}
Canvas->Pen->Color = iSelect==index ? RGB(47,50,57) : RGB(30,31,36);
Canvas->Brush->Color = iSelect==index ? RGB(47,50,57) : RGB(58,63,69);
Canvas->Polygon(P,3);
Canvas->Draw( l, framRet.Top - SEL_HEIGH ,m_img );
Canvas->Font->Color = iMouse==index ? RGB(145,164,170) : RGB(120,126,148);
// Canvas->Font->Size = g_szFont8;
Canvas->TextOutW( P[3].X+4, P[3].Y+2, strText );
delete[] P;
}
void __fastcall TStyleSelPanel::CMMouseMove(System::TObject* Sender,
System::Classes::TShiftState Shift, int X, int Y)
{
TRect rct;
rct.init(framRet.Right-3*SEL_LINE-SEL_RIGHT+10,framRet.Top-SEL_HEIGH,
framRet.Right-SEL_RIGHT,framRet.Top+2);
if( iSelect!=STYLE && X>framRet.Right-SEL_RIGHT-3*SEL_LINE+10 && X<framRet.Right-SEL_RIGHT-2*SEL_LINE + 5
&& Y<framRet.Top && Y>framRet.Top-SEL_HEIGH )
{
if(iMouse != STYLE){
iMouse = STYLE;
InvalidateRect(Handle,&rct,true);
}
}
else if( iSelect!=INSTR && X>framRet.Right-SEL_RIGHT-2*SEL_LINE+5 && X<framRet.Right-SEL_RIGHT-SEL_LINE
&& Y<framRet.Top && Y>framRet.Top-SEL_HEIGH )
{
if(iMouse!=INSTR){
iMouse = INSTR;
InvalidateRect(Handle,&rct,true);
}
}
else if( iSelect!=SORT && X>framRet.Right-SEL_LINE-SEL_RIGHT+5 && X<framRet.Right-SEL_RIGHT
&& Y<framRet.Top && Y>framRet.Top-SEL_HEIGH )
{
if( iMouse != SORT ){
iMouse = SORT;
InvalidateRect(Handle,&rct,true);
}
}
else if(iMouse!=-1){
iMouse = -1;
InvalidateRect(Handle,&rct,true);
}
}
void __fastcall TStyleSelPanel::CMMouseDown(System::TObject* Sender, System::Uitypes::TMouseButton Button,
System::Classes::TShiftState Shift, int X, int Y)
{
int iPos = -1;
if( iSelect!=STYLE && X>framRet.Right-SEL_RIGHT-3*SEL_LINE+10 && X<framRet.Right-SEL_RIGHT-2*SEL_LINE + 5
&& Y<framRet.Top && Y>framRet.Top-SEL_HEIGH ) //点击分类
{
iPos = STYLE;
}
else if( iSelect!=INSTR && X>framRet.Right-SEL_RIGHT-2*SEL_LINE+5 && X<framRet.Right-SEL_RIGHT-SEL_LINE
&& Y<framRet.Top && Y>framRet.Top-SEL_HEIGH ) //点击乐器
{
iPos = INSTR;
}
else if( iSelect!=SORT && X>framRet.Right-SEL_LINE-SEL_RIGHT+5 && X<framRet.Right-SEL_RIGHT
&& Y<framRet.Top && Y>framRet.Top-SEL_HEIGH )
{
iPos = SORT;
}
if( iPos>=0 ){
iSelect = iPos;
oldX = 0;
oldY = 0;
int retHeight = GetHeight();
if( Height!=retHeight ){
Height = retHeight;
}
Parent->Perform( WM_SIZE, 0, MAKELONG( Parent->Width, Parent->Height ) );
Parent->Invalidate();
}
}
int TStyleSelPanel::GetHeight()
{
framRet.init( FRAME_LEFT, FRAME_TOP, Width - FRAME_LEFT, Height - FRAME_BOTTOM );
int btnWidth = Width - 2*FRAME_LEFT - BTN_LEFT;
int retHeight = Height;
if( iSelect == STYLE ){
int numX = btnWidth/( BTN_LEFT + BTN_WIDTH ); //行
int numY = ceil(m_ListStyle->Count/(double)numX ); //列
int AddLeft = (btnWidth - ((double)numX)*(BTN_WIDTH + BTN_LEFT))/((double)numX);
if( oldX!=numX || oldY!=numY || oldAddLeft!=AddLeft ){
oldX = numX;
oldY = numY;
oldAddLeft = AddLeft;
for( int i=0; i<m_ListInstrBtn->Count; i++ )
((SearchItem*)m_ListInstrBtn->Items[i])->Visible = false;
for( int i=0; i<2; i++ ){
m_lblSort[i]->Visible = false;
m_cbSort[i]->Visible = false;
}
retHeight = numY*(BTN_TOP+BTN_HEIGHT)+FRAME_TOP+FRAME_BOTTOM + BTN_TOP;
for( int i=0; i<numY; i++ ){
for(int j=0; j<numX;j++){
int m = i*numX + j;
if( m >= m_ListStyle->Count || m<0 )
break;
((SearchItem*)m_ListStyle->Items[m])->Left = BTN_LEFT+framRet.Left + j*(BTN_WIDTH + BTN_LEFT + AddLeft);
((SearchItem*)m_ListStyle->Items[m])->Top = BTN_TOP+framRet.Top + i*(BTN_TOP + BTN_HEIGHT);
((SearchItem*)m_ListStyle->Items[m])->Visible = true;
}
}
}
}
else if(iSelect == INSTR){
int numX = btnWidth/( BTN_LEFT+BTN_WIDTH ); //行
int numY = ceil(m_ListInstrBtn->Count/(double)numX ); //列
int AddLeft = (btnWidth - ((double)numX)*(BTN_WIDTH + BTN_LEFT))/((double)numX);
if( oldX!=numX || oldY!=numY || oldAddLeft!=AddLeft ){
oldX = numX;
oldY = numY;
oldAddLeft = AddLeft;
for( int i=0; i<m_ListStyle->Count; i++ )
((SearchItem*)m_ListStyle->Items[i])->Visible = false;
for( int i=0; i<2; i++ ){
m_lblSort[i]->Visible = false;
m_cbSort[i]->Visible = false;
}
retHeight = numY*(BTN_TOP+BTN_HEIGHT)+FRAME_TOP+FRAME_BOTTOM + BTN_TOP;
// OutputDebugString(IntToStr(AddLeft).c_str());
for( int i=0; i<numY; i++ ){
for(int j=0; j<numX;j++){
int m = i*numX +j;
if( m >= m_ListInstrBtn->Count || m<0 )
break;
((SearchItem*)m_ListInstrBtn->Items[m])->Left = BTN_LEFT+framRet.Left + j*(BTN_LEFT + BTN_WIDTH+AddLeft);
((SearchItem*)m_ListInstrBtn->Items[m])->Top = BTN_TOP+framRet.Top + i*(BTN_TOP + BTN_HEIGHT);
((SearchItem*)m_ListInstrBtn->Items[m])->Visible = true;
}
}
}
}
else{
for( int i=0; i<m_ListInstrBtn->Count; i++ )
((SearchItem*)m_ListInstrBtn->Items[i])->Visible = false;
for( int i=0; i<m_ListStyle->Count; i++ )
((SearchItem*)m_ListStyle->Items[i])->Visible = false;
int numX = btnWidth / ( BTN_LEFT + m_lblSort[0]->Width + m_cbSort[0]->Width + 10 ),
numY = ceil( 2 / (double)numX );
for( int i=0; i<numY; i++ ){
int pos = BTN_LEFT + framRet.Left + 10;
for(int j=0; j<numX;j++){
int m = i*numX +j;
if( m >= 2 || m<0 )
break;
m_lblSort[m]->Top = BTN_TOP+framRet.Top + i*(BTN_TOP + BTN_HEIGHT);
m_lblSort[m]->Visible = true;
m_lblSort[m]->Left = pos;
m_cbSort[m]->Top = BTN_TOP+framRet.Top + i*(BTN_TOP + BTN_HEIGHT);
m_cbSort[m]->Visible = true;
m_cbSort[m]->Left = m_lblSort[m]->Left + m_lblSort[m]->Width;
pos = m_cbSort[m]->Left + m_cbSort[m]->Width + 15;
}
}
m_cbSort[0]->DefItemIndex = iSortType;
m_cbSort[1]->DefItemIndex = iSortMode;
retHeight = numY*(BTN_TOP + BTN_HEIGHT) + FRAME_TOP + FRAME_BOTTOM + BTN_TOP;
}
return retHeight;
/* //LineEdit
m_LineEit->Left = framRet.Left + 3;
m_LineEit->Top = framRet.Top - SEL_HEIGH -3;
if( framRet.Width()- SEL_RIGHT - 2*SEL_LINE < MAX_EDIT_W )
m_LineEit->Width = framRet.Width()- SEL_RIGHT - 2*SEL_LINE;
else
m_LineEit->Width = MAX_EDIT_W;
m_LineEit->Height = SEL_HEIGH-2;
// if( !m_LineEit->Visible ) //显示LineEdit
// m_LineEit->Visible = true;
*/
}
void __fastcall TStyleSelPanel::WMSize( Winapi::Messages::TWMSize &Message )
{
if( Message.Width>FRAME_LEFT && Message.Height>FRAME_BOTTOM ){
framRet.init( FRAME_LEFT, FRAME_TOP,
Message.Width - FRAME_LEFT,
Message.Height - FRAME_BOTTOM );
int retHeight = GetHeight();
if( Height!=retHeight ){
Height = retHeight;
}
}
else{
OutputDebugString( L"error." );
}
}
void __fastcall TStyleSelPanel::CMClick(System::TObject* Sender)
{
if( ((SearchItem*)Sender)==m_ListStyle->Items[m_ListStyle->Count-2] ){ //全选
((SearchItem*)m_ListStyle->Items[m_ListStyle->Count-2])->Checked = false;
for( int i=0; i<m_ListStyle->Count-2; i++ ){
((SearchItem*)m_ListStyle->Items[i])->Checked = true;
}
}
else if( ((SearchItem*)Sender)==m_ListStyle->Items[m_ListStyle->Count-1] ){ //全不选
((SearchItem*)m_ListStyle->Items[m_ListStyle->Count-1])->Checked = false;
for( int i=0; i<m_ListStyle->Count-2; i++ ){
((SearchItem*)m_ListStyle->Items[i])->Checked = false;
}
}
else if(iSelect==INSTR ){
for( int i=0; i<m_ListInstrBtn->Count; i++ ){
if( ((SearchItem*)m_ListInstrBtn->Items[i])!=((SearchItem*)Sender)&&((SearchItem*)m_ListInstrBtn->Items[i])->Checked )
((SearchItem*)m_ListInstrBtn->Items[i])->Checked = false;
}
}
if( iSelect==STYLE){
DStyle.Length = 0; //清空列表
for(int i=0;i<m_ListStyle->Count-2;i++){ //去除掉全选与全不选按钮
if( ((SearchItem*)m_ListStyle->Items[i])->Checked ){
DStyle[DStyle.Length++] = ((SearchItem*)m_ListStyle->Items[i])->Tag;
}
}
}
else if( iSelect==INSTR ){
DInStr.Length = 0; //清空列表
for( int i=0;i<m_ListInstrBtn->Count;i++ ){
if( ((SearchItem*)m_ListInstrBtn->Items[i])->Checked ){
for( int n= 0;n<((SearchItem*)m_ListInstrBtn->Items[i])->count;n++ ){
DInStr[DInStr.Length++] = ((SearchItem*)m_ListInstrBtn->Items[i])->classify[n];
}
}
}
}
PostMessage( Parent->Handle, UM_SEARCH, NULL, NULL );//msg.WParam,msg.LParam );
}
void TStyleSelPanel::AddStyleButton(String sCaption,int iTag,bool bCheck )
{
SearchItem *m_StyleBtn = new SearchItem(this);
m_StyleBtn->Parent = this;
m_StyleBtn->Visible = false;
m_StyleBtn->Width = BTN_WIDTH;
m_StyleBtn->Height = BTN_HEIGHT;
m_StyleBtn->BoxColor =RGB( 39,42,47 );
m_StyleBtn->Font->Color = RGB( 145,164,170 );
m_StyleBtn->Font->Name = g_strTxtFontName;
m_StyleBtn->Font->Size = g_szFont9;
m_StyleBtn->Caption = sCaption;
m_StyleBtn->Checked = bCheck;
m_StyleBtn->OnClick = CMClick;
m_StyleBtn->Tag = iTag;
m_ListStyle->Add(m_StyleBtn);
}
void TStyleSelPanel::AddInstrButton(String sCaption,int num,...)
{
va_list parg;
va_start(parg, num);
SearchItem *m_InstrBtn = new SearchItem(this);
m_InstrBtn->Parent = this;
m_InstrBtn->Visible = false;
m_InstrBtn->Width = BTN_WIDTH;
m_InstrBtn->Height = BTN_HEIGHT;
m_InstrBtn->BoxColor = RGB( 39,42,47 );//RGB( 30,31,36 );
m_InstrBtn->Font->Color = RGB( 145,164,170 );
m_InstrBtn->Font->Name = g_strTxtFontName;
m_InstrBtn->Font->Size = g_szFont9;
m_InstrBtn->Caption = sCaption;
m_InstrBtn->OnClick = CMClick;
m_InstrBtn->count = num;
va_start(parg, num);
for( int i=0;i<num;i++ ){
int arg = va_arg(parg,int);
m_InstrBtn->classify[i] = arg;
}
va_end(parg);
m_ListInstrBtn->Add(m_InstrBtn);
}
void __fastcall TStyleSelPanel::CMMouseEnter(Winapi::Messages::TMessage &Msg)
{
Screen->Cursor = crDefault;
}
void TStyleSelPanel::Reset(void) //重置按钮
{
for( int i=0;i<m_ListStyle->Count-2;i++ ){
((SearchItem*)m_ListStyle->Items[i])->Checked = true;
}
DStyle.Length = 0; //清空列表
for(int i=0;i<m_ListStyle->Count-2;i++){ //加载所有按钮
if( ((SearchItem*)m_ListStyle->Items[i])->Checked ){
DStyle[DStyle.Length++] = ((SearchItem*)m_ListStyle->Items[i])->Tag;
}
}
for( int i=0;i<m_ListInstrBtn->Count;i++ ){
((SearchItem*)m_ListInstrBtn->Items[i])->Checked = false;
}
DInStr.Length = 0;
int retHeight = GetHeight();
if( Height!=retHeight ){
Height = retHeight;
}
}
void __fastcall TStyleSelPanel::SortChanged(TComboBoxItem *Sender, int Index)
{
bool bChanged = false;
if( iSortType!=m_cbSort[0]->DefItemIndex ){
iSortType = m_cbSort[0]->DefItemIndex;
bChanged = true;
}
else if(iSortMode!=m_cbSort[1]->DefItemIndex ){
iSortMode = m_cbSort[1]->DefItemIndex;
bChanged = true;
}
if( bChanged )
PostMessage( Parent->Handle, UM_SEARCH, NULL, NULL );
}