Module: wine Branch: master Commit: 23dfef0d9ecda65a01992a7ac9dfbe9df67b93bd URL: http://source.winehq.org/git/wine.git/?a=commit;h=23dfef0d9ecda65a01992a7ac9...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Sep 22 17:56:40 2011 +0400
comctl32/monthcal: Enable multiple calendars support.
---
dlls/comctl32/monthcal.c | 108 ++++++++++++++++++++++++++-------------- dlls/comctl32/tests/monthcal.c | 22 +++----- 2 files changed, 78 insertions(+), 52 deletions(-)
diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c index 762a792..5f8a36c 100644 --- a/dlls/comctl32/monthcal.c +++ b/dlls/comctl32/monthcal.c @@ -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; + + INT xdiv, dx, dy, i, j, x, y, c_dx, c_dy; + WCHAR buff[80]; TEXTMETRICW tm; - HFONT currentFont; - INT xdiv, dx, dy, i; + SIZE size, sz; RECT client; - WCHAR buff[80]; + 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;
+ /* 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); + + /* TODO: ensure that count is properly adjusted to fit 12 months constraint */ + if (x == 0) x = 1; + if (y == 0) y = 1; + + 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++) + { + /* set months */ + infoPtr->calendars[i] = infoPtr->calendars[0]; + MONTHCAL_GetMonth(&infoPtr->calendars[i].month, i); + } + /* offset all rectangles to center in client area */ - dx = (client.right - title->right) / 2; - dy = (client.bottom - todayrect->bottom) / 2; + 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 + dx < 0) dx = 0; - if (title->top + dy < 0) dy = 0; + if (title->left + c_dx < 0) c_dx = 0; + if (title->top + c_dy < 0) c_dy = 0;
- if (dx != 0 || dy != 0) + for (i = 0; i < y; 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); + 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); + } }
- /* TODO: update calendars count */ - infoPtr->dim.cx = infoPtr->dim.cy = 1; + 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) diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c index 87aadec..ccf8881 100644 --- a/dlls/comctl32/tests/monthcal.c +++ b/dlls/comctl32/tests/monthcal.c @@ -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); }