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.
RnQ/RnQ/RnQTips.pas

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.