* Sync to trunk r63845.
[reactos.git] / dll / cpl / desk / appearance.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: dll/cpl/desk/appearance.c
5 * PURPOSE: Appearance property page
6 *
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Timo Kreuzer (timo[dot]kreuzer[at]web[dot]de)
9 */
10
11 #include "desk.h"
12
13 /******************************************************************************/
14
15 static void
16 AppearancePage_UpdateThemePreview(HWND hwndDlg, GLOBALS *g)
17 {
18 if (g->ActiveTheme.ThemeActive)
19 {
20 RECT rcWindow;
21
22 GetClientRect(GetDlgItem(hwndDlg, IDC_APPEARANCE_PREVIEW), &rcWindow);
23 if (DrawThemePreview(g->hdcThemePreview, &g->Scheme, &g->ActiveTheme, &rcWindow))
24 {
25 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SET_HDC_PREVIEW, 0, (LPARAM)g->hdcThemePreview);
26 return;
27 }
28 }
29
30 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->Scheme);
31 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SET_HDC_PREVIEW, 0, 0);
32 }
33
34 static void
35 AppearancePage_LoadSelectedScheme(HWND hwndDlg, GLOBALS *g)
36 {
37 if (g->ActiveTheme.ThemeActive == FALSE )
38 {
39 LoadSchemeFromReg(&g->Scheme, &g->ActiveTheme);
40 }
41 else
42 {
43 LoadSchemeFromTheme(&g->Scheme, &g->ActiveTheme);
44 }
45
46 g_GlobalData.desktop_color = g->Scheme.crColor[COLOR_DESKTOP];
47 }
48
49 static void
50 AppearancePage_ShowStyles(HWND hwndDlg, int nIDDlgItem, PTHEME_STYLE pStyles, PTHEME_STYLE pActiveStyle)
51 {
52 int iListIndex;
53 HWND hwndList = GetDlgItem(hwndDlg, nIDDlgItem);
54 PTHEME_STYLE pCurrentStyle;
55
56 SendMessage(hwndList, CB_RESETCONTENT , 0, 0);
57
58 for (pCurrentStyle = pStyles;
59 pCurrentStyle;
60 pCurrentStyle = pCurrentStyle->NextStyle)
61 {
62 iListIndex = SendMessage(hwndList, CB_ADDSTRING, 0, (LPARAM)pCurrentStyle->DisplayName);
63 SendMessage(hwndList, CB_SETITEMDATA, iListIndex, (LPARAM)pCurrentStyle);
64 if (pCurrentStyle == pActiveStyle)
65 {
66 SendMessage(hwndList, CB_SETCURSEL, (WPARAM)iListIndex, 0);
67 }
68 }
69 }
70
71 static void
72 AppearancePage_ShowColorSchemes(HWND hwndDlg, GLOBALS *g)
73 {
74 AppearancePage_ShowStyles(hwndDlg,
75 IDC_APPEARANCE_COLORSCHEME,
76 g->ActiveTheme.Theme->ColoursList,
77 g->ActiveTheme.Color);
78 }
79
80 static void
81 AppearancePage_ShowSizes(HWND hwndDlg, GLOBALS *g)
82 {
83 PTHEME_STYLE pSizes;
84
85 if (g->ActiveTheme.Theme->SizesList)
86 pSizes = g->ActiveTheme.Theme->SizesList;
87 else
88 pSizes = g->ActiveTheme.Color->ChildStyle;
89
90 AppearancePage_ShowStyles(hwndDlg,
91 IDC_APPEARANCE_SIZE,
92 pSizes,
93 g->ActiveTheme.Size);
94 }
95
96 static INT_PTR
97 AppearancePage_OnInit(HWND hwndDlg)
98 {
99 INT iListIndex;
100 HWND hwndTheme;
101 GLOBALS *g;
102 RECT rcPreview;
103 HDC hdcScreen;
104 PTHEME pTheme;
105
106 g = (GLOBALS*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBALS));
107 if (g == NULL)
108 return FALSE;
109
110 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)g);
111
112 g->bInitializing = TRUE;
113
114 if (!LoadCurrentScheme(&g->Scheme))
115 return FALSE;
116
117 g->pThemes = LoadThemes();
118 if (g->pThemes)
119 {
120 if (!GetActiveTheme(g->pThemes, &g->ActiveTheme))
121 g->ActiveTheme.ThemeActive = FALSE;
122
123 /*
124 * Keep a copy of the selected classic theme in order to select this
125 * when user selects the classic theme (and not a horrible random theme )
126 */
127 if (!GetActiveClassicTheme(g->pThemes, &g->ClassicTheme))
128 {
129 g->ClassicTheme.Theme = g->pThemes;
130 g->ClassicTheme.Color = g->pThemes->ColoursList;
131 g->ClassicTheme.Size = g->ClassicTheme.Color->ChildStyle;
132 }
133
134 if (g->ActiveTheme.ThemeActive == FALSE)
135 g->ActiveTheme = g->ClassicTheme;
136
137 GetClientRect(GetDlgItem(hwndDlg, IDC_APPEARANCE_PREVIEW), &rcPreview);
138
139 hdcScreen = GetDC(NULL);
140 g->hbmpThemePreview = CreateCompatibleBitmap(hdcScreen, rcPreview.right, rcPreview.bottom);
141 g->hdcThemePreview = CreateCompatibleDC(hdcScreen);
142 SelectObject(g->hdcThemePreview, g->hbmpThemePreview);
143 ReleaseDC(NULL, hdcScreen);
144
145 hwndTheme = GetDlgItem(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE);
146
147 for (pTheme = g->pThemes; pTheme; pTheme = pTheme->NextTheme)
148 {
149 iListIndex = SendMessage(hwndTheme, CB_ADDSTRING, 0, (LPARAM)pTheme->DisplayName);
150 SendMessage(hwndTheme, CB_SETITEMDATA, iListIndex, (LPARAM)pTheme);
151 if (pTheme == g->ActiveTheme.Theme)
152 {
153 SendMessage(hwndTheme, CB_SETCURSEL, (WPARAM)iListIndex, 0);
154 }
155 }
156
157 if (g->ActiveTheme.Theme)
158 {
159 AppearancePage_ShowColorSchemes(hwndDlg, g);
160 AppearancePage_ShowSizes(hwndDlg, g);
161 AppearancePage_UpdateThemePreview(hwndDlg, g);
162 }
163 }
164 g->bInitializing = FALSE;
165
166 return FALSE;
167 }
168
169 static VOID
170 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g)
171 {
172 HeapFree(GetProcessHeap(), 0, g);
173 }
174
175 static PVOID
176 GetSelectedData(HWND hwndDlg, int nIDDlgItem)
177 {
178 HWND hwndCombo;
179 INT sel;
180
181 hwndCombo = GetDlgItem(hwndDlg, nIDDlgItem);
182 sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
183 if (sel == CB_ERR)
184 return NULL;
185 return (PVOID)SendMessage(hwndCombo, CB_GETITEMDATA, (WPARAM)sel, 0);
186 }
187
188 INT_PTR CALLBACK
189 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
190 {
191 GLOBALS *g;
192 LPNMHDR lpnm;
193
194 g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER);
195
196 switch (uMsg)
197 {
198 case WM_INITDIALOG:
199 return AppearancePage_OnInit(hwndDlg);
200
201 case WM_DESTROY:
202 AppearancePage_OnDestroy(hwndDlg, g);
203 break;
204
205 case WM_COMMAND:
206 if(g == NULL || g->bInitializing)
207 return FALSE;
208
209 switch (LOWORD(wParam))
210 {
211 case IDC_APPEARANCE_EFFECTS:
212 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_EFFAPPEARANCE),
213 hwndDlg, EffAppearanceDlgProc, (LPARAM)g) == IDOK)
214 {
215 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
216 g->Scheme = g->SchemeAdv;
217 g->bSchemeChanged = TRUE;
218 }
219 break;
220
221 case IDC_APPEARANCE_ADVANCED:
222 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_ADVAPPEARANCE),
223 hwndDlg, AdvAppearanceDlgProc, (LPARAM)g) == IDOK)
224 {
225 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
226 g->bSchemeChanged = TRUE;
227 g->Scheme = g->SchemeAdv;
228 g_GlobalData.desktop_color = g->Scheme.crColor[COLOR_DESKTOP];
229
230 AppearancePage_UpdateThemePreview(hwndDlg, g);
231 }
232 break;
233
234 case IDC_APPEARANCE_COLORSCHEME:
235 if (HIWORD(wParam) == CBN_SELCHANGE)
236 {
237 g->ActiveTheme.Color = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_COLORSCHEME);
238 if (g->ActiveTheme.Color->ChildStyle != NULL)
239 g->ActiveTheme.Size = g->ActiveTheme.Color->ChildStyle;
240
241 g->bSchemeChanged = TRUE;
242 if (g->ActiveTheme.ThemeActive)
243 g->bThemeChanged = TRUE;
244
245 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
246
247 AppearancePage_LoadSelectedScheme(hwndDlg, g);
248 AppearancePage_ShowSizes(hwndDlg, g);
249 AppearancePage_UpdateThemePreview(hwndDlg, g);
250 }
251 break;
252
253 case IDC_APPEARANCE_VISUAL_STYLE:
254 if (HIWORD(wParam) == CBN_SELCHANGE)
255 {
256 PTHEME pTheme = (PTHEME)GetSelectedData(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE);
257
258 if (g->ClassicTheme.Theme == pTheme)
259 g->ActiveTheme = g->ClassicTheme;
260 else
261 {
262 g->ActiveTheme.Theme = pTheme;
263 g->ActiveTheme.Size = pTheme->SizesList;
264 g->ActiveTheme.Color = pTheme->ColoursList;
265 g->ActiveTheme.ThemeActive = TRUE;
266 }
267
268 g->bThemeChanged = TRUE;
269 g->bSchemeChanged = TRUE;
270
271 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
272
273 AppearancePage_ShowColorSchemes(hwndDlg, g);
274 AppearancePage_ShowSizes(hwndDlg, g);
275 AppearancePage_LoadSelectedScheme(hwndDlg, g);
276 AppearancePage_UpdateThemePreview(hwndDlg, g);
277 }
278 break;
279
280 case IDC_APPEARANCE_SIZE:
281 if (HIWORD(wParam) == CBN_SELCHANGE)
282 {
283 g->ActiveTheme.Size = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_SIZE);
284 g->bSchemeChanged = TRUE;
285 if(g->ActiveTheme.ThemeActive)
286 g->bThemeChanged = TRUE;
287
288 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
289
290 AppearancePage_LoadSelectedScheme(hwndDlg, g);
291 AppearancePage_UpdateThemePreview(hwndDlg, g);
292 }
293 }
294 break;
295
296 case WM_NOTIFY:
297 lpnm = (LPNMHDR)lParam;
298 switch (lpnm->code)
299 {
300 case PSN_APPLY:
301
302 if (g->bThemeChanged)
303 {
304 ActivateTheme(&g->ActiveTheme);
305 }
306
307 if (g->bSchemeChanged)
308 {
309 ApplyScheme(&g->Scheme, &g->ActiveTheme);
310 if (g->ActiveTheme.ThemeActive == FALSE)
311 g->ClassicTheme = g->ActiveTheme;
312 }
313
314 AppearancePage_UpdateThemePreview(hwndDlg, g);
315 g->bThemeChanged = FALSE;
316 g->bSchemeChanged = FALSE;
317 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)PSNRET_NOERROR);
318 return TRUE;
319
320 case PSN_KILLACTIVE:
321 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE);
322 return TRUE;
323
324 case PSN_SETACTIVE:
325 if (g->Scheme.crColor[COLOR_DESKTOP] != g_GlobalData.desktop_color)
326 {
327 g->Scheme.crColor[COLOR_DESKTOP] = g_GlobalData.desktop_color;
328 AppearancePage_UpdateThemePreview(hwndDlg, g);
329 }
330 break;
331 }
332 break;
333 }
334
335 return FALSE;
336 }