xref: /reactos/dll/cpl/desk/appearance.c (revision 527f2f90)
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 }
337