зеркало из https://github.com/mozilla/gecko-dev.git
Bug 845491: Make Plugin Hang UI push buttons automatically resize to fit their text. r=jmathies
This commit is contained in:
Родитель
fb7e710309
Коммит
4a8bc89113
|
@ -12,11 +12,29 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace plugins {
|
namespace plugins {
|
||||||
|
|
||||||
|
struct WinInfo
|
||||||
|
{
|
||||||
|
WinInfo(HWND aHwnd, POINT& aPos, SIZE& aSize)
|
||||||
|
:hwnd(aHwnd)
|
||||||
|
{
|
||||||
|
pos.x = aPos.x;
|
||||||
|
pos.y = aPos.y;
|
||||||
|
size.cx = aSize.cx;
|
||||||
|
size.cy = aSize.cy;
|
||||||
|
}
|
||||||
|
HWND hwnd;
|
||||||
|
POINT pos;
|
||||||
|
SIZE size;
|
||||||
|
};
|
||||||
|
typedef std::vector<WinInfo> WinInfoVec;
|
||||||
|
|
||||||
PluginHangUIChild* PluginHangUIChild::sSelf = nullptr;
|
PluginHangUIChild* PluginHangUIChild::sSelf = nullptr;
|
||||||
const int PluginHangUIChild::kExpectedMinimumArgc = 10;
|
const int PluginHangUIChild::kExpectedMinimumArgc = 10;
|
||||||
const DWORD PluginHangUIChild::kProcessTimeout = 1200000U;
|
const DWORD PluginHangUIChild::kProcessTimeout = 1200000U;
|
||||||
|
@ -124,6 +142,95 @@ PluginHangUIChild::SHangUIDlgProc(HWND aDlgHandle, UINT aMsgCode,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginHangUIChild::ResizeButtons()
|
||||||
|
{
|
||||||
|
// Control IDs are specified right-to-left as they appear in the dialog
|
||||||
|
UINT ids[] = { IDC_STOP, IDC_CONTINUE };
|
||||||
|
UINT numIds = sizeof(ids)/sizeof(ids[0]);
|
||||||
|
|
||||||
|
// Pass 1: Compute the ideal size
|
||||||
|
bool needResizing = false;
|
||||||
|
SIZE idealSize = {0};
|
||||||
|
WinInfoVec winInfo;
|
||||||
|
for (UINT i = 0; i < numIds; ++i) {
|
||||||
|
HWND wnd = GetDlgItem(mDlgHandle, ids[i]);
|
||||||
|
if (!wnd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the button's dimensions in screen coordinates
|
||||||
|
RECT curRect;
|
||||||
|
if (!GetWindowRect(wnd, &curRect)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get (x,y) position of the button in client coordinates
|
||||||
|
POINT pt;
|
||||||
|
pt.x = curRect.left;
|
||||||
|
pt.y = curRect.top;
|
||||||
|
if (!ScreenToClient(mDlgHandle, &pt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request the button's text margins
|
||||||
|
RECT margins;
|
||||||
|
if (!Button_GetTextMargin(wnd, &margins)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the button's width and height
|
||||||
|
SIZE curSize;
|
||||||
|
curSize.cx = curRect.right - curRect.left;
|
||||||
|
curSize.cy = curRect.bottom - curRect.top;
|
||||||
|
|
||||||
|
// Request the button's ideal width and height and add in the margins
|
||||||
|
SIZE size = {0};
|
||||||
|
if (!Button_GetIdealSize(wnd, &size)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size.cx += margins.left + margins.right;
|
||||||
|
size.cy += margins.top + margins.bottom;
|
||||||
|
|
||||||
|
// Size all buttons to be the same width as the longest button encountered
|
||||||
|
idealSize.cx = std::max(idealSize.cx, size.cx);
|
||||||
|
idealSize.cy = std::max(idealSize.cy, size.cy);
|
||||||
|
|
||||||
|
// We won't bother resizing unless we need extra space
|
||||||
|
if (idealSize.cx > curSize.cx) {
|
||||||
|
needResizing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the relevant info for the resize, if any. We do this even if
|
||||||
|
// needResizing is false because another button may trigger a resize later.
|
||||||
|
winInfo.push_back(WinInfo(wnd, pt, curSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needResizing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass 2: Resize the windows
|
||||||
|
int deltaX = 0;
|
||||||
|
HDWP hwp = BeginDeferWindowPos((int) winInfo.size());
|
||||||
|
if (!hwp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (WinInfoVec::const_iterator itr = winInfo.begin();
|
||||||
|
itr != winInfo.end(); ++itr) {
|
||||||
|
// deltaX accumulates the size changes so that each button's x coordinate
|
||||||
|
// can compensate for the width increases
|
||||||
|
deltaX += idealSize.cx - itr->size.cx;
|
||||||
|
hwp = DeferWindowPos(hwp, itr->hwnd, NULL, itr->pos.x - deltaX, itr->pos.y,
|
||||||
|
idealSize.cx, itr->size.cy,
|
||||||
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
if (!hwp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EndDeferWindowPos(hwp);
|
||||||
|
}
|
||||||
|
|
||||||
INT_PTR
|
INT_PTR
|
||||||
PluginHangUIChild::HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam,
|
PluginHangUIChild::HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam,
|
||||||
LPARAM aLParam)
|
LPARAM aLParam)
|
||||||
|
@ -144,6 +251,7 @@ PluginHangUIChild::HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam,
|
||||||
SetDlgItemText(aDlgHandle, IDC_NOFUTURE, mNoFutureText);
|
SetDlgItemText(aDlgHandle, IDC_NOFUTURE, mNoFutureText);
|
||||||
SetDlgItemText(aDlgHandle, IDC_CONTINUE, mWaitBtnText);
|
SetDlgItemText(aDlgHandle, IDC_CONTINUE, mWaitBtnText);
|
||||||
SetDlgItemText(aDlgHandle, IDC_STOP, mKillBtnText);
|
SetDlgItemText(aDlgHandle, IDC_STOP, mKillBtnText);
|
||||||
|
ResizeButtons();
|
||||||
HANDLE icon = LoadImage(NULL, IDI_QUESTION, IMAGE_ICON, 0, 0,
|
HANDLE icon = LoadImage(NULL, IDI_QUESTION, IMAGE_ICON, 0, 0,
|
||||||
LR_DEFAULTSIZE | LR_SHARED);
|
LR_DEFAULTSIZE | LR_SHARED);
|
||||||
if (icon) {
|
if (icon) {
|
||||||
|
|
|
@ -67,6 +67,9 @@ private:
|
||||||
bool
|
bool
|
||||||
SetMainThread();
|
SetMainThread();
|
||||||
|
|
||||||
|
void
|
||||||
|
ResizeButtons();
|
||||||
|
|
||||||
INT_PTR
|
INT_PTR
|
||||||
HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam, LPARAM aLParam);
|
HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam, LPARAM aLParam);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче