rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 Filename : Util_SystemGUI.cpp
|
nuclear@0
|
4 Content : OS GUI access, usually for diagnostics.
|
nuclear@0
|
5 Created : October 20, 2014
|
nuclear@0
|
6 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
9 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
10 which is provided at the time of installation or download, or which
|
nuclear@0
|
11 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
12
|
nuclear@0
|
13 You may obtain a copy of the License at
|
nuclear@0
|
14
|
nuclear@0
|
15 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
16
|
nuclear@0
|
17 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
18 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
20 See the License for the specific language governing permissions and
|
nuclear@0
|
21 limitations under the License.
|
nuclear@0
|
22
|
nuclear@0
|
23 *************************************************************************************/
|
nuclear@0
|
24
|
nuclear@0
|
25 #include "Util_SystemGUI.h"
|
nuclear@0
|
26 #include "../Kernel/OVR_UTF8Util.h"
|
nuclear@0
|
27 #include <stdio.h>
|
nuclear@0
|
28
|
nuclear@0
|
29 #if defined(OVR_OS_MS)
|
nuclear@0
|
30 #include <Windows.h>
|
nuclear@0
|
31 #endif
|
nuclear@0
|
32
|
nuclear@0
|
33
|
nuclear@0
|
34 namespace OVR { namespace Util {
|
nuclear@0
|
35
|
nuclear@0
|
36
|
nuclear@0
|
37 #if defined(OVR_OS_MS)
|
nuclear@0
|
38
|
nuclear@0
|
39 // On Windows we implement a manual dialog message box. The reason for this is that there's no way to
|
nuclear@0
|
40 // have a message box like this without either using MFC or WinForms or relying on Windows Vista+.
|
nuclear@0
|
41
|
nuclear@0
|
42 bool DisplayMessageBox(const char* pTitle, const char* pText)
|
nuclear@0
|
43 {
|
nuclear@0
|
44 #define ID_EDIT 100
|
nuclear@0
|
45
|
nuclear@0
|
46 struct Dialog
|
nuclear@0
|
47 {
|
nuclear@0
|
48 static size_t LineCount(const char* pText)
|
nuclear@0
|
49 {
|
nuclear@0
|
50 size_t count = 0;
|
nuclear@0
|
51 while(*pText)
|
nuclear@0
|
52 {
|
nuclear@0
|
53 if(*pText++ == '\n')
|
nuclear@0
|
54 count++;
|
nuclear@0
|
55 }
|
nuclear@0
|
56 return count;
|
nuclear@0
|
57 }
|
nuclear@0
|
58
|
nuclear@0
|
59 static WORD* WordUp(WORD* pIn){ return (WORD*)((((uintptr_t)pIn + 3) >> 2) << 2); }
|
nuclear@0
|
60
|
nuclear@0
|
61 static BOOL CALLBACK Proc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
nuclear@0
|
62 {
|
nuclear@0
|
63 switch (iMsg)
|
nuclear@0
|
64 {
|
nuclear@0
|
65 case WM_INITDIALOG:
|
nuclear@0
|
66 {
|
nuclear@0
|
67 HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT);
|
nuclear@0
|
68
|
nuclear@0
|
69 const char* pText = (const char*)lParam;
|
nuclear@0
|
70 SetWindowTextA(hWndEdit, pText);
|
nuclear@0
|
71
|
nuclear@0
|
72 HFONT hFont = CreateFontW(-11, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Courier New");
|
nuclear@0
|
73 if(hFont)
|
nuclear@0
|
74 SendMessage(hWndEdit, WM_SETFONT, WPARAM(hFont), TRUE);
|
nuclear@0
|
75
|
nuclear@0
|
76 SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0);
|
nuclear@0
|
77
|
nuclear@0
|
78 return TRUE;
|
nuclear@0
|
79 }
|
nuclear@0
|
80
|
nuclear@0
|
81 case WM_COMMAND:
|
nuclear@0
|
82 switch (LOWORD(wParam))
|
nuclear@0
|
83 {
|
nuclear@0
|
84 case ID_EDIT:
|
nuclear@0
|
85 {
|
nuclear@0
|
86 // Handle messages from the edit control here.
|
nuclear@0
|
87 HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT);
|
nuclear@0
|
88 SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0);
|
nuclear@0
|
89 return TRUE;
|
nuclear@0
|
90 }
|
nuclear@0
|
91
|
nuclear@0
|
92 case IDOK:
|
nuclear@0
|
93 EndDialog(hDlg, 0);
|
nuclear@0
|
94 return TRUE;
|
nuclear@0
|
95 }
|
nuclear@0
|
96 break;
|
nuclear@0
|
97 }
|
nuclear@0
|
98
|
nuclear@0
|
99 return FALSE;
|
nuclear@0
|
100 }
|
nuclear@0
|
101 };
|
nuclear@0
|
102
|
nuclear@0
|
103
|
nuclear@0
|
104 char dialogTemplateMemory[1024];
|
nuclear@0
|
105 memset(dialogTemplateMemory, 0, sizeof(dialogTemplateMemory));
|
nuclear@0
|
106 DLGTEMPLATE* pDlg = (LPDLGTEMPLATE)dialogTemplateMemory;
|
nuclear@0
|
107
|
nuclear@0
|
108 const size_t textLineCount = Dialog::LineCount(pText);
|
nuclear@0
|
109
|
nuclear@0
|
110 // Sizes are in Windows dialog units, which are relative to a character size. Depends on the font and environment settings. Often the pixel size will be ~3x the dialog unit x size. Often the pixel size will be ~3x the dialog unit y size.
|
nuclear@0
|
111 const int kGutterSize = 6; // Empty border space around controls within the dialog
|
nuclear@0
|
112 const int kButtonWidth = 24;
|
nuclear@0
|
113 const int kButtonHeight = 10;
|
nuclear@0
|
114 const int kDialogWidth = 600; // To do: Clip this against screen bounds.
|
nuclear@0
|
115 const int kDialogHeight = ((textLineCount > 100) ? 400 : ((textLineCount > 25) ? 300 : 200));
|
nuclear@0
|
116
|
nuclear@0
|
117 // Define a dialog box.
|
nuclear@0
|
118 pDlg->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
|
nuclear@0
|
119 pDlg->cdit = 2; // Control count
|
nuclear@0
|
120 pDlg->x = 10; // X position To do: Center the dialog.
|
nuclear@0
|
121 pDlg->y = 10;
|
nuclear@0
|
122 pDlg->cx = (short)kDialogWidth;
|
nuclear@0
|
123 pDlg->cy = (short)kDialogHeight;
|
nuclear@0
|
124 WORD* pWord = (WORD*)(pDlg + 1);
|
nuclear@0
|
125 *pWord++ = 0; // No menu
|
nuclear@0
|
126 *pWord++ = 0; // Default dialog box class
|
nuclear@0
|
127
|
nuclear@0
|
128 WCHAR* pWchar = (WCHAR*)pWord;
|
nuclear@0
|
129 const size_t titleLength = strlen(pTitle);
|
nuclear@0
|
130 size_t wcharCount = OVR::UTF8Util::DecodeString(pWchar, pTitle, (titleLength > 128) ? 128 : titleLength);
|
nuclear@0
|
131 pWord += wcharCount + 1;
|
nuclear@0
|
132
|
nuclear@0
|
133 // Define an OK button.
|
nuclear@0
|
134 pWord = Dialog::WordUp(pWord);
|
nuclear@0
|
135
|
nuclear@0
|
136 DLGITEMTEMPLATE* pDlgItem = (DLGITEMTEMPLATE*)pWord;
|
nuclear@0
|
137 pDlgItem->x = pDlg->cx - (kGutterSize + kButtonWidth);
|
nuclear@0
|
138 pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight);
|
nuclear@0
|
139 pDlgItem->cx = kButtonWidth;
|
nuclear@0
|
140 pDlgItem->cy = kButtonHeight;
|
nuclear@0
|
141 pDlgItem->id = IDOK;
|
nuclear@0
|
142 pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
nuclear@0
|
143
|
nuclear@0
|
144 pWord = (WORD*)(pDlgItem + 1);
|
nuclear@0
|
145 *pWord++ = 0xFFFF;
|
nuclear@0
|
146 *pWord++ = 0x0080; // button class
|
nuclear@0
|
147
|
nuclear@0
|
148 pWchar = (WCHAR*)pWord;
|
nuclear@0
|
149 pWchar[0] = 'O'; pWchar[1] = 'K'; pWchar[2] = '\0'; // Not currently localized.
|
nuclear@0
|
150 pWord += 3; // OK\0
|
nuclear@0
|
151 *pWord++ = 0; // no creation data
|
nuclear@0
|
152
|
nuclear@0
|
153 // Define an EDIT contol.
|
nuclear@0
|
154 pWord = Dialog::WordUp(pWord);
|
nuclear@0
|
155
|
nuclear@0
|
156 pDlgItem = (DLGITEMTEMPLATE*)pWord;
|
nuclear@0
|
157 pDlgItem->x = kGutterSize;
|
nuclear@0
|
158 pDlgItem->y = kGutterSize;
|
nuclear@0
|
159 pDlgItem->cx = pDlg->cx - (kGutterSize + kGutterSize);
|
nuclear@0
|
160 pDlgItem->cy = pDlg->cy - (kGutterSize + kButtonHeight + kGutterSize + (kGutterSize / 2));
|
nuclear@0
|
161 pDlgItem->id = ID_EDIT;
|
nuclear@0
|
162 pDlgItem->style = ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;
|
nuclear@0
|
163
|
nuclear@0
|
164 pWord = (WORD*)(pDlgItem + 1);
|
nuclear@0
|
165 *pWord++ = 0xFFFF;
|
nuclear@0
|
166 *pWord++ = 0x0081; // edit class atom
|
nuclear@0
|
167 *pWord++ = 0; // no creation data
|
nuclear@0
|
168
|
nuclear@0
|
169 LRESULT ret = DialogBoxIndirectParam(NULL, (LPDLGTEMPLATE)pDlg, NULL, (DLGPROC)Dialog::Proc, (LPARAM)pText);
|
nuclear@0
|
170
|
nuclear@0
|
171 return (ret != 0);
|
nuclear@0
|
172 }
|
nuclear@0
|
173 #elif defined(OVR_OS_MAC)
|
nuclear@0
|
174 // For Apple we use the Objective C implementation in Util_GUI.mm
|
nuclear@0
|
175 #else
|
nuclear@0
|
176 // To do.
|
nuclear@0
|
177 bool DisplayMessageBox(const char* pTitle, const char* pText)
|
nuclear@0
|
178 {
|
nuclear@0
|
179 printf("\n\nMessageBox\n%s\n", pTitle);
|
nuclear@0
|
180 printf("%s\n\n", pText);
|
nuclear@0
|
181 return false;
|
nuclear@0
|
182 }
|
nuclear@0
|
183 #endif
|
nuclear@0
|
184
|
nuclear@0
|
185
|
nuclear@0
|
186 } } // namespace OVR::Util
|
nuclear@0
|
187
|
nuclear@0
|
188
|
nuclear@0
|
189
|
nuclear@0
|
190
|