568 lines
15 KiB
C++
568 lines
15 KiB
C++
//---------------------------------------------------------------------------
|
|
|
|
#pragma hdrstop
|
|
|
|
#include "ListPanel.h"
|
|
#include "GlobalUnit.h"
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
|
|
#define LP_ITEM_OVER RGB(67, 73, 80)
|
|
#define LP_ITEM_SELECTED RGB(29, 31, 35)
|
|
#define LP_ITEM_DEF RGB(47, 50, 57)
|
|
|
|
#define IS_OVER 1
|
|
#define IS_SELECTED 2
|
|
#define IS_UNSELECTED 3
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TListPanelItem::TListPanelItem(String Caption, TListPanelItemClick OnItemClick)
|
|
{
|
|
FCaption = Caption;
|
|
FOnItemClick = OnItemClick;
|
|
Tag = 0;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanelItem::DrawItem(TCanvas *Canvas, TRect Rect, int flag)
|
|
{
|
|
switch (flag) {
|
|
case IS_OVER:
|
|
Canvas->Brush->Color = LP_ITEM_OVER;
|
|
break;
|
|
|
|
case IS_SELECTED:
|
|
Canvas->Brush->Color = LP_ITEM_SELECTED;
|
|
break;
|
|
|
|
default:
|
|
Canvas->Brush->Color = LP_ITEM_DEF;
|
|
}
|
|
|
|
/* 绘制背景 */
|
|
Canvas->FillRect(Rect);
|
|
|
|
Canvas->Font->Color = TColor(RGB(201, 214, 229));
|
|
|
|
/* 绘制文字 */
|
|
int var_TextRectTop = Rect.Top + (Rect.Height() - Canvas->TextHeight(FCaption)) / 2;
|
|
|
|
TRect var_TextRect(4, var_TextRectTop, Rect.Right - 4, Rect.Bottom);
|
|
|
|
Canvas->TextRect(var_TextRect, FCaption);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
#define LP_BORDER RGB(106, 111, 117)
|
|
#define LP_BACKGRND RGB(47, 50, 57)//39, 42, 47)
|
|
|
|
#define LP_BORDER_HL RGB(30, 32, 36)
|
|
#define LP_BACKGRND_HL RGB(67, 73, 80)
|
|
|
|
#define LP_TXT_NOR RGB(213, 221, 232)
|
|
#define LP_TXT_DISABLE RGB(100, 108, 119)
|
|
#define LP_BREAK RGB(100, 108, 119)
|
|
#define LP_BOARD_FILL RGB(76, 82, 91)
|
|
|
|
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
|
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
|
|
|
#define MARGIN 2
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TListPanel::TListPanel(TComponent *Owner) : TPanel(Owner)
|
|
{
|
|
// m_ItemRectList = new TList();
|
|
m_ItemList = new TList();
|
|
|
|
Canvas->Font->Color = LP_TXT_NOR;
|
|
|
|
FItemHeight = 20;
|
|
FSelectedItemIndex = -1;
|
|
|
|
m_CurrentItemIndex = -1;
|
|
m_RealShowCount = 0;
|
|
|
|
m_BeginIndex = 0;
|
|
m_EndIndex = 0;
|
|
|
|
m_IsLButtonDown = false;
|
|
|
|
m_ScrollBar = new TSkinScrollBar(NULL);
|
|
m_ScrollBar->Visible = false;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TListPanel::~TListPanel()
|
|
{
|
|
/* if(m_ItemRectList)
|
|
{
|
|
for( int i=0; i<m_ItemRectList->Count; i++ ){
|
|
delete m_ItemRectList->Items[i];
|
|
}
|
|
|
|
m_ItemRectList->Clear();
|
|
delete m_ItemRectList;
|
|
m_ItemRectList = NULL;
|
|
}
|
|
*/
|
|
for( int i=0; i<m_ItemList->Count; i++ ){
|
|
delete m_ItemList->Items[i];
|
|
}
|
|
|
|
m_ItemList->Clear();
|
|
delete m_ItemList;
|
|
m_ItemList = NULL;
|
|
|
|
if(m_ScrollBar)
|
|
{
|
|
delete m_ScrollBar;
|
|
m_ScrollBar = NULL;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::AddItem(TListPanelItem* Item)
|
|
{
|
|
m_ItemList->Add(Item);
|
|
|
|
/* if(HandleAllocated()) {
|
|
Reset();
|
|
}
|
|
*/
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::Clear()
|
|
{
|
|
for( int i=0; i<m_ItemList->Count; i++ ){
|
|
delete m_ItemList->Items[i];
|
|
}
|
|
m_ItemList->Clear();
|
|
|
|
FSelectedItemIndex = -1;
|
|
m_CurrentItemIndex = -1;
|
|
|
|
m_BeginIndex = 0;
|
|
m_EndIndex = 0;
|
|
|
|
ResetScroll();
|
|
// if(HandleAllocated()) {
|
|
// Reset();
|
|
|
|
// Repaint();
|
|
// }
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::CreateWnd()
|
|
{
|
|
TPanel::CreateWnd();
|
|
|
|
// 设置滚动条属性
|
|
m_ScrollBar->Height = Height - 2;
|
|
m_ScrollBar->Top = 1;
|
|
m_ScrollBar->Left = Width - m_ScrollBar->Width - 1;
|
|
m_ScrollBar->Parent = this;
|
|
m_ScrollBar->m_pWndCtrl = this;
|
|
|
|
//最大显示数
|
|
m_ShowCount = (Height - 2 * MARGIN) / FItemHeight;
|
|
|
|
// 记录显示区域
|
|
/* m_ItemRectList->Clear();
|
|
m_ItemRectList->Add(new TRect(MARGIN, MARGIN, Width - MARGIN, FItemHeight + MARGIN));
|
|
for(int i = 1; i < m_ShowCount; i++)
|
|
{
|
|
int var_ItemTop = i * FItemHeight + MARGIN;
|
|
int var_ItemBottom = var_ItemTop + FItemHeight;
|
|
|
|
m_ItemRectList->Add(new TRect(MARGIN, var_ItemTop, Width - MARGIN, var_ItemBottom));
|
|
}
|
|
*/
|
|
// 记录Item区域
|
|
m_ItemArea = TRect(MARGIN, MARGIN, Width - MARGIN, m_ShowCount * FItemHeight + MARGIN);
|
|
|
|
ResetScroll();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListPanel::GetItemsCount()
|
|
{
|
|
if(m_ItemList)
|
|
return m_ItemList->Count;
|
|
else
|
|
return -1;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
//void __fastcall TListPanel::SetTextFontSize(int sz)
|
|
//{
|
|
// Canvas->Font->Size = sz;
|
|
//}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::SetTextFont(String name, int size)
|
|
{
|
|
Canvas->Font->Name = name;
|
|
Canvas->Font->Size = size;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
TListPanelItem *__fastcall TListPanel::GetItem(int Index)
|
|
{
|
|
if(ItemsCount == 0 || Index < 0 || Index > ItemsCount)
|
|
return NULL;
|
|
else
|
|
return (TListPanelItem *)m_ItemList->Items[Index];
|
|
}
|
|
/*/---------------------------------------------------------------------------
|
|
TRect *__fastcall TListPanel::GetItemRect(int Index)
|
|
{
|
|
return (TRect *)m_ItemRectList->Items[Index];
|
|
}
|
|
*/
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y)
|
|
{
|
|
TPanel::MouseDown(Button, Shift, X, Y);
|
|
|
|
if(m_ScrollBar->Visible && Button == 0) {
|
|
m_IsLButtonDown = true;
|
|
m_ScrollBar->Enabled = false;
|
|
}
|
|
|
|
int areaRight = 0;
|
|
|
|
m_ScrollBar->Visible ? areaRight = m_ItemArea.Right - m_ScrollBar->Width - 1
|
|
: areaRight = m_ItemArea.Right;
|
|
|
|
if(Button == 0 && X >= m_ItemArea.Left && X < areaRight && Y >= m_ItemArea.Top
|
|
&& Y < m_ItemArea.Bottom && ItemsCount > 0)
|
|
{
|
|
int index = (Y - MARGIN) / FItemHeight + m_BeginIndex;
|
|
|
|
if(index < m_ItemList->Count && m_ItemList->Count != 0)
|
|
{
|
|
if(FSelectedItemIndex != index)
|
|
{
|
|
if(FSelectedItemIndex >= m_BeginIndex && FSelectedItemIndex < m_EndIndex)
|
|
SetItemStatus(FSelectedItemIndex, IS_UNSELECTED);
|
|
|
|
FSelectedItemIndex = index;
|
|
|
|
SetItemStatus(FSelectedItemIndex, IS_SELECTED);
|
|
}
|
|
|
|
GetItem(FSelectedItemIndex)->OnItemClicked(this, FSelectedItemIndex);
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::MouseMove(TShiftState Shift, int X, int Y)
|
|
{
|
|
TPanel::MouseMove(Shift, X, Y);
|
|
|
|
if(m_IsLButtonDown) return;
|
|
|
|
if(m_MouseX == X && m_MouseY == Y) return;
|
|
|
|
m_MouseX = X;
|
|
m_MouseY = Y;
|
|
|
|
int areaRight = 0, index = -1;
|
|
|
|
m_ScrollBar->Visible ? areaRight = m_ItemArea.Right - m_ScrollBar->Width - 1
|
|
: areaRight = m_ItemArea.Right;
|
|
|
|
if(X >= m_ItemArea.Left && X < areaRight && Y >= m_ItemArea.Top
|
|
&& Y < m_ItemArea.Bottom && ItemsCount > 0)
|
|
{
|
|
index = (Y - MARGIN) / FItemHeight + m_BeginIndex;
|
|
|
|
if(index < m_ItemList->Count && m_ItemList->Count != 0)
|
|
{
|
|
if(index != m_CurrentItemIndex)
|
|
{
|
|
/* 还原上一次选中项 */
|
|
if(m_CurrentItemIndex >= m_BeginIndex && m_CurrentItemIndex < m_EndIndex)
|
|
{
|
|
m_CurrentItemIndex == FSelectedItemIndex ? SetItemStatus(m_CurrentItemIndex, IS_SELECTED)
|
|
: SetItemStatus(m_CurrentItemIndex, IS_UNSELECTED);
|
|
}
|
|
/* 更新当前选择项 */
|
|
m_CurrentItemIndex = index;
|
|
/* 重绘选中项 */
|
|
m_CurrentItemIndex == FSelectedItemIndex ? SetItemStatus(m_CurrentItemIndex, IS_SELECTED)
|
|
: SetItemStatus(m_CurrentItemIndex, IS_OVER);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( ( index<0 || index>m_ItemList->Count )
|
|
&& m_CurrentItemIndex >= m_BeginIndex
|
|
&& m_CurrentItemIndex < m_EndIndex ){
|
|
m_CurrentItemIndex==FSelectedItemIndex ? SetItemStatus(m_CurrentItemIndex, IS_SELECTED)
|
|
: SetItemStatus(m_CurrentItemIndex, IS_UNSELECTED);
|
|
m_CurrentItemIndex = -1;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::MouseUp(TMouseButton Button, TShiftState Shift, int X, int Y)
|
|
{
|
|
TPanel::MouseUp(Button, Shift, X, Y);
|
|
|
|
if(m_ScrollBar->Visible && Button == 0) {
|
|
m_IsLButtonDown = false;
|
|
m_ScrollBar->Enabled = true;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::SetItemStatus(int Index, int flag)
|
|
{
|
|
int var_ItemTop = ( Index - m_BeginIndex ) * FItemHeight + MARGIN;
|
|
TRect rtDraw( MARGIN, var_ItemTop, Width - MARGIN, var_ItemTop + FItemHeight );
|
|
|
|
GetItem(Index)->DrawItem(Canvas, rtDraw, flag);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::SetSelectedItemIndex(int Index)
|
|
{
|
|
if(FSelectedItemIndex != Index) {
|
|
if( FSelectedItemIndex>=m_BeginIndex && FSelectedItemIndex<m_EndIndex ){
|
|
SetItemStatus( FSelectedItemIndex-m_BeginIndex, IS_UNSELECTED );
|
|
}
|
|
|
|
if( Index<0 || Index>=m_ItemList->Count ){
|
|
FSelectedItemIndex = -1;
|
|
}
|
|
else{
|
|
FSelectedItemIndex = Index;
|
|
|
|
int posScroll = m_BeginIndex;
|
|
if( Index<m_BeginIndex ){
|
|
posScroll = Index;
|
|
}
|
|
else if( Index>=m_EndIndex ){
|
|
posScroll = Index - m_ShowCount + 1;
|
|
}
|
|
|
|
if( posScroll==m_BeginIndex ){
|
|
SetItemStatus( FSelectedItemIndex-m_BeginIndex, IS_SELECTED );
|
|
}
|
|
else if( m_ScrollBar->Visible ){
|
|
ScrollPos( posScroll );
|
|
m_ScrollBar->SetPosition(posScroll);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::Paint()
|
|
{
|
|
Canvas->Lock();
|
|
for(int Index = m_BeginIndex; Index < m_EndIndex; Index++)
|
|
{
|
|
if(Index == FSelectedItemIndex)
|
|
SetItemStatus(Index, IS_SELECTED);
|
|
else if(Index == m_CurrentItemIndex)
|
|
SetItemStatus(Index, IS_OVER);
|
|
else
|
|
SetItemStatus(Index, IS_UNSELECTED);
|
|
}
|
|
|
|
if( m_ShowCount > ItemsCount ){
|
|
int var_Top = ItemsCount * FItemHeight + MARGIN,
|
|
var_Bottom = var_Top + ( m_ShowCount - ItemsCount ) * FItemHeight;
|
|
TRect rtDraw( MARGIN, var_Top, Width - MARGIN, var_Bottom );
|
|
|
|
Canvas->Brush->Color = LP_BACKGRND;
|
|
Canvas->FillRect(rtDraw);
|
|
}
|
|
|
|
Canvas->Unlock();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::ResetScroll()
|
|
{
|
|
m_RealShowCount = MIN(ItemsCount, m_ShowCount);
|
|
|
|
if( FSelectedItemIndex>=0 ){
|
|
if( FSelectedItemIndex < m_BeginIndex ){
|
|
m_BeginIndex = FSelectedItemIndex;
|
|
}
|
|
else if( FSelectedItemIndex >= m_BeginIndex + m_ShowCount ){
|
|
m_BeginIndex = FSelectedItemIndex - m_ShowCount + 1;
|
|
}
|
|
}
|
|
|
|
m_EndIndex = min( m_BeginIndex + m_RealShowCount, ItemsCount );
|
|
|
|
if( ItemsCount > m_ShowCount) {
|
|
m_ScrollBar->Visible = true;
|
|
m_ScrollBar->SetRange(0, ItemsCount - 1);
|
|
m_ScrollBar->SetPageSize(m_ShowCount);
|
|
m_ScrollBar->SetPosition(m_BeginIndex);
|
|
}
|
|
else {
|
|
m_ScrollBar->Visible = false;
|
|
}
|
|
|
|
Paint();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::ScrollPos(int Pos)
|
|
{
|
|
if(Pos >= 0 && Pos < ItemsCount){
|
|
int var_bIndex = Pos;
|
|
int var_eIndex = Pos + m_RealShowCount;
|
|
|
|
if(var_eIndex > ItemsCount)
|
|
{
|
|
var_eIndex = ItemsCount;
|
|
var_bIndex = var_eIndex - m_RealShowCount;
|
|
}
|
|
|
|
if(var_bIndex != m_BeginIndex)
|
|
{
|
|
m_BeginIndex = var_bIndex;
|
|
m_EndIndex = var_eIndex;
|
|
|
|
Paint();
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::WMEraseBkgnd(TWMEraseBkgnd &Message)
|
|
{
|
|
TCanvas* var_BKCanvas = new TCanvas();
|
|
var_BKCanvas->Handle = Message.DC;
|
|
|
|
TRect var_Rect = GetClientRect();
|
|
|
|
var_BKCanvas->Brush->Color = LP_BACKGRND; // 绘制底色
|
|
var_BKCanvas->FillRect(var_Rect);
|
|
|
|
var_BKCanvas->Brush->Color = LP_BORDER; // 绘制边框
|
|
var_BKCanvas->FrameRect(var_Rect);
|
|
|
|
delete var_BKCanvas;
|
|
var_BKCanvas = NULL;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::WMMouseWheel(TWMMouseWheel &Message)
|
|
{
|
|
UINT nSBCode;
|
|
|
|
if(m_IsLButtonDown) return;
|
|
|
|
if(Message.WheelDelta < 0)
|
|
{
|
|
nSBCode = SB_LINEDOWN;
|
|
}
|
|
else
|
|
{
|
|
nSBCode = SB_LINEUP;
|
|
}
|
|
|
|
if(m_ScrollBar->Visible)
|
|
Perform(WM_VSCROLL, MAKELONG(nSBCode, 0), NULL);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::CMMouseLeave(TMessage &Message)
|
|
{
|
|
m_CurrentItemIndex = -1;
|
|
|
|
Repaint();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TListPanel::WMVScroll(TWMScroll &Message)
|
|
{
|
|
int minpos, maxpos, page, curpos;
|
|
|
|
m_ScrollBar->GetScrollRange(& minpos, & maxpos);
|
|
|
|
page = m_ScrollBar->GetPageSize();
|
|
curpos = m_ScrollBar->GetScrollPos();
|
|
|
|
switch(Message.ScrollCode)
|
|
{
|
|
case SB_TOP:
|
|
curpos = minpos;
|
|
break;
|
|
|
|
case SB_BOTTOM:
|
|
curpos = maxpos - page + 1;
|
|
break;
|
|
|
|
case SB_ENDSCROLL:
|
|
break;
|
|
|
|
case SB_LINEUP:
|
|
if(curpos > minpos)
|
|
{
|
|
curpos--;
|
|
}
|
|
break;
|
|
|
|
case SB_LINEDOWN:
|
|
if(curpos < maxpos - page + 1)
|
|
{
|
|
curpos++;
|
|
}
|
|
break;
|
|
|
|
case SB_PAGEUP:
|
|
if(curpos > minpos)
|
|
{
|
|
curpos = MAX(minpos, curpos - page);
|
|
}
|
|
break;
|
|
|
|
case SB_PAGEDOWN:
|
|
if(curpos < maxpos)
|
|
{
|
|
curpos = MIN(maxpos - page + 1, curpos + page);
|
|
}
|
|
break;
|
|
|
|
case SB_THUMBPOSITION:
|
|
curpos = Message.Pos;
|
|
break;
|
|
|
|
case SB_THUMBTRACK:
|
|
curpos = Message.Pos;
|
|
break;
|
|
}
|
|
|
|
if(Message.ScrollBar != m_ScrollBar->Handle)
|
|
{
|
|
m_ScrollBar->SetPosition(curpos);
|
|
}
|
|
|
|
ScrollPos(curpos);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TListPanel::TextWidth(String text)
|
|
{
|
|
return Canvas->TextWidth(text);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TListPanel::WMSize(Winapi::Messages::TWMSize &Message)
|
|
{
|
|
DefaultHandler( &Message );
|
|
|
|
m_ScrollBar->Height = Height - 2;
|
|
m_ScrollBar->Top = 1;
|
|
m_ScrollBar->Left = Width - m_ScrollBar->Width - 1;
|
|
|
|
//最大显示数
|
|
m_ShowCount = (Height - 2 * MARGIN) / FItemHeight;
|
|
// 记录显示区域
|
|
/* m_ItemRectList->Clear();
|
|
m_ItemRectList->Add(new TRect(MARGIN, MARGIN, Width - MARGIN, FItemHeight + MARGIN));
|
|
for(int i = 1; i < m_ShowCount; i++)
|
|
{
|
|
int var_ItemTop = i * FItemHeight + MARGIN;
|
|
int var_ItemBottom = var_ItemTop + FItemHeight;
|
|
|
|
m_ItemRectList->Add(new TRect(MARGIN, var_ItemTop, Width - MARGIN, var_ItemBottom));
|
|
}
|
|
*/
|
|
// 记录Item区域
|
|
m_ItemArea = TRect(MARGIN, MARGIN, Width - MARGIN, m_ShowCount * FItemHeight + MARGIN);
|
|
|
|
// ResetScroll();
|
|
}
|
|
//---------------------------------------------------------------------------
|