unit QXuQQPanel;
interface
uses
Windows, Classes, SysUtils, StdCtrls, Graphics, ExtCtrls, Controls, Forms,
Messages,Dialogs;
type
TXuMemberNotifyEvent = procedure(Sender: TObject; AData: Pointer) of object;
TXuIconNotifyEvent = procedure(Sender: TObject; AData: Pointer) of object;
TXuQQIconData = class
private
FIconDesc: string;
FIconName: string;
FIconID: string;
public
property IconID: string read FIconID write FIconID;
property IconName: string read FIconName write FIconName;
property IconDesc: string read FIconDesc write FIconDesc;
end;
TXuQQIcon = class(TPanel)
private
FImage: TImage;
FData: Pointer;
FOnIconClick: TXuIconNotifyEvent;
FOnIconDoubleClick: TXuIconNotifyEvent;
FNormalIcon: string;
FHotIcon: string;
procedure SetNormalIcon(const Value: string);
procedure SetData(const Value: Pointer);
protected
procedure OnImgClick(Sender: TObject);
procedure OnImgDblClick(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
public
property Data: Pointer read FData write SetData;
property Image: TImage read FImage write FImage;
property NormalIcon: string read FNormalIcon write SetNormalIcon;
property HotIcon: string read FHotIcon write FHotIcon;
property OnIconClick: TXuIconNotifyEvent read FOnIconClick write FOnIconClick;
property OnIconDoubleClick: TXuIconNotifyEvent read FOnIconDoubleClick write FOnIconDoubleClick;
end;
TXuQQIconArray = array of TXuQQIcon;
TXuQQPerson = class
private
FUserID: string;
FUserDesc: string;
FUserName: string;
FUserIcons: TXuQQIconArray;
FUserHead: string;
FNameColor: TColor;
public
procedure AddIcon(Ico: TXuQQIcon);
procedure RemoveIcon(Index: Integer);
constructor Create;
public
property UserID: string read FUserID write FUserID;
property UserName: string read FUserName write FUserName;
property UserDesc: string read FUserDesc write FUserDesc;
property UserIcons: TXuQQIconArray read FUserIcons write FUserIcons;
property UserHead: string read FUserHead write FUserHead;
property NameColor: TColor read FNameColor write FNameColor default clBlack;
end;
TXuQQMember = class(TPanel)
private
FHeadImage: TImage;
FPnlCont: TPanel;
FPNickName: TPanel;
FPDesc: TPanel;
FPExtension: TPanel;
{ FGlass: TRaNGlassPanel; }
FNickName: TLabel;
FDesc: TLabel;
FExtension: TLabel;
FData: Pointer;
FQQIcons: TXuQQIconArray;
FUserID: string;
FOnMouseEnter: TNotifyEvent;
FOnMouseLeave: TNotifyEvent;
protected
procedure DoMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
procedure DoMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
procedure OnGlassMouseEnter(Sender: TObject);
procedure OnGlassMouseLeave(Sender: TObject);
procedure OnGlassClick(Sender: TObject);
procedure OnGlassDoubleClick(Sender: TObject);
procedure OnImageMouseEnter(Sender: TObject);
procedure OnImageMouseLeave(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure AddIcon(Ico: TXuQQIcon);
procedure RemoveIcon(Index: Integer);
public
property Data: Pointer read FData write FData;
property QQIcons: TXuQQIconArray read FQQIcons write FQQIcons;
published
property UserID: string read FUserID write FUserID;
property HeadImage: TImage read FHeadImage write FHeadImage;
property NickName: TLabel read FNickName write FNickName;
property Desc: TLabel read FDesc write FDesc;
property Extension: TLabel read FExtension write FExtension;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
end;
TXuQQMemberArray = array of TXuQQMember;
TXuQQGroup = class(TPanel)
private
FMembers: TXuQQMemberArray;
function GetMemberCount: Integer;
procedure SetMemberCount(const Value: Integer);
public
constructor Create(AOwner: TComponent); override;
function AddMember(person: TXuQQPerson): Boolean;
procedure RemoveMember(Index: Integer);
public
property Members: TXuQQMemberArray read FMembers write FMembers;
published
property MemberCount: Integer read GetMemberCount write SetMemberCount;
end;
TXuQQGroupWTitle = class(TPanel)
private
FTitle: TPanel;
FGroup: TXuQQGroup;
FTitleImage: TImage;
FTitleName: TLabel;
m_MouseDown,m_ClickStatus:Boolean;
procedure FillColor(IsDown,IsOpen:Boolean;StrCol:TColor;EndCol:TColor;CurCan:TCanvas);
procedure PaintPic(ACanvas: TCanvas; Bitmap: TBitmap);
protected
procedure OnTitleClick(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure OnTitleMouseEnter(Sender: TObject);
procedure OnTitleMouseLeave(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
procedure Expand;
procedure Packup;
published
property Title: TPanel read FTitle write FTitle;
property TitleImage: TImage read FTitleImage write FTitleImage;
property TitleName: TLabel read FTitleName write FTitleName;
property QQGroup: TXuQQGroup read FGroup write FGroup;
end;
TXuQQGroupWTitleArray = array of TXuQQGroupWTitle;
TXuQQPanel = class(TScrollBox)
private
FGroups: TXuQQGroupWTitleArray;
FOnMemberClick: TXuMemberNotifyEvent;
FOnMemberDblClick: TXuMemberNotifyEvent;
function GetGroupCount: Integer;
procedure SetGroupCount(const Value: Integer);
protected
procedure SetPanelHeight;
public
constructor Create(AOwner: TComponent); override;
function AddGroup(AName: string): Boolean;
procedure RemoveGroup(Index: Integer);
procedure ExpandAll;
procedure PackupAll;
public
property Groups: TXuQQGroupWTitleArray read FGroups write FGroups;
published
property GroupCount: Integer read GetGroupCount write SetGroupCount;
property OnMemberClick: TXuMemberNotifyEvent read FOnMemberClick write FOnMemberClick;
property OnMemberDblClick: TXuMemberNotifyEvent read FOnMemberDblClick write FOnMemberDblClick;
end;
procedure Register;
implementation
{$R CnQQPanel.res}
var
OldXuQQGroupWTitle:TXuQQGroupWTitle;
procedure Register;
begin
RegisterComponents('Samples', [TXuQQPanel]);
end;
{ TXuQQPanel }
function TXuQQPanel.AddGroup(AName: string): Boolean;
var
len: Integer;
i: Integer;
hasGroup: Boolean;
begin
hasGroup := False;
len := length(FGroups);
for i := 0 to len - 1 do
begin
if FGroups[i].FTitleName.Caption = AName then
begin
hasGroup := True;
Break;
end;
end;
if hasGroup then
begin
Result := False;
Exit;
end;
SetLength(FGroups, len + 1);
len:=len;
FGroups[len] := TXuQQGroupWTitle.Create(self);
FGroups[len].Parent := self;
FGroups[len].Caption := EmptyStr;
FGroups[len].Align := alTop;
FGroups[len].FTitleName.Caption := AName;
FGroups[len].FillColor(false,false,clWhite,clWhite,FGroups[len].FTitleImage.Canvas);
if len = 0 then
FGroups[len].Top := 0
else
FGroups[len].Top := FGroups[len-1].Top + FGroups[len-1].Height + 1;
SetWindowRgn(FGroups[len].FTitle.handle,CreateRoundRectRgn(0,0,FGroups[len].FTitle.width,FGroups[len].FTitle.height,4,4),true);
SetPanelHeight;
Result := True;
end;
constructor TXuQQPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BevelOuter := bvNone;
Color := clWindow;
end;
procedure TXuQQPanel.ExpandAll;
var
i: Integer;
begin
for i := 0 to length(FGroups) - 1 do
FGroups[i].Expand;
end;
function TXuQQPanel.GetGroupCount: Integer;
begin
Result := Length(FGroups);
end;
procedure TXuQQPanel.PackupAll;
var
i: Integer;
begin
for i := 0 to length(FGroups) - 1 do
FGroups[i].Packup;
end;
procedure TXuQQPanel.RemoveGroup(Index: Integer);
var
len: Integer;
i: Integer;
begin
len := length(FGroups);
FGroups[Index].Free;
for i := Index to len - 2 do
FGroups[i] := FGroups[i+1];
SetLength(FGroups, len - 1 );
SetPanelHeight;
end;
procedure TXuQQPanel.SetGroupCount(const Value: Integer);
var
i: Integer;
begin
SetLength(FGroups, Value);
for i := 0 to Length(FGroups) - 1 do
begin
if not Assigned(FGroups[i]) then
begin
FGroups[i] := TXuQQGroupWTitle.Create(self);
FGroups[i].Parent := self;
FGroups[i].Caption := EmptyStr;
FGroups[i].Align := alTop;
if i = 0 then
FGroups[i].Top := 0
else
FGroups[i].Top := FGroups[i-1].Top + FGroups[i-1].Height + 1;
end;
end;
SetPanelHeight;
end;
procedure TXuQQPanel.SetPanelHeight;
var
i: Integer;
h: Integer;
begin
h := 0;
for i := 0 to Length(FGroups) - 1 do
h := h + FGroups[i].Height;
Height := h;
end;
{ TXuQQGroupWTitle }
constructor TXuQQGroupWTitle.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BevelOuter := bvNone;
Color := clWindow;
m_MouseDown:=false;
FTitle := TPanel.Create(self);
FTitle.Parent := self;
FTitle.BevelOuter := bvNone;
FTitle.Height := 22;
FTitle.Align := alTop;
FTitle.Caption := EmptyStr;
FTitle.OnMouseDown :=OnTitleClick;
FTitle.Color := clWindow;
FTitleImage:= TImage.Create(self);
FTitleImage.Parent := FTitle;
FTitleImage.Align := alTop;
FTitleImage.OnMouseDown := OnTitleClick;
FTitleImage.Transparent := True;
FTitleName := TLabel.Create(self);
FTitleName.Parent := FTitle;
FTitleName.Align := alnone;
FTitleName.Left:=20;
FTitleName.Top:=3;
FTitleName.Font.Style:=[fsbold];
FTitleName.Transparent:=true;
FTitleName.Caption := EmptyStr;
FTitleName.Layout := tlCenter;
FTitleName.OnMouseDown := OnTitleClick;
FTitleName.Color := clWindow;
FGroup:= TXuQQGroup.Create(Self);
FGroup.Parent := self;
FGroup.Caption := EmptyStr;
FGroup.Top := 23;
FGroup.Align := alTop;
FGroup.Color := clRed;
FGroup.Visible:=false;
end;
procedure TXuQQGroupWTitle.Expand;
begin
if not FGroup.Visible then
begin
FGroup.Show;
FGroup.Top := 23;
FTitleImage.Picture.Bitmap.LoadFromResourceName(HInstance,'ARROWDOWN');
Height := 22 + FGroup.Height;
// notify
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end;
end;
procedure TXuQQGroupWTitle.FillColor(IsDown,IsOpen:Boolean;StrCol, EndCol: TColor; CurCan: TCanvas);
var
ColorS, ColorE: TColor;
I, X, Y, nX, nY: Integer;
rDel: Real;
nRed, nGreen, nBlue: Integer;
Buf : TBitmap;
begin
Buf:=TBitmap.Create;
CurCan.FillRect(CurCan.ClipRect);
if IsOpen then
Buf.Handle:=LoadBitmap(HInstance,'ARROWDOWN')
else
Buf.Handle:=LoadBitmap(HInstance,'ARROW');
if IsDown then
begin
ColorS := StrCol;
ColorE := EndCol;
X := 0;
Y := 0;
nX := Width ;
nY := 1;
nRed := GetRValue(ColorS);
nGreen := GetGValue(ColorS);
nBlue := GetBValue(ColorS);
for I := 0 to Height - 1 do begin
CurCan.Brush.Color := RGB(nRed, nGreen, nBlue);
CurCan.FillRect(Rect(X, Y, X + nX, Y + nY));
rDel := nY * I / Height ;//关键!根据距离渐变
Inc(Y, nY);
nRed := Round(GetRValue(ColorS) + (GetRValue(ColorE) - GetRValue(ColorS)) * rDel);
nGreen := Round(GetGValue(ColorS) + (GetGValue(ColorE) - GetGValue(ColorS)) * rDel);
nBlue := Round(GetBValue(ColorS) + (GetBValue(ColorE) - GetBValue(ColorS)) * rDel);
end;
PaintPic(CurCan,Buf);
//BitBlt(FTitleImage.Canvas.Handle, 0, 0, Buf.Width, Buf.Height, Buf.Canvas.Handle, 0, 0, SRCCOPY);
end
else
begin
PaintPic(CurCan,Buf);
// BitBlt(CurCan.Handle, 0, 0, Buf.Width, Buf.Height, Buf.Canvas.Handle, 0, 0, SRCCOPY);
end;
Buf.Free;
end;
procedure TXuQQGroupWTitle.OnTitleClick(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if OldXuQQGroupWTitle<>self then
begin
if Assigned(OldXuQQGroupWTitle) then
FillColor(false,OldXuQQGroupWTitle.FGroup.Visible,clWhite,clWhite,OldXuQQGroupWTitle.FTitleImage.Canvas);
if FGroup.Visible then
begin
// FGroup.Visible:=False;
FGroup.Hide;
Height := 22;
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end
else
begin
// FGroup.Visible:=true;
FGroup.Show;
Height := 22 + FGroup.Height;
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end;
FillColor(true,FGroup.Visible,$00FFE7CF,$00FCE1CF,FTitleImage.Canvas);
OldXuQQGroupWTitle:=self;
end
else
begin
if FGroup.Visible then
begin
FGroup.Visible:=False;
FGroup.Hide;
Height := 22;
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end
else
begin
FGroup.Visible:=true;
FGroup.Show;
Height := 22 + FGroup.Height;
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end;
FillColor(true,FGroup.Visible,$00FFE7CF,$00FCE1CF,FTitleImage.Canvas);
end;
{ if FGroup.Visible then
begin
FGroup.Hide;
FTitleImage.Picture.Bitmap.LoadFromResourceName(HInstance,'ARROW');
Height := 22;
// notify
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end
else
begin
FGroup.Top := 23;
FGroup.Show;
FTitleImage.Picture.Bitmap.LoadFromResourceName(HInstance,'ARROWDOWN');
Height := 22 + FGroup.Height;
// notify
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end; }
// OldXuQQGroupWTitle:=TXuQQGroupWTitle(Sender);
end;
procedure TXuQQGroupWTitle.OnTitleMouseEnter(Sender: TObject);
begin
FTitle.Color := $00F8ECE4;
end;
procedure TXuQQGroupWTitle.OnTitleMouseLeave(Sender: TObject);
begin
FTitle.Color := clWindow;
end;
procedure TXuQQGroupWTitle.Packup;
begin
if not FGroup.Visible then
begin
FGroup.Hide;
Height := 22;
// notify
if Owner.ClassName = 'TXuQQPanel' then
TXuQQPanel(Owner).SetPanelHeight;
end;
end;
procedure TXuQQGroupWTitle.PaintPic(ACanvas: TCanvas; Bitmap: TBitmap); //画透明图标
var
ImageList : TImageList;
TransColor : TColor;
begin
if (Bitmap.Width = 0) or (Bitmap.Height = 0) then
Exit;
TransColor := Bitmap.Canvas.Pixels[0, 0];
ImageList := TImageList.CreateSize(Bitmap.Width, Bitmap.Height);
try
ImageList.AddMasked(Bitmap, TransColor);
ImageList.Draw(ACanvas, 0, 0, 0, Enabled);
finally
ImageList.Free();
end;
end;
{ TXuQQGroup }
function TXuQQGroup.AddMember(person: TXuQQPerson): Boolean;
var
i: Integer;
userAdded: Boolean;
len: Integer;
j: Integer;
begin
userAdded := False;
for i := 0 to Length(FMembers) - 1 do
begin
if FMembers[i].UserID = person.UserID then
begin
userAdded := True;
Break;
end;
end;
if userAdded then
begin
Result := False;
Exit;
end;
len := Length(FMembers);
SetLength(FMembers, len + 1);
FMembers[len] := TXuQQMember.Create(self);
FMembers[len].Parent := self;
FMembers[len].Caption := EmptyStr;
FMembers[len].Align := alTop;
if len = 0 then
FMembers[len].Top := 0
else
FMembers[len].Top := FMembers[len-1].Top + FMembers[len-1].Height + 1;
FMembers[len].NickName.Caption := person.UserName;
// FMembers[len].NickName.Font.Color :=clWhite;// person.NameColor;
FMembers[len].Desc.Caption := person.UserDesc;
FMembers[len].UserID := person.UserID;
//if FileExists(person.UserHead) then
// FMembers[len].HeadImage.Picture.LoadFromFile(person.UserHead);
for j := 0 to Length(person.FUserIcons) - 1 do
FMembers[len].AddIcon(person.FUserIcons[j]);
FMembers[len].Data := person;
Height := 54 * (len + 1);
if Owner.ClassName = 'TXuQQGroupWTitle' then
TXuQQGroupWTitle(Owner).Height := 22 + Height;
Result := True;
end;
constructor TXuQQGroup.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BevelOuter := bvNone;
Color := clWindow;
SetMemberCount(0);
end;
function TXuQQGroup.GetMemberCount: Integer;
begin
Result := Length(FMembers);
end;
procedure TXuQQGroup.RemoveMember(Index: Integer);
var
i: Integer;
len: Integer;
begin
FMembers[Index].Free;
for i := Index to Length(FMembers) - 2 do
begin
FMembers[i] := FMembers[i+1];
end;
len := Length(FMembers);
SetLength(FMembers, len - 1);
Height := 54 * (len - 1);
if Owner.ClassName = 'TXuQQGroupWTitle' then
TXuQQGroupWTitle(Owner).Height := 22 + Height;
end;
procedure TXuQQGroup.SetMemberCount(const Value: Integer);
var
i: Integer;
begin
for i := Length(FMembers) - 1 downto 0 do
FMembers[i].Free;
SetLength(FMembers, Value);
for i := 0 to Length(FMembers) - 1 do
begin
FMembers[i] := TXuQQMember.Create(self);
FMembers[i].Parent := self;
FMembers[i].Caption := EmptyStr;
FMembers[i].Align := alTop;
if i = 0 then
FMembers[i].Top := 0
else
FMembers[i].Top := FMembers[i-1].Top + FMembers[i-1].Height + 1;
end;
Height := 54 * Value;
if Owner.ClassName = 'TXuQQGroupWTitle' then
TXuQQGroupWTitle(Owner).Height := 22 + Height;
end;
{ TXuQQMember }
procedure TXuQQMember.AddIcon(Ico: TXuQQIcon);
var
len: Integer;
begin
len := Length(FQQIcons);
SetLength(FQQIcons, len + 1);
FQQIcons[len] := ico;
FQQIcons[len].Parent := FPExtension;
FQQIcons[len].Align := alLeft;
end;
constructor TXuQQMember.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BevelOuter := bvNone;
Height := 54;
Color := clred;
// OnMouseEnter := OnGlassMouseEnter;
// OnMouseLeave := OnGlassMouseLeave;
// OnClick := OnGlassClick;
// OnDblClick := OnGlassDoubleClick;
{ FHeadImage := TImage.Create(self);
FHeadImage.Parent := self;
FHeadImage.Align := alLeft;
FHeadImage.Height := 40;
FHeadImage.Width := 40;
FHeadImage.Transparent := True;
FPnlCont := TPanel.Create(self);
FPnlCont.Parent := self;
FPnlCont.BevelOuter := bvNone;
FPnlCont.Caption := EmptyStr;
FPnlCont.Align := alClient;
FPnlCont.Color := clWindow;
FNickName := TLabel.Create(self);
FNickName.Parent := FPNickName;
FNickName.Color := clred;
FNickName.Align := alClient;
FNickName.Layout := tlCenter; }
end;
destructor TXuQQMember.Destroy;
begin
inherited;
end;
procedure TXuQQMember.DoMouseEnter(var Msg: TMessage);
begin
;
end;
procedure TXuQQMember.DoMouseLeave(var Msg: TMessage);
begin
;
end;
procedure TXuQQMember.OnGlassClick(Sender: TObject);
begin
;
end;
procedure TXuQQMember.OnGlassDoubleClick(Sender: TObject);
begin
;
end;
procedure TXuQQMember.OnGlassMouseEnter(Sender: TObject);
begin
Color := $00E9E0DA;
FPnlCont.Color := $00E9E0DA;
FPNickName.Color := $00E9E0DA;
FPDesc.Color := $00E9E0DA;
FPExtension.Color := $00E9E0DA;
end;
procedure TXuQQMember.OnGlassMouseLeave(Sender: TObject);
begin
Color := clWindow;
FPnlCont.Color := clWindow;
FPNickName.Color := clWindow;
FPDesc.Color := clWindow;
FPExtension.Color := clWindow;
end;
procedure TXuQQMember.OnImageMouseEnter(Sender: TObject);
begin
;
end;
procedure TXuQQMember.OnImageMouseLeave(Sender: TObject);
begin
;
end;
procedure TXuQQMember.RemoveIcon(Index: Integer);
begin
;
end;
{ TXuQQPerson }
procedure TXuQQPerson.AddIcon(Ico: TXuQQIcon);
var
len: Integer;
begin
len:=length(FUserIcons);
SetLength(FUserIcons, len + 1);
FUserIcons[len] := ico;
end;
constructor TXuQQPerson.Create;
begin
FNameColor := clBlack;
end;
procedure TXuQQPerson.RemoveIcon(Index: Integer);
var
i: Integer;
len: Integer;
begin
len := length(FUserIcons);
FUserIcons[Index].Free;
for i := index to len - 2 do
FUserIcons[i] := FUserIcons[i+1];
Setlength(FUserIcons, len -1);
end;
{ TXuQQIcon }
constructor TXuQQIcon.Create(AOwner: TComponent);
begin
inherited;
BevelOuter := bvNone;
ParentColor := True;
Height := 18;
Width := 18;
FImage := TImage.Create(self);
FImage.Parent := self;
FImage.Stretch := True;
FImage.Align := alClient;
FImage.Transparent := True;
FImage.OnClick := OnImgClick;
FImage.OnDblClick := OnImgDblClick;
end;
procedure TXuQQIcon.OnImgClick(Sender: TObject);
begin
if Assigned(OnIconClick) then
OnIconClick(Self, Data);
end;
procedure TXuQQIcon.OnImgDblClick(Sender: TObject);
begin
if Assigned(OnIconDoubleClick) then
OnIconDoubleClick(Self, Data);
end;
procedure TXuQQIcon.SetData(const Value: Pointer);
begin
FData := Value;
FImage.ShowHint := FData <> nil;
if FData <> nil then
begin
FImage.Hint := TXuQQIconData(Value).IconDesc;
end;
end;
procedure TXuQQIcon.SetNormalIcon(const Value: string);
begin
FNormalIcon := Value;
FImage.Picture.Bitmap.LoadFromFile(Value);
end;
end.