comctl32/monthcal: Enable multiple calendars support.
This commit is contained in:
parent
a68cbe98d4
commit
23dfef0d9e
|
@ -71,6 +71,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(monthcal);
|
|||
#define MC_PREVNEXTMONTHTIMER 1 /* Timer IDs */
|
||||
#define MC_TODAYUPDATETIMER 2
|
||||
|
||||
#define MC_CALENDAR_PADDING 6
|
||||
|
||||
#define countof(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
/* convert from days to 100 nanoseconds unit - used as FILETIME unit */
|
||||
|
@ -2392,7 +2394,6 @@ MONTHCAL_SetFocus(const MONTHCAL_INFO *infoPtr)
|
|||
static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
|
||||
{
|
||||
static const WCHAR O0W[] = { '0','0',0 };
|
||||
HDC hdc = GetDC(infoPtr->hwndSelf);
|
||||
RECT *title=&infoPtr->calendars[0].title;
|
||||
RECT *prev=&infoPtr->titlebtnprev;
|
||||
RECT *next=&infoPtr->titlebtnnext;
|
||||
|
@ -2402,16 +2403,19 @@ static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
|
|||
RECT *weeknumrect=&infoPtr->calendars[0].weeknums;
|
||||
RECT *days=&infoPtr->calendars[0].days;
|
||||
RECT *todayrect=&infoPtr->todayrect;
|
||||
SIZE size, sz;
|
||||
TEXTMETRICW tm;
|
||||
HFONT currentFont;
|
||||
INT xdiv, dx, dy, i;
|
||||
RECT client;
|
||||
|
||||
INT xdiv, dx, dy, i, j, x, y, c_dx, c_dy;
|
||||
WCHAR buff[80];
|
||||
TEXTMETRICW tm;
|
||||
SIZE size, sz;
|
||||
RECT client;
|
||||
HFONT font;
|
||||
HDC hdc;
|
||||
|
||||
GetClientRect(infoPtr->hwndSelf, &client);
|
||||
|
||||
currentFont = SelectObject(hdc, infoPtr->hFont);
|
||||
hdc = GetDC(infoPtr->hwndSelf);
|
||||
font = SelectObject(hdc, infoPtr->hFont);
|
||||
|
||||
/* get the height and width of each day's text */
|
||||
GetTextMetricsW(hdc, &tm);
|
||||
|
@ -2441,6 +2445,10 @@ static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
|
|||
/* recalculate the height and width increments and offsets */
|
||||
GetTextExtentPoint32W(hdc, O0W, 2, &size);
|
||||
|
||||
/* restore the originally selected font */
|
||||
SelectObject(hdc, font);
|
||||
ReleaseDC(infoPtr->hwndSelf, hdc);
|
||||
|
||||
xdiv = (infoPtr->dwStyle & MCS_WEEKNUMBERS) ? 8 : 7;
|
||||
|
||||
infoPtr->width_increment = size.cx * 2 + 4;
|
||||
|
@ -2461,21 +2469,17 @@ static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
|
|||
next->right = title->right - 4;
|
||||
next->left = next->right - (title->bottom - title->top);
|
||||
|
||||
/* titlemonth->left and right change based upon the current month */
|
||||
/* and are recalculated in refresh as the current month may change */
|
||||
/* without the control being resized */
|
||||
/* titlemonth->left and right change based upon the current month
|
||||
and are recalculated in refresh as the current month may change
|
||||
without the control being resized */
|
||||
titlemonth->top = titleyear->top = title->top + (infoPtr->height_increment)/2;
|
||||
titlemonth->bottom = titleyear->bottom = title->bottom - (infoPtr->height_increment)/2;
|
||||
|
||||
/* setup the dimensions of the rectangle we draw the names of the */
|
||||
/* days of the week in */
|
||||
weeknumrect->left = 0;
|
||||
|
||||
if(infoPtr->dwStyle & MCS_WEEKNUMBERS)
|
||||
weeknumrect->right = prev->right;
|
||||
else
|
||||
weeknumrect->right = weeknumrect->left;
|
||||
/* week numbers */
|
||||
weeknumrect->left = 0;
|
||||
weeknumrect->right = infoPtr->dwStyle & MCS_WEEKNUMBERS ? prev->right : 0;
|
||||
|
||||
/* days abbreviated names */
|
||||
wdays->left = days->left = weeknumrect->right;
|
||||
wdays->right = days->right = wdays->left + 7 * infoPtr->width_increment;
|
||||
wdays->top = title->bottom;
|
||||
|
@ -2489,29 +2493,62 @@ static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
|
|||
todayrect->top = days->bottom;
|
||||
todayrect->bottom = days->bottom + infoPtr->height_increment;
|
||||
|
||||
/* offset all rectangles to center in client area */
|
||||
dx = (client.right - title->right) / 2;
|
||||
dy = (client.bottom - todayrect->bottom) / 2;
|
||||
/* compute calendar count, update all calendars */
|
||||
x = (client.right + MC_CALENDAR_PADDING) / (title->right - title->left + MC_CALENDAR_PADDING);
|
||||
/* today label affects whole height */
|
||||
if (infoPtr->dwStyle & MCS_NOTODAY)
|
||||
y = (client.bottom + MC_CALENDAR_PADDING) / (days->bottom - title->top + MC_CALENDAR_PADDING);
|
||||
else
|
||||
y = (client.bottom - todayrect->bottom + todayrect->top + MC_CALENDAR_PADDING) /
|
||||
(days->bottom - title->top + MC_CALENDAR_PADDING);
|
||||
|
||||
/* if calendar doesn't fit client area show it at left/top bounds */
|
||||
if (title->left + dx < 0) dx = 0;
|
||||
if (title->top + dy < 0) dy = 0;
|
||||
/* TODO: ensure that count is properly adjusted to fit 12 months constraint */
|
||||
if (x == 0) x = 1;
|
||||
if (y == 0) y = 1;
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
infoPtr->dim.cx = x;
|
||||
infoPtr->dim.cy = y;
|
||||
infoPtr->calendars = ReAlloc(infoPtr->calendars, MONTHCAL_GetCalCount(infoPtr) * sizeof(CALENDAR_INFO));
|
||||
|
||||
for (i = 1; i < MONTHCAL_GetCalCount(infoPtr); i++)
|
||||
{
|
||||
OffsetRect(title, dx, dy);
|
||||
OffsetRect(prev, dx, dy);
|
||||
OffsetRect(next, dx, dy);
|
||||
OffsetRect(titlemonth, dx, dy);
|
||||
OffsetRect(titleyear, dx, dy);
|
||||
OffsetRect(wdays, dx, dy);
|
||||
OffsetRect(weeknumrect, dx, dy);
|
||||
OffsetRect(days, dx, dy);
|
||||
OffsetRect(todayrect, dx, dy);
|
||||
/* set months */
|
||||
infoPtr->calendars[i] = infoPtr->calendars[0];
|
||||
MONTHCAL_GetMonth(&infoPtr->calendars[i].month, i);
|
||||
}
|
||||
|
||||
/* TODO: update calendars count */
|
||||
infoPtr->dim.cx = infoPtr->dim.cy = 1;
|
||||
/* offset all rectangles to center in client area */
|
||||
c_dx = (client.right - x * title->right - MC_CALENDAR_PADDING * (x-1)) / 2;
|
||||
c_dy = (client.bottom - y * todayrect->bottom - MC_CALENDAR_PADDING * (y-1)) / 2;
|
||||
|
||||
/* if calendar doesn't fit client area show it at left/top bounds */
|
||||
if (title->left + c_dx < 0) c_dx = 0;
|
||||
if (title->top + c_dy < 0) c_dy = 0;
|
||||
|
||||
for (i = 0; i < y; i++)
|
||||
{
|
||||
for (j = 0; j < x; j++)
|
||||
{
|
||||
dx = j*(title->right - title->left + MC_CALENDAR_PADDING) + c_dx;
|
||||
dy = i*(days->bottom - title->top + MC_CALENDAR_PADDING) + c_dy;
|
||||
|
||||
OffsetRect(&infoPtr->calendars[i*x+j].title, dx, dy);
|
||||
OffsetRect(&infoPtr->calendars[i*x+j].titlemonth, dx, dy);
|
||||
OffsetRect(&infoPtr->calendars[i*x+j].titleyear, dx, dy);
|
||||
OffsetRect(&infoPtr->calendars[i*x+j].wdays, dx, dy);
|
||||
OffsetRect(&infoPtr->calendars[i*x+j].weeknums, dx, dy);
|
||||
OffsetRect(&infoPtr->calendars[i*x+j].days, dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
OffsetRect(prev, c_dx, c_dy);
|
||||
OffsetRect(next, (x-1)*(title->right - title->left + MC_CALENDAR_PADDING) + c_dx, c_dy);
|
||||
|
||||
i = infoPtr->dim.cx * infoPtr->dim.cy - infoPtr->dim.cx;
|
||||
todayrect->left = infoPtr->calendars[i].title.left;
|
||||
todayrect->right = infoPtr->calendars[i].title.right;
|
||||
todayrect->top = infoPtr->calendars[i].days.bottom;
|
||||
todayrect->bottom = infoPtr->calendars[i].days.bottom + infoPtr->height_increment;
|
||||
|
||||
TRACE("dx=%d dy=%d client[%s] title[%s] wdays[%s] days[%s] today[%s]\n",
|
||||
infoPtr->width_increment,infoPtr->height_increment,
|
||||
|
@ -2520,11 +2557,6 @@ static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
|
|||
wine_dbgstr_rect(wdays),
|
||||
wine_dbgstr_rect(days),
|
||||
wine_dbgstr_rect(todayrect));
|
||||
|
||||
/* restore the originally selected font */
|
||||
SelectObject(hdc, currentFont);
|
||||
|
||||
ReleaseDC(infoPtr->hwndSelf, hdc);
|
||||
}
|
||||
|
||||
static LRESULT MONTHCAL_Size(MONTHCAL_INFO *infoPtr, int Width, int Height)
|
||||
|
|
|
@ -1316,18 +1316,15 @@ static void test_monthrange(void)
|
|||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible);
|
||||
todo_wine {
|
||||
expect(2, res);
|
||||
}
|
||||
expect(2, res);
|
||||
|
||||
expect(2000, st_visible[0].wYear);
|
||||
expect(11, st_visible[0].wMonth);
|
||||
expect(1, st_visible[0].wDay);
|
||||
expect(2000, st_visible[1].wYear);
|
||||
expect(12, st_visible[1].wMonth);
|
||||
expect(31, st_visible[1].wDay);
|
||||
|
||||
todo_wine {
|
||||
expect(12, st_visible[1].wMonth);
|
||||
expect(31, st_visible[1].wDay);
|
||||
}
|
||||
res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, (LPARAM)st_daystate);
|
||||
todo_wine {
|
||||
expect(4, res);
|
||||
|
@ -1335,12 +1332,9 @@ static void test_monthrange(void)
|
|||
expect(2000, st_daystate[0].wYear);
|
||||
expect(10, st_daystate[0].wMonth);
|
||||
expect(29, st_daystate[0].wDay);
|
||||
|
||||
todo_wine {
|
||||
expect(2001, st_daystate[1].wYear);
|
||||
expect(1, st_daystate[1].wMonth);
|
||||
expect(6, st_daystate[1].wDay);
|
||||
}
|
||||
expect(2001, st_daystate[1].wYear);
|
||||
expect(1, st_daystate[1].wMonth);
|
||||
expect(6, st_daystate[1].wDay);
|
||||
|
||||
ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_monthrange_seq, "monthcal monthrange", FALSE);
|
||||
|
||||
|
@ -1814,7 +1808,7 @@ static void test_MCM_GETCALENDARCOUNT(void)
|
|||
return;
|
||||
}
|
||||
|
||||
todo_wine expect(2, ret);
|
||||
expect(2, ret);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue