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

536 lines
15 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "NotificationContentPanelUnit.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
#define SCOLLBAR_WIDTH (14)
#define TOP_BUTTOM (10)
#define LEFT_RIGHT (SCOLLBAR_WIDTH + 20)
#define LINE_HEIGHT (25)
#define DB_NAME_LINE (2)
#define DB_NAME_HEIGHT (DB_NAME_LINE*LINE_HEIGHT)
#define DB_NAME_RECT_LEFT (10)
#define DB_NAME_RECT_HEIGHT (20)
#define DB_NAME_TEXT_LEFT (5)
#define DB_NAME_TEXT_WIDTH (10)
#define PIC_TO_LEFT (LEFT_RIGHT)
#define PIC_HEIGHT (45)
#define PIC_WIDTH (45)
#define PIC_LEFT (LEFT_RIGHT)
#define PIC_RIGHT (PIC_LEFT + PIC_WIDTH + LEFT_RIGHT)
#define LABEL_TO_LEFT (PIC_LEFT)
#define LABEL_MAX_WIDTH_PIC (Width - PIC_RIGHT - LEFT_RIGHT)
#define LABEL_MAX_WIDTH (Width - LABEL_TO_LEFT - LEFT_RIGHT)
#define LABEL_HEIGHT (PIC_HEIGHT/2)
const static COLORREF
CLR_TXT_HOT = RGB(171, 186, 207),
CLR_CONTENT_BKG = RGB(56, 61, 67),
CLR_CONTENT_DB_NAME_BKG = RGB(47, 50, 56),
CLR_CONTENT_DB_NAME_FRAME = RGB(32, 35, 39),
CLR_CONTENT_DB_LINE_DARK = RGB(32, 35, 39),
CLR_CONTENT_DB_LINE_LIGHT = RGB(76, 81, 87);
//---------------------------------------------------------------------------
__fastcall TNotiContenPanel::TNotiContenPanel( TComponent* Owner, VCTJSONDB *VCJsonContent)
: Vcl::Extctrls::TPanel( Owner )
{
ParentColor = true;
m_VCJsonContent = VCJsonContent;
m_ScrollBar = NULL;
m_iTopLine =0;
m_iShowLine = 1;
SetContent();
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::CreateWnd()
{
Vcl::Extctrls::TPanel::CreateWnd();
SetShowLine();
}
//---------------------------------------------------------------------------
__fastcall TNotiContenPanel::~TNotiContenPanel()
{
if( m_ScrollBar ){
delete m_ScrollBar;
m_ScrollBar = NULL;
}
vector<TPicture *>::iterator vc_pFindPIC;
for( vc_pFindPIC = ItemPIC.begin();
vc_pFindPIC != ItemPIC.end();
vc_pFindPIC++ )
{
if( *vc_pFindPIC ) {
delete *vc_pFindPIC;
*vc_pFindPIC = NULL;
}
}
vector<VCURLLABEL*>::iterator vc_pFindItemLabel;
for( vc_pFindItemLabel = ItemLabel.begin();
(vc_pFindItemLabel != ItemLabel.end());
vc_pFindItemLabel++ )
{
vector<TUrlLabel*>::iterator vc_pFindLabel;
VCURLLABEL* vcLabel = *vc_pFindItemLabel;
for( vc_pFindLabel = (*vcLabel).begin();
vc_pFindLabel!= (*vcLabel).end();
vc_pFindLabel++ )
{
if( *vc_pFindLabel ) {
delete *vc_pFindLabel;
*vc_pFindLabel = NULL;
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
TRect rect = GetClientRect();
TCanvas* tempCanvas = new TCanvas;
tempCanvas->Handle = Message.DC;
tempCanvas->Brush->Color = CLR_CONTENT_BKG; //背景颜色
tempCanvas->FillRect( rect );
delete tempCanvas;
tempCanvas = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::WMVScroll(Winapi::Messages::TWMScroll &Message)
{
int minpos, maxpos, page, curpos;
m_ScrollBar->GetScrollRange(&minpos, &maxpos);
page = m_ScrollBar->GetPageSize();
// Get the current position of scroll box.
curpos = m_ScrollBar->GetScrollPos();
// Determine the new position of scroll box.
switch (Message.ScrollCode)
{
case SB_TOP: // Scroll to far top.
curpos = minpos;
break;
case SB_BOTTOM: // Scroll to far bottom.
curpos = maxpos-page+1;
break;
case SB_ENDSCROLL: // End scroll.
break;
case SB_LINEUP: // Scroll left.
if (curpos > minpos)
curpos--;
break;
case SB_LINEDOWN: // Scroll right.
if (curpos < maxpos-page+1)
curpos++;
break;
case SB_PAGEUP: // Scroll one page left.
if (curpos > minpos)
curpos = (minpos > curpos-page) ? minpos : curpos-page;
//max(minpos, curpos-page);
break;
case SB_PAGEDOWN: // Scroll one page right.
if( curpos<maxpos )
curpos = (maxpos-page+1 < curpos+page) ? maxpos-page+1 : curpos+page;
//min(maxpos-page+1, curpos+page);
break;
case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
curpos = Message.Pos; // of the scroll box at the end of the drag operation.
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. nPos is the
curpos = Message.Pos; // position that the scroll box has been dragged to.
break;
}
// Set the new position of the thumb (scroll box).
if( Message.ScrollBar!=m_ScrollBar->Handle ){
m_ScrollBar->SetPosition(curpos);
// Paint();
}
if( m_iTopLine != curpos ){
m_iTopLine = curpos;
Invalidate();
}
Message.Result = true;
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::WMMouseWheel(TWMMouseWheel &Message)
{
if( m_ScrollBar->Visible ){
UINT nSBCode;
if( Message.WheelDelta>0 ) nSBCode = SB_LINEUP;
else nSBCode = SB_LINEDOWN;
Perform( WM_VSCROLL, MAKELONG(nSBCode,0), NULL );
}
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::SetContent()
{
bool bPicExist, bLabelExist;
VCTJSONDB::iterator vc_pFindContent;
for( vc_pFindContent = (*m_VCJsonContent).begin();
vc_pFindContent != (*m_VCJsonContent).end();
vc_pFindContent++)
{
int dbNum = 0;
VCTJSON::iterator vc_pFindContentPIC;
for( vc_pFindContentPIC = (*vc_pFindContent).vcContent.begin();
vc_pFindContentPIC != (*vc_pFindContent).vcContent.end();
vc_pFindContentPIC++)
{
bPicExist = bLabelExist = false;
//===========图片信息
TPicture *picImg = NULL;
TUrlPaintBox *tmpPicDraw = NULL;
String strExit = (*vc_pFindContentPIC).strNamePic;
if( strExit.Length() ) {
picImg = new TPicture();
picImg->LoadFromFile( strExit );
bPicExist = true;
if( bPicExist ) {
tmpPicDraw = new TUrlPaintBox(this);
tmpPicDraw->Parent = this;
tmpPicDraw->GraphicImg = picImg;
tmpPicDraw->StrUrl = (*vc_pFindContentPIC).strUrl;
tmpPicDraw->Visible = true;
}
}
ItemPIC.push_back( picImg );
ItemPICDraw.push_back( tmpPicDraw );
//===========文字信息
VCURLLABEL *tmpVCUrlLabel = new VCURLLABEL();
//链接信息
TUrlLabel *tmpLabel = CreateLabel((*vc_pFindContentPIC).strName,
(*vc_pFindContentPIC).strUrl);
if( tmpLabel!=NULL ) {
tmpVCUrlLabel->push_back(tmpLabel);
bLabelExist = true;
}
//说明信息
tmpLabel = CreateLabel((*vc_pFindContentPIC).strAuthor, L"");
if( tmpLabel!=NULL ) {
tmpVCUrlLabel->push_back(tmpLabel);
bLabelExist = true;
}
if( !bLabelExist) { //如果说明不存在
ItemPIC.pop_back();
ItemPICDraw.pop_back();
if( picImg ) { delete picImg; picImg=NULL;};
if( tmpPicDraw ) { delete tmpPicDraw; tmpPicDraw=NULL;};
if( tmpVCUrlLabel ) { delete tmpVCUrlLabel; tmpVCUrlLabel=NULL;};
}else {
ItemLabel.push_back(tmpVCUrlLabel);
dbNum++;
}
}
//===========类型信息
if( bLabelExist ) {
ItemDBName.push_back((*vc_pFindContent).strDbName);
ItemDBNameNum.push_back(dbNum);
}
}
}
//---------------------------------------------------------------------------
TUrlLabel* __fastcall TNotiContenPanel::CreateLabel(String caption, String url)
{
TUrlLabel *tmpUrlLabel;
if( caption.Length() ) {
tmpUrlLabel = new TUrlLabel(this);
tmpUrlLabel->Parent = this;
tmpUrlLabel->Caption = caption;
tmpUrlLabel->StrUrl = url;
}else { tmpUrlLabel=NULL; }
return tmpUrlLabel;
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::CutOffLabelString()
{
int maxPicExsit = LABEL_MAX_WIDTH_PIC;
int maxPicNo = LABEL_MAX_WIDTH;
int maxLabelLen;
vector<TPicture*>::iterator vc_pFindItemPIC;
vector<VCURLLABEL*>::iterator vc_pFindLBItem = ItemLabel.begin();
for( vc_pFindLBItem = ItemLabel.begin(),
vc_pFindItemPIC = ItemPIC.begin();
vc_pFindLBItem != ItemLabel.end(),
vc_pFindItemPIC != ItemPIC.end();
vc_pFindLBItem++,
vc_pFindItemPIC++)
{
if( (*vc_pFindItemPIC) == NULL ){
maxLabelLen = maxPicNo;
}else{
maxLabelLen = maxPicExsit;
}
vector<TUrlLabel*>::iterator vc_pFindLabel;
VCURLLABEL* vcLabel = *vc_pFindLBItem;
for( vc_pFindLabel = (*vcLabel).begin();
vc_pFindLabel!= (*vcLabel).end();
vc_pFindLabel++)
{
String caption = (*vc_pFindLabel)->Caption;
TSize size = Canvas->TextExtent( caption );
int nLen = caption.Length();
if( size.Width >= maxLabelLen )
{
nLen = nLen*(maxLabelLen)/size.Width;
nLen -= 1;
if(nLen <= 0){
caption = caption.SubString(0, 1);
}else{
caption = caption.SubString(0, nLen);
caption += "..";
}
(*vc_pFindLabel)->Caption = caption;
}
}
}
}
//---------------------------------------------------------------------------
int __fastcall TNotiContenPanel::GetLineNumber()
{
int linePIC;
int linePICExist = (PIC_HEIGHT%LINE_HEIGHT==0)?(PIC_HEIGHT/LINE_HEIGHT):
((PIC_HEIGHT/LINE_HEIGHT)+1);
int lineLabel = 0;
int lineNumber = 0;
vector<TPicture*>::iterator vc_pFindItemPIC;
vector<VCURLLABEL*>::iterator vc_pFindItemLabel;
for( vc_pFindItemLabel =ItemLabel.begin(),
vc_pFindItemPIC = ItemPIC.begin();
vc_pFindItemLabel != ItemLabel.end()&&
vc_pFindItemPIC != ItemPIC.end();
vc_pFindItemLabel++,
vc_pFindItemPIC++)
{
if( (*vc_pFindItemPIC) == NULL ) {
linePIC = 0;
}else{
linePIC = linePICExist;
}
VCURLLABEL* vcLabel = *vc_pFindItemLabel;
lineLabel = (*vcLabel).size();
int lineNumberTmp = lineNumber;
// if( linePIC>lineLabel ) {
// lineNumber += linePIC;
// }else {
// lineNumber += lineLabel;
// }
lineNumber += linePICExist;
ItemLine.push_back(lineNumber - lineNumberTmp);
}
lineNumber += ItemDBName.size()*DB_NAME_LINE;
return lineNumber;
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::SetShowLine()
{
CutOffLabelString();
int totalLine = GetLineNumber();
// m_iShowLine = (Height - 2*TOP_BUTTOM)/LINE_HEIGHT;
m_iShowLine = Height/LINE_HEIGHT;
if( totalLine>m_iShowLine ){
m_ScrollBar = new TSkinScrollBar(this);
m_ScrollBar->m_pWndCtrl = this;
m_ScrollBar->Parent = this;
m_ScrollBar->Height = Height-2;
// m_ScrollBar->Width = SCOLLBAR_WIDTH;
m_ScrollBar->Left = Width - m_ScrollBar->Width - 1;
m_ScrollBar->Top = 1;
m_ScrollBar->SetRange( 0,totalLine-1 );
m_ScrollBar->SetPageSize(m_iShowLine);
m_ScrollBar->SetPosition( m_iTopLine );
m_ScrollBar->Visible = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TNotiContenPanel::Paint(void)
{
int contentHeight = 0;
int curX = 0;
int curY = 0;
int curWidth = 0;
int curHeight = 0;
int contentStart = -m_iTopLine*LINE_HEIGHT;
int dbNum = 0;
bool dbNameShow = true;
vector<int>::iterator vc_pFindItemDBNameNum = ItemDBNameNum.begin();
vector<String>::iterator vc_pFindItemDBName = ItemDBName.begin();
vector<int>::iterator vc_pFindItemLine;
vector<TPicture*>::iterator vc_pFindItemPIC;
vector<TUrlPaintBox*>::iterator vc_pFindItemPICDraw;
vector<VCURLLABEL*>::iterator vc_pFindItemLabel;
if( vc_pFindItemDBNameNum == ItemDBNameNum.end()
|| vc_pFindItemDBName == ItemDBName.end() )
return;
for( vc_pFindItemLine = ItemLine.begin(),
vc_pFindItemPIC = ItemPIC.begin(),
vc_pFindItemPICDraw = ItemPICDraw.begin(),
vc_pFindItemLabel = ItemLabel.begin();
(vc_pFindItemLine != ItemLine.end())&&
(vc_pFindItemPIC != ItemPIC.end()) &&
(vc_pFindItemPICDraw != ItemPICDraw.end()),
(vc_pFindItemLabel != ItemLabel.end());
vc_pFindItemLine++,
vc_pFindItemPIC++,
vc_pFindItemPICDraw++,
vc_pFindItemLabel++ )
{
if( dbNameShow && dbNum == 0 )
{
contentHeight = DB_NAME_HEIGHT;
//类型信息
dbNum = (*vc_pFindItemDBNameNum) - 1;
TSize sizeFont = Canvas->TextExtent((*vc_pFindItemDBName));
curX = DB_NAME_RECT_LEFT;
curY = contentStart + contentHeight/2 - DB_NAME_RECT_HEIGHT/2;
curWidth = sizeFont.Width;
curHeight = DB_NAME_RECT_HEIGHT;
Canvas->Brush->Color = CLR_CONTENT_DB_NAME_BKG;
Canvas->FillRect(TRect(curX, curY, curX+curWidth+DB_NAME_TEXT_WIDTH, curY+curHeight));
Canvas->Brush->Color = CLR_CONTENT_DB_NAME_FRAME;
Canvas->FrameRect(TRect(curX, curY,curX+curWidth+DB_NAME_TEXT_WIDTH, curY+curHeight));
curX = DB_NAME_RECT_LEFT + DB_NAME_TEXT_LEFT;
curY = curY + (DB_NAME_RECT_HEIGHT - sizeFont.Height)/2;
Canvas->Font->Color = CLR_TXT_HOT;
Canvas->Brush->Style = bsClear;
Canvas->TextOutW(curX, curY, (*vc_pFindItemDBName));
if( vc_pFindItemDBName != ItemDBName.end() &&
vc_pFindItemDBNameNum != ItemDBNameNum.end())
{
vc_pFindItemDBName++;
vc_pFindItemDBNameNum++;
}
if( vc_pFindItemDBName == ItemDBName.end() ){
dbNameShow = false;
}
contentStart += contentHeight;
}else {
dbNum--;
}
//图片
contentHeight = (*vc_pFindItemLine)*LINE_HEIGHT;
curY = contentStart + (contentHeight - PIC_HEIGHT)/2;
bool bPicExsit = true;
if( (*vc_pFindItemPIC) != NULL ) {
curX = PIC_LEFT;
curWidth = PIC_HEIGHT;
curHeight = PIC_WIDTH;
(*vc_pFindItemPICDraw)->SetBounds(curX, curY, curWidth, curHeight);
// Canvas->StretchDraw( TRect(curX, curY, curX+curWidth, curY+curHeight),
// (*vc_pFindItemPIC)->Graphic );
}else{
bPicExsit = false;
}
//文字说明
vector<TUrlLabel*>::iterator vc_pFindLabel;
VCURLLABEL* vcLabel = *vc_pFindItemLabel;
// int labelStart = contentStart + (contentHeight - (*vcLabel).size()*LINE_HEIGHT)/2;
int labelStart,lineStart;
labelStart = lineStart = curY;
for( vc_pFindLabel = (*vcLabel).begin();
vc_pFindLabel!= (*vcLabel).end();
vc_pFindLabel++ )
{
// if( bPicExsit ) {
curX = PIC_RIGHT + (LABEL_MAX_WIDTH_PIC - (*vc_pFindLabel)->Width)/2;
// }else{
// curX = LABEL_TO_LEFT + (LABEL_MAX_WIDTH - (*vc_pFindLabel)->Width)/2;
// }
curY = labelStart + (LABEL_HEIGHT - (*vc_pFindLabel)->Height)/2;
(*vc_pFindLabel)->Left = curX;
(*vc_pFindLabel)->Top = curY;
labelStart += LABEL_HEIGHT;
}
lineStart += PIC_HEIGHT;
Canvas->Pen->Color = CLR_CONTENT_DB_LINE_DARK;
Canvas->MoveTo( PIC_RIGHT, lineStart-1 );
Canvas->LineTo( Width-LEFT_RIGHT, lineStart-1 );
Canvas->Pen->Color = CLR_CONTENT_DB_LINE_LIGHT;
Canvas->MoveTo( PIC_RIGHT, lineStart );
Canvas->LineTo( Width-LEFT_RIGHT, lineStart );
contentStart += contentHeight;
}
}
//---------------------------------------------------------------------------