1 #include "studiox_includes.h"
2 #include "express_table_row.h"
3 #include "string_scroll_wheel_edit_dlg.h"
4
5 extern CFont NormalFont;
6
7 enum string_scroll_wheel_edit_dlg_test_commands{
8 TEST_SET_STRING = 1,
9 TEST_SAVE,
10 TEST_CANCEL
11 };
12
13 enum CONTROL_IDS{
14 ID_STRING_INDEX = 4096,
15 ID_STRING_VAL,
16 ID_STRING_ID
17 };
18
19 extern CString target_class_name;
20 // string_scroll_wheel_edit_dlg dialog
21
IMPLEMENT_DYNAMIC(string_scroll_wheel_edit_dlg,express_dialog)22 IMPLEMENT_DYNAMIC(string_scroll_wheel_edit_dlg, express_dialog)
23
24 BEGIN_MESSAGE_MAP(string_scroll_wheel_edit_dlg, express_dialog)
25 ON_MESSAGE(STUDIO_TEST, OnTestMessage)
26 END_MESSAGE_MAP()
27
28 ///////////////////////////////////////////////////////////////////////////////
29 string_scroll_wheel_edit_dlg::string_scroll_wheel_edit_dlg(int display_index, CArray<GX_RESOURCE_ID> *value_list, CWnd* pParent /*=NULL*/)
30 : express_dialog(string_scroll_wheel_edit_dlg::IDD, pParent)
31 {
32 IconId = IDB_PROPS_VIEW;
33 SetTitleText("String Scroll Wheel Edit");
34
35 mpStringIdList = value_list;
36 mOldStringIdList.Copy(*value_list);
37 mDisplayIndex = display_index;
38
39 studiox_project *project = GetOpenProject();
40
41 if (project)
42 {
43 mpProject = project;
44
45 if (project->mDisplays[mDisplayIndex].stable)
46 {
47 mpTable = new string_table(*project->mDisplays[mDisplayIndex].stable);
48 }
49 else
50 {
51 mpTable = new string_table;
52 }
53 }
54 else
55 {
56 exit(1);
57 }
58 }
59
60 ///////////////////////////////////////////////////////////////////////////////
~string_scroll_wheel_edit_dlg()61 string_scroll_wheel_edit_dlg::~string_scroll_wheel_edit_dlg()
62 {
63 if (mpTable)
64 {
65 delete mpTable;
66 }
67
68 if (mpValueListFrame)
69 {
70 delete mpValueListFrame;
71 }
72 }
73
74 ///////////////////////////////////////////////////////////////////////////////
DoDataExchange(CDataExchange * pDX)75 void string_scroll_wheel_edit_dlg::DoDataExchange(CDataExchange* pDX)
76 {
77 express_dialog::DoDataExchange(pDX);
78
79 if (pDX->m_bSaveAndValidate)
80 {
81 if (mpProject->mDisplays[mDisplayIndex].stable)
82 {
83 delete mpProject->mDisplays[mDisplayIndex].stable;
84 mpTable->Sort();
85 mpProject->mDisplays[mDisplayIndex].stable = mpTable;
86 mpTable = NULL;
87
88 if (GetResourceView())
89 {
90 GetResourceView()->RebuildStringItems();
91 }
92 }
93 }
94 else
95 {
96 mpStringIdList->Copy(mOldStringIdList);
97 }
98 }
99
OnInitDialog()100 BOOL string_scroll_wheel_edit_dlg::OnInitDialog()
101 {
102 express_dialog::OnInitDialog();
103
104 CRect frame_size;
105 CRect size;
106
107 GetDlgItem(IDC_INDEX_LABEL)->GetWindowRect(&size);
108 ScreenToClient(&size);
109
110 GetClientRect(&frame_size);
111
112 frame_size.left += 5;
113 frame_size.top = size.bottom + 5;
114 frame_size.right -= 5;
115 frame_size.bottom -= m_status_bar_height + 10;
116
117 // Create value list frame
118 mpValueListFrame = new value_list_frame(mpStringIdList, mpTable);
119 mpValueListFrame->Create(target_class_name, _T("ValueListFrame"),
120 WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | WS_TABSTOP,
121 frame_size, this, 0);
122
123 AddCancelButton();
124 AddSaveButton();
125
126 return TRUE;
127 }
128
TestSetRowData(int row_id,CString string)129 void string_scroll_wheel_edit_dlg::TestSetRowData(int row_id, CString string)
130 {
131 CWnd* child = mpValueListFrame->GetWindow(GW_CHILD);
132 value_list_row* row;
133
134
135 while (child)
136 {
137 row = (value_list_row*)child;
138
139 if (row->GetRowId() == row_id)
140 {
141 CRect list_client;
142 CRect rect;
143
144 mpValueListFrame->GetClientRect(&list_client);
145 mpValueListFrame->ClientToScreen(&list_client);
146
147 row->GetWindowRect(&rect);
148
149 if (rect.top < list_client.top)
150 {
151 mpValueListFrame->Scroll(rect.top - list_client.top);
152 }
153 else if (rect.bottom > list_client.bottom)
154 {
155 mpValueListFrame->Scroll(rect.bottom - list_client.bottom);
156 }
157
158 row->SetData(_T(""), string);
159 row->SendMessage(WM_COMMAND, MAKEWPARAM(ID_STRING_VAL, EN_KILLFOCUS),
160 (LPARAM)(row->GetTextEdit()->m_hWnd));
161 }
162 child = child->GetWindow(GW_HWNDNEXT);
163 }
164 }
165
166 //////////////////////////////////////////////////////////////////////////////
OnTestMessage(WPARAM wParam,LPARAM lParam)167 LRESULT string_scroll_wheel_edit_dlg::OnTestMessage(WPARAM wParam, LPARAM lParam)
168 {
169 CStringArray param;
170 INT id;
171 CString string;
172
173 switch (wParam)
174 {
175 case TEST_SET_STRING:
176 SplitString(GetTestingParam(0), ',', ¶m);
177 id = _tstoi(param.GetAt(0));
178 string = param.GetAt(1);
179
180 TestSetRowData(id, string);
181 break;
182
183 case TEST_SAVE:
184 OnOK();
185 break;
186
187 case TEST_CANCEL:
188 OnCancel();
189 break;
190 }
191
192 return 0;
193 }
194
BEGIN_MESSAGE_MAP(value_list_row,express_table_row)195 BEGIN_MESSAGE_MAP(value_list_row, express_table_row)
196 ON_WM_CREATE()
197 ON_EN_KILLFOCUS(ID_STRING_VAL, OnChangeStringText)
198 ON_CBN_SELCHANGE(ID_STRING_ID, OnChangeStringId)
199 ON_WM_ERASEBKGND()
200 END_MESSAGE_MAP()
201
202 ///////////////////////////////////////////////////////////////////////////////
203 value_list_row::value_list_row(int row_id)
204 {
205 mRowId = row_id;
206 }
207
208 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)209 int value_list_row::OnCreate(LPCREATESTRUCT lpCreateStruct)
210 {
211 if (express_table_row::OnCreate(lpCreateStruct) == -1)
212 return -1;
213
214 CRect client;
215 CRect size;
216
217 // TODO: Add your specialized creation code here
218 GetClientRect(&client);
219
220 CFont* font = &NormalFont;
221
222 size = client;
223 size.top += 5;
224 size.bottom -= 5;
225 size.left += 3;
226 size.right = client.Width() / 3 - 35;
227 CString text;
228 text.Format(_T("%d"), mRowId);
229 mIndexPrompt.Create(text, WS_CHILD | SS_CENTER | WS_VISIBLE, size, this, ID_STRING_INDEX);
230 mIndexPrompt.SetFont(font);
231
232 size.left = size.right + 15;
233 size.right = client.right - 5;
234
235 int width = size.right - size.left + 1;
236 size.right = size.left + width / 2 - 5;
237 mStringIdCombo.Create(WS_CHILD | WS_TABSTOP | CBS_DROPDOWNLIST | CBS_SORT | WS_VISIBLE | WS_VSCROLL, size, this, ID_STRING_ID);
238 mStringIdCombo.SetFont(font);
239 SetControlAccessibleName(mStringIdCombo.GetSafeHwnd(), _T("Index ") + text + _T(" String ID"));
240
241 size.left = size.right + 5;
242 size.right = client.right - 5;
243
244 mStringTextEdit.Create(WS_CHILD | SS_RIGHT | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL, size, this, ID_STRING_VAL);
245 mStringTextEdit.SetFont(font);
246 SetControlAccessibleName(mStringTextEdit.GetSafeHwnd(), _T("Index ") + text + _T(" String Value"));
247
248 value_list_frame *frame = (value_list_frame*)GetParent();
249 if (frame)
250 {
251 string_table *table = frame->GetStringTable();
252 if (table)
253 {
254 int string_id = 1;
255 int box_index;
256
257 while (string_id < table->CountStrings())
258 {
259 box_index = mStringIdCombo.AddString(table->GetResourceIdName(string_id));
260 mStringIdCombo.SetItemData(box_index, string_id);
261 string_id++;
262 }
263
264 mStringIdCombo.InsertString(0, _T("None"));
265 mStringIdCombo.SetItemData(0, 0);
266 mStringIdCombo.SetCurSel(0);
267 }
268 }
269
270 return 0;
271 }
272
273 ///////////////////////////////////////////////////////////////////////////////
OnEraseBkgnd(CDC * pDC)274 BOOL value_list_row::OnEraseBkgnd(CDC* pDC)
275 {
276 CBrush newBrush(RGB(210, 210, 210));
277 CBrush *pOldBrush;
278
279 pOldBrush = pDC->SelectObject(&newBrush);
280
281 CRect rect;
282 pDC->GetClipBox(&rect); // Erase the area needed
283
284 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
285 PATCOPY);
286 pDC->SelectObject(pOldBrush);
287 return TRUE;
288 }
289
290 ///////////////////////////////////////////////////////////////////////////////
PreTranslateKeyDown(WPARAM keyvalue)291 BOOL value_list_row::PreTranslateKeyDown(WPARAM keyvalue)
292 {
293 CWnd* focus_owner = GetFocus();
294 CWnd* next_focus_owner = NULL;
295 value_list_frame* list = (value_list_frame*)GetParent();
296 CRect list_client;
297
298 list->GetClientRect(&list_client);
299 list->ClientToScreen(&list_client);
300
301 switch (keyvalue)
302 {
303 case VK_LEFT:
304 case VK_RIGHT:
305 case VK_UP:
306 case VK_DOWN:
307 case VK_HOME:
308 case VK_END:
309 next_focus_owner = GetNextTabStopChild(focus_owner, keyvalue);
310 break;
311
312 case VK_PRIOR:
313 if (list->Scroll(-list_client.Height()))
314 {
315 next_focus_owner = GetNextTabStopChild(focus_owner, keyvalue, list_client.Height() / list->GetRowHeight());
316 }
317 break;
318
319 case VK_NEXT:
320 if (list->Scroll(list_client.Height()))
321 {
322 next_focus_owner = GetNextTabStopChild(focus_owner, keyvalue, list_client.Height() / list->GetRowHeight());
323 }
324 break;
325
326 default:
327 return FALSE;
328 }
329
330 if (next_focus_owner)
331 {
332 CRect rect;
333
334 next_focus_owner->GetWindowRect(&rect);
335
336 if (rect.top < list_client.top)
337 {
338 list->Scroll(rect.top - list_client.top);
339 }
340 else if (rect.bottom > list_client.bottom)
341 {
342 list->Scroll(rect.bottom - list_client.bottom);
343 }
344
345 AssignFocus(next_focus_owner);
346 }
347
348 return TRUE;
349 }
350
351 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)352 BOOL value_list_row::PreTranslateMessage(MSG* pMsg)
353 {
354 // TODO: Add your specialized code here and/or call the base class
355 if (pMsg->message == WM_KEYDOWN)
356 {
357 if (pMsg->wParam == VK_TAB)
358 {
359 //handle tab key
360 value_list_frame* frame = (value_list_frame*)GetParent();
361 string_scroll_wheel_edit_dlg* dlg = (string_scroll_wheel_edit_dlg*)frame->GetParent();
362 CWnd* child = dlg->GetNextDlgTabItem(frame, FALSE);
363 if (child)
364 {
365 child->SetFocus();
366 return TRUE;
367 }
368 }
369
370 CWnd* child = GetFocus();
371 CComboBox* box = NULL;
372 TCHAR class_name[MAX_PATH];
373 GetClassName(child->GetSafeHwnd(), class_name, MAX_PATH - 1);
374 if (class_name[0] == 'C')
375 {
376 //"ComboBox"
377 box = (CComboBox*)child;
378 }
379
380 if (!box || !box->GetDroppedState())
381 {
382 if (PreTranslateKeyDown(pMsg->wParam))
383 {
384 return TRUE;
385 }
386 }
387 }
388
389 return express_table_row::PreTranslateMessage(pMsg);
390 }
391
392 ///////////////////////////////////////////////////////////////////////////////
OnChangeStringId()393 void value_list_row::OnChangeStringId()
394 {
395 value_list_frame *frame = (value_list_frame*)GetParent();
396 string_table *table = frame->GetStringTable();
397
398 int res_id = mStringIdCombo.GetItemData(mStringIdCombo.GetCurSel());
399 CString id_name = table->GetResourceIdName(res_id);
400
401 if (mStringId != id_name)
402 {
403 mStringId = id_name;
404
405 SetUtf8Text(&mStringTextEdit, table->GetString(id_name));
406 }
407
408 frame->NotifyStringIdChanged(mRowId, res_id);
409 }
410
411 ///////////////////////////////////////////////////////////////////////////////
OnChangeStringText()412 void value_list_row::OnChangeStringText()
413 {
414 value_list_frame *frame = (value_list_frame*)GetParent();
415 string_table *table = frame->GetStringTable();
416 CString string;
417
418 mStringTextEdit.GetWindowText(string);
419
420 int res_id = mStringIdCombo.GetItemData(mStringIdCombo.GetCurSel());
421 CString id_name;
422
423 if (res_id)
424 {
425 id_name = table->GetResourceIdName(res_id);
426
427 if (table->GetString(id_name) == string)
428 {
429 // no change, just return
430 return;
431 }
432 }
433
434 if (string.IsEmpty())
435 {
436 id_name = "";
437 res_id = 0;
438 mStringIdCombo.SetCurSel(0);
439 }
440 else
441 {
442 int string_index = table->CheckAddString(string);
443 id_name = table->GetStringId(string_index);
444 res_id = table->GetResourceId(id_name);
445
446 if (mStringIdCombo.GetCount() == res_id)
447 {
448 frame->NotifyStringIdAdded(id_name, res_id);
449 mStringIdCombo.SelectString(0, id_name);
450 }
451 }
452 frame->NotifyStringIdChanged(mRowId, res_id);
453 }
454
455 ///////////////////////////////////////////////////////////////////////////////
SetData(CString id,CString text)456 void value_list_row::SetData(CString id, CString text)
457 {
458 mStringId = id;
459 mStringText = text;
460
461 if (id.IsEmpty())
462 {
463 mStringIdCombo.SetCurSel(0);
464 }
465 else
466 {
467 mStringIdCombo.SelectString(0, id);
468 }
469 SetDlgItemText(ID_STRING_VAL, text);
470
471 Invalidate();
472 }
473
474 ///////////////////////////////////////////////////////////////////////////////
InsertStringId(CString id_name,GX_RESOURCE_ID res_id)475 void value_list_row::InsertStringId(CString id_name, GX_RESOURCE_ID res_id)
476 {
477 int index;
478 index = mStringIdCombo.AddString(id_name);
479 mStringIdCombo.SetItemData(index, res_id);
480 }
481
482
BEGIN_MESSAGE_MAP(value_list_frame,CWnd)483 BEGIN_MESSAGE_MAP(value_list_frame, CWnd)
484 ON_WM_CREATE()
485 ON_WM_VSCROLL()
486 ON_WM_MOUSEWHEEL()
487 ON_WM_DESTROY()
488 ON_WM_SETFOCUS()
489 END_MESSAGE_MAP()
490
491 ///////////////////////////////////////////////////////////////////////////////
492 value_list_frame::value_list_frame(CArray<GX_RESOURCE_ID>* string_id_list, string_table *stable)
493 {
494 mpStringIdList = string_id_list;
495 mpTable = stable;
496 mRowHeight = 0;
497
498 m_scroll_helper = new CScrollHelper;
499 m_scroll_helper->AttachWnd(this);
500 }
501
502 ///////////////////////////////////////////////////////////////////////////////
~value_list_frame()503 value_list_frame::~value_list_frame()
504 {
505
506 if (m_scroll_helper)
507 {
508 delete m_scroll_helper;
509 }
510 }
511
OnDestroy()512 void value_list_frame::OnDestroy()
513 {
514 CWnd::OnDestroy();
515
516 // TODO: Add your message handler code here
517 CWnd* child = GetWindow(GW_CHILD);
518
519 while (child)
520 {
521 child->DestroyWindow();
522 delete child;
523 child = GetWindow(GW_CHILD);
524 }
525 }
526
527
528 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)529 int value_list_frame::OnCreate(LPCREATESTRUCT lpCreateStruct)
530 {
531 if (CWnd::OnCreate(lpCreateStruct) == -1)
532 return -1;
533
534 // TODO: Add your specialized creation code here
535 CRect client;
536
537 GetClientRect(&client);
538 mRowHeight = (client.Height() + VISIBLE_VALUE_ROWS - 1) / VISIBLE_VALUE_ROWS;
539
540 client.bottom = client.top + mRowHeight;
541
542 value_list_row *row;
543 int row_count = mpStringIdList->GetCount();
544 int res_id;
545 CString id_name;
546 CString text;
547
548 //add row window
549 for (int index = 0; index < row_count; index++)
550 {
551 row = new value_list_row(index);
552 row->Create(target_class_name, _T("ValueListRow"), WS_CHILD | WS_VISIBLE, client, this, 0, NULL);
553
554 res_id = mpStringIdList->GetAt(index);
555 id_name = mpTable->GetResourceIdName(res_id);
556 text = mpTable->GetString(id_name);
557
558 row->SetData(id_name, text);
559
560 client.OffsetRect(0, mRowHeight);
561 }
562
563 m_scroll_helper->SetDisplaySize(0, row_count * mRowHeight);
564
565 return 0;
566 }
567
568 ///////////////////////////////////////////////////////////////////////////////
OnVScroll(UINT nSBCode,UINT nPos,CScrollBar * bar)569 void value_list_frame::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* bar)
570 {
571 // Compute the desired change or delta in scroll position.
572 m_scroll_helper->OnVScroll(nSBCode, nPos, bar);
573 }
574
575 ///////////////////////////////////////////////////////////////////////////////
OnMouseWheel(UINT nFlags,short zDelta,CPoint pt)576 BOOL value_list_frame::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
577 {
578 // TODO: Add your message handler code here and/or call default
579 return m_scroll_helper->OnMouseWheel(nFlags, zDelta, pt);
580 }
581
582 ///////////////////////////////////////////////////////////////////////////////
OnSetFocus(CWnd * pOldWnd)583 void value_list_frame::OnSetFocus(CWnd* pOldWnd)
584 {
585 CWnd::OnSetFocus(pOldWnd);
586
587 // TODO: Add your message handler code here
588 //pick first row
589 CWnd* child = GetWindow(GW_CHILD);
590 CRect list_client;
591 CRect rect;
592
593 GetClientRect(&list_client);
594 ClientToScreen(&list_client);
595
596 // set focus to the first visible child
597 while (child)
598 {
599 child->GetWindowRect(&rect);
600
601 if (rect.top < list_client.top)
602 {
603 child = child->GetWindow(GW_HWNDNEXT);
604 }
605 else
606 {
607 //pick first child of the row
608 child = child->GetWindow(GW_CHILD);
609
610 while (child)
611 {
612 if (child->GetStyle() & WS_TABSTOP)
613 {
614 child->SetFocus();
615 break;
616 }
617
618 child = child->GetWindow(GW_HWNDNEXT);
619 }
620
621 break;
622 }
623 }
624 }
625
626 ///////////////////////////////////////////////////////////////////////////////
NotifyStringIdAdded(CString id_name,GX_RESOURCE_ID res_id)627 void value_list_frame::NotifyStringIdAdded(CString id_name, GX_RESOURCE_ID res_id)
628 {
629 CWnd* child = GetWindow(GW_CHILD);
630
631 while (child)
632 {
633 ((value_list_row*)child)->InsertStringId(id_name, res_id);
634 child = child->GetWindow(GW_HWNDNEXT);
635 }
636 }
637
638 ///////////////////////////////////////////////////////////////////////////////
NotifyStringIdChanged(int index,GX_RESOURCE_ID id)639 void value_list_frame::NotifyStringIdChanged(int index, GX_RESOURCE_ID id)
640 {
641 if (index < mpStringIdList->GetCount())
642 {
643 mpStringIdList->SetAt(index, id);
644 }
645 }
646
647 ///////////////////////////////////////////////////////////////////////////////
Scroll(int delta)648 BOOL value_list_frame::Scroll(int delta)
649 {
650 CSize pos = m_scroll_helper->GetScrollPos();
651 int new_cy;
652
653 new_cy = pos.cy + delta;
654
655 if (delta > 0)
656 {
657 CSize display_size = m_scroll_helper->GetDisplaySize();
658 CSize page_size = m_scroll_helper->GetPageSize();
659
660 int maxScrollPos = display_size.cy - page_size.cy;
661
662 if (new_cy > maxScrollPos)
663 {
664 new_cy = maxScrollPos;
665 }
666 }
667 else
668 {
669 if (new_cy < 0)
670 {
671 new_cy = 0;
672 }
673 }
674
675 if (new_cy != pos.cy)
676 {
677 m_scroll_helper->SetScrollPos(SB_VERT, new_cy, TRUE);
678 return TRUE;
679 }
680
681 return FALSE;
682 }
683