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

548 lines
14 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ListViewMove.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define LINE_LEN 2
#define LP_ITEM_OVER RGB(67, 73, 80)
#define LP_ITEM_SELECTED RGB(0, 0, 0)
#define LP_ITEM_DEF RGB(39, 42, 47)
#define FontClolor TColor(0xBDAA9C)
#define FramColor RGB(23, 23, 23)
static const COLORREF CLR_LINE_D = RGB( 18, 19, 21 ),
CLR_LINE_L = RGB( 140, 141, 145 );
//---------------------------------------------------------------------------
__fastcall TListViewMove::TListViewMove(TComponent* Owner)
: TListViewBase( Owner )
{
m_LstData = new TList();;
m_pMovLine = new TBitmap();
m_pMovLine->SetSize(LINE_LEN, LINE_LEN);
m_pMovLine->Canvas->Brush->Style = bsClear;
for( int indexY=0; indexY<LINE_LEN; indexY++ )
{
bool bLine = (indexY%2==0)?true:false;
for( int indexX=0; indexX<LINE_LEN; indexX++ )
{
bool bEven = (indexX%2==0)?true:false;
if(bLine) bEven = !bEven;
m_pMovLine->Canvas->Pixels[indexX][indexY] =
(bEven==true)?CLR_LINE_D:CLR_LINE_L;
}
}
m_iSrc = m_iDes = -1;
m_pMovBmp = new TBitmap();
m_pMovPanel = new TPanelDB(this);
m_pMovPanel->Parent = this;
m_pMovPanel->OnPaintBKG = DoMovPaint;
m_pMovPanel->Visible = false;
RightCellChange = true;
bMovBottom = false;
}
//---------------------------------------------------------------------------
__fastcall TListViewMove::~TListViewMove()
{
SAFE_DELETE(m_pMovLine);
SAFE_DELETE(m_pMovBmp);
SAFE_DELETE(m_pMovPanel);
NULL_RETURN(m_LstData)
for( int i=0; i<m_LstData->Count; i++ ) {
DATAInfo *pInfo = (DATAInfo *)(m_LstData->Items[i]);
SAFE_DELETE(pInfo)
}
m_LstData->Clear();
SAFE_DELETE(m_LstData);
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoCellHgt(TTableView *Sender, int index)
{
return CELL_HEIGHT;
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoMDNum(TTableView *Sender)
{
NULL_RETURN0(m_LstData)
return m_LstData->Count;
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DoDrawBKG(TPanelDB *Sender, TCanvas *pCanvas, TRect rtBKG)
{
pCanvas->Brush->Color = LP_ITEM_DEF;
pCanvas->FillRect(rtBKG);
rtBKG = TRect(0, 0, Sender->Width, Sender->Height);
pCanvas->Brush->Color = FramColor;
pCanvas->Pen->Color = FramColor;
pCanvas->FrameRect(rtBKG);
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoTitle(TTableView *Sender)
{
TPanelDB *pTitle = new TPanelDB(this);
pTitle->SetBounds(0, 0, Width, 1);
pTitle->Color = FramColor;
return (int)pTitle;
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoBottom(TTableView *Sender)
{
TPanelDB *pBottom = new TPanelDB(this);
pBottom->SetBounds(0, Height-1, Width, 1);
pBottom->Color = FramColor;
return (int)pBottom;
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DoCellDraw(TStateBtn *sender, int BsTmp, TRect rtTmp, TCanvas *pCanvas)
{
NULL_RETURN(sender)
DATAInfo *pInfo = (DATAInfo *)sender->m_Data;
String strCaption = pInfo->caption;
TSize szFont = pCanvas->TextExtent(strCaption);
if( Bs_NORMAL==BsTmp ) {
pCanvas->Brush->Color = LP_ITEM_DEF;
}else if( Bs_ENTER==BsTmp ){
pCanvas->Brush->Color = LP_ITEM_OVER;
}else if( Bs_DOWN==BsTmp ){
pCanvas->Brush->Color = LP_ITEM_SELECTED;
}
if( BsTmp==Bs_ENTER ||
BsTmp==Bs_DOWN )
{
pCanvas->FillRect(rtTmp);
}
pCanvas->Brush->Style = bsClear;
pCanvas->Font->Color = FontClolor;
//----´¦Àí×Ö·û¹ý³¤------
int nBorder = 4;
int nWidth = m_nCapWidth-nBorder*2;
if( nWidth>0 ){
szFont = pCanvas->TextExtent(strCaption);
if( szFont.Width>nWidth ){
UnicodeString strShorty = strCaption;
while( pCanvas->TextWidth( strShorty )>nWidth ){
strShorty = strShorty.SubString( 1, strShorty.Length()-2 );
}
strCaption = strShorty;
strCaption+="...";
szFont = pCanvas->TextExtent(strCaption);
}
//-----------
pCanvas->TextOutW( m_nCapLeft+nBorder+(nWidth-szFont.Width)/2,
rtTmp.Top+(rtTmp.Height()-szFont.Height)/2,
strCaption);
}
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoCellData(TStateBtn *sender)
{
NULL_RETURN0(m_LstData)
NULL_RETURN0(sender)
sender->SetData(m_LstData->Items[sender->Index]);
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DoCellDBClick(TStateBtn *sender)
{
NULL_RETURN(sender)
if(FOnItemDBLClick) {
DATAInfo *pInfo = (DATAInfo *)sender->m_Data;
FOnItemDBLClick(sender->Index, pInfo->bOn);
}
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DoIconDraw(TStateBtn *sender, int BsTmp, TRect rtTmp, TCanvas *pCanvas)
{
NULL_RETURN(sender)
TGraphic *pIMG = (TGraphic *)sender->m_Data;
int iWidth = pIMG->Width/3;
int nTrans =
BsTmp==Bs_NORMAL ? 0:
BsTmp==Bs_ENTER ? (-iWidth):
BsTmp==Bs_DOWN ? (-2*iWidth):(-3*iWidth);
if( 0==sender->Index ) {
DATAInfo *pInfo = (DATAInfo *)(sender->m_PAR->m_Data);
if( pInfo->bOn ) {
pIMG = m_pImgOn;
}
}
if( Bs_NORMAL==BsTmp ||
Bs_ENTER==BsTmp ||
Bs_DOWN==BsTmp )
{
HRGN rgnClip = CreateRectRgn( rtTmp.Left, rtTmp.Top,
rtTmp.Left+rtTmp.Width(), rtTmp.Top+rtTmp.Height() );
SelectClipRgn( pCanvas->Handle, rgnClip );
pCanvas->Draw(rtTmp.Left+nTrans, rtTmp.Top, pIMG);
SelectClipRgn( pCanvas->Handle, NULL );
DeleteObject(rgnClip);
}
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoIconData(TStateBtn *sender)
{
NULL_RETURN0(sender)
if( 0==sender->Index ) {
sender->SetData(m_pImgOff);
}
else if(1==sender->Index) {
sender->SetData(m_pImgDel);
}
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoIconsNum(TStateBtn *parent)
{
return 2;
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoIconsBounds(TStateBtn *sender, TRect &rtBounds)
{
NULL_RETURN0(sender)
TGraphic *pTmp = (TGraphic *)sender->m_Data;
int iLeft, iTop, iWidth, iHeight;
iWidth = pTmp->Width/3;
iHeight = pTmp->Height;
iTop = (CELL_HEIGHT-pTmp->Height)/2;
if( 0==sender->Index ) {
iLeft = 5;
m_nCapLeft = iLeft+iWidth;
}
else if(1==sender->Index) {
iLeft = m_RtContent.Left + m_RtContent.Width() - pTmp->Width/3 - 5;
m_nCapWidth = iLeft - m_nCapLeft;
}
rtBounds = TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight);
return 0;
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DoIconLClick(TStateBtn *sender)
{
NULL_RETURN(sender)
TStateBtn *parent = sender->m_PAR;
int index = parent->Index;
DATAInfo *pInfo = (DATAInfo *)parent->m_Data;
bool bOn = pInfo->bOn;
if( 0==sender->Index ) {
pInfo->bOn = !bOn;
if(FOnItemStateChange) FOnItemStateChange( index, !bOn );
}
else if(1==sender->Index) {
if(FOnItemDelete && FOnItemDelete( index, -1 ) ) {
DeleteItem(index);
}
else {
sender->Enter = false;
sender->Down = false;
sender->Paint();
TRect rt = sender->GetBounds();
RECT rtInvalid;
rtInvalid.left = rt.Left;
rtInvalid.top = rt.Top;
rtInvalid.right = rt.Right;
rtInvalid.left = rt.Bottom;
InvalidateRect(this->Handle, &rtInvalid, false);
}
}
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoClickL(TStateBtn *Sender, TPoint pt)
{
if(Sender && Sender->m_PAR)
Sender = Sender->m_PAR;
m_pMovBmp->SetSize(Sender->Width, Sender->Height);
StretchBlt(m_pMovBmp->Canvas->Handle,
0, 0, Sender->Width, Sender->Height,
m_CanvasDr->Handle,
Sender->Left, Sender->Top, Sender->Width, Sender->Height,
SRCCOPY);
m_pMovPanel->SetBounds(Sender->Left, Sender->Top, Sender->Width, Sender->Height);
return 0;
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoClickLP(TStateBtn *Sender, TPoint pt)
{
if( m_iSrc!=-1 && m_iDes!=-1 ) {
m_pMovPanel->Visible = false;
if( OnItemMoveEnd && OnItemMoveEnd( m_iSrc, m_iDes ) ) {
if( m_iSrc<m_iDes )
m_iDes -= 1;
m_LstData->Move(m_iSrc, m_iDes);
this->IndSel = m_iDes;
this->ReloadData( GetCellBeg() );
}
}
m_iSrc = m_iDes = -1;
Screen->Cursor = crDefault;
bMovBottom = false;
return 0;
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoMDMOV(TStateBtn *Src, TStateBtn *Des, TPoint pt)
{
if( Src && NULL!=Src->m_PAR )
return 0;
if(Des && Des->m_PAR)
Des = Des->m_PAR;
if(Src && Des && (Src!=Des||Src->Index!=IndSel) && PtInRect( m_RtContent, pt ) ) {
m_iSrc = IndSel;
m_iDes = Des->Index;
TRect rtLine;
rtLine.Left = Des->Left;
rtLine.Top = Des->Top;
rtLine.Right = Des->Left+Des->Width;
rtLine.Bottom = Des->Top+LINE_LEN;
Canvas->Brush->Bitmap = m_pMovLine;
Canvas->FillRect(rtLine);
m_pMovPanel->Top = pt.Y;
m_pMovPanel->Visible = true;
if( OnItemMoveIng ) {
if( OnItemMoveIng( m_iSrc, m_iDes ) ) {
Screen->Cursor = crDrag;
}
else {
Screen->Cursor = crNoDrop;
m_iDes = -1;
}
}
else {
Screen->Cursor = crDrag;
}
bMovBottom = false;
}
else if( !bMovBottom ){
m_iDes = -1;
m_pMovPanel->Visible = false;
if( -1!=m_iSrc )
Screen->Cursor = crNoDrop;
if(!Src && !Des) {
Screen->Cursor = crDefault;
m_iSrc = m_iDes = -1;
}
}
return 0;
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoMDBottom(TTableView *Sender)
{
if( -1!=m_iSrc )
{
TStateBtn *Des = GetCellAds(Count-1);
if( Des && Des->Index!=IndSel )
{
bMovBottom = true;
m_iSrc = IndSel;
m_iDes = Des->Index+1;
TRect rtLine;
rtLine.Left = Des->Left;
rtLine.Top = Des->Top+Des->Height-LINE_LEN;
rtLine.Right = Des->Left+Des->Width;
rtLine.Bottom = rtLine.Top+LINE_LEN;
Canvas->Brush->Bitmap = m_pMovLine;
Canvas->FillRect(rtLine);
m_pMovPanel->Top = Des->Top+Des->Height;
m_pMovPanel->Visible = true;
if( OnItemMoveIng ) {
if( OnItemMoveIng( m_iSrc, m_iDes ) ) {
Screen->Cursor = crDrag;
}
else {
Screen->Cursor = crNoDrop;
m_iDes = -1;
}
}
else {
Screen->Cursor = crDrag;
}
}
}
return 0;
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DoMovPaint(TPanelDB *Sender, TCanvas *pCanvas, TRect rtBKG)
{
TPanel *panel = (TPanel *)Sender;
TRect rtThis = TRect(0, 0, panel->Width, panel->Height);
SetBkMode( pCanvas->Handle, TRANSPARENT);
StyleServices()->DrawParentBackground( panel->Handle, pCanvas->Handle, NULL, false, rtThis);
BLENDFUNCTION BFun;
BFun.BlendOp = AC_SRC_OVER;
BFun.BlendFlags = 0;
BFun.SourceConstantAlpha = 100;
BFun.AlphaFormat = 0;
::AlphaBlend( pCanvas->Handle,
0, 0, rtThis.Width(), rtThis.Height(),
m_pMovBmp->Canvas->Handle,
0, 0, m_pMovBmp->Width, m_pMovBmp->Height,
BFun);
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::DoClickR(TStateBtn *Sender, TPoint pt)
{
NULL_RETURN0(Sender)
if(FOnItemRightClick && !Sender->m_PAR) {
DATAInfo *pInfo = (DATAInfo *)Sender->m_Data;
FOnItemRightClick(Sender->Index, pInfo->bOn, pt);
}
return 0;
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::AddIcon(TPngImage *pImgDel, TPngImage *pImgOff, TPngImage *pImgOn)
{
m_pImgDel = pImgDel;
m_pImgOff = pImgOff;
m_pImgOn = pImgOn;
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::AddItem(String caption, bool bOn, bool bPaint, int insertIndex)
{
NULL_RETURN(m_LstData)
DATAInfo *pInfo = new DATAInfo(caption, bOn);
if( insertIndex<0 || insertIndex>m_LstData->Count )
insertIndex = m_LstData->Count;
if(0<=insertIndex && insertIndex<=m_LstData->Count )
m_LstData->Insert(insertIndex, pInfo);
if( bPaint ) {
IndSel = insertIndex;
if( IsCellVisible(insertIndex) )
ReloadData( GetCellBeg() );
else
ReloadData( insertIndex );
}
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::DeleteItem(int index, bool bPaint)
{
NULL_RETURN(m_LstData)
if( 0<=index && index<m_LstData->Count ) {
DATAInfo *pInfo = (DATAInfo *)(m_LstData->Items[index]);
SAFE_DELETE(pInfo)
m_LstData->Delete(index);
if( bPaint ) {
IndSel = NOSET;
if( IsCellVisible(index) )
ReloadData( GetCellBeg() );
else
ReloadData( index-1 );
}
}
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::MoveItems(int srcIndex, int desIndex)
{
NULL_RETURN(m_LstData)
if(srcIndex<0) srcIndex = 0;
else if(srcIndex>=m_LstData->Count ) {
srcIndex = m_LstData->Count-1;
}
if(desIndex<0) desIndex = 0;
else if(desIndex>=m_LstData->Count ) {
desIndex = m_LstData->Count-1;
}
if( srcIndex==desIndex ) return;
if( 0<=srcIndex && srcIndex<m_LstData->Count &&
0<=desIndex && desIndex<m_LstData->Count ) {
m_LstData->Move(srcIndex, desIndex);
IndSel = desIndex;
ReloadData( desIndex );
}
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::ClearAllItems()
{
NULL_RETURN(m_LstData)
for( int i=0; i<m_LstData->Count; i++ ) {
DATAInfo *pInfo = (DATAInfo *)(m_LstData->Items[i]);
SAFE_DELETE(pInfo)
}
m_LstData->Clear();
this->ReloadData();
}
//---------------------------------------------------------------------------
void __fastcall TListViewMove::SetItemState(int index, bool bOn, bool bPaint)
{
if( 0<=index && index<m_LstData->Count ) {
DATAInfo *pInfo = (DATAInfo *)(m_LstData->Items[index]);
pInfo->bOn = bOn;
if( bPaint ) {
if( IsCellVisible(index) ) ReloadData( GetCellBeg() );
else ReloadData( index );
}
}
}
//---------------------------------------------------------------------------
int __fastcall TListViewMove::GetItemState(int index)
{
if( 0<=index && index<m_LstData->Count ) {
DATAInfo *pInfo = (DATAInfo *)(m_LstData->Items[index]);
return pInfo->bOn;
}
return -1;
}
//---------------------------------------------------------------------------