Files
AC_Pro/Component/TextButton/TextButton.cpp
T
2026-06-13 00:05:19 +08:00

495 lines
13 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#pragma package(smart_init)
#include "TextButton.h"
////////////////////////////////////////////////////////////////////////////////////
#define PIXEL_EXTERNAL_FRAME 1 //外边界大小
#define PIXEL_INTERNAL_FARME 1 //内边界大小
#define PIXEL_INTERNAL_BOUND 1 //圆角大小
#define PIXLE_TEXT_LEFT_OFFSET 3 //文字左边偏移距离
#define PIXEL_TEXT_X Width - 2*PIXLE_TEXT_LEFT_OFFSET
static const COLORREF
CLR_TXT_NOR = RGB( 156, 170, 189 ),
CLR_TXT_HOT = RGB( 201, 214, 229 ),
CLR_TXT_DIS = RGB( 75, 77, 79 ),
clrFrameExBound = RGB(65,70,77),
clrFrameExNormal = RGB(125,128,131),
clrFrameExEnter = RGB(145,156,170),
clrFrameExDisable = RGB(109,114,120),
clrFrameBoundNormal = RGB(68,70,73),
clrFrameBoundEnter = RGB(70,72,76),
clrFrameNormal = RGB(44,46,48),
clrLineNormal = RGB(44,46,48),
clrRectNormal = RGB(74,80,88),
clrRectDisable = RGB(100,106,113),
//角从左到右,从上到下
clrCapArrowOpenBound[10]=
{ RGB(50,54,60),RGB(54,58,64),RGB(57,61,67),RGB(58,63,69),
RGB(58,63,69),RGB(62,67,74),RGB(64,69,76),
RGB(66,71,78),RGB(68,74,81),
RGB(71,77,85)},
clrCapArrowOpenLine[4] =
{ RGB(59,64,70),
RGB(65,70,77),
RGB(69,75,82),
RGB(73,78,86)},
clrExFrameBound[4] =
{ RGB(81,87,94),
RGB(94,100,107),
RGB(113,118,124),
RGB(126,130,136)
},
clrExFrameBoundDisable[4] =
{ RGB(77,83,91),
RGB(86,91,99),
RGB(98,103,110),
RGB(105,110,117)
};
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TTextButton *)
{
new TTextButton(NULL);
}
//---------------------------------------------------------------------------
namespace Textbutton
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TTextButton)};
RegisterComponents(L"Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
__fastcall TTextButton::TTextButton(TComponent* Owner)
: TGraphicControl(Owner)
{
Height = 25; //a default Height
Width = 75; //a default Width
FStateCount = 4; //default state count
FDown = false;
ShowHint = true;
}
//---------------------------------------------------------------------------
__fastcall TTextButton::~TTextButton(void)
{
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::Paint(void)
{
if( FDown ) EtatBtn = 2;
if( !Enabled ) EtatBtn = 3;
PaintCustomer();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::MouseDown(System::Uitypes::TMouseButton Button,
System::Classes::TShiftState Shift, int X, int Y)
{
TGraphicControl::MouseDown( Button, Shift, X, Y );
if( Button==mbLeft && Enabled && FStateCount>2){
EtatBtn = 2; // Pressed
Paint();
Refresh();
}
TCustomForm * parentForm = GetParentForm( this );
if( parentForm && parentForm==Application->MainForm ){
TPoint pt(X,Y);
pt = ClientToParent( pt, parentForm );
Application->MainForm->OnMouseDown( NULL, Button, Shift, pt.X, pt.Y );
}
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::MouseUp(System::Uitypes::TMouseButton Button,
System::Classes::TShiftState Shift, int X, int Y)
{
TGraphicControl::MouseUp( Button, Shift, X, Y );
if( Button==mbLeft && Enabled ){
if( X>=0 && X<Width && Y>=0 && Y<Height )
EtatBtn = 1; //Mouse Entered
else
EtatBtn = 0; //normal;
Paint();
Refresh(); //repaint component
}
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::CMMouseEnter(Winapi::Messages::TMessage &Msg)
{
if( Enabled && !ComponentState.Contains(csDesigning) ){
EtatBtn = 1; // Mouse Entered
Paint();
Refresh(); //repainting the component
}
if( FOnMouseEnter )
FOnMouseEnter(this); //if user set a mouse enter procedure then we execute it
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::CMMouseLeave(Winapi::Messages::TMessage &Msg)
{
if( Enabled && !ComponentState.Contains(csDesigning) ) {
EtatBtn = 0; //Normal
Paint();
Refresh(); //repainting the component
}
if( FOnMouseLeave )
FOnMouseLeave(this); //if user set a mouse leave procedure then we execute it
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::Click(void)
{
TCustomForm * parentForm = GetParentForm( this );
if( parentForm ){
parentForm->ModalResult = FModalResult;
}
TGraphicControl::Click();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::SetEnabled(bool Value)
{
if(FStateCount<4) //can't be disable
Value = true;
TGraphicControl::SetEnabled(Value);
if( Enabled )
EtatBtn = 0;
else
EtatBtn = 3;
Paint();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::SetStateCount( int count )
{
if( count>4 ) count = 4;
if( count<2 ) count = 2;
FStateCount = count;
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::SetDown(bool value)
{
if( FStateCount<3 )
value = false;
FDown = value;
if( FDown==False )
EtatBtn = 0; //is the mouse down is false then we reset the component state to normal
Paint();
Refresh(); //we repaint the componet)
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::SetFontSize( int value )
{
Canvas->Font->Size = value;
Paint();
Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::SetFontName(System::Uitypes::TFontName value)
{
Canvas->Font->Name = value;
Paint();
Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::SetTextFont(String name, int size)
{
Canvas->Font->Name = name;
Canvas->Font->Size = size;
Paint();
Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::PaintCustomer(void)
{
TRect rectDraw = GetClientRect();
TRect tmpRet = rectDraw;
//================画外边框
if(EtatBtn == 0){
Canvas->Brush->Color = clrFrameExNormal;
Canvas->Pen->Color = clrFrameExNormal;
}else if(EtatBtn == 3){
Canvas->Brush->Color = clrFrameExDisable;
Canvas->Pen->Color = clrFrameExDisable;
}else {
Canvas->Brush->Color = clrFrameExEnter;
Canvas->Pen->Color = clrFrameExEnter;
}
int X,Y;
//上
Y = 0;
X = PIXEL_EXTERNAL_FRAME ;
Canvas->MoveTo( X, Y );
X = Width - PIXEL_EXTERNAL_FRAME ;
Canvas->LineTo( X, Y );
//下
Y = Height - PIXEL_EXTERNAL_FRAME ;
X = PIXEL_EXTERNAL_FRAME ;
Canvas->MoveTo( X, Y );
X = Width - PIXEL_EXTERNAL_FRAME ;
Canvas->LineTo( X, Y );
//左
X = 0 ;
Y = PIXEL_EXTERNAL_FRAME ;
Canvas->MoveTo( X, Y );
Y = Height - PIXEL_EXTERNAL_FRAME ;
Canvas->LineTo( X, Y );
//右
X = Width - PIXEL_EXTERNAL_FRAME ;
Y = PIXEL_EXTERNAL_FRAME ;
Canvas->MoveTo( X, Y );
Y = Height - PIXEL_EXTERNAL_FRAME ;
Canvas->LineTo( X, Y );
//画外边框圆角
int iLPixl, iTPixl, iRPixl, iBPixl ;
TRect tmpRetPic = rectDraw; //画内部区域渐变图像
int iDistant = 1; //画点right和bottom - 1
for(int i=0;i<4;i++)
{
//角 4*4 上左右 下左右
iLPixl = tmpRetPic.Left + i;
iTPixl = tmpRetPic.Top;
iRPixl = tmpRetPic.Right - i - iDistant;
iBPixl = tmpRetPic.Bottom - iDistant;
if(EtatBtn == 3)
Canvas->Pen->Color = clrExFrameBoundDisable[i];
else
Canvas->Pen->Color = clrExFrameBound[i];
Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;
if(i>0){ //每个角对称
iLPixl = tmpRetPic.Left;
iTPixl = tmpRetPic.Top + i;
iRPixl = tmpRetPic.Right - iDistant;
iBPixl = tmpRetPic.Bottom - i - iDistant;
Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;
}
}
//=================画内边框
//画圆角
if(EtatBtn == 0) Canvas->Pen->Color = clrFrameBoundNormal;
else Canvas->Pen->Color = clrFrameBoundEnter;
tmpRet.Top = PIXEL_EXTERNAL_FRAME;
tmpRet.left = PIXEL_EXTERNAL_FRAME;
Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;
tmpRet.left = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;
//////////////
tmpRet.Top = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
tmpRet.left = PIXEL_EXTERNAL_FRAME;
Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;
tmpRet.left = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;
//画线
Canvas->Pen->Color = clrFrameNormal;
// int X,Y;
//上
Y = PIXEL_EXTERNAL_FRAME;
X = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
Canvas->MoveTo( X, Y );
X = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Canvas->LineTo( X, Y );
//下
Y = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
X = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
Canvas->MoveTo( X, Y );
X = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Canvas->LineTo( X, Y );
//左
X = PIXEL_EXTERNAL_FRAME ;
Y = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
Canvas->MoveTo( X, Y );
Y = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Canvas->LineTo( X, Y );
//右
X = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Y = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
Canvas->MoveTo( X, Y );
Y = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
Canvas->LineTo( X, Y );
//==============画内部区域
if(3 == EtatBtn){
Canvas->Brush->Color = clrRectDisable;
Canvas->Pen->Color = clrRectDisable;
}else{
Canvas->Brush->Color = clrRectNormal;
Canvas->Pen->Color = clrRectNormal;
}
tmpRet.Left = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
tmpRet.Top = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
tmpRet.Right = Width - tmpRet.Left;
tmpRet.Bottom = Height - tmpRet.Top;
Canvas->Rectangle(tmpRet.Left, tmpRet.Top,
tmpRet.Right, tmpRet.Bottom);
if(3 != EtatBtn)
{
if(2 == EtatBtn) // down
{
tmpRetPic = rectDraw; //画内部区域渐变图像
iDistant = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
tmpRetPic.Left += iDistant;
tmpRetPic.Top += iDistant;
tmpRetPic.Right -= iDistant;
tmpRetPic.Bottom -= iDistant;
iDistant = 1; //画点right和bottom - 1
int iTmpAdd = 0;//clrCapArrowOpenBound 当前位置
for(int i=0; i<4; i++)
{
//边线
Canvas->Brush->Color = clrCapArrowOpenLine[i];
Canvas->FrameRect(tmpRetPic);
int iadd = 0;//clrCapArrowOpenBound 当前位置增加
for(int j=0; j<4-i; j++) {
//角 4*4 上左右 下左右
iLPixl = tmpRetPic.Left + j;
iTPixl = tmpRetPic.Top;
iRPixl = tmpRetPic.Right - j - iDistant;
iBPixl = tmpRetPic.Bottom - iDistant;
Canvas->Pen->Color = clrCapArrowOpenBound[iTmpAdd+j];
Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;
if(j>0){ //每个角对称
iLPixl = tmpRetPic.Left;
iTPixl = tmpRetPic.Top + j;
iRPixl = tmpRetPic.Right - iDistant;
iBPixl = tmpRetPic.Bottom - j - iDistant;
Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;
}
iadd++;
}
iTmpAdd += iadd;
tmpRetPic.Left += iDistant;
tmpRetPic.Top += iDistant;
tmpRetPic.Right -= iDistant;
tmpRetPic.Bottom -= iDistant;
}
}
}
PaintCustomerText();
}
//---------------------------------------------------------------------------
void __fastcall TTextButton::PaintCustomerText(void)
{
int X,Y;
if( !Text.IsEmpty() ){
if( EtatBtn==0 ){
Canvas->Font->Color = CLR_TXT_NOR;
}
else if( EtatBtn==3 ){
Canvas->Font->Color = CLR_TXT_DIS;
}
else{
Canvas->Font->Color = CLR_TXT_HOT;
}
Canvas->Brush->Style = bsClear;
String strText = FText;
TSize size = Canvas->TextExtent( strText );
int nLen = strText.Length();
if( size.Width > PIXEL_TEXT_X)
{
nLen = nLen*(PIXEL_TEXT_X)/size.Width;
nLen -= 1;
if(nLen <= 0){
strText = strText.SubString(0, 1);
}else{
strText = strText.SubString(0, nLen);
strText += "..";
}
size = Canvas->TextExtent( strText );
}
X = PIXLE_TEXT_LEFT_OFFSET + ( PIXEL_TEXT_X - size.Width )/2;
Y = ( Height -size.Height )/2;
Canvas->TextOut( X, Y, strText );
}
}
//---------------------------------------------------------------------------