548 lines
14 KiB
C++
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;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|