void ThumbInfo::PositionThumb(int nX, int nY) { POINT pos = { nX, nY }; HDWP hdwp = BeginDeferWindowPos(1); ThumbInfo *pThumb = this; while (pThumb) { pThumb->PositionThumbWorker(pos.x, pos.y, &pos); if (nullptr != pThumb->hwnd) /* Wine fix. */ hdwp = DeferWindowPos(hdwp, pThumb->hwnd, HWND_TOPMOST, pos.x, pos.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); pThumb->ptPos = pos; pos.x += pThumb->szSize.cx; pThumb = fcOpt.bMoveTogether ? thumbList.FindThumb(pThumb->dockOpt.hwndRight) : nullptr; } EndDeferWindowPos(hdwp); }
void ThumbInfo::PositionThumbWorker(int nX, int nY, POINT *newPos) { RECT rc; RECT rcThumb; int nNewX; int nNewY; int nWidth; int nHeight; POINT pt; RECT rcLeft; RECT rcTop; RECT rcRight; RECT rcBottom; BOOL bDocked; BOOL bDockedLeft; BOOL bDockedRight; BOOL bLeading; // Get thumb dimnsions GetThumbRect(&rcThumb); nWidth = rcThumb.right - rcThumb.left; nHeight = rcThumb.bottom - rcThumb.top; // Docking and screen boundaries check SnapToScreen(rcThumb, nX, nY, &nNewX, &nNewY); bLeading = dockOpt.hwndRight != nullptr; if (fcOpt.bMoveTogether) UndockThumbs(this, thumbList.FindThumb(dockOpt.hwndLeft)); for (auto &it : thumbList) { if (it == this) continue; GetThumbRect(&rcThumb); OffsetRect(&rcThumb, nX - rcThumb.left, nY - rcThumb.top); it->GetThumbRect(&rc); // These are rects we will dock into rcLeft.left = rc.left - nOffs; rcLeft.top = rc.top - nOffs; rcLeft.right = rc.left + nOffs; rcLeft.bottom = rc.bottom + nOffs; rcTop.left = rc.left - nOffs; rcTop.top = rc.top - nOffs; rcTop.right = rc.right + nOffs; rcTop.bottom = rc.top + nOffs; rcRight.left = rc.right - nOffs; rcRight.top = rc.top - nOffs; rcRight.right = rc.right + nOffs; rcRight.bottom = rc.bottom + nOffs; rcBottom.left = rc.left - nOffs; rcBottom.top = rc.bottom - nOffs; rcBottom.right = rc.right + nOffs; rcBottom.bottom = rc.bottom + nOffs; bDockedLeft = bDockedRight = FALSE; // Upper-left pt.x = rcThumb.left; pt.y = rcThumb.top; bDocked = FALSE; if (PtInRect(&rcRight, pt)) { nNewX = rc.right; bDocked = TRUE; } if (PtInRect(&rcBottom, pt)) { nNewY = rc.bottom; if (PtInRect(&rcLeft, pt)) nNewX = rc.left; } if (PtInRect(&rcTop, pt)) { nNewY = rc.top; bDockedLeft = bDocked; } // Upper-right pt.x = rcThumb.right; pt.y = rcThumb.top; bDocked = FALSE; if (!bLeading && PtInRect(&rcLeft, pt)) { if (!bDockedLeft) { nNewX = rc.left - nWidth; bDocked = TRUE; } else if (rc.right == rcThumb.left) bDocked = TRUE; } if (PtInRect(&rcBottom, pt)) { nNewY = rc.bottom; if (PtInRect(&rcRight, pt)) nNewX = rc.right - nWidth; } if (!bLeading && PtInRect(&rcTop, pt)) { nNewY = rc.top; bDockedRight = bDocked; } if (fcOpt.bMoveTogether) { if (bDockedRight) DockThumbs(this, it); if (bDockedLeft) DockThumbs(it, this); } // Lower-left pt.x = rcThumb.left; pt.y = rcThumb.bottom; if (PtInRect(&rcRight, pt)) nNewX = rc.right; if (PtInRect(&rcTop, pt)) { nNewY = rc.top - nHeight; if (PtInRect(&rcLeft, pt)) nNewX = rc.left; } // Lower-right pt.x = rcThumb.right; pt.y = rcThumb.bottom; if (!bLeading && PtInRect(&rcLeft, pt)) nNewX = rc.left - nWidth; if (!bLeading && PtInRect(&rcTop, pt)) { nNewY = rc.top - nHeight; if (PtInRect(&rcRight, pt)) { nNewX = rc.right - nWidth; } } } // Adjust coords once again SnapToScreen(rcThumb, nNewX, nNewY, &nNewX, &nNewY); newPos->x = nNewX; newPos->y = nNewY; }
void ThumbInfo::ResizeThumb() { int index = FLT_FONTID_NOTONLIST; himlMiranda = Clist_GetImageList(); if (himlMiranda == nullptr) return; SIZEL sizeIcon; ImageList_GetIconSize_my(himlMiranda, sizeIcon); HDC hdc = GetWindowDC(hwnd); if (!db_get_b(hContact, "CList", "NotOnList", 0)) { char *szProto = GetContactProto(hContact); if (nullptr != szProto) { int nStatus = Proto_GetStatus(szProto); int nContactStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); int nApparentMode = db_get_w(hContact, szProto, "ApparentMode", 0); if ((nStatus == ID_STATUS_INVISIBLE && nApparentMode == ID_STATUS_ONLINE) || (nStatus != ID_STATUS_INVISIBLE && nApparentMode == ID_STATUS_OFFLINE)) { if (ID_STATUS_OFFLINE == nContactStatus) index = FLT_FONTID_OFFINVIS; else index = FLT_FONTID_INVIS; } else if (ID_STATUS_OFFLINE == nContactStatus) index = FLT_FONTID_OFFLINE; else index = FLT_FONTID_CONTACTS; } } else index = FLT_FONTID_NOTONLIST; HFONT hOldFont = (HFONT)SelectObject(hdc, hFont[index]); // Get text and icon sizes SIZEL sizeText; GetTextExtentPoint32(hdc, ptszName, (int)mir_wstrlen(ptszName), &sizeText); SelectObject(hdc, hOldFont); // Transform text size POINT ptText; ptText.x = sizeText.cx; ptText.y = sizeText.cy; LPtoDP(hdc, &ptText, 1); szSize.cx = fcOpt.bFixedWidth ? fcOpt.nThumbWidth : sizeIcon.cx + ptText.x + 10; szSize.cy = ((sizeIcon.cy > ptText.y) ? sizeIcon.cy : ptText.y) + 4; SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, szSize.cx, szSize.cy, SWP_NOMOVE | SWP_NOACTIVATE); RefreshContactIcon(0xFFFFFFFF); ReleaseDC(hwnd, hdc); // Move the docked widnow if needed ThumbInfo *pNextThumb = thumbList.FindThumb(dockOpt.hwndRight); if (pNextThumb) { RECT rcThumb; GetThumbRect(&rcThumb); pNextThumb->PositionThumb(rcThumb.right, rcThumb.top); } }