1 // PaletteLayoutDlg.cpp : implementation file
2 //
3
4 #include "stdafx.h"
5 #include "afxdialogex.h"
6 #include "express_table_row.h"
7 #include "PaletteLayoutDlg.h"
8
9 extern CString target_class_name;
10
11 enum CONTROL_IDS {
12 ID_REDFIELD = 4096,
13 ID_GREENFIELD,
14 ID_BLUEFIELD,
15 ID_ALPHAFIELD,
16 ID_PAL_INDEX
17 };
18
19 enum palette_layout_dlg_test_commands{
20 TEST_SET_PREDEFINED_PALETTE_ENTRY = 1,
21 TEST_SET_PALETTE_COLOR,
22 TEST_SAVE_PALETTE_EDIT,
23 TEST_CANCEL_PALETTE_EDIT
24 };
25
26 // PaletteLayoutDlg dialog
BEGIN_MESSAGE_MAP(PaletteLayoutDlg,express_dialog)27 BEGIN_MESSAGE_MAP(PaletteLayoutDlg, express_dialog)
28 //ON_BN_CLICKED(IDC_BROWSE_PATH, &NewProjectDlg::OnBnClickedBrowsePath)
29 //ON_BN_CLICKED(ID_CANCEL, &NewProjectDlg::OnCancel)
30 ON_WM_SHOWWINDOW()
31 ON_WM_SYSCHAR()
32 ON_WM_PAINT()
33 ON_WM_VSCROLL()
34 ON_COMMAND(IDOK, &PaletteLayoutDlg::OnReturnKey)
35
36 ON_BN_CLICKED(IDOK, &PaletteLayoutDlg::OnBnClickedOk)
37 ON_BN_CLICKED(IDCANCEL, &PaletteLayoutDlg::OnCancel)
38 ON_BN_CLICKED(IDCANCEL, &PaletteLayoutDlg::OnCancel)
39 ON_BN_CLICKED(IDC_IMPORT_PALETTE, &PaletteLayoutDlg::OnBnClickedImportPalette)
40 ON_BN_CLICKED(IDC_EXPORT_PALETTE, &PaletteLayoutDlg::OnBnClickedExportPalette)
41 ON_BN_CLICKED(IDC_DEFAULT_PALETTE, &PaletteLayoutDlg::OnBnClickedDefaultPalette)
42
43 ON_EN_KILLFOCUS(IDC_TOTAL_PALETTE_ENTRIES, &PaletteLayoutDlg::OnEnChangeTotalPaletteEntries)
44 ON_EN_KILLFOCUS(IDC_USER_PALETTE_ENTRIES, &PaletteLayoutDlg::OnEnChangeUserPaletteEntries)
45 ON_MESSAGE(STUDIO_TEST, &PaletteLayoutDlg::OnTestMessage)
46 ON_BN_CLICKED(IDC_GEN_GRADIENT, &PaletteLayoutDlg::OnGenGradient)
47 END_MESSAGE_MAP()
48
49 ///////////////////////////////////////////////////////////////////////////////
50 PaletteLayoutDlg::PaletteLayoutDlg(int display, int theme, CWnd* pParent /*=NULL*/)
51 : express_dialog(PaletteLayoutDlg::IDD, pParent)
52 {
53 IconId = IDB_RECENT_PROJECT;
54 SetTitleText("Edit Palette");
55
56 mDisplay = display;
57 mTheme = theme;
58 mpProject = GetOpenProject();
59 mPaletteResetToDefault = FALSE;
60 mpPaletteFrame = NULL;
61
62 // save current settings in case user cancels after making changes:
63
64 if (!mpProject->mDisplays[mDisplay].themes[mTheme].palette)
65 {
66 //create default palette
67 ProjectConfigDlg::CreateDefaultPalette(mpProject, mDisplay, mTheme);
68 }
69
70 if (mpProject->mDisplays[mDisplay].themes[mTheme].palette)
71 {
72 theme_info* tinfo = &mpProject->mDisplays[mDisplay].themes[mTheme];
73 old_pal_total_entries = tinfo->palette_total_size;
74 old_pal_predefined = tinfo->palette_predefined;
75 memcpy_s(OldPalette, sizeof(OldPalette), tinfo->palette, tinfo->palette_total_size * sizeof(GX_COLOR));
76 }
77 }
78
79 ///////////////////////////////////////////////////////////////////////////////
~PaletteLayoutDlg()80 PaletteLayoutDlg::~PaletteLayoutDlg()
81 {
82 if (mpPaletteFrame)
83 {
84 delete mpPaletteFrame;
85 }
86 }
87
88
89 ///////////////////////////////////////////////////////////////////////////////
OnInitDialog()90 BOOL PaletteLayoutDlg::OnInitDialog()
91 {
92 express_dialog::OnInitDialog();
93
94 // TODO: Add extra initialization here
95 CRect client;
96 CRect size;
97 CRect scrollsize;
98
99 GetClientRect(&client);
100
101 // Get palette scroll bar size
102 GetDlgItem(IDC_PALETTE_SCROLL)->GetWindowRect(&scrollsize);
103 ScreenToClient(&scrollsize);
104
105 client.left += 10;
106 client.top = scrollsize.top;
107 client.right = scrollsize.left - 5;
108 client.bottom = scrollsize.bottom;
109
110 // Create palette frame
111 mpPaletteFrame = new palette_frame(&mpProject->mDisplays[mDisplay].themes[mTheme]);
112 mpPaletteFrame->Create(target_class_name, _T("PaletteFrame"), WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_TABSTOP, client, this, 0, NULL);
113
114 AddCancelButton();
115 AddSaveButton();
116
117 return TRUE; // return TRUE unless you set the focus to a control
118 // EXCEPTION: OCX Property Pages should return FALSE
119 }
120
121 ///////////////////////////////////////////////////////////////////////////////
OnShowWindow(BOOL bShow,UINT nStatus)122 void PaletteLayoutDlg::OnShowWindow(BOOL bShow, UINT nStatus)
123 {
124 express_dialog::OnShowWindow(bShow, nStatus);
125 }
126
127 ///////////////////////////////////////////////////////////////////////////////
NotifyColorChanged(int index,GX_COLOR newcolor)128 void PaletteLayoutDlg::NotifyColorChanged(int index, GX_COLOR newcolor)
129 {
130 if (index < mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined)
131 {
132 mpProject->mDisplays[mDisplay].themes[mTheme].palette[index] = newcolor;
133 mpProject->SetModified();
134 }
135 }
136
137 ///////////////////////////////////////////////////////////////////////////////
OnPaint()138 void PaletteLayoutDlg::OnPaint()
139 {
140 express_dialog::OnPaint();
141 }
142
143 ///////////////////////////////////////////////////////////////////////////////
DoDataExchange(CDataExchange * pDX)144 void PaletteLayoutDlg::DoDataExchange(CDataExchange* pDX)
145 {
146 int auto_entries;
147
148 CDialog::DoDataExchange(pDX);
149 DDX_Text(pDX, IDC_THEME_NAME, mpProject->mDisplays[mDisplay].themes[mTheme].theme_name);
150 DDX_Text(pDX, IDC_TOTAL_PALETTE_ENTRIES, mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size);
151 DDX_Text(pDX, IDC_USER_PALETTE_ENTRIES, mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined);
152
153 auto_entries = mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size - mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
154 DDX_Text(pDX, IDC_AUTO_PALETTE_ENTRIES, auto_entries);
155 DDX_Control(pDX, IDC_PALETTE_SCROLL, mPalIndexScroll);
156
157 SCROLLINFO info;
158 info.fMask = SIF_RANGE|SIF_POS|SIF_PAGE;
159 info.nMin = 0;
160 info.nMax = 255;
161 info.nPage = VISIBLE_PALETTE_ROWS;
162 info.nPos = 0;
163
164 mPalIndexScroll.SetScrollInfo(&info);
165 }
166
167 ///////////////////////////////////////////////////////////////////////////////
OnReturnKey()168 void PaletteLayoutDlg::OnReturnKey()
169 {
170 CWnd *pctrl = GetFocus();
171 int ctrl_id = pctrl->GetDlgCtrlID();
172
173 switch(ctrl_id)
174 {
175 case IDC_TOTAL_PALETTE_ENTRIES:
176 OnEnChangeTotalPaletteEntries();
177 break;
178
179 case IDC_USER_PALETTE_ENTRIES:
180 OnEnChangeUserPaletteEntries();
181 break;
182
183 case IDOK:
184 OnBnClickedOk();
185 break;
186 }
187 return;
188 }
189
190 ///////////////////////////////////////////////////////////////////////////////
191 /* go throught the color resources in this theme, and if any of the colors
192 have an index larger than palette pre-defined size, reset that color index to
193 the best match. This function is called when the user reduces the pre-defined
194 palette size.
195 */
CheckResetColorIndexes(res_info * info,GX_COLOR * new_palette,USHORT new_pal_size)196 void PaletteLayoutDlg::CheckResetColorIndexes(res_info *info, GX_COLOR *new_palette, USHORT new_pal_size)
197 {
198 while(info)
199 {
200 if (info->type == RES_TYPE_COLOR)
201 {
202 if (info->colorval >= new_pal_size)
203 {
204 if (info->colorval < (ULONG) old_pal_predefined)
205 {
206 Pixel old_color(OldPalette[info->colorval]);
207 info->colorval = image_reader::GetNearestPaletteColor(old_color, new_palette, new_pal_size);
208 }
209 else
210 {
211 info->colorval = 0;
212 }
213 }
214 }
215 if (info->child)
216 {
217 CheckResetColorIndexes(info->child, new_palette, new_pal_size);
218 }
219 info = info->next;
220 }
221 }
222
223 ///////////////////////////////////////////////////////////////////////////////
224 // PaletteLayoutDlg message handlers
225 ///////////////////////////////////////////////////////////////////////////////
OnBnClickedOk()226 void PaletteLayoutDlg::OnBnClickedOk()
227 {
228 studiox_project *project = GetOpenProject();
229
230 if (project)
231 {
232 if (mPaletteResetToDefault)
233 {
234 // Remap colors to the best match in the new color palette.
235 ProjectConfigDlg::ColorTableConvert(mpProject->mDisplays[mDisplay].themes[mTheme].GetFirstResourceInfo(),
236 OldPalette,
237 old_pal_predefined,
238 mpProject->mDisplays[mDisplay].colorformat,
239 mpProject->mDisplays[mDisplay].themes[mTheme].palette,
240 mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined,
241 mpProject->mDisplays[mDisplay].colorformat);
242 }
243 else
244 {
245 /* If any of the color resources are using an index greater than the
246 number of pre-defined entried, remap that entry of the color table
247 */
248
249 int new_pal_size = mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
250 if (new_pal_size < old_pal_predefined)
251 {
252 CheckResetColorIndexes(project->mDisplays[mDisplay].themes[mTheme].GetFirstResourceInfo(),
253 mpProject->mDisplays[mDisplay].themes[mTheme].palette, new_pal_size);
254 }
255 }
256
257 /* If we are running in palette mode, we need to remap the color resources to the
258 new palette
259 */
260 project->InitializeAllPixelmaps();
261 GetResourceView()->OnDisplaySelect(GetProjectView()->GetActiveDisplay(), TRUE);
262 }
263
264 CDialog::OnOK();
265 }
266
267
268 ///////////////////////////////////////////////////////////////////////////////
OnCancel()269 void PaletteLayoutDlg::OnCancel()
270 {
271 // TODO: Add your control notification handler code here
272
273 // restore palette settings:
274
275 if (mpProject->mDisplays[mDisplay].themes[mTheme].palette)
276 {
277 theme_info* tinfo = &mpProject->mDisplays[mDisplay].themes[mTheme];
278 tinfo->palette_total_size = old_pal_total_entries;
279 tinfo->palette_predefined = old_pal_predefined;
280 memcpy_s(tinfo->palette, tinfo->palette_total_size * sizeof(GX_COLOR), OldPalette, sizeof(OldPalette));
281 mPaletteResetToDefault = FALSE;
282 }
283 CDialog::OnCancel();
284 }
285
286 ///////////////////////////////////////////////////////////////////////////////
OnEnChangeTotalPaletteEntries()287 void PaletteLayoutDlg::OnEnChangeTotalPaletteEntries()
288 {
289 int newval = GetDlgItemInt(IDC_TOTAL_PALETTE_ENTRIES, NULL, TRUE);
290
291 if (newval >= 2 && newval <= 256)
292 {
293 mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size = newval;
294
295 // check to see if we need to update pre-defined count
296 if (mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined >= newval)
297 {
298 mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined = newval - 1;
299 SetDlgItemInt(IDC_USER_PALETTE_ENTRIES, mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined);
300 }
301
302 // update the leftover count
303 int autocount = newval - mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
304 SetDlgItemInt(IDC_AUTO_PALETTE_ENTRIES, autocount);
305 mpProject->SetModified();
306 }
307 else
308 {
309 ErrorMsg("The palette total size must be between 2 and 256 entries.", this);
310 SetDlgItemInt(IDC_TOTAL_PALETTE_ENTRIES, mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size);
311 }
312 }
313
314
315 ///////////////////////////////////////////////////////////////////////////////
OnEnChangeUserPaletteEntries()316 void PaletteLayoutDlg::OnEnChangeUserPaletteEntries()
317 {
318 int totalcount = mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size;
319 int usercount = GetDlgItemInt(IDC_USER_PALETTE_ENTRIES, NULL, TRUE);
320
321 if (usercount >= 0 && usercount < totalcount)
322 {
323 int old_usercount = mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
324
325 mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined = usercount;
326
327 // update the leftover count
328 int autocount = totalcount - usercount;
329 SetDlgItemInt(IDC_AUTO_PALETTE_ENTRIES, autocount);
330 mpProject->SetModified();
331
332 for (int index = old_usercount; index < usercount; index++)
333 {
334 //initiate new added entries
335 mpProject->mDisplays[mDisplay].themes[mTheme].palette[index] = 0xff000000;
336 }
337
338 mpPaletteFrame->SetRowData();
339 }
340 else
341 {
342 ErrorMsg("The pre-defined palette entries must be between 1 and (total palette size - 1).", this);
343 SetDlgItemInt(IDC_USER_PALETTE_ENTRIES, mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined);
344 }
345 }
346
347
348 ///////////////////////////////////////////////////////////////////////////////
OnBnClickedImportPalette()349 void PaletteLayoutDlg::OnBnClickedImportPalette()
350 {
351 // TODO: Add your control notification handler code here
352 CString Pathname;
353 int count;
354 int index;
355
356 if (BrowseForSingleFile(_T("Select Palette File"),
357 _T("Palette Files\0*.palx\0\0"), _T("palx"), Pathname, this))
358 {
359 xml_reader reader;
360
361 if (!reader.ReadFile(CString(Pathname)))
362 {
363 ErrorMsg("Unable to read palette file", this);
364 return;
365 }
366
367 if (!reader.EnterSection("GUIX_Palette"))
368 {
369 ErrorMsg("Invalid palette file format", this);
370 return;
371 }
372 reader.ReadInt("total_entries", mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size);
373 reader.ReadInt("user_entries", count);
374 mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined = count;
375
376 if (!mpProject->mDisplays[mDisplay].themes[mTheme].palette)
377 {
378 mpProject->mDisplays[mDisplay].themes[mTheme].palette = new GX_COLOR[256];
379 }
380
381 for (index = 0; index < count; index++)
382 {
383 reader.ReadHex("rgb", mpProject->mDisplays[mDisplay].themes[mTheme].palette[index]);
384 }
385 reader.CloseSection();
386
387 int totalcount = mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size;
388 int usercount = mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
389
390 SetDlgItemInt(IDC_TOTAL_PALETTE_ENTRIES, totalcount);
391 SetDlgItemInt(IDC_USER_PALETTE_ENTRIES, usercount);
392 int autocount = totalcount - usercount;
393 SetDlgItemInt(IDC_AUTO_PALETTE_ENTRIES, autocount);
394
395 mpPaletteFrame->SetRowData();
396 mpProject->SetModified();
397 }
398 }
399
400
401 ///////////////////////////////////////////////////////////////////////////////
OnBnClickedExportPalette()402 void PaletteLayoutDlg::OnBnClickedExportPalette()
403 {
404 // TODO: Add your control notification handler code here
405 TCHAR SavePathname[MAX_PATH];
406 TCHAR FileName[MAX_PATH];
407 int count;
408 int index;
409
410 SavePathname[0] = 0;
411 FileName[0] = 0;
412
413 if (GetOutputFileName(SavePathname, FileName,
414 _T("Select Palette Output file"),
415 _T("Palette Files\0*.palx\0\0"),
416 NULL, _T("palx")), this)
417 {
418 xml_writer writer;
419
420 if (!writer.OpenFile(CString(SavePathname)))
421 {
422 ErrorMsg("Unable to write palette file", this);
423 return;
424 }
425
426 writer.WriteHeader("GUIX_Palette");
427 writer.OpenTag("GUIX_Palette");
428 writer.WriteInt("total_entries", mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size);
429
430 count = mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
431 writer.WriteInt("user_entries", count);
432
433 for (index = 0; index < count; index++)
434 {
435 writer.WriteHex("rgb", mpProject->mDisplays[mDisplay].themes[mTheme].palette[index]);
436 }
437 writer.CloseTag("GUIX_Palette");
438 writer.CloseFile();
439 }
440 }
441
442
443
444 ///////////////////////////////////////////////////////////////////////////////
OnBnClickedDefaultPalette()445 void PaletteLayoutDlg::OnBnClickedDefaultPalette()
446 {
447 // TODO: Add your control notification handler code here
448 ProjectConfigDlg::CreateDefaultPalette(mpProject, mDisplay, mTheme);
449
450 mPaletteResetToDefault = TRUE;
451
452 mpProject->SetModified();
453
454 int totalcount = mpProject->mDisplays[mDisplay].themes[mTheme].palette_total_size;
455 int usercount = mpProject->mDisplays[mDisplay].themes[mTheme].palette_predefined;
456
457 SetDlgItemInt(IDC_TOTAL_PALETTE_ENTRIES, totalcount);
458 SetDlgItemInt(IDC_USER_PALETTE_ENTRIES, usercount);
459 int autocount = totalcount - usercount;
460 SetDlgItemInt(IDC_AUTO_PALETTE_ENTRIES, autocount);
461
462 mpPaletteFrame->SetRowData();
463 }
464
465 ///////////////////////////////////////////////////////////////////////////////
OnGenGradient()466 void PaletteLayoutDlg::OnGenGradient()
467 {
468 INT start_index, end_index;
469 theme_info *theme = &mpProject->mDisplays[mDisplay].themes[mTheme];
470
471 start_index = GetDlgItemInt(IDC_START_INDEX);
472 end_index = GetDlgItemInt(IDC_END_INDEX);
473
474 if (start_index < 0)
475 {
476 start_index = 0;
477 }
478
479 if (end_index > theme->palette_predefined - 1)
480 {
481 end_index = theme->palette_predefined - 1;
482 }
483
484 if (start_index < end_index)
485 {
486 int bcolor, balpha, bred, bgreen, bblue;
487 int fcolor, falpha, fred, fgreen, fblue;
488 int ncolor, nalpha, nred, ngreen, nblue;
489 int count = end_index - start_index;
490
491 //pick start color
492 fcolor = theme->palette[start_index];
493
494 //pick end color
495 bcolor = theme->palette[end_index];
496
497 falpha = (fcolor >> 24) & 0xff;
498 fred = (unsigned char)(fcolor >> 16);
499 fgreen = (fcolor >> 8) & 0xff;
500 fblue = fcolor & 0xff;
501
502 balpha = (bcolor >> 24) & 0xff;
503 bred = (unsigned char)(bcolor >> 16);
504 bgreen = (bcolor >> 8) & 0xff;
505 bblue = bcolor & 0xff;
506
507 start_index++;
508
509 for (int index = 1; index < count; index++)
510 {
511 //gen gradient color
512 nalpha = (((balpha - falpha) * index) / count) + falpha;
513 nred = (((bred - fred) * index) / count) + fred;
514 nblue = (((bblue - fblue) * index) / count) + fblue;
515 ngreen = (((bgreen - fgreen) * index) / count) + fgreen;
516 ncolor = (nalpha << 24) | (nred << 16) | (ngreen << 8) | nblue;
517
518 theme->palette[start_index++] = ncolor;
519 }
520
521 mpPaletteFrame->SetRowData();
522 }
523 }
524
Scroll(int deltaPos)525 void PaletteLayoutDlg::Scroll(int deltaPos)
526 {
527 int top_index = mpPaletteFrame->GetTopIndex();
528
529 if (deltaPos != 0)
530 {
531 // Compute the new scroll position.
532 top_index += deltaPos;
533
534 if (top_index < 0)
535 {
536 top_index = 0;
537 }
538 else
539 {
540 if (top_index + VISIBLE_PALETTE_ROWS > 256)
541 {
542 top_index = 256 - VISIBLE_PALETTE_ROWS;
543 }
544 }
545 if (top_index != mpPaletteFrame->GetTopIndex())
546 {
547 mpPaletteFrame->SetTopIndex(top_index);
548 ::SetScrollPos(mPalIndexScroll.GetSafeHwnd(), SB_CTL, top_index, TRUE);
549 mpPaletteFrame->SetRowData();
550 }
551 }
552 }
553
554 ///////////////////////////////////////////////////////////////////////////////
OnVScroll(UINT nSBCode,UINT nPos,CScrollBar * bar)555 void PaletteLayoutDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *bar)
556 {
557 int deltaPos = 0;
558 int top_index = mpPaletteFrame->GetTopIndex();
559
560 switch( nSBCode )
561 {
562 case SB_LINEUP:
563 // Up arrow button on scrollbar was pressed.
564 deltaPos = -1;
565 break;
566
567 case SB_LINEDOWN:
568 // Down arrow button on scrollbar was pressed.
569 deltaPos = 1;
570 break;
571
572 case SB_PAGEUP:
573 // User clicked inbetween up arrow and thumb.
574 deltaPos = -VISIBLE_PALETTE_ROWS;
575 break;
576
577 case SB_PAGEDOWN:
578 // User clicked inbetween thumb and down arrow.
579 deltaPos = VISIBLE_PALETTE_ROWS;
580 break;
581
582 case SB_THUMBTRACK:
583 // Scrollbar thumb is being dragged.
584 deltaPos = nPos - top_index;
585 break;
586
587 case SB_THUMBPOSITION:
588 // Scrollbar thumb was released.
589 deltaPos = nPos - top_index;
590 break;
591
592 default:
593 // We don't process other scrollbar messages.
594 return;
595 }
596
597 // Scroll the window if needed.
598 Scroll(deltaPos);
599 }
600
601 ///////////////////////////////////////////////////////////////////////////////
OnTestMessage(WPARAM wParam,LPARAM lParam)602 LRESULT PaletteLayoutDlg::OnTestMessage(WPARAM wParam, LPARAM lParam)
603 {
604 CString text;
605 CWnd *pWnd;
606 int index;
607 GX_COLOR color;
608 CStringArray strlist;
609
610 switch (wParam)
611 {
612 case TEST_SET_PREDEFINED_PALETTE_ENTRY:
613 pWnd = GetDlgItem(IDC_USER_PALETTE_ENTRIES);
614
615 if (pWnd)
616 {
617 text.Format(_T("%d"), lParam);
618 pWnd->SetWindowText(text);
619 SendMessage(WM_COMMAND, MAKEWPARAM(IDC_USER_PALETTE_ENTRIES, EN_KILLFOCUS), (LPARAM)pWnd->m_hWnd);
620 }
621 break;
622
623 case TEST_SET_PALETTE_COLOR:
624 SplitString(GetTestingParam(0), ',', &strlist);
625 index = _tstoi(strlist.GetAt(0));
626 color = _tstoi(strlist.GetAt(1));
627 NotifyColorChanged(index, color);
628 break;
629
630 case TEST_SAVE_PALETTE_EDIT:
631 OnOK();
632 break;
633
634 case TEST_CANCEL_PALETTE_EDIT:
635 OnCancel();
636 break;
637 }
638
639 return 0;
640 }
641
BEGIN_MESSAGE_MAP(palette_row,express_table_row)642 BEGIN_MESSAGE_MAP(palette_row, express_table_row)
643 ON_WM_PAINT()
644 ON_WM_CREATE()
645 ON_WM_ERASEBKGND()
646 ON_EN_KILLFOCUS(ID_REDFIELD, palette_row::ColorChanged)
647 ON_EN_KILLFOCUS(ID_GREENFIELD, palette_row::ColorChanged)
648 ON_EN_KILLFOCUS(ID_BLUEFIELD, palette_row::ColorChanged)
649 ON_EN_KILLFOCUS(ID_ALPHAFIELD, palette_row::ColorChanged)
650 END_MESSAGE_MAP()
651
652
653 ///////////////////////////////////////////////////////////////////////////////
654 palette_row::palette_row()
655 {
656 mIndex = -1;
657 }
658
659 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)660 int palette_row::OnCreate(LPCREATESTRUCT lpCreateStruct)
661 {
662 express_table_row::OnCreate(lpCreateStruct);
663 CRect client;
664 CRect size;
665
666 GetClientRect(&client);
667
668 int offset = client.Width() / 8;
669 size = client;
670 size.top += 4;
671 size.bottom -= 4;
672 size.left += 5;
673 size.right = offset - 10;
674 mIndexPrompt.Create(_T("--"), WS_CHILD | SS_CENTER | WS_VISIBLE, size, this, ID_PAL_INDEX);
675
676 size.left = offset * 4 + 5;
677 size.right = size.left + offset - 5;
678 mAlphaField.Create(WS_CHILD | SS_RIGHT | WS_VISIBLE | ES_NUMBER | WS_BORDER | WS_TABSTOP, size, this, ID_ALPHAFIELD);
679 SetAccessibleDescription(mAlphaField.GetSafeHwnd(), L"Use arrow keys to navigate.");
680 SetAccessibleFullDescription(mAlphaField.GetSafeHwnd(), L"Use arrow keys to navigate.");
681
682 size.OffsetRect(offset, 0);
683 mRedField.Create(WS_CHILD|SS_RIGHT|WS_VISIBLE|ES_NUMBER|WS_BORDER | WS_TABSTOP, size, this, ID_REDFIELD);
684 SetAccessibleDescription(mRedField.GetSafeHwnd(), L"Use arrow keys to navigate.");
685 SetAccessibleFullDescription(mRedField.GetSafeHwnd(), L"Use arrow keys to navigate.");
686
687 size.OffsetRect(offset, 0);
688 mGreenField.Create(WS_CHILD|SS_RIGHT|WS_VISIBLE|ES_NUMBER|WS_BORDER | WS_TABSTOP, size, this, ID_GREENFIELD);
689 SetAccessibleDescription(mGreenField.GetSafeHwnd(), L"Use arrow keys to navigate.");
690 SetAccessibleFullDescription(mGreenField.GetSafeHwnd(), L"Use arrow keys to navigate.");
691
692 size.OffsetRect(offset, 0);
693 mBlueField.Create(WS_CHILD|SS_RIGHT|WS_VISIBLE|ES_NUMBER|WS_BORDER | WS_TABSTOP, size, this, ID_BLUEFIELD);
694 SetAccessibleDescription(mBlueField.GetSafeHwnd(), L"Use arrow keys to navigate.");
695 SetAccessibleFullDescription(mBlueField.GetSafeHwnd(), L"Use arrow keys to navigate.");
696 return 0;
697 }
698
699
700 ///////////////////////////////////////////////////////////////////////////////
SetData(int index,GX_COLOR color,BOOL Enabled)701 void palette_row::SetData(int index, GX_COLOR color, BOOL Enabled)
702 {
703 CEdit *edit;
704
705 if (mIndex != index)
706 {
707 CString acc_name;
708
709 // set accessible names
710 acc_name.Format(_T("alpha %d"), index);
711 SetControlAccessibleName(GetDlgItem(ID_ALPHAFIELD)->GetSafeHwnd(), acc_name.GetString());
712
713 acc_name.Format(_T("red %d"), index);
714 SetControlAccessibleName(GetDlgItem(ID_REDFIELD)->GetSafeHwnd(), acc_name.GetString());
715
716 acc_name.Format(_T("green %d"), index);
717 SetControlAccessibleName(GetDlgItem(ID_GREENFIELD)->GetSafeHwnd(), acc_name.GetString());
718
719 acc_name.Format(_T("blue %d"), index);
720 SetControlAccessibleName(GetDlgItem(ID_BLUEFIELD)->GetSafeHwnd(), acc_name.GetString());
721
722 mIndex = index;
723 }
724
725 mColor = color;
726 mEnabled = Enabled;
727
728 SetDlgItemInt(ID_PAL_INDEX, index);
729
730 if (Enabled)
731 {
732 mAlpha = (color >> 24) & 0xff;
733 SetDlgItemInt(ID_ALPHAFIELD, mAlpha);
734
735 mRed = (unsigned char) (color >> 16);
736 SetDlgItemInt(ID_REDFIELD, mRed);
737
738 mGreen = (color >> 8) & 0xff;
739 SetDlgItemInt(ID_GREENFIELD, mGreen);
740
741 mBlue = color & 0xff;
742 SetDlgItemInt(ID_BLUEFIELD, mBlue);
743
744 edit = (CEdit *)GetDlgItem(ID_ALPHAFIELD);
745 edit->SetReadOnly(FALSE);
746 edit = (CEdit *) GetDlgItem(ID_REDFIELD);
747 edit->SetReadOnly(FALSE);
748 edit = (CEdit *) GetDlgItem(ID_GREENFIELD);
749 edit->SetReadOnly(FALSE);
750 edit = (CEdit *) GetDlgItem(ID_BLUEFIELD);
751 edit->SetReadOnly(FALSE);
752 }
753 else
754 {
755 SetDlgItemText(ID_ALPHAFIELD, _T("- - "));
756 SetDlgItemText(ID_REDFIELD, _T("- - "));
757 SetDlgItemText(ID_GREENFIELD, _T("- - "));
758 SetDlgItemText(ID_BLUEFIELD, _T("- - "));
759 edit = (CEdit *)GetDlgItem(ID_ALPHAFIELD);
760 edit->SetReadOnly();
761 edit = (CEdit *) GetDlgItem(ID_REDFIELD);
762 edit->SetReadOnly();
763 edit = (CEdit *) GetDlgItem(ID_GREENFIELD);
764 edit->SetReadOnly();
765 edit = (CEdit *) GetDlgItem(ID_BLUEFIELD);
766 edit->SetReadOnly();
767 }
768 Invalidate();
769 }
770
771
772 ///////////////////////////////////////////////////////////////////////////////
OnPaint()773 void palette_row::OnPaint()
774 {
775 CBrush boxbrush;
776 // CBrush *old_brush;
777 CRect boxsize;
778 CPaintDC dc(this);
779 express_table_row::OnPaint();
780
781 GetClientRect(&boxsize);
782 int offset = boxsize.Width() / 8;
783 boxsize.left = offset + 10;
784 boxsize.right = offset * 4 - 10;
785 boxsize.top += 5;
786 boxsize.bottom -= 5;
787
788 if (mEnabled)
789 {
790 boxbrush.CreateSolidBrush(RGB(mRed, mGreen, mBlue));
791 }
792 else
793 {
794 boxbrush.CreateHatchBrush(HS_BDIAGONAL, RGB(0, 0, 0));
795 }
796 //old_brush = dc->SelectObject(&boxbrush);
797
798 dc.FillRect(&boxsize, &boxbrush);
799 }
800
801 ///////////////////////////////////////////////////////////////////////////////
OnEraseBkgnd(CDC * pDC)802 BOOL palette_row::OnEraseBkgnd(CDC* pDC)
803 {
804 CBrush evenBrush(RGB(210, 210, 210));
805 CBrush oddBrush(RGB(190, 190, 190));
806 CBrush *pOldBrush;
807
808 if (mIndex & 1)
809 {
810 pOldBrush = pDC->SelectObject(&oddBrush);
811 }
812 else
813 {
814 pOldBrush = pDC->SelectObject(&evenBrush);
815 }
816 CRect rect;
817 pDC->GetClipBox(&rect); // Erase the area needed
818
819 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
820 PATCOPY);
821 pDC->SelectObject(pOldBrush);
822 return TRUE;
823 }
824
825 ///////////////////////////////////////////////////////////////////////////////
ColorChanged()826 void palette_row::ColorChanged()
827 {
828 BOOL changed = FALSE;
829 int val = GetDlgItemInt(ID_ALPHAFIELD);
830 if (val < 0 || val > 255)
831 {
832 SetDlgItemInt(ID_ALPHAFIELD, mAlpha);
833 }
834 else
835 {
836 mAlpha = val;
837 changed = TRUE;
838 }
839
840 val = GetDlgItemInt(ID_REDFIELD);
841 if (val < 0 || val > 255)
842 {
843 SetDlgItemInt(ID_REDFIELD, mRed);
844 }
845 else
846 {
847 mRed = val;
848 changed = TRUE;
849 }
850
851 val = GetDlgItemInt(ID_GREENFIELD);
852 if (val < 0 || val > 255)
853 {
854 SetDlgItemInt(ID_GREENFIELD, mGreen);
855 }
856 else
857 {
858 mGreen = val;
859 changed = TRUE;
860 }
861 val = GetDlgItemInt(ID_BLUEFIELD);
862 if (val < 0 || val > 255)
863 {
864 SetDlgItemInt(ID_BLUEFIELD, mBlue);
865 }
866 else
867 {
868 mBlue = val;
869 changed = TRUE;
870 }
871
872 if (changed)
873 {
874 mColor = (mAlpha << 24) | (mRed << 16) | (mGreen << 8) | mBlue;
875
876 palette_frame *win = (palette_frame*) GetParent();
877 win->NotifyColorChanged(mIndex, mColor);
878 Invalidate(); // force repaint color swatch
879 }
880 }
881
882 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)883 BOOL palette_row::PreTranslateMessage(MSG *pMsg)
884 {
885 if (pMsg->message == WM_KEYDOWN)
886 {
887 CWnd* focus_owner = GetFocus();
888 CWnd* next_focus_owner = NULL;
889 palette_frame *frame = (palette_frame*)GetParent();
890
891 switch (pMsg->wParam)
892 {
893 case VK_RETURN:
894 ColorChanged();
895 break;
896
897 case VK_LEFT:
898 case VK_RIGHT:
899 next_focus_owner = GetNextTabStopChild(focus_owner, pMsg->wParam);
900 break;
901
902 case VK_UP:
903 next_focus_owner = GetNextTabStopChild(focus_owner, pMsg->wParam);
904 if (!next_focus_owner)
905 {
906 if (frame->GetTopIndex() > 0)
907 {
908 frame->Scroll(-1);
909 }
910 next_focus_owner = focus_owner;
911 }
912 break;
913
914 case VK_DOWN:
915 next_focus_owner = GetNextTabStopChild(focus_owner, pMsg->wParam);
916 if (!next_focus_owner)
917 {
918 if (frame->GetTopIndex() < 256 - VISIBLE_PALETTE_ROWS)
919 {
920 frame->Scroll(1);
921 }
922 next_focus_owner = focus_owner;
923 }
924 break;
925
926 case VK_HOME:
927 next_focus_owner = GetNextTabStopChild(focus_owner, pMsg->wParam);
928 if (frame->GetTopIndex() > 0)
929 {
930 frame->Scroll(-frame->GetTopIndex());
931 }
932 break;
933
934 case VK_END:
935 next_focus_owner = GetNextTabStopChild(focus_owner, pMsg->wParam);
936 if (frame->GetTopIndex() < 256 - VISIBLE_PALETTE_ROWS)
937 {
938 frame->Scroll(256 - VISIBLE_PALETTE_ROWS - frame->GetTopIndex());
939 }
940 break;
941
942 case VK_PRIOR:
943 next_focus_owner = focus_owner;
944 frame->Scroll(-VISIBLE_PALETTE_ROWS);
945 break;
946
947 case VK_NEXT:
948 next_focus_owner = focus_owner;
949 frame->Scroll(VISIBLE_PALETTE_ROWS);
950 break;
951
952 default:
953 return express_table_row::PreTranslateMessage(pMsg);
954 }
955
956 if (next_focus_owner == focus_owner)
957 {
958 next_focus_owner->NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, OBJID_CLIENT, CHILDID_SELF);
959 CString msg(L"edit ");
960 if (::GetWindowLongPtr(next_focus_owner->GetSafeHwnd(), GWL_STYLE) & ES_READONLY)
961 {
962 msg.Append(L"read only ");
963 }
964 msg.Append(L"Use arrow keys to navigate.");
965 frame->UpdateStatusMsg(msg);
966 }
967
968 AssignFocus(next_focus_owner);
969 return TRUE;
970 }
971
972 return express_table_row::PreTranslateMessage(pMsg);
973 }
974
975
BEGIN_MESSAGE_MAP(palette_frame,CWnd)976 BEGIN_MESSAGE_MAP(palette_frame, CWnd)
977 ON_WM_CREATE()
978 ON_WM_SETFOCUS()
979 END_MESSAGE_MAP()
980
981 ///////////////////////////////////////////////////////////////////////////////
982 palette_frame::palette_frame(theme_info *theme)
983 {
984 mpTheme = theme;
985 mTopIndex = 0;
986 }
987
988 ///////////////////////////////////////////////////////////////////////////////
~palette_frame()989 palette_frame::~palette_frame()
990 {
991 };
992
993 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)994 int palette_frame::OnCreate(LPCREATESTRUCT lpCreateStruct)
995 {
996 if (CWnd::OnCreate(lpCreateStruct) == -1)
997 return -1;
998
999 // TODO: Add your specialized creation code here
1000 int index;
1001 CRect client;
1002
1003 GetClientRect(&client);
1004 int row_height = (client.Height() + VISIBLE_PALETTE_ROWS - 1) / VISIBLE_PALETTE_ROWS;
1005
1006 GetClientRect(&client);
1007 client.bottom = client.top + row_height;
1008
1009 for (index = 0; index < VISIBLE_PALETTE_ROWS; index++)
1010 {
1011 mPaletteRows[index].Create(target_class_name, _T("PaletteRow"),
1012 WS_CHILD | WS_VISIBLE, client, this, NULL);
1013 client.OffsetRect(0, row_height);
1014 }
1015
1016 SetRowData();
1017
1018 mStatusMsg.Create(L"", WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
1019 SetLiveRegion(mStatusMsg.GetSafeHwnd());
1020 return 0;
1021 }
1022
1023 ///////////////////////////////////////////////////////////////////////////////
OnSetFocus(CWnd * pOldWnd)1024 void palette_frame::OnSetFocus(CWnd* pOldWnd)
1025 {
1026 CWnd::OnSetFocus(pOldWnd);
1027
1028 //pick first row
1029 palette_row* parent = (palette_row*)GetWindow(GW_CHILD);
1030 CWnd* child;
1031
1032 // set focus to the first child that has WS_TABSTOP style
1033 if (parent)
1034 {
1035 //pick first child of the row
1036 child = parent->GetWindow(GW_CHILD);
1037
1038 //loop through child list until we find a child with WS_TABSTOP style,
1039 //and pass focus to this child
1040 while (child)
1041 {
1042 if (child->GetStyle() & WS_TABSTOP)
1043 {
1044 parent->AssignFocus(child);
1045 break;
1046 }
1047
1048 child = child->GetWindow(GW_HWNDNEXT);
1049 }
1050 }
1051 // TODO: Add your message handler code here
1052 }
1053
1054 ///////////////////////////////////////////////////////////////////////////////
SetRowData()1055 void palette_frame::SetRowData()
1056 {
1057 int index;
1058 BOOL Enabled;
1059 GX_COLOR color;
1060 int slot;
1061
1062 for (index = 0; index < VISIBLE_PALETTE_ROWS; index++)
1063 {
1064 slot = index + mTopIndex;
1065 if (slot < mpTheme->palette_predefined)
1066 {
1067 Enabled = TRUE;
1068 }
1069 else
1070 {
1071 Enabled = FALSE;
1072 }
1073
1074 color = mpTheme->palette[slot];
1075 mPaletteRows[index].SetData(index + mTopIndex, color, Enabled);
1076 }
1077 }
1078
1079 ///////////////////////////////////////////////////////////////////////////////
NotifyColorChanged(int index,GX_COLOR color)1080 void palette_frame::NotifyColorChanged(int index, GX_COLOR color)
1081 {
1082 PaletteLayoutDlg* dlg = (PaletteLayoutDlg*)GetParent();
1083
1084 dlg->NotifyColorChanged(index, color);
1085 }
1086
1087 ///////////////////////////////////////////////////////////////////////////////
Scroll(int deltaPos)1088 void palette_frame::Scroll(int deltaPos)
1089 {
1090 PaletteLayoutDlg* dlg = (PaletteLayoutDlg*)GetParent();
1091 dlg->Scroll(deltaPos);
1092 }
1093
1094 ///////////////////////////////////////////////////////////////////////////////
UpdateStatusMsg(CString msg)1095 void palette_frame::UpdateStatusMsg(CString msg)
1096 {
1097 mStatusMsg.SetWindowText(msg);
1098 mStatusMsg.NotifyWinEvent(
1099 EVENT_OBJECT_LIVEREGIONCHANGED,
1100 OBJID_CLIENT,
1101 CHILDID_SELF);
1102 }
1103