Added a simple unit test for wxWindow::ClientToScreen().
[wxWidgets.git] / tests / misc / guifuncs.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/misc/misctests.cpp
3 // Purpose: test miscellaneous GUI functions
4 // Author: Vadim Zeitlin
5 // Created: 2008-09-22
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "testprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/defs.h"
21
22 #ifndef WX_PRECOMP
23 #include "wx/gdicmn.h"
24 #include "wx/filefn.h"
25 #endif // !PCH
26
27 #include "wx/app.h"
28 #include "wx/button.h"
29 #include "wx/clipbrd.h"
30 #include "wx/dataobj.h"
31
32 #include "asserthelper.h"
33
34 // ----------------------------------------------------------------------------
35 // test class
36 // ----------------------------------------------------------------------------
37
38 class MiscGUIFuncsTestCase : public CppUnit::TestCase
39 {
40 public:
41 MiscGUIFuncsTestCase() { }
42
43 private:
44 CPPUNIT_TEST_SUITE( MiscGUIFuncsTestCase );
45 CPPUNIT_TEST( DisplaySize );
46 CPPUNIT_TEST( URLDataObject );
47 CPPUNIT_TEST( ParseFileDialogFilter );
48 CPPUNIT_TEST( ClientToScreen );
49 CPPUNIT_TEST( FindWindowAtPoint );
50 CPPUNIT_TEST_SUITE_END();
51
52 void DisplaySize();
53 void URLDataObject();
54 void ParseFileDialogFilter();
55 void ClientToScreen();
56 void FindWindowAtPoint();
57
58 DECLARE_NO_COPY_CLASS(MiscGUIFuncsTestCase)
59 };
60
61 // register in the unnamed registry so that these tests are run by default
62 CPPUNIT_TEST_SUITE_REGISTRATION( MiscGUIFuncsTestCase );
63
64 // also include in its own registry so that these tests can be run alone
65 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MiscGUIFuncsTestCase, "MiscGUIFuncsTestCase" );
66
67 void MiscGUIFuncsTestCase::DisplaySize()
68 {
69 // test that different (almost) overloads return the same results
70 int w, h;
71 wxDisplaySize(&w, &h);
72 wxSize sz = wxGetDisplaySize();
73
74 CPPUNIT_ASSERT_EQUAL( w, sz.x );
75 CPPUNIT_ASSERT_EQUAL( h, sz.y );
76
77 // test that passing NULL works as expected, e.g. doesn't crash
78 wxDisplaySize(NULL, NULL);
79 wxDisplaySize(&w, NULL);
80 wxDisplaySize(NULL, &h);
81
82 CPPUNIT_ASSERT_EQUAL( w, sz.x );
83 CPPUNIT_ASSERT_EQUAL( h, sz.y );
84
85 // test that display PPI is something reasonable
86 sz = wxGetDisplayPPI();
87 CPPUNIT_ASSERT( sz.x < 1000 && sz.y < 1000 );
88 }
89
90 void MiscGUIFuncsTestCase::URLDataObject()
91 {
92 // this tests for buffer overflow, see #11102
93 const char * const
94 url = "http://something.long.to.overwrite.plenty.memory.example.com";
95 wxURLDataObject * const dobj = new wxURLDataObject(url);
96 CPPUNIT_ASSERT_EQUAL( url, dobj->GetURL() );
97
98 wxClipboardLocker lockClip;
99 CPPUNIT_ASSERT( wxTheClipboard->SetData(dobj) );
100 wxTheClipboard->Flush();
101 }
102
103 void MiscGUIFuncsTestCase::ParseFileDialogFilter()
104 {
105 wxArrayString descs,
106 filters;
107
108 CPPUNIT_ASSERT_EQUAL
109 (
110 1,
111 wxParseCommonDialogsFilter("Image files|*.jpg;*.png", descs, filters)
112 );
113
114 CPPUNIT_ASSERT_EQUAL( "Image files", descs[0] );
115 CPPUNIT_ASSERT_EQUAL( "*.jpg;*.png", filters[0] );
116
117 CPPUNIT_ASSERT_EQUAL
118 (
119 2,
120 wxParseCommonDialogsFilter
121 (
122 "All files (*.*)|*.*|Python source (*.py)|*.py",
123 descs, filters
124 )
125 );
126
127 CPPUNIT_ASSERT_EQUAL( "*.*", filters[0] );
128 CPPUNIT_ASSERT_EQUAL( "*.py", filters[1] );
129
130 // Test some invalid ones too.
131 WX_ASSERT_FAILS_WITH_ASSERT
132 (
133 wxParseCommonDialogsFilter
134 (
135 "All files (*.*)|*.*|Python source (*.py)|*.py|",
136 descs, filters
137 )
138 );
139 }
140
141 void MiscGUIFuncsTestCase::ClientToScreen()
142 {
143 wxWindow* const tlw = wxTheApp->GetTopWindow();
144 CPPUNIT_ASSERT( tlw );
145
146 wxPanel* const
147 p1 = new wxPanel(tlw, wxID_ANY, wxPoint(0, 0), wxSize(100, 50));
148 wxPanel* const
149 p2 = new wxPanel(tlw, wxID_ANY, wxPoint(0, 50), wxSize(100, 50));
150 wxWindow* const
151 b = new wxWindow(p2, wxID_ANY, wxPoint(10, 10), wxSize(30, 10));
152
153 // We need this to realize the windows created above under wxGTK.
154 wxYield();
155
156 const wxPoint tlwOrig = tlw->ClientToScreen(wxPoint(0, 0));
157
158 CPPUNIT_ASSERT_EQUAL
159 (
160 tlwOrig + wxPoint(0, 50),
161 p2->ClientToScreen(wxPoint(0, 0))
162 );
163
164 CPPUNIT_ASSERT_EQUAL
165 (
166 tlwOrig + wxPoint(10, 60),
167 b->ClientToScreen(wxPoint(0, 0))
168 );
169
170 p1->Destroy();
171 p2->Destroy();
172 }
173
174 namespace
175 {
176
177 // This class is used as a test window here. We can't use a real wxButton
178 // because we can't create other windows as its children in wxGTK.
179 class TestButton : public wxWindow
180 {
181 public:
182 TestButton(wxWindow* parent, const wxString& label, const wxPoint& pos)
183 : wxWindow(parent, wxID_ANY, pos, wxSize(100, 50))
184 {
185 SetLabel(label);
186 }
187 };
188
189 // Helper function returning the label of the window at the given point or
190 // "NONE" if there is no window there.
191 wxString GetLabelOfWindowAtPoint(wxWindow* parent, int x, int y)
192 {
193 wxWindow* const
194 win = wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(x, y)));
195 return win ? win->GetLabel() : wxString("NONE");
196 }
197
198 } // anonymous namespace
199
200 void MiscGUIFuncsTestCase::FindWindowAtPoint()
201 {
202 wxWindow* const parent = wxTheApp->GetTopWindow();
203 CPPUNIT_ASSERT( parent );
204
205 // Set a label to allow distinguishing it from the other windows in the
206 // assertion messages.
207 parent->SetLabel("parent");
208
209 CPPUNIT_ASSERT_EQUAL_MESSAGE
210 (
211 "No window for a point outside of the window",
212 "NONE",
213 GetLabelOfWindowAtPoint(parent, 900, 900)
214 );
215
216 wxWindow* btn1 = new TestButton(parent, "1", wxPoint(10, 10));
217 CPPUNIT_ASSERT_EQUAL_MESSAGE
218 (
219 "Point over a child control corresponds to it",
220 btn1->GetLabel(),
221 GetLabelOfWindowAtPoint(parent, 11, 11)
222 );
223
224 CPPUNIT_ASSERT_EQUAL_MESSAGE
225 (
226 "Point outside of any child control returns the TLW itself",
227 parent->GetLabel(),
228 GetLabelOfWindowAtPoint(parent, 5, 5)
229 );
230
231 wxWindow* btn2 = new TestButton(parent, "2", wxPoint(10, 90));
232 btn2->Disable();
233 CPPUNIT_ASSERT_EQUAL_MESSAGE
234 (
235 "Point over a disabled child control still corresponds to it",
236 btn2->GetLabel(),
237 GetLabelOfWindowAtPoint(parent, 11, 91)
238 );
239
240 btn2->Hide();
241 CPPUNIT_ASSERT_EQUAL_MESSAGE
242 (
243 "Point over a hidden child control doesn't take it into account",
244 parent->GetLabel(),
245 GetLabelOfWindowAtPoint(parent, 11, 91)
246 );
247
248 btn2->Show();
249 wxWindow* btn3 = new TestButton(btn2, "3", wxPoint(0, 0));
250 btn3->Disable();
251 CPPUNIT_ASSERT_EQUAL_MESSAGE
252 (
253 "Point over recursive disabled child controls corresponds to deepest child",
254 btn3->GetLabel(),
255 GetLabelOfWindowAtPoint(parent, 11, 91)
256 );
257
258 wxDELETE(btn1);
259 wxDELETE(btn3); // delete child before parent
260 wxDELETE(btn2);
261 }