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

440 lines
12 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "UpDownUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
static const COLORREF
RGB_EXTERNAL_FRAME = RGB(168,180,196),
RGB_INTERNAL_NOR = RGB(168,180,196), //272a2f
RGB_INTERNAL_HIG = RGB(107,112,120), //4a5058
RGB_INTERNAL_PUSH = RGB(80,84,90), //32363c
RGB_INTERNAL_LINE_NOR = RGB(25,27,30), //191b1e
RGB_INTERNAL_LINE_HIG = RGB(58,63,69), //3a3f45
RGB_INTERNAL_LINE_PUSH = RGB(38,41,45), //26292d
RGB_INTERNAL_FRAME_NOR = RGB(84,89,95),
RGB_INTERNAL_FRAME_HIG = RGB(68,74,81),
RGB_INTERNAL_FRAME_PUSH = RGB(50,54,60),
RGB_RECT_DISPART_LINE = RGB(157,168,183);
#define PIXL_EXTERNAL_FRAME 1
#define PIXL_INTERNAL_FRAME 1
#define PIXL_INTERNAL2RECT 1
#define PIXL_INTERNAL_LINE 1
#define PIXL_INTERL_WIDTH (Width- \
4*(PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME+PIXL_INTERNAL2RECT)+1)/2
#define PIXL_INTERL_HEIGHT (Height- \
4*(PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME+PIXL_INTERNAL2RECT)+1)/2
__fastcall UpDownUnit::TUpDown::TUpDown(System::Classes::TComponent* AOwner)
:Vcl::Comctrls::TUpDown(AOwner)
{
if(Width%2)
Width += 1;
m_pCanvas = new TControlCanvas();
((TControlCanvas*)m_pCanvas)->Control = this;
m_pTimer = new TTimer(this);
m_pTimer->Enabled = false;
m_pTimer->OnTimer = TimerProc;
}
//---------------------------------------------------------------------------
__fastcall UpDownUnit::TUpDown::~TUpDown()
{
if( m_pTimer ){
delete m_pTimer;
m_pTimer = NULL;
}
if( m_pCanvas ){
delete m_pCanvas;
m_pCanvas = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::PaintWindow(HDC DC)
{
if( !m_pCanvas->Handle )
m_pCanvas->Handle = DC;
Draw(STATE_NORMAL, ORIENTATION_ALL);
TRect rClient = GetClientRect();
m_pCanvas->Brush->Color = RGB_EXTERNAL_FRAME;
m_pCanvas->Pen->Color = RGB_EXTERNAL_FRAME;
//外边框
m_pCanvas->FrameRect(rClient);
//中间分割线
m_pCanvas->Pen->Color = RGB_RECT_DISPART_LINE;
int X,Y;
if(Orientation == udHorizontal) {
X = PIXL_EXTERNAL_FRAME + 2*PIXL_INTERNAL_FRAME+2*PIXL_INTERNAL2RECT+
PIXL_INTERL_WIDTH;
Y = 0;
m_pCanvas->MoveTo(X,Y);
Y = Height;
m_pCanvas->LineTo(X,Y);
}else {
Y = PIXL_EXTERNAL_FRAME + 2*PIXL_INTERNAL_FRAME+2*PIXL_INTERNAL2RECT+
PIXL_INTERL_HEIGHT;
X = 0;
m_pCanvas->MoveTo(X,Y);
X = Width;
m_pCanvas->LineTo(X,Y);
}
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::WMPaint(Winapi::Messages::TWMPaint &Message)
{
PaintHandler(Message);
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::WMLButtonDown(TWMMouse &Message)
{
if( OnClick==NULL )
return;
SetCapture(Handle);
m_iDown = true;
int iOrentation = HitTest(Message.XPos, Message.YPos);
m_iCurOrentation = m_iPreOrentation = iOrentation;
if(iOrentation == ORIENTATION_LEFT) {
if(Orientation == udHorizontal)
OnClick(this, btPrev );
else
OnClick(this, btNext );
}else if(iOrentation == ORIENTATIONRIGHT) {
if(Orientation == udHorizontal)
OnClick(this, btNext );
else
OnClick(this, btPrev );
}
Draw(STATE_PUSH, iOrentation);
m_pTimer->Interval = TIME_DELAY;
m_pTimer->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::WMLButtonUp(TWMMouse &Message)
{
ReleaseCapture();
m_iDown = false;
m_pTimer->Enabled = false;
int iOrentation = HitTest(Message.XPos, Message.YPos);
if(iOrentation != ORIENTATION_NONE)
Draw(STATE_HIGHLIGHT, iOrentation);
else
Draw(STATE_NORMAL, ORIENTATION_ALL);
m_iCurOrentation = m_iPreOrentation = -1;
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::WMMouseMove(TWMMouse &Message)
{
if(!m_iDown)
Draw(STATE_HIGHLIGHT, HitTest(Message.XPos, Message.YPos));
else
Draw(STATE_PUSH, HitTest(Message.XPos, Message.YPos));
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::CMMouseLeave(TMessage &Message)
{
if(!m_iDown) {
Draw(STATE_NORMAL, ORIENTATION_ALL);
m_iCurOrentation = m_iPreOrentation = -1;
}
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::Draw(int iState, int iOrentation)
{
if(iOrentation == ORIENTATION_NONE)
return;
TRect rClient = GetClientRect();
TRect temrClient = rClient;
int X,Y;
//当前区域为右边,则左边画普通色
if( iOrentation==ORIENTATIONRIGHT || iOrentation==ORIENTATION_ALL ||
(iOrentation==ORIENTATION_LEFT&&iState!=STATE_NORMAL) )
{
if(iOrentation==ORIENTATIONRIGHT || iOrentation==ORIENTATION_ALL){
m_pCanvas->Brush->Color = RGB_INTERNAL_NOR;
m_pCanvas->Pen->Color = RGB_INTERNAL_NOR;
}else if(iState==STATE_HIGHLIGHT){
m_pCanvas->Brush->Color = RGB_INTERNAL_HIG;
m_pCanvas->Pen->Color = RGB_INTERNAL_HIG;
}else if(iState==STATE_PUSH){
m_pCanvas->Brush->Color = RGB_INTERNAL_PUSH;
m_pCanvas->Pen->Color = RGB_INTERNAL_PUSH;
}
if(Orientation == udHorizontal) {
temrClient.Left = PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME;
temrClient.Top = PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME;
temrClient.Right = temrClient.Left + 2*PIXL_INTERNAL2RECT + PIXL_INTERL_WIDTH;
temrClient.Bottom = Height - temrClient.Top ;
}else {
temrClient.Left = PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME;
temrClient.Top = PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME;
temrClient.Right = Width - temrClient.Left;
temrClient.Bottom = temrClient.Top + 2*PIXL_INTERNAL2RECT + PIXL_INTERL_HEIGHT;
}
m_pCanvas->Rectangle(temrClient.Left, temrClient.Top,
temrClient.Right,temrClient.Bottom);
//////////////////////////
if(iOrentation==ORIENTATIONRIGHT || iOrentation==ORIENTATION_ALL){
m_pCanvas->Pen->Color = RGB_INTERNAL_LINE_NOR;
}else if(iState==STATE_HIGHLIGHT){
m_pCanvas->Pen->Color = RGB_INTERNAL_LINE_HIG;
}else if(iState==STATE_PUSH){
m_pCanvas->Pen->Color = RGB_INTERNAL_LINE_PUSH;
}
if(Orientation == udHorizontal) {
X = PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME+PIXL_INTERNAL2RECT;
Y = Height/2-1;
m_pCanvas->Pixels[X][Y] = m_pCanvas->Pen->Color;
X += 1;
Y -= 1;
m_pCanvas->MoveTo(X,Y);
Y += 3;
m_pCanvas->LineTo(X,Y);
X += 1;
m_pCanvas->MoveTo(X,Y);
Y -= 5;
m_pCanvas->LineTo(X,Y);
}else {
// Y = PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME+PIXL_INTERNAL2RECT+PIXL_INTERL_HEIGHT;
Y = temrClient.Top + temrClient.Height()/2 - 1;
X = Width/2-1;
m_pCanvas->Pixels[X][Y] = m_pCanvas->Pen->Color;
Y += 1;
X -= 1;
m_pCanvas->MoveTo(X,Y);
X += 3;
m_pCanvas->LineTo(X,Y);
Y += 1;
m_pCanvas->MoveTo(X,Y);
X -= 5;
m_pCanvas->LineTo(X,Y);
}
//内边框左
if(iOrentation==ORIENTATIONRIGHT || iOrentation==ORIENTATION_ALL){
m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_NOR;
m_pCanvas->Pen->Color = RGB_INTERNAL_FRAME_NOR;
}else if(iState==STATE_HIGHLIGHT){
m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_HIG;
m_pCanvas->Pen->Color = RGB_INTERNAL_FRAME_HIG;
}else if(iState==STATE_PUSH){
m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_PUSH;
m_pCanvas->Pen->Color = RGB_INTERNAL_FRAME_PUSH;
}
if(Orientation == udHorizontal) {
rClient.left = PIXL_EXTERNAL_FRAME;
rClient.Top = PIXL_EXTERNAL_FRAME;
rClient.Right = rClient.left + 2*PIXL_INTERNAL_FRAME+2*PIXL_INTERNAL2RECT+
PIXL_INTERL_WIDTH;
rClient.Bottom -= rClient.Top;
}else {
rClient.left = PIXL_EXTERNAL_FRAME;
rClient.Top = PIXL_EXTERNAL_FRAME;
rClient.Right -= rClient.left;
rClient.Bottom = rClient.Top + 2*PIXL_INTERNAL_FRAME+2*PIXL_INTERNAL2RECT+
PIXL_INTERL_HEIGHT;;
}
m_pCanvas->FrameRect(rClient);
}
//当前区域为左边,则右边画普通色
if( iOrentation==ORIENTATION_LEFT || iOrentation==ORIENTATION_ALL ||
(iOrentation==ORIENTATIONRIGHT&&iState!=STATE_NORMAL) )
{
if(iOrentation==ORIENTATION_LEFT || iOrentation==ORIENTATION_ALL){
m_pCanvas->Brush->Color = RGB_INTERNAL_NOR;
m_pCanvas->Pen->Color = RGB_INTERNAL_NOR;
}else if(iState==STATE_HIGHLIGHT){
m_pCanvas->Brush->Color = RGB_INTERNAL_HIG;
m_pCanvas->Pen->Color = RGB_INTERNAL_HIG;
}else if(iState==STATE_PUSH){
m_pCanvas->Brush->Color = RGB_INTERNAL_PUSH;
m_pCanvas->Pen->Color = RGB_INTERNAL_PUSH;
}
if(Orientation == udHorizontal) {
temrClient.Left = temrClient.Right+2*PIXL_INTERNAL_FRAME+PIXL_INTERNAL_LINE;
temrClient.Right = Width - (PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME);
}else {
temrClient.Top = temrClient.Bottom+2*PIXL_INTERNAL_FRAME+PIXL_INTERNAL_LINE;
temrClient.Bottom = Height - (PIXL_EXTERNAL_FRAME+PIXL_INTERNAL_FRAME);
}
m_pCanvas->Rectangle(temrClient.Left, temrClient.Top,
temrClient.Right,temrClient.Bottom);
//////////////////////////////
if(iOrentation==ORIENTATION_LEFT || iOrentation==ORIENTATION_ALL){
m_pCanvas->Pen->Color = RGB_INTERNAL_LINE_NOR;
}else if(iState==STATE_HIGHLIGHT){
m_pCanvas->Pen->Color = RGB_INTERNAL_LINE_HIG;
}else if(iState==STATE_PUSH){
m_pCanvas->Pen->Color = RGB_INTERNAL_LINE_PUSH;
}
if(Orientation == udHorizontal) {
X = temrClient.Left+3;
Y = Height/2-1;
m_pCanvas->Pixels[X][Y] = m_pCanvas->Pen->Color;
X -= 1;
Y -= 1;
m_pCanvas->MoveTo(X,Y);
Y += 3;
m_pCanvas->LineTo(X,Y);
X -= 1;
m_pCanvas->MoveTo(X,Y);
Y -= 5;
m_pCanvas->LineTo(X,Y);
}else {
// Y = temrClient.Top+3;
Y = temrClient.Top + temrClient.Height()/2 + 1;
X = Width/2-1;
m_pCanvas->Pixels[X][Y] = m_pCanvas->Pen->Color;
Y -= 1;
X -= 1;
m_pCanvas->MoveTo(X,Y);
X += 3;
m_pCanvas->LineTo(X,Y);
Y -= 1;
m_pCanvas->MoveTo(X,Y);
X -= 5;
m_pCanvas->LineTo(X,Y);
}
//内边框右
if(iOrentation==ORIENTATION_LEFT || iOrentation==ORIENTATION_ALL){
m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_NOR;
m_pCanvas->Pen->Color = RGB_INTERNAL_FRAME_NOR;
}else if(iState==STATE_HIGHLIGHT){
m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_HIG;
m_pCanvas->Pen->Color = RGB_INTERNAL_FRAME_HIG;
}else if(iState==STATE_PUSH){
m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_PUSH;
m_pCanvas->Pen->Color = RGB_INTERNAL_FRAME_PUSH;
}
if(Orientation == udHorizontal) {
rClient.left = rClient.Right+PIXL_INTERNAL_LINE;
rClient.Right = Width - PIXL_EXTERNAL_FRAME;
}else {
rClient.Top = rClient.Bottom+PIXL_INTERNAL_LINE;
rClient.Bottom = Height - PIXL_EXTERNAL_FRAME;
}
m_pCanvas->FrameRect(rClient);
}
}
//---------------------------------------------------------------------------
int __fastcall UpDownUnit::TUpDown::HitTest(int x, int y)
{
if(y<0 || y>Height || x<0 || x>Width)
return ORIENTATION_NONE;
if(Orientation == udHorizontal) {
if(x>=0 && x<=Width/2 )
return ORIENTATION_LEFT;
else if(x>Width/2 && x<=Width)
return ORIENTATIONRIGHT;
}else{
if(y>=0 && y<=Height/2 )
return ORIENTATION_LEFT;
else if(y>Height/2 && y<=Height)
return ORIENTATIONRIGHT;
}
return ORIENTATION_NONE;
}
//---------------------------------------------------------------------------
void __fastcall UpDownUnit::TUpDown::TimerProc(TObject* Sender)
{
if(m_iDown){
m_pTimer->Interval = TIME_DELAY;
m_pTimer->Enabled = true;
TPoint pt;
GetCursorPos(&pt);
pt = ScreenToClient(pt);
m_iCurOrentation = HitTest(pt.X, pt.Y);
if(m_iCurOrentation == m_iPreOrentation) {
if(m_iCurOrentation == ORIENTATION_LEFT) {
if(Orientation == udHorizontal)
OnClick(this, btPrev );
else
OnClick(this, btNext );
}else if(m_iCurOrentation == ORIENTATIONRIGHT) {
if(Orientation == udHorizontal)
OnClick(this, btNext );
else
OnClick(this, btPrev );
}
Draw(STATE_PUSH, m_iCurOrentation);
}
}else{
m_pTimer->Enabled = false;
}
}
//---------------------------------------------------------------------------