1 // recent_project_win.cpp : implementation file
2 //
3
4 #include "studiox_includes.h"
5 #include "recent_project_win.h"
6 extern INI_INFO StudioXIni;
7
8 #ifdef _DEBUG
9 #define new DEBUG_NEW
10 #endif
11
12 #define NEW_BUTTON_HEIGHT 36
13 #define NEW_BUTTON_WIDTH 190
14
15 extern CString target_class_name;
16 extern CFont MediumFont;
17
18
BEGIN_MESSAGE_MAP(recent_project_win,express_dialog)19 BEGIN_MESSAGE_MAP(recent_project_win, express_dialog)
20 ON_WM_CREATE()
21 ON_WM_SHOWWINDOW()
22 ON_BN_CLICKED(IDC_CREATE_PROJECT, OnBnClickedCreateProject)
23 END_MESSAGE_MAP()
24
25 ///////////////////////////////////////////////////////////////////////////////
26 recent_project_win::recent_project_win(int width, int height, CWnd* pParent /*=NULL*/)
27 : express_dialog(width, height)
28 {
29 IconId = IDB_RECENT_PROJECT;
30 SetTitleText("Recent Projects");
31 }
32
33 ///////////////////////////////////////////////////////////////////////////////
~recent_project_win()34 recent_project_win::~recent_project_win()
35 {
36 }
37
38 ///////////////////////////////////////////////////////////////////////////////
GetCreateNewProjectButtonSize(CRect & parentSize)39 CRect recent_project_win::GetCreateNewProjectButtonSize(CRect &parentSize)
40 {
41 CRect size;
42
43 int dpi = GetSystemDPI();
44 int text_scaler = GetTextScaler();
45
46 size.bottom = parentSize.bottom - 4;
47 size.top = size.bottom - GetScaledValue(NEW_BUTTON_HEIGHT, dpi, text_scaler);
48 size.right = parentSize.right - 4;
49 size.left = size.right - GetScaledValue(NEW_BUTTON_WIDTH, dpi, text_scaler);
50
51 return size;
52 }
53
54 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)55 int recent_project_win::OnCreate(LPCREATESTRUCT lpCreateStruct)
56 {
57 CRect client;
58 CRect size;
59
60 express_dialog::OnCreate(lpCreateStruct);
61 GetClientRect(&client);
62
63 int space = MulDiv(10, GetSystemDPI(), DEFAULT_DPI_96);;
64 size.left = client.left + space;
65 size.right = client.right - space;
66 size.top = client.top + m_title_bar_height + space;
67 size.bottom = client.bottom - m_status_bar_height - space;
68
69 mRecentListFrame.Create(target_class_name, _T("Recent Projects"),
70 WS_VISIBLE | WS_CHILD | WS_TABSTOP, size, this, 0);
71
72 size = GetCreateNewProjectButtonSize(client);
73 new_button.Create(_T("Create New Project"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW | WS_TABSTOP, size, this, IDC_CREATE_PROJECT);
74 new_button.LoadBitmaps(IDB_NEW_PROJECT_NORMAL, IDB_NEW_PROJECT_PRESSED);
75 new_button.SetWindowText(_T("Create New Project..."));
76 return 0;
77 }
78
79 ///////////////////////////////////////////////////////////////////////////////
OnShowWindow(BOOL Show,UINT status)80 void recent_project_win::OnShowWindow(BOOL Show, UINT status)
81 {
82 if (Show)
83 {
84 mRecentListFrame.UpdateRecentList();
85 }
86 CWnd::OnShowWindow(Show, status);
87 }
88
89 ///////////////////////////////////////////////////////////////////////////////
UpdateRecentList()90 void recent_project_win::UpdateRecentList()
91 {
92 mRecentListFrame.UpdateRecentList();
93 }
94
95 ///////////////////////////////////////////////////////////////////////////////
OnBnClickedCreateProject()96 void recent_project_win::OnBnClickedCreateProject()
97 {
98 // TODO: Add your control notification handler code here
99 GetProjectView()->NewProject(this);
100 }
101
102 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)103 BOOL recent_project_win::PreTranslateMessage(MSG* pMsg)
104 {
105 // TODO: Add your specialized code here and/or call the base class
106 if (pMsg->message == WM_KEYDOWN &&
107 pMsg->wParam == VK_RETURN &&
108 GetFocus() == &new_button)
109 {
110 OnBnClickedCreateProject();
111 return TRUE;
112 }
113
114 return express_dialog::PreTranslateMessage(pMsg);
115 }
116
BEGIN_MESSAGE_MAP(recent_list_frame,CWnd)117 BEGIN_MESSAGE_MAP(recent_list_frame, CWnd)
118 ON_WM_CTLCOLOR()
119 ON_WM_CREATE()
120 //ON_WM_SHOWWINDOW()
121 ON_WM_MOUSEMOVE()
122 ON_WM_LBUTTONDOWN()
123 ON_WM_ERASEBKGND()
124 ON_WM_SETFOCUS()
125 ON_WM_KILLFOCUS()
126 END_MESSAGE_MAP()
127
128 ///////////////////////////////////////////////////////////////////////////////
129 recent_list_frame::recent_list_frame(CWnd* parent)
130 {
131 if (!StudioXIni.recent_project_paths[0].IsEmpty())
132 {
133 mHighlightRow = 0;
134 }
135 else
136 {
137 mHighlightRow = -1;
138 }
139 mHiBrush.CreateSolidBrush(RGB_COLOR_BLUE);
140 mBgBrush.CreateSolidBrush(GetSysColor(CTLCOLOR_DLG));
141 mGrayBrush.CreateSolidBrush(RGB_COLOR_GRAY);
142 }
143
144 ///////////////////////////////////////////////////////////////////////////////
~recent_list_frame()145 recent_list_frame::~recent_list_frame()
146 {
147
148 }
149
150 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)151 int recent_list_frame::OnCreate(LPCREATESTRUCT lpCreateStruct)
152 {
153 if (CWnd::OnCreate(lpCreateStruct) == -1)
154 {
155 return -1;
156 }
157 int id_list[] = { IDC_RECENT_1, IDC_RECENT_2, IDC_RECENT_3, IDC_RECENT_4, IDC_RECENT_5 };
158 CRect size;
159 GetClientRect(&size);
160
161 int row_height = GetRowHeight();
162 int space = (size.Height() - row_height * MAX_RECENT_PROJECTS) / (MAX_RECENT_PROJECTS - 1);
163 size.bottom = size.top + row_height;
164
165 mNumRecentProjects = 0;
166
167 for (int index = 0; index < MAX_RECENT_PROJECTS; index++)
168 {
169 mRecentList[index].Create(StudioXIni.recent_project_paths[index], WS_VISIBLE | SS_LEFT | SS_WORDELLIPSIS, size, this, id_list[index]);
170 mRecentList[index].SetFont(&MediumFont);
171 SetLiveRegion(mRecentList[index].GetSafeHwnd());
172 size.OffsetRect(0, row_height + space);
173
174 if (StudioXIni.recent_project_paths[index].IsEmpty())
175 {
176 mRecentList[index].ShowWindow(FALSE);
177 }
178 else
179 {
180 mNumRecentProjects++;
181 }
182 }
183 return 0;
184 }
185
186
187
188 ///////////////////////////////////////////////////////////////////////////////
UpdateRecentList(void)189 void recent_list_frame::UpdateRecentList(void)
190 {
191 mNumRecentProjects = 0;
192 for (int index = 0; index < MAX_RECENT_PROJECTS; index++)
193 {
194 if (!StudioXIni.recent_project_paths[index].IsEmpty())
195 {
196 mRecentList[index].ShowWindow(TRUE);
197 mNumRecentProjects++;
198 }
199 else
200 {
201 mRecentList[index].ShowWindow(FALSE);
202 }
203
204 mRecentList[index].SetWindowText(StudioXIni.recent_project_paths[index]);
205 }
206 }
207
208 ///////////////////////////////////////////////////////////////////////////////
FindStatic(CPoint point)209 int recent_list_frame::FindStatic(CPoint point)
210 {
211 int newselect = -1;
212 CString text;
213 CRect size;
214 ClientToScreen(&point);
215
216 for (int index = 0; index < mNumRecentProjects; index++)
217 {
218 mRecentList[index].GetWindowText(text);
219
220 if (!text.IsEmpty())
221 {
222 mRecentList[index].GetWindowRect(&size);
223
224 if (size.PtInRect(point))
225 {
226 newselect = index;
227 break;
228 }
229 }
230 }
231
232 return newselect;
233 }
234
235 ///////////////////////////////////////////////////////////////////////////////
GetRowHeight()236 int recent_list_frame::GetRowHeight()
237 {
238 CDC* dc = GetDC();
239 CFont* old_font = dc->SelectObject(&MediumFont);
240 int row_height = dc->GetTextExtent(_T("fg"), 1).cy;
241 dc->SelectObject(old_font);
242 ReleaseDC(dc);
243 return row_height;
244 }
245
246 ///////////////////////////////////////////////////////////////////////////////
OnMouseMove(UINT nFlags,CPoint point)247 void recent_list_frame::OnMouseMove(UINT nFlags, CPoint point)
248 {
249 int newselect = FindStatic(point);
250
251 if ((newselect >= 0) && (newselect != mHighlightRow))
252 {
253 mRecentList[mHighlightRow].Invalidate(FALSE);
254 mHighlightRow = newselect;
255 mRecentList[mHighlightRow].Invalidate(FALSE);
256 }
257 }
258
259 ///////////////////////////////////////////////////////////////////////////////
OnLButtonDown(UINT nFlags,CPoint point)260 void recent_list_frame::OnLButtonDown(UINT nFlags, CPoint point)
261 {
262 int newselect = FindStatic(point);
263
264 if (newselect >= 0)
265 {
266 GetProjectView()->OpenHistoryProject(newselect);
267 }
268 }
269
270 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)271 BOOL recent_list_frame::PreTranslateMessage(MSG* pMsg)
272 {
273 // TODO: Add your specialized code here and/or call the base class
274 if (pMsg->message == WM_KEYDOWN)
275 {
276 switch (pMsg->wParam)
277 {
278 case VK_UP:
279 if (mHighlightRow > 0)
280 {
281 mRecentList[mHighlightRow].Invalidate();
282 mHighlightRow--;
283 mRecentList[mHighlightRow].Invalidate();
284 mRecentList[mHighlightRow].NotifyWinEvent(EVENT_OBJECT_LIVEREGIONCHANGED, OBJID_CLIENT, CHILDID_SELF);
285 }
286 return TRUE;
287
288 case VK_DOWN:
289 if ((mHighlightRow >= 0) && (mHighlightRow < mNumRecentProjects - 1))
290 {
291 mRecentList[mHighlightRow].Invalidate();
292 mHighlightRow++;
293 mRecentList[mHighlightRow].Invalidate();
294 mRecentList[mHighlightRow].NotifyWinEvent(EVENT_OBJECT_LIVEREGIONCHANGED, OBJID_CLIENT, CHILDID_SELF);
295 }
296 return TRUE;
297
298 case VK_RETURN:
299 if (mHighlightRow >= 0)
300 {
301 GetProjectView()->OpenHistoryProject(mHighlightRow);
302 }
303 return TRUE;
304 }
305 }
306
307 return CWnd::PreTranslateMessage(pMsg);
308 }
309
310 ///////////////////////////////////////////////////////////////////////////////
OnCtlColor(CDC * pDC,CWnd * pWnd,UINT nCtlColor)311 HBRUSH recent_list_frame::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
312 {
313 if (nCtlColor == CTLCOLOR_STATIC)
314 {
315 if ((mHighlightRow >= 0) &&
316 (&mRecentList[mHighlightRow] == pWnd))
317 {
318 pDC->SetTextColor(RGB_COLOR_WHITE);
319 pDC->SetBkMode(TRANSPARENT);
320
321 if (GetFocus() == this)
322 {
323 return mHiBrush;
324 }
325 else
326 {
327 return mGrayBrush;
328 }
329 }
330 }
331
332 return CWnd::OnCtlColor(pDC, pWnd, nCtlColor);;
333 }
334
335 ///////////////////////////////////////////////////////////////////////////////
OnEraseBkgnd(CDC * pDC)336 BOOL recent_list_frame::OnEraseBkgnd(CDC* pDC)
337 {
338 // TODO: Add your message handler code here and/or call default
339 CBrush* pOldBrush = pDC->SelectObject(&mBgBrush);
340
341 CRect rect;
342 pDC->GetClipBox(&rect); // Erase the area needed
343
344 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
345 pDC->SelectObject(pOldBrush);
346
347 return TRUE;
348 }
349
350 ///////////////////////////////////////////////////////////////////////////////
OnSetFocus(CWnd * pOldWnd)351 void recent_list_frame::OnSetFocus(CWnd* pOldWnd)
352 {
353 CWnd::OnSetFocus(pOldWnd);
354
355 if (mHighlightRow >= 0)
356 {
357 // Invalidate selected row.
358 mRecentList[mHighlightRow].Invalidate();
359
360 // Raise a UIA LiveRegionChanged
361 // event so that a screen reader is made aware of a change to the LiveRegion.
362 // Make sure the updated text is set on the label before making this call.
363 mRecentList[mHighlightRow].NotifyWinEvent(
364 EVENT_OBJECT_LIVEREGIONCHANGED,
365 OBJID_CLIENT,
366 CHILDID_SELF);
367 }
368 }
369
370
OnKillFocus(CWnd * pNewWnd)371 void recent_list_frame::OnKillFocus(CWnd* pNewWnd)
372 {
373 CWnd::OnKillFocus(pNewWnd);
374
375 if (mHighlightRow >= 0)
376 {
377 // Invalidate selected row.
378 mRecentList[mHighlightRow].Invalidate();
379 }
380 }
381