You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1070 lines
32 KiB
Plaintext
1070 lines
32 KiB
Plaintext
{
|
|
This file is part of R&Q.
|
|
Under same license
|
|
}
|
|
unit RnQTips;
|
|
{$I RnQConfig.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Graphics, Types, Classes, SysUtils, Forms,
|
|
events, RnQProtocol, RDutils,
|
|
tipDlg, RnQGraphics32, GR32;
|
|
|
|
{$I NoRTTI.inc}
|
|
// procedure TipAdd2(ev:Thevent; bmp2 : tbitmap; seconds : Integer = -1);
|
|
procedure TipAdd3(ev: Thevent; bmp2: TRnQBitmap = nil; pCnt: TRnQContact = nil; seconds: Integer = -1);
|
|
// procedure TipAdd(bmp : Tbitmap; seconds : Integer = -1); overload;
|
|
// procedure TipAdd(ev:Thevent; seconds : Integer = -1); overload;
|
|
// procedure TipAdd(gpBmp : tGPbitmap; seconds : Integer = -1); overload;
|
|
procedure TipRemove(ev: Thevent); overload;
|
|
procedure TipRemove(cnt: TRnQContact); overload;
|
|
procedure TipsUpdateByCnt(c: TRnQContact);
|
|
procedure TipsProced;
|
|
procedure tipDrawEvent(destDC: HDC; ev: Thevent; pCnt: TRnQContact; var maxX, maxY: Integer; calcOnly: Boolean);
|
|
|
|
implementation
|
|
|
|
uses
|
|
math, StrUtils, Base64,
|
|
RQUtil, RnQSysUtils, RnQBinUtils,
|
|
RDGlobal, RQThemes, RnQLangs,
|
|
globalLib, utilLib, RDtrayLib, RnQPics,
|
|
{$IFDEF UNICODE}
|
|
AnsiStrings,
|
|
// Character,
|
|
{$ENDIF}
|
|
protocol_ICQ, ICQConsts,
|
|
chatDlg, mainDlg;
|
|
|
|
procedure TipsDraw(Sender: TtipFrm; mode: Tmodes; info: Pointer; pMaxX, pMaxY: Integer; calcOnly: Boolean);
|
|
var
|
|
hb: HBRUSH;
|
|
begin
|
|
if not Sender.HandleAllocated then
|
|
Exit;
|
|
|
|
Sender.Canvas.Lock;
|
|
try
|
|
case mode of
|
|
TM_EVENT:
|
|
tipDrawEvent(Sender.Canvas.Handle, Thevent(info), nil, pMaxX, pMaxY, calcOnly);
|
|
TM_PIC:
|
|
Sender.Canvas.Draw(0, 0, TBitmap(info));
|
|
TM_PIC_EX:
|
|
if Assigned(TRnQBitmap(info)) then
|
|
if Assigned(TRnQBitmap(info).fBmp) then
|
|
begin
|
|
hb := CreateSolidBrush(ColorToRGB(theme.GetColor('tip.bg', clInfoBk)));
|
|
FillRect(Sender.Canvas.Handle, Sender.Canvas.ClipRect, hb);
|
|
DrawRbmp(Sender.Canvas.Handle, TRnQBitmap(info));
|
|
end;
|
|
TM_BDay:
|
|
tipDrawEvent(Sender.Canvas.Handle, NIL, TRnQContact(info), pMaxX, pMaxY, calcOnly);
|
|
end;
|
|
finally
|
|
Sender.Canvas.Unlock;
|
|
end;
|
|
end;
|
|
|
|
procedure TipsDestroy(Sender: TtipFrm);
|
|
begin
|
|
case Sender.info.mode of
|
|
TM_EVENT:
|
|
if Assigned(Sender.info.obj) then
|
|
begin
|
|
Thevent(Sender.info.obj).Free;
|
|
Sender.info.obj := NIL;
|
|
end;
|
|
TM_PIC:
|
|
if Assigned(Sender.info.obj) then
|
|
begin
|
|
TBitmap(Sender.info.obj).Free;
|
|
Sender.info.obj := NIL;
|
|
end;
|
|
TM_PIC_EX:
|
|
if Assigned(Sender.info.obj) then
|
|
begin
|
|
TRnQBitmap(Sender.info.obj).Free;
|
|
Sender.info.obj := NIL;
|
|
end;
|
|
TM_BDay:
|
|
if Assigned(Sender.info.obj) then
|
|
begin
|
|
// info.cnt.Free;
|
|
Sender.info.obj := NIL;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function CopyPic(BMP: TBitmap32): TBitmap32;
|
|
type
|
|
PColor32 = ^TColor32;
|
|
TColor32 = type Cardinal;
|
|
function SetAlpha(Color32: TColor32; NewAlpha: Integer): TColor32;
|
|
begin
|
|
if NewAlpha < 0 then
|
|
NewAlpha := 0
|
|
else if NewAlpha > 255 then
|
|
NewAlpha := 255;
|
|
Result := (Color32 and $00FFFFFF) or (TColor32(NewAlpha) shl 24);
|
|
end;
|
|
|
|
var
|
|
// R:TRect;
|
|
r, c: Cardinal;
|
|
PC: PColor32;
|
|
begin
|
|
Result := TBitmap32.create;
|
|
begin
|
|
// Result.PixelFormat := bmp.PixelFormat;
|
|
Result.SetSize(BMP.Width, BMP.Height);
|
|
// Result.Transparent := bmp.Transparent;
|
|
// Result.TransparentColor := bmp.TransparentColor;
|
|
// Result.TransparentMode := bmp.TransparentMode;
|
|
// R := Rect(0 ,20, 100, 100);
|
|
// FillRect(pic.Canvas.Handle, r, CreateSolidBrush(clRed));
|
|
BitBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, BMP.Canvas.Handle, 0, 0, SrcCopy);
|
|
// if Result.PixelFormat = pf32bit then
|
|
// begin
|
|
for r := 0 to BMP.Height - 1 do
|
|
begin
|
|
PC := Pointer(Result.ScanLine[r]);
|
|
for c := 0 to BMP.Width - 1 do
|
|
begin
|
|
PC^ := SetAlpha(PC^, $FF);
|
|
Inc(PC);
|
|
end;
|
|
end;
|
|
// end;
|
|
// DrawText(pic.Canvas.Handle, PChar('Ïðèâåò'), -1, R, DT_SINGLELINE);// or DT_VCENTER);
|
|
end;
|
|
// mode:=TM_PIC;
|
|
// counter:=0;
|
|
// time:=now;
|
|
// ev := NIL;
|
|
end;
|
|
|
|
procedure TipAdd3(ev: Thevent; bmp2: TRnQBitmap = nil; pCnt: TRnQContact = nil; seconds: Integer = -1);
|
|
var
|
|
// isEv: Boolean;
|
|
// isPic: Boolean;
|
|
tipType: byte; { 1 - ev, 2 - pic, 3 - birthday }
|
|
|
|
item: TRnQTip;
|
|
// cnt, idx: Integer;
|
|
// minX, minY: Integer;
|
|
needW, needH: Integer;
|
|
work: Trect;
|
|
not_ok: Boolean;
|
|
rt: TRnQTip;
|
|
// not_ok: Boolean;
|
|
// rt: TRnQTip;
|
|
|
|
sR: RawByteString;
|
|
sl: Integer;
|
|
i, k, imgcnt: Integer;
|
|
pic: TBitmap32;
|
|
|
|
ti: TTipInfo;
|
|
tempPic: TBitmap;
|
|
begin
|
|
// if ( TipsMaxCnt = 0 ) then
|
|
if MainPrefs.getPrefIntDef('show-tips-count', 20) = 0 then
|
|
exit;
|
|
|
|
if locked then
|
|
exit;
|
|
|
|
if Assigned(ev) then
|
|
tipType := 1
|
|
else if Assigned(bmp2) then
|
|
tipType := 2
|
|
else if Assigned(pCnt) then
|
|
tipType := 3
|
|
else
|
|
exit;
|
|
|
|
case tipType of
|
|
1:
|
|
begin // Show event
|
|
if ((ev <> NIL) and not(BE_TIP in supportedBehactions[ev.kind])) or ((ev.kind in [EK_msg, EK_url])
|
|
// user reading this message in chat window
|
|
and chatFrm.isVisible and ev.who.equals(chatFrm.thisChat.who)) then
|
|
exit;
|
|
|
|
if ev.kind in [EK_url, EK_msg, EK_contacts, EK_authReq, EK_automsg] then
|
|
begin
|
|
sR := ev.getBodyBin;
|
|
sl := Length(ev.getBodyText);
|
|
end
|
|
else
|
|
sl := 0;
|
|
|
|
work := desktopWorkArea(mainDlg.RnQmain.Handle);
|
|
item := TRnQTip.create;
|
|
|
|
needW := 0;
|
|
needH := 0;
|
|
tempPic := createBitmap(1, 1);
|
|
tipDrawEvent(tempPic.Canvas.Handle, ev, NIL, needW, needH, True);
|
|
tempPic.Free;
|
|
needH := min(work.Bottom - work.Top - TipsMaxTop, needH);
|
|
// needW := min()
|
|
item.time := ev.when;
|
|
item.showSeconds := seconds;
|
|
item.counter := item.showSeconds;
|
|
// item.ev := ev;
|
|
|
|
with behaviour[ev.kind] do
|
|
begin
|
|
item.counter := TipTime;
|
|
if behaviour[ev.kind].TipTimes then
|
|
item.counter := item.counter * sl + TipTimePlus;
|
|
if item.counter <= 0 then
|
|
item.counter := 20;
|
|
end;
|
|
end;
|
|
2:
|
|
begin // Show pic
|
|
work := desktopWorkArea(mainDlg.RnQmain.Handle);
|
|
needH := bmp2.Height;
|
|
needW := bmp2.Width;
|
|
|
|
item := TRnQTip.create;
|
|
item.time := now;
|
|
item.showSeconds := seconds;
|
|
item.counter := seconds;
|
|
end;
|
|
3:
|
|
begin // Show birthday
|
|
// Exit;
|
|
|
|
work := desktopWorkArea(mainDlg.RnQmain.Handle);
|
|
item := TRnQTip.create;
|
|
needW := 0;
|
|
needH := 0;
|
|
|
|
tempPic := createBitmap(1, 1);
|
|
tipDrawEvent(tempPic.Canvas.Handle, NIL, pCnt, needW, needH, True);
|
|
tempPic.Free;
|
|
needH := min(work.Bottom - work.Top - TipsMaxTop, needH);
|
|
// needW := min()
|
|
item.time := now;
|
|
item.showSeconds := MAXWORD;
|
|
item.counter := MAXWORD;
|
|
end
|
|
else
|
|
exit;
|
|
end;
|
|
|
|
case tipType of
|
|
1:
|
|
begin
|
|
// item.frm.show(ev, item.x, item.Y);
|
|
ti.mode := TM_EVENT;
|
|
ti.obj := ev.clone;
|
|
end;
|
|
2:
|
|
begin
|
|
// item.form.show(bmp2, item.x, item.Y);
|
|
ti.mode := TM_PIC_EX;
|
|
ti.obj := bmp2.clone(RDGlobal.MakeRect(0, 0, bmp2.GetWidth, bmp2.GetHeight));
|
|
end;
|
|
3:
|
|
begin
|
|
// item.frm.show(pCnt, item.x, item.Y);
|
|
ti.mode := TM_BDay;
|
|
ti.obj := pCnt;
|
|
end;
|
|
end;
|
|
|
|
if AddTip(item, ti, needW, needH) then
|
|
begin
|
|
item.form.OnPaintTip := TipsDraw;
|
|
item.form.OnTipDestroy := TipsDestroy;
|
|
item.form.AlphaBlend := True;
|
|
item.form.AlphaBlendValue := 0;
|
|
item.form.showTip;
|
|
// MainPrefs.getPrefBoolDef('transparency-tray', False);
|
|
// MainPrefs.getPrefIntDef('transparency-vtray', 220)
|
|
end;
|
|
end;
|
|
|
|
procedure TipRemove(ev: Thevent);
|
|
var
|
|
i: Integer;
|
|
rt: TRnQTip;
|
|
begin
|
|
If Assigned(tipsList) then
|
|
begin
|
|
for i := 0 to tipsList.Count - 1 do
|
|
begin
|
|
rt := TRnQTip(tipsList.Items[i]);
|
|
if Assigned(rt) and Assigned(rt.form) then
|
|
if (rt.form.info.mode = TM_EVENT) and (rt.form.info.obj = ev) then
|
|
begin
|
|
tipsList.Items[i] := nil;
|
|
rt.form.Close;
|
|
rt.form := NIL;
|
|
rt.Free;
|
|
end;
|
|
end;
|
|
// Check4NIL;
|
|
// if tipsList.Count = 0 then
|
|
// FreeAndNil(tipsList);
|
|
MoveTips;
|
|
end;
|
|
end;
|
|
|
|
procedure TipRemove(cnt: TRnQContact);
|
|
var
|
|
i: Integer;
|
|
rt: TRnQTip;
|
|
begin
|
|
if not Assigned(cnt) then
|
|
exit;
|
|
If Assigned(tipsList) then
|
|
begin
|
|
for i := 0 to tipsList.Count - 1 do
|
|
begin
|
|
rt := TRnQTip(tipsList.Items[i]);
|
|
if Assigned(rt) and Assigned(rt.form) and
|
|
(((rt.form.info.mode = TM_EVENT) and Assigned(rt.form.info.obj) and Assigned(Thevent(rt.form.info.obj).who) and
|
|
Thevent(rt.form.info.obj).who.equals(cnt)) or ((rt.form.info.mode = TM_BDay) and Assigned(rt.form.info.obj) and
|
|
TRnQContact(rt.form.info.obj).equals(cnt))) then
|
|
try
|
|
tipsList.Items[i] := nil;
|
|
rt.form.Close;
|
|
rt.form := NIL;
|
|
rt.Free;
|
|
except
|
|
end;
|
|
end;
|
|
// Check4NIL;
|
|
// if tipsList.Count = 0 then
|
|
// FreeAndNil(tipsList);
|
|
end;
|
|
MoveTips;
|
|
end;
|
|
|
|
procedure TipsUpdateByCnt(c: TRnQContact);
|
|
var
|
|
i: Integer;
|
|
rt: TRnQTip;
|
|
begin
|
|
If Assigned(tipsList) then
|
|
for i := 0 to tipsList.Count - 1 do
|
|
begin
|
|
rt := TRnQTip(tipsList.Items[i]);
|
|
if Assigned(rt) and Assigned(rt.form) and (rt.form.info.mode = TM_EVENT) and Assigned(rt.form.info.obj) and
|
|
Thevent(rt.form.info.obj).who.equals(c) then
|
|
begin
|
|
rt.form.Repaint;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TipsProced;
|
|
var
|
|
i: Integer;
|
|
tipFrm: TtipFrm;
|
|
cur_ev: Thevent;
|
|
rt: TRnQTip;
|
|
begin
|
|
If Assigned(tipsList) then
|
|
if tipsList.Count > 0 then
|
|
for i := tipsList.Count - 1 downto 0 do
|
|
if not Assigned(tipsList.Items[i]) then
|
|
tipsList.Delete(i);
|
|
|
|
if Assigned(tipsList) then
|
|
for i := 0 to tipsList.Count - 1 do
|
|
begin
|
|
rt := TRnQTip(tipsList.Items[i]);
|
|
if Assigned(rt) then
|
|
begin
|
|
tipFrm := rt.form;
|
|
if Assigned(tipFrm) then
|
|
with tipFrm do
|
|
if not mousedown then
|
|
if actionCount = 0 then
|
|
begin
|
|
// shutdown tip-window
|
|
if rt.counter >= 0 then
|
|
dec(rt.counter);
|
|
if rt.counter <= 0 then
|
|
begin
|
|
// hide();
|
|
tipsList.Items[i] := nil;
|
|
tipFrm.Close;
|
|
rt.form := nil;
|
|
// TRnQTip(tipsList.Items[i]).frm.Free;
|
|
rt.Free;
|
|
MoveTips;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// manages tip-window clicks
|
|
dec(actionCount);
|
|
if actionCount = 0 then
|
|
begin
|
|
if (info.mode = TM_EVENT) and (info.obj <> NIL) then
|
|
cur_ev := Thevent(info.obj).clone
|
|
else
|
|
cur_ev := NIL;
|
|
Close;
|
|
tipsList.Items[i] := nil;
|
|
rt.form := nil;
|
|
// TRnQTip(tipsList.Items[i]).frm.Free;
|
|
rt.Free;
|
|
MoveTips;
|
|
if Assigned(cur_ev) then
|
|
case action of
|
|
TA_2lclick:
|
|
begin
|
|
chatFrm.openOn(cur_ev.who);
|
|
if not chatFrm.moveToTimeOrEnd(cur_ev.who, cur_ev.when) then
|
|
chatFrm.addEvent(cur_ev.who, cur_ev.clone);
|
|
end;
|
|
TA_rclick:
|
|
eventQ.removeEvent(cur_ev.who);
|
|
end;
|
|
action := TA_null;
|
|
cur_ev.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if ShowBalloonTime > 0 then
|
|
begin
|
|
dec(ShowBalloonTime, RnQmain.timer.Interval);
|
|
if ShowBalloonTime <= 0 then
|
|
statusIcon.hideBalloon;
|
|
end;
|
|
end;
|
|
|
|
procedure tipDrawEvent(destDC: HDC; ev: Thevent; pCnt: TRnQContact; var maxX, maxY: Integer; calcOnly: Boolean);
|
|
var
|
|
x, y, h: Integer;
|
|
fullR, Rcap, r, work: Trect;
|
|
// pc: pchar;
|
|
vSize: Tsize;
|
|
font: TFont;
|
|
|
|
// gr: TGPGraphics;
|
|
// fnt: TGPFont;
|
|
// gfmt: TGPStringFormat;
|
|
// br: TGPBrush;
|
|
// pen: TGPPen;
|
|
// gpR, resR: TGPRectF;
|
|
// pth: TGPGraphicsPath;
|
|
res: Tsize;
|
|
// cname,
|
|
info, infoImg, sA: RawByteString;
|
|
s: String;
|
|
days2BD: SmallInt;
|
|
|
|
dc: HDC;
|
|
ABitmap, HOldBmp: HBITMAP;
|
|
|
|
oldFont: HFONT;
|
|
brLog: LOGBRUSH;
|
|
oldBr, hb: HBRUSH;
|
|
oldPen, Hp: HPEN;
|
|
oldMode: Integer;
|
|
ta: UINT;
|
|
ClrBg: TColor;
|
|
Clr2: Cardinal;
|
|
|
|
rad: Integer;
|
|
|
|
i, k, imgY, imgX, imgcnt: Integer;
|
|
// l, m : Integer;
|
|
// proc : Byte;
|
|
RnQPicStream: TMemoryStream;
|
|
vRnQpicEx: TRnQBitmap;
|
|
b: byte;
|
|
st: byte;
|
|
drawAvt: Boolean;
|
|
thisCnt: TRnQContact;
|
|
stsArr: TStatusArray;
|
|
// xStsArr : TXStatStrArr;
|
|
|
|
p: TPicName;
|
|
// picN : TPicName;
|
|
r2: TGPRect;
|
|
ms: Integer;
|
|
|
|
imgList: TStringList;
|
|
begin
|
|
// inherited;
|
|
if calcOnly then
|
|
begin
|
|
maxX := 0;
|
|
maxY := 0;
|
|
end;
|
|
|
|
if (pCnt = nil) and ((ev = nil) or (ev.who = nil)) then
|
|
Exit;
|
|
|
|
fullR.Left := 0;
|
|
fullR.Top := 0;
|
|
fullR.Right := maxX;
|
|
fullR.Bottom := maxY;
|
|
|
|
if calcOnly then
|
|
begin
|
|
fullR.Right := min(MAXSHORT, maxX);
|
|
fullR.Bottom := min(MAXSHORT, maxY);
|
|
end;
|
|
|
|
HOldBmp := 0;
|
|
// if not calcOnly then
|
|
try
|
|
dc := CreateCompatibleDC(destDC);
|
|
with fullR do
|
|
begin
|
|
ABitmap := CreateCompatibleBitmap(destDC, Right - Left, Bottom - Top);
|
|
if (ABitmap = 0) and (Right - Left + Bottom - Top <> 0) then
|
|
raise EOutOfResources.create('Out of Resources');
|
|
HOldBmp := SelectObject(dc, ABitmap);
|
|
SetWindowOrgEx(dc, Left, Top, nil);
|
|
end;
|
|
finally
|
|
end;
|
|
// else
|
|
// DC := 0;
|
|
|
|
try
|
|
thisCnt := nil;
|
|
if Assigned(ev) and Assigned(ev.who) then
|
|
thisCnt := ev.who
|
|
else if Assigned(pCnt) then
|
|
thisCnt := pCnt
|
|
else
|
|
s := '';
|
|
if Assigned(thisCnt) then
|
|
s := thisCnt.displayed;
|
|
// cname:=contact.displayed;
|
|
work := desktopWorkArea(mainDlg.RnQmain.Handle);
|
|
|
|
x := 4;
|
|
// R.left := x;
|
|
y := 2;
|
|
if calcOnly then
|
|
begin
|
|
maxX := x;
|
|
maxY := y;
|
|
end;
|
|
// gpR.Y := y;
|
|
// gpR.X := x;
|
|
{ begin
|
|
h := FontStyleRegular;
|
|
if fsBold in font.Style then
|
|
h := h or FontStyleBold;
|
|
if fsItalic in font.Style then
|
|
h := h or FontStyleItalic;
|
|
fnt := TGPFont.Create(font.Name, font.Size, h, UnitPoint);
|
|
end;
|
|
gfmt := TGPStringFormat.Create(//StringFormatFlagsNoWrap or
|
|
StringFormatFlagsMeasureTrailingSpaces);
|
|
gfmt.SetLineAlignment(StringAlignmentNear);
|
|
gfmt.SetHotkeyPrefix(HotkeyPrefixNone); }
|
|
|
|
// gr.MeasureString(s, length(s), fnt, MakePoint(gpR.X, gpR.Y), gfmt, resR);
|
|
// gr.MeasureString(cname, Length(cname), fnt, gpR, resR);
|
|
|
|
if Assigned(ev) then
|
|
p := event2imgName(ev.kind)
|
|
else if Assigned(pCnt) then
|
|
begin
|
|
days2BD := pCnt.days2BD;
|
|
case days2BD of
|
|
0:
|
|
p := PIC_BIRTH;
|
|
1:
|
|
p := PIC_BIRTH1;
|
|
2:
|
|
p := PIC_BIRTH2;
|
|
else
|
|
p := PIC_BIRTH + 'n';
|
|
end;
|
|
end
|
|
else
|
|
p := '';
|
|
if not calcOnly then // Paint Background
|
|
begin
|
|
// gr := TGPGraphics.Create(DC);
|
|
{ gr := TGPGraphics.Create(dc);
|
|
//cnv.Brush.Style:=bsSolid;
|
|
//cnv.brush.color:=theme.GetColor('tip.bg');//tip.bgcolor;
|
|
//cnv.fillRect(cnv.ClipRect);
|
|
br := TGPSolidBrush.Create(theme.GetAColor('tip.bg', clInfoBk));
|
|
gr.FillRectangle(br, MakeRect(fullR));
|
|
br.Free;
|
|
FreeAndNil(gr); }
|
|
ClrBg := theme.GetColor('tip.bg', clInfoBk);
|
|
ClrBg := theme.GetColor('tip.bg.' + p, ClrBg);
|
|
|
|
hb := CreateSolidBrush(ColorToRGB(ClrBg));
|
|
// oldBr := SelectObject(DC, hb);
|
|
FillRect(dc, fullR, hb);
|
|
DeleteObject(hb);
|
|
// if Not calcOnly then
|
|
// Caption BG
|
|
Rcap.Left := 1;
|
|
Rcap.Top := 1;
|
|
Rcap.Right := maxX - 1;
|
|
Rcap.Bottom := 20;
|
|
Clr2 := theme.GetColor('tip.caption', ClrBg);
|
|
// Clr2 := theme.GetAColor('tip.caption.' + p, theme.GetColor('tip.caption', ClrBg));
|
|
FillRect(dc, Rcap, CreateSolidBrush(ColorToRGB(Clr2)));
|
|
{$IFDEF USE_GDIPLUS}
|
|
// GPFillGradient(DC, Rcap, Clr2, AlphaMask or ABCD_ADCB(ColorToRGB(ClrBg)), gdVertical);
|
|
{$ELSE USE_GDIPLUS}
|
|
// FillGradient(DC, Rcap, Clr2, AlphaMask or Cardinal(ColorToRGB(ClrBg)), gdVertical);
|
|
{$ENDIF USE_GDIPLUS}
|
|
// Info BG
|
|
Rcap.Left := 1;
|
|
Rcap.Top := 20;
|
|
Rcap.Right := maxX - 1;
|
|
Rcap.Bottom := maxY - 1;
|
|
Clr2 := theme.GetColor('tip.info', ClrBg);
|
|
// Clr2 := theme.GetAColor('tip.info.' + p, theme.GetColor('tip.info', ClrBg));
|
|
FillRect(dc, Rcap, CreateSolidBrush(ColorToRGB(Clr2)));
|
|
{$IFDEF USE_GDIPLUS}
|
|
// GPFillGradient(DC, Rcap, Clr2, AlphaMask or ABCD_ADCB(ColorToRGB(ClrBg)), gdVertical);
|
|
{$ELSE USE_GDIPLUS}
|
|
// FillGradient(DC, Rcap, Clr2, AlphaMask or Cardinal(ColorToRGB(ClrBg)), gdVertical);
|
|
{$ENDIF USE_GDIPLUS}
|
|
end;
|
|
if calcOnly then
|
|
vSize := theme.GetPicSize(RQteDefault, p)
|
|
else
|
|
vSize := theme.drawPic(dc, x, y, p);
|
|
|
|
p := '';
|
|
Inc(x, vSize.cx + 2);
|
|
// gpR.X := x;
|
|
r := fullR;
|
|
r.Left := x;
|
|
font := TFont.create;
|
|
font.Assign(Screen.HintFont);
|
|
theme.ApplyFont('tip.contact', font);
|
|
oldFont := SelectObject(dc, font.Handle);
|
|
// oldColor :=
|
|
SetTextColor(dc, ColorToRGB(font.Color));
|
|
// DrawText(DC, PChar(s), -1, R, DT_CALCRECT or DT_SINGLELINE);// or DT_VCENTER);
|
|
DrawText(dc, PChar(s), Length(s), r, DT_CALCRECT or DT_SINGLELINE); // or DT_VCENTER);
|
|
GetTextExtentPoint32(dc, PChar(s), Length(s), res);
|
|
|
|
// inc(x, cnv.textWidth(cname)+3);
|
|
Inc(x, res.cx + 3);
|
|
// h:=cnv.textHeight('J')*4 div 3;
|
|
// if size.cy > h then
|
|
// h:=size.cy;
|
|
// gpR.Y := h - Round(resR.Height);
|
|
h := max(vSize.cy, res.cy);
|
|
r.Top := h - res.cy;
|
|
|
|
if not calcOnly then
|
|
begin
|
|
r.BottomRight := fullR.BottomRight;
|
|
// cnv.textOut(x,y+2,cname);
|
|
// br := TGPSolidBrush.Create(gpColorFromAlphaColor($FF, theme.GetFont('tip.contact').Color));
|
|
// gr.DrawString(s, length(s), fnt, gpR, gfmt, br);
|
|
// br.Free;
|
|
|
|
// oldFont := SelectObject(DC, Font.Handle);
|
|
// oldColor :=
|
|
SetTextColor(dc, ColorToRGB(font.Color));
|
|
oldMode := SetBKMode(dc, TRANSPARENT);
|
|
// DrawText(DC, PChar(s), -1, R, DT_SINGLELINE or DT_NOPREFIX); //or DT_VCENTER
|
|
DrawText(dc, PChar(s), Length(s), r, DT_SINGLELINE or DT_NOPREFIX); // or DT_VCENTER
|
|
// SetBKMode(DC, oldMode);
|
|
// GetTextExtentPoint32(DC,pchar(s),length(s), res);
|
|
end;
|
|
// fnt.Free;
|
|
SelectObject(dc, oldFont);
|
|
// font.Free;
|
|
// font := theme.GetFont('tip');
|
|
// font := Screen.HintFont;
|
|
font.Assign(Screen.HintFont);
|
|
theme.ApplyFont('tip', font);
|
|
{ begin
|
|
h := FontStyleRegular;
|
|
if fsBold in font.Style then
|
|
h := h or FontStyleBold;
|
|
if fsItalic in font.Style then
|
|
h := h or FontStyleItalic;
|
|
fnt := TGPFont.Create(font.Name, font.Size, h, UnitPoint);
|
|
end; }
|
|
|
|
if Assigned(ev) then
|
|
s := getTranslation(tipevent2str[ev.kind])
|
|
else if Assigned(pCnt) then
|
|
begin
|
|
if days2BD in [0 .. 2] then
|
|
s := getTranslation(tipBirth2str[days2BD])
|
|
else
|
|
s := intToStr(days2BD) + ' days to birthday';
|
|
drawAvt := True;
|
|
end
|
|
else
|
|
s := '';
|
|
r := fullR;
|
|
r.Left := x;
|
|
// R.Top := y+2;
|
|
r.Top := h - res.cy;
|
|
// gpR.X := x;
|
|
// gpR.Y := y+2;
|
|
oldFont := SelectObject(dc, font.Handle);
|
|
// oldColor :=
|
|
SetTextColor(dc, ColorToRGB(font.Color));
|
|
// CreateFontIndirect()
|
|
// gr.MeasureString(s, length(s), fnt, MakePoint(gpR.X, gpR.Y), gfmt, resR);
|
|
// DrawText(DC, PChar(s), -1, R, DT_CALCRECT or DT_SINGLELINE or DT_NOPREFIX); // or DT_VCENTER
|
|
DrawText(dc, PChar(s), Length(s), r, DT_CALCRECT or DT_SINGLELINE or DT_NOPREFIX); // or DT_VCENTER
|
|
GetTextExtentPoint32(dc, PChar(s), Length(s), res);
|
|
if not calcOnly then
|
|
begin
|
|
// cnv.textOut(x,y+2,cname);
|
|
// br := TGPSolidBrush.Create(gpColorFromAlphaColor($FF, theme.GetFont('tip').Color));
|
|
// gr.DrawString(s, length(s), fnt, gpR, gfmt, br);
|
|
// br.Free;
|
|
oldMode := SetBKMode(dc, TRANSPARENT);
|
|
// DrawText(DC, PChar(s), -1, R, DT_SINGLELINE or DT_NOPREFIX); //or DT_VCENTER
|
|
DrawText(dc, PChar(s), Length(s), r, DT_SINGLELINE or DT_NOPREFIX); // or DT_VCENTER
|
|
// SetBKMode(DC, oldMode);
|
|
end;
|
|
|
|
// cnv.textOut(x,y+2, s);
|
|
// inc(x, cnv.textWidth(s)+2);
|
|
// inc(x, round(resR.Width)+2);
|
|
Inc(x, res.cx + 2);
|
|
|
|
if Assigned(ev) then
|
|
if ev.kind in [EK_INCOMING, EK_STATUSCHANGE] then
|
|
begin
|
|
// sa := ev.bInfo;
|
|
sA := ev.getBodyBin;
|
|
if Length(sA) >= 4 then
|
|
begin
|
|
st := (str2int(sA));
|
|
|
|
if Assigned(thisCnt) then
|
|
begin
|
|
stsArr := thisCnt.fProto.statuses;
|
|
if { (st >= Low(stsArr)) and } (st <= High(stsArr)) then
|
|
begin
|
|
b := infoToXStatus(sA);
|
|
p := status2imgName(st, (Length(sA) > 4) and Boolean(sA[5]));
|
|
// if (not XStatusAsMain) and (st <> SC_ONLINE)and (b>0) then
|
|
if (st <> byte(SC_ONLINE)) or (not XStatusAsMain) or (b = 0) then
|
|
begin
|
|
if calcOnly then
|
|
// inc(X, statusDrawExt(0, 0, 0, st, (length(sa)>4) and boolean(sa[5])).cx)
|
|
Inc(x, theme.GetPicSize(RQteDefault, p).cx)
|
|
else
|
|
// inc(X, statusDrawExt(DC, X+2, Y, st, (length(sa)>4) and boolean(sa[5])).cx)
|
|
Inc(x, theme.drawPic(dc, x + 2, y, p).cx);
|
|
Inc(x, 2);
|
|
end;
|
|
// with statusDrawExt(cnv.Handle, curX+2, curY, Tstatus(str2int(s)), (length(s)>4) and boolean(s[5])) do
|
|
if (b > 0) then
|
|
begin
|
|
if { (b >= Low(xStsArr)) and } (b <= High(XStatusArray)) then
|
|
begin
|
|
p := XStatusArray[b].PicName;
|
|
if calcOnly then
|
|
Inc(x, theme.GetPicSize(RQteDefault, p).cx + 1)
|
|
else
|
|
vSize := theme.drawPic(dc, x + 1, y, p);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
Inc(x, 4);
|
|
// inc(y, h);
|
|
// inc(y, max(round(resR.Height), vSize.cy) + 2);
|
|
Inc(y, max(res.cy, vSize.cy) + 2);
|
|
if calcOnly then
|
|
begin
|
|
maxX := x;
|
|
maxY := y;
|
|
end;
|
|
|
|
if Assigned(ev) then
|
|
begin
|
|
drawAvt := False;
|
|
|
|
// if ev.kind in [EK_url,EK_msg,EK_contacts,EK_authReq,EK_automsg, EK_file] then
|
|
if ev.isHasBody then
|
|
begin
|
|
// gpR.Y := y;
|
|
// gpR.X := 4;
|
|
r.Left := 4;
|
|
r.Top := y;
|
|
r.Bottom := 10000;
|
|
if calcOnly then
|
|
begin
|
|
i := r.Left + (work.Right - work.Left) div 3;
|
|
// gpR.Width :=(work.right - work.left) div 3
|
|
r.Right := i;
|
|
end
|
|
else
|
|
// gpR.Width :=maxX;
|
|
r.Right := maxX;
|
|
// R.top:=y;
|
|
// R.right:=(work.right-work.left) div 3;
|
|
// R.bottom:=y;
|
|
s := ev.getBodyText; // By Rapid D!
|
|
// pc:=@info[1];
|
|
// drawText(cnv.handle, pc, -1, R, DT_WORDBREAK+DT_EXTERNALLEADING+DT_NOPREFIX+DT_CALCRECT );
|
|
// drawText(cnv.handle, pc, -1, R, DT_WORDBREAK+DT_EXTERNALLEADING+DT_NOPREFIX );
|
|
// gr.MeasureString(s, length(s), fnt, gpR, gfmt, resR);
|
|
// oldFont := SelectObject(DC, Font.Handle);
|
|
// oldColor :=
|
|
if s > '' then
|
|
begin
|
|
ta := GetTextAlign(dc);
|
|
SetTextAlign(dc, ta or TA_LEFT or TA_TOP or TA_NOUPDATECP); // Need to DrawText and DrawTextEx
|
|
if not calcOnly then
|
|
begin
|
|
SetTextColor(dc, ColorToRGB(font.Color));
|
|
// cnv.textOut(x,y+2,cname);
|
|
{
|
|
gr := TGPGraphics.Create(DC);
|
|
br := TGPSolidBrush.Create(gpColorFromAlphaColor($FF, theme.GetFont('tip').Color));
|
|
gr.DrawString(s, length(s), fnt, gpR, gfmt, br);
|
|
br.Free;
|
|
FreeAndNil(GR);
|
|
}
|
|
oldMode := SetBKMode(dc, TRANSPARENT);
|
|
DrawText(dc, PChar(s), Length(s), r, DT_CALCRECT or DT_WORDBREAK or DT_EXTERNALLEADING or DT_NOPREFIX);
|
|
DrawText(dc, PChar(s), Length(s), r, DT_WORDBREAK or DT_EXTERNALLEADING or DT_NOPREFIX);
|
|
// DrawTextEx(DC, @s[1], Length(s), R, DT_WORDBREAK or DT_EXTERNALLEADING or DT_NOPREFIX, NIL); // or DT_VCENTER or DT_SINGLELINE
|
|
// SetBKMode(DC, oldMode);
|
|
Inc(y, r.Height);
|
|
end
|
|
else
|
|
begin
|
|
// r.Bottom := 0;
|
|
DrawText(dc, PChar(s), Length(s), r, DT_CALCRECT or DT_WORDBREAK or DT_EXTERNALLEADING or DT_NOPREFIX);
|
|
// or DT_VCENTER or DT_SINGLELINE
|
|
// s := s + ' '#13#10;
|
|
// DrawTextEx(DC, @s[1], Length(s), R, DT_CALCRECT or DT_WORDBREAK or DT_EXTERNALLEADING or DT_NOPREFIX, NIL); // or DT_VCENTER or DT_SINGLELINE
|
|
{ l := Length(s);
|
|
m := 1; R.Right := 0; R.Bottom := 0;
|
|
while l > 0 do
|
|
begin
|
|
GetTextExtentExPoint(DC, @s[m], l, i, @k, NIL, vSize);
|
|
GetTextExtentPoint32(DC, @s[m], k, vSize);
|
|
Dec(l, k);
|
|
Inc(m, k);
|
|
if R.Right < vSize.cx then
|
|
r.Right := vSize.cx;
|
|
Inc(r.Bottom, vSize.cy);
|
|
end;
|
|
// r.Right := vSize.cx;
|
|
// r.Bottom := vSize.cy;
|
|
}
|
|
if r.Right > i then
|
|
r.Right := i;
|
|
// GetTextExtentPoint32(DC,pchar(s),length(s), res);
|
|
// maxY := Round(gpR.Y + resR.Height) + 3;
|
|
// maxX := max(maxX, round(resR.Width)) + 3;
|
|
// maxY := R.Top + res.cy + 5;
|
|
// maxX := max(maxX, res.cx) + 5;
|
|
maxY := max(maxY, r.Bottom) + 5;
|
|
maxX := max(maxX, r.Right) + 5;
|
|
end;
|
|
end;
|
|
|
|
// SelectObject(DC, oldFont);
|
|
// inc(R.bottom,7);
|
|
// inc(R.right,7);
|
|
// maxY:=R.bottom;
|
|
// if R.right > maxX then
|
|
// maxX:=R.right;
|
|
end
|
|
else if ev.kind in [EK_incoming, EK_outgoing] then
|
|
drawAvt := True;
|
|
|
|
// if ev.kind in [EK_url,EK_msg,EK_contacts,EK_authReq,EK_automsg, EK_statuschange, EK_ONCOMING] then
|
|
if ev.kind = EK_msg then
|
|
begin
|
|
// info := ev.decrittedInfoOrg
|
|
// info := ev.bInfo
|
|
info := ev.getBodyBin
|
|
end
|
|
else
|
|
info := '';
|
|
|
|
imgList := TStringList.create;
|
|
parseMsgImages(info, imgList);
|
|
if imgList.Count > 0 then
|
|
begin
|
|
x := 5;
|
|
Inc(y, 5);
|
|
end;
|
|
imgX := 0;
|
|
imgY := 0;
|
|
|
|
for imgcnt := 0 to imgList.Count - 1 do
|
|
begin
|
|
infoImg := Base64DecodeString(imgList.Strings[imgcnt]);
|
|
RnQPicStream := TMemoryStream.create;
|
|
RnQPicStream.SetSize(Length(infoImg));
|
|
RnQPicStream.Position := 0;
|
|
RnQPicStream.Write(infoImg[1], Length(infoImg));
|
|
RnQPicStream.Position := 0;
|
|
|
|
vRnQpicEx := TRnQBitmap.create;
|
|
if loadPic(TStream(RnQPicStream), vRnQpicEx, 0, PA_FORMAT_UNK, 'RnQImageEx', True) then
|
|
if Assigned(vRnQpicEx.fBmp) then
|
|
begin
|
|
res.cx := vRnQpicEx.GetWidth;
|
|
res.cy := vRnQpicEx.GetHeight;
|
|
if calcOnly then
|
|
begin
|
|
Inc(imgX, res.cx + 5);
|
|
imgY := max(imgY, res.cy + 5);
|
|
end
|
|
else
|
|
begin
|
|
DrawRbmp(dc, vRnQpicEx, x, y);
|
|
Inc(x, res.cx + 5);
|
|
end
|
|
end;
|
|
RnQPicStream.Free;
|
|
end;
|
|
imgList.Free;
|
|
|
|
if calcOnly then
|
|
begin
|
|
maxX := max(maxX, imgX) + 5;
|
|
maxY := maxY + imgY;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF RNQ_AVATARS}
|
|
if drawAvt and avatarShowInTray and Assigned(thisCnt) then
|
|
with thisCnt do
|
|
if Assigned(icon.BMP) then
|
|
begin
|
|
r2.x := 8;
|
|
r2.y := y;
|
|
if MainPrefs.getPrefBoolDef('show-tips-use-avt-size', True) then
|
|
begin
|
|
ms := MainPrefs.getPrefIntDef('show-tips-avt-size', 100); // TipsMaxAvtSize
|
|
with BoundsSize(icon.BMP.GetWidth, icon.BMP.GetHeight, ms, ms) do
|
|
begin
|
|
r2.Width := cx;
|
|
r2.Height := cy;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
r2.Width := icon.BMP.GetWidth;
|
|
r2.Height := icon.BMP.GetHeight;
|
|
end;
|
|
if not calcOnly then
|
|
DrawRbmp(dc, icon.BMP, r2);
|
|
// cnv.Draw(5, y+3, contact.icon);
|
|
Inc(y, 10 + r2.Height);
|
|
if calcOnly then
|
|
begin
|
|
maxY := y;
|
|
if r2.x + r2.Width + 8 > maxX then
|
|
maxX := r2.x + r2.Width + 8;
|
|
end;
|
|
end;
|
|
{$ENDIF RNQ_AVATARS}
|
|
SelectObject(dc, oldFont);
|
|
font.Free;
|
|
// fnt.Free;
|
|
// gfmt.Free;
|
|
|
|
// cnv.Brush.Style := bsClear;
|
|
// cnv.r
|
|
// cnv.RoundRect(0, 0, maxX, maxY, round_R+1, round_R+1);
|
|
// cnv.frameRect(rect(0,0,maxX,maxY));
|
|
begin
|
|
if not TryStrToInt(theme.GetString('tip.radius'), rad) then
|
|
rad := 0;
|
|
if rad > 0 then
|
|
begin
|
|
{ gr := TGPGraphics.Create(DC);
|
|
pth := TGPGraphicsPath.Create(FillModeAlternate);
|
|
// pth.AddRectangle(MakeRect(fullR));
|
|
pth.StartFigure;
|
|
pth.AddArc(0, 0, rad+1, rad+1, 180, 90);
|
|
pth.AddArc(maxX - rad-2, 0, rad+1, rad+1, -90, 90);
|
|
pth.AddArc(maxX - rad-2, maxY-rad-2, rad+1, rad+1, 0, 90);
|
|
pth.AddArc(0, maxY-rad-2, rad+1, rad+1, 90, 90);
|
|
pth.CloseFigure;
|
|
pen := TGPPen.Create(aclBlack);
|
|
gr.DrawPath(pen, pth);
|
|
pen.Free;
|
|
pth.Free;
|
|
gr.Free; }
|
|
brLog.lbStyle := BS_HOLLOW;
|
|
// brLog.lbColor := ColorToRGB(theme.GetColor('tip.bg', clInfoBk));
|
|
brLog.lbColor := 0;
|
|
hb := CreateBrushIndirect(brLog);
|
|
oldBr := SelectObject(dc, hb);
|
|
Hp := CreatePen(PS_SOLID, 1, clSilver);
|
|
oldPen := SelectObject(dc, Hp);
|
|
RoundRect(dc, 0, 0, maxX, maxY, rad + 1, rad + 1);
|
|
SelectObject(dc, oldBr);
|
|
DeleteObject(hb);
|
|
SelectObject(dc, oldPen);
|
|
DeleteObject(Hp);
|
|
end
|
|
else
|
|
begin
|
|
// pen := TGPPen.Create(aclBlack);
|
|
// gr.DrawRectangle(pen, 0, 0, maxX-1, maxY-1);
|
|
// pen.Free;
|
|
|
|
// hB := //CreateSolidBrush(ColorToRGB(theme.GetColor('tip.bg', clInfoBk)));
|
|
// brLog.lbStyle := BS_HOLLOW;
|
|
brLog.lbStyle := BS_SOLID;
|
|
// brLog.lbColor := ColorToRGB(theme.GetColor('tip.bg', clInfoBk));
|
|
brLog.lbColor := clSilver;
|
|
hb := CreateBrushIndirect(brLog);
|
|
// Hp := CreatePen(PS_SOLID, 1, clBlack);
|
|
// oldPen := SelectObject(DC, hp);
|
|
oldBr := SelectObject(dc, hb);
|
|
// FillRect(DC, fullR, hb);
|
|
FrameRect(dc, fullR, hb);
|
|
// FrameRect(DC, )
|
|
// Rectangle(DC, 0, 0, maxX, maxY);
|
|
SelectObject(dc, oldBr);
|
|
DeleteObject(hb);
|
|
// SelectObject(DC, oldPen);
|
|
// DeleteObject(hB);
|
|
end;
|
|
|
|
end;
|
|
|
|
finally
|
|
if not calcOnly then
|
|
BitBlt(destDC, fullR.Left, fullR.Top, fullR.Right - fullR.Left, fullR.Bottom - fullR.Top, dc, fullR.Left,
|
|
fullR.Top, SrcCopy);
|
|
|
|
SelectObject(dc, HOldBmp);
|
|
DeleteObject(ABitmap);
|
|
DeleteDC(dc);
|
|
end;
|
|
end; // tipDrawEvent
|
|
|
|
end.
|