//--------------------------------------------------------------------------- #include #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; indexYCanvas->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; iCount; 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_iSrcMove(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 && indexCount ) { 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 && srcIndexCount && 0<=desIndex && desIndexCount ) { m_LstData->Move(srcIndex, desIndex); IndSel = desIndex; ReloadData( desIndex ); } } //--------------------------------------------------------------------------- void __fastcall TListViewMove::ClearAllItems() { NULL_RETURN(m_LstData) for( int i=0; iCount; 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 && indexCount ) { 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 && indexCount ) { DATAInfo *pInfo = (DATAInfo *)(m_LstData->Items[index]); return pInfo->bOn; } return -1; } //---------------------------------------------------------------------------