Files
AccompanyCube/PopMenuUnit.cpp
T
2026-06-13 00:10:11 +08:00

236 lines
6.4 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "GlobalUnit.h"
#include "PopMenuUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define POPMENU_MINWIDTH 60
#define BREAK_HEIGHT 5
#define CLR_DISABLE RGB(163,153,143)
__fastcall TPopMenu::TPopMenu(TComponent* Owner)
: TPopupMenu( Owner )
{
m_pPicChecked = m_pPicNormal = m_pPicHover = NULL;
OwnerDraw = TRUE;
AutoHotkeys = maManual;
m_pFntText = new TFont();
m_pFntText->Name = "黑体";
m_pFntText->Size = int(10 * 96.0 / g_yDpi + 0.5);
m_clrNormal = RGB(60,43,23);
m_clrHover = RGB(232,212,191);
m_clrBreak = RGB(150,118,80);
m_clrFrame = RGB(206,162,126);
m_pPicNormal = new TBitmap;
m_pPicNormal->LoadFromResourceName(int(HInstance), "MenuNormalBar");
m_pPicHover = new TBitmap;
m_pPicHover->LoadFromResourceName(int(HInstance), "MenuHoverBar");
m_pPicChecked = new TBitmap;
m_pPicChecked->LoadFromResourceName(int(HInstance), "MenuChecked");
}
__fastcall TPopMenu::~TPopMenu()
{
if( m_pPicNormal )
delete m_pPicNormal;
if( m_pPicHover )
delete m_pPicHover;
if( m_pPicChecked )
delete m_pPicChecked;
if( m_pFntText )
delete m_pFntText;
ClearMenuItem();
}
void TPopMenu::CreateCustomMenuItem( String strCaption, TNotifyEvent aClickEvent,
int subIndex, bool bEnabled, bool bChecked, int iTag )
{
TMenuItem * pItem = new TMenuItem( this );
pItem->Caption = strCaption;
pItem->OnAdvancedDrawItem = OwnerDrawItem;
pItem->OnMeasureItem = OwnerMeasureItem;
pItem->OnClick = aClickEvent;
pItem->Checked = bChecked;
pItem->Enabled = bEnabled;
pItem->Tag = iTag;
if( subIndex==-1 )
Items->Add( pItem );
else
Items->Items[subIndex]->Add( pItem );
}
void TPopMenu::ClearMenuItem()
{
for( int i=Items->Count-1; i>=0; i-- ){
Items->Delete(i);
}
}
void __fastcall TPopMenu::OwnerDrawItem(TObject* Sender, TCanvas* ACanvas, const TRect &ARect, TOwnerDrawState State)
{
TMenuItem *pItem = (TMenuItem*)Sender;
TRect rectDraw(ARect.left , ARect.top, ARect.right, ARect.bottom);
if( pItem->MenuIndex==0 ){ //第一个菜单项
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( ARect.left, ARect.top );
ACanvas->LineTo( ARect.right, ARect.top );
ACanvas->Pen->Color = m_clrFrame;
ACanvas->MoveTo( ARect.left+1, ARect.top+1 );
ACanvas->LineTo( ARect.right-1, ARect.top+1 );
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( ARect.left+2, ARect.top+2 );
ACanvas->LineTo( ARect.right-2, ARect.top+2 );
ACanvas->Pixels[ARect.left][ARect.top+1] = m_clrBreak;
ACanvas->Pixels[ARect.left][ARect.top+2] = m_clrBreak;
ACanvas->Pixels[ARect.right-1][ARect.top+1] = m_clrBreak;
ACanvas->Pixels[ARect.right-1][ARect.top+2] = m_clrBreak;
ACanvas->Pixels[ARect.left+1][ARect.top+2] = m_clrFrame;
ACanvas->Pixels[ARect.right-2][ARect.top+2] = m_clrFrame;
rectDraw.top += 3;
}
TMenuItem * pItemParent = pItem->Parent;
if( pItem->MenuIndex==pItemParent->Count-1 ){ //最后一个菜单项
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( ARect.left, ARect.bottom-1 );
ACanvas->LineTo( ARect.right, ARect.bottom-1 );
ACanvas->Pen->Color = m_clrFrame;
ACanvas->MoveTo( ARect.left+1, ARect.bottom-2 );
ACanvas->LineTo( ARect.right-1, ARect.bottom-2 );
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( ARect.left+2, ARect.bottom-3 );
ACanvas->LineTo( ARect.right-2, ARect.bottom-3 );
ACanvas->Pixels[ARect.left][ARect.bottom-2] = m_clrBreak;
ACanvas->Pixels[ARect.left][ARect.bottom-3] = m_clrBreak;
ACanvas->Pixels[ARect.right-1][ARect.bottom-2] = m_clrBreak;
ACanvas->Pixels[ARect.right-1][ARect.bottom-3] = m_clrBreak;
ACanvas->Pixels[ARect.left+1][ARect.bottom-3] = m_clrFrame;
ACanvas->Pixels[ARect.right-2][ARect.bottom-3] = m_clrFrame;
rectDraw.bottom -= 3;
}
//绘制左边框
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( rectDraw.left, rectDraw.top );
ACanvas->LineTo( rectDraw.left, rectDraw.bottom );
ACanvas->Pen->Color = m_clrFrame;
ACanvas->MoveTo( rectDraw.left+1, rectDraw.top );
ACanvas->LineTo( rectDraw.left+1, rectDraw.bottom );
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( rectDraw.left+2, rectDraw.top );
ACanvas->LineTo( rectDraw.left+2, rectDraw.bottom );
rectDraw.left += 3;
//绘制右边框
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( rectDraw.right-1, rectDraw.top );
ACanvas->LineTo( rectDraw.right-1, rectDraw.bottom );
ACanvas->Pen->Color = m_clrFrame;
ACanvas->MoveTo( rectDraw.right-2, rectDraw.top );
ACanvas->LineTo( rectDraw.right-2, rectDraw.bottom );
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( rectDraw.right-3, rectDraw.top );
ACanvas->LineTo( rectDraw.right-3, rectDraw.bottom );
rectDraw.right -= 3;
//绘制背景
if( State.Contains(odSelected) && !State.Contains(odDisabled) ){
//高亮项
m_pFntText->Color = m_clrHover;
ACanvas->StretchDraw( rectDraw, m_pPicHover );
}
else{
if( State.Contains(odDisabled) ){
//禁用项
m_pFntText->Color = CLR_DISABLE;
}
else{
//常规项
m_pFntText->Color = m_clrNormal;
}
ACanvas->StretchDraw( rectDraw, m_pPicNormal );
}
//绘制Check框
if( State.Contains(odChecked) ){
TRect rectCheck( rectDraw.left+4, rectDraw.top+4, rectDraw.left+20, rectDraw.top+20 );
ACanvas->StretchDraw( rectCheck, m_pPicChecked );
}
//绘制伴奏类型颜色
if( pItem->Tag>0 && (pItem->Tag & SHOW_STAGE_VAR) ){
TRect rectVar( rectDraw.right-28, rectDraw.top+4, rectDraw.right-4, rectDraw.top+20 );
ACanvas->Pen->Color = m_clrFrame;
ACanvas->Brush->Color = g_clrStage[pItem->Tag & 0xFFFF];
ACanvas->Rectangle( rectVar );
}
if( pItem->IsLine() ){
ACanvas->Pen->Color = m_clrFrame;
ACanvas->MoveTo( rectDraw.left+6, rectDraw.top+2 );
ACanvas->LineTo( rectDraw.right-6, rectDraw.top+2 );
}
else{
TFont *oldFont = ACanvas->Font;
ACanvas->Font = m_pFntText;
ACanvas->Brush->Style = bsClear;
ACanvas->TextRect( ARect, rectDraw.left+24, rectDraw.top+6, pItem->Caption ); //输出菜单文字
ACanvas->Font = oldFont;
}
}
void __fastcall TPopMenu::OwnerMeasureItem(TObject* Sender, TCanvas* ACanvas, int &Width, int &Height)
{
TMenuItem *pItem = (TMenuItem*)Sender;
// if( pItem->Tag>=0 )
Width += 36;
// if( pItem->Checked )
Width += 24;
if( pItem->IsLine() )
Height = BREAK_HEIGHT;
else{
Height = m_pPicNormal->Height;
if( pItem->MenuIndex==0 ) //第一个菜单项
Height += 3;
TMenuItem * pItemParent = pItem->Parent;
if( pItem->MenuIndex==pItemParent->Count-1) //最后一个菜单项
Height += 3;
}
}