/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta_reference/common/src/Utilities/wxGuiTools.cpp
ViewVC logotype

Contents of /branch/r3113_0.9.7_beta_reference/common/src/Utilities/wxGuiTools.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 174 - (show annotations) (download)
Mon Sep 13 17:24:24 2010 UTC (9 years, 11 months ago) by william
File size: 13610 byte(s)
merge r171-173 from https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/debug/0.X/0.9.X/0.9.7/r3113
-- pick up:
* local versioning support from trunk
* get rig of annoying warnings
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "wxGuiTools.h"
18 #include "pxStaticText.h"
19
20 #include <wx/app.h>
21 #include <wx/window.h>
22
23 const pxAlignmentType
24 pxCentre = { pxAlignmentType::Center }, // Horizontal centered alignment
25 pxCenter = pxCentre,
26 pxMiddle = { pxAlignmentType::Middle }, // vertical centered alignment
27
28 pxAlignLeft = { pxAlignmentType::Left },
29 pxAlignRight = { pxAlignmentType::Right },
30 pxAlignTop = { pxAlignmentType::Top },
31 pxAlignBottom = { pxAlignmentType::Bottom };
32
33 const pxStretchType
34 pxShrink = { pxStretchType::Shrink },
35 pxExpand = { pxStretchType::Expand },
36 pxShaped = { pxStretchType::Shaped },
37 pxReserveHidden = { pxStretchType::ReserveHidden },
38 pxFixedMinimum = { pxStretchType::FixedMinimum };
39
40 wxSizerFlags pxAlignmentType::Apply( wxSizerFlags flags ) const
41 {
42 switch( intval )
43 {
44 case Centre:
45 flags.Align( flags.GetFlags() | wxALIGN_CENTRE_HORIZONTAL );
46 break;
47
48 case Middle:
49 flags.Align( flags.GetFlags() | wxALIGN_CENTRE_VERTICAL );
50 break;
51
52 case Left:
53 flags.Left();
54 break;
55
56 case Right:
57 flags.Right();
58 break;
59
60 case Top:
61 flags.Top();
62 break;
63
64 case Bottom:
65 flags.Bottom();
66 break;
67 }
68 return flags;
69 }
70
71 wxSizerFlags pxStretchType::Apply( wxSizerFlags flags ) const
72 {
73 switch( intval )
74 {
75 case Shrink:
76 //pxFail( "wxSHRINK is an ignored stretch flag." );
77 break;
78
79 case Expand:
80 flags.Expand();
81 break;
82
83 case Shaped:
84 flags.Shaped();
85 break;
86
87 case ReserveHidden:
88 flags.ReserveSpaceEvenIfHidden();
89 break;
90
91 case FixedMinimum:
92 flags.FixedMinSize();
93 break;
94
95 //case Tile:
96 // pxAssert( "pxTile is an unsupported stretch tag (ignored)." );
97 //break;
98 }
99 return flags;
100 }
101
102 wxSizerFlags operator& ( const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2 )
103 {
104 //return align.Apply( _flgs );
105 wxSizerFlags retval;
106
107 uint allflags = (_flgs.GetFlags() | _flgs2.GetFlags());
108
109 retval.Align( allflags & wxALIGN_MASK );
110 if( allflags & wxEXPAND ) retval.Expand();
111 if( allflags & wxSHAPED ) retval.Shaped();
112 if( allflags & wxFIXED_MINSIZE ) retval.FixedMinSize();
113 if( allflags & wxRESERVE_SPACE_EVEN_IF_HIDDEN ) retval.ReserveSpaceEvenIfHidden();
114
115 // Compounding borders is probably a fair approach:
116 retval.Border( allflags & wxALL, _flgs.GetBorderInPixels() + _flgs2.GetBorderInPixels() );
117
118 // Compounding proportions works as well, I figure.
119 retval.Proportion( _flgs.GetProportion() + _flgs2.GetProportion() );
120
121 return retval;
122 }
123
124 // ----------------------------------------------------------------------------
125 // Reference/Handle versions!
126
127 void operator+=( wxSizer& target, wxWindow* src )
128 {
129 target.Add( src );
130 }
131
132 void operator+=( wxSizer& target, wxSizer* src )
133 {
134 target.Add( src );
135 }
136
137 void operator+=( wxSizer& target, wxWindow& src )
138 {
139 target.Add( &src );
140 }
141
142 void operator+=( wxSizer& target, wxSizer& src )
143 {
144 target.Add( &src );
145 }
146
147 void operator+=( wxSizer& target, int spacer )
148 {
149 target.AddSpacer( spacer );
150 }
151
152 void operator+=( wxSizer& target, const pxStretchSpacer& spacer )
153 {
154 target.AddStretchSpacer( spacer.proportion );
155 }
156
157 void operator+=( wxWindow& target, int spacer )
158 {
159 if( !pxAssert( target.GetSizer() != NULL ) ) return;
160 target.GetSizer()->AddSpacer( spacer );
161 }
162
163 void operator+=( wxWindow& target, const pxStretchSpacer& spacer )
164 {
165 if( !pxAssert( target.GetSizer() != NULL ) ) return;
166 target.GetSizer()->AddStretchSpacer( spacer.proportion );
167 }
168
169 // ----------------------------------------------------------------------------
170 // Pointer versions! (note that C++ requires one of the two operator params be a
171 // "poper" object type (non-pointer), so that's why there's only a couple of these.
172
173 void operator+=( wxSizer* target, wxWindow& src )
174 {
175 if( !pxAssert( target != NULL ) ) return;
176 target->Add( &src );
177 }
178
179 void operator+=( wxSizer* target, wxSizer& src )
180 {
181 if( !pxAssert( target != NULL ) ) return;
182 target->Add( &src );
183 }
184
185 // ----------------------------------------------------------------------------
186
187 // Returns FALSE if the window position is considered invalid, which means that it's title
188 // bar is most likely not easily grabble. Such a window should be moved to a valid or
189 // default position.
190 bool pxIsValidWindowPosition( const wxWindow& window, const wxPoint& windowPos )
191 {
192 // The height of the window is only revlevant to the height of a title bar, which is
193 // all we need visible for the user to be able to drag the window into view. But
194 // there's no way to get that info from wx, so we'll just have to guesstimate...
195
196 wxSize sizeMatters( window.GetSize().GetWidth(), 32 ); // if some gui has 32 pixels of undraggable title bar, the user deserves to suffer.
197 return wxGetDisplayArea().Contains( wxRect( windowPos, sizeMatters ) );
198 }
199
200 // Retrieves the area of the screen, which can be used to enforce a valid zone for
201 // window positioning. (top/left coords are almost always (0,0) and bottom/right
202 // is the resolution of the desktop).
203 wxRect wxGetDisplayArea()
204 {
205 return wxRect( wxPoint(), wxGetDisplaySize() );
206 }
207
208 // --------------------------------------------------------------------------------------
209 // pxSizerFlags
210 // --------------------------------------------------------------------------------------
211 // FlagsAccessors - Provides read-write copies of standard sizer flags for our interface.
212 // These standard definitions provide a consistent and pretty interface for our GUI.
213 // Without them things look compacted, misaligned, and yucky!
214 //
215 // Implementation Note: Accessors are all provisioned as dynamic (realtime) sizer calculations.
216 // I've preferred this over cstatic const variables on the premise that spacing logic could
217 // in the future become a dynamic value (currently it is affixed to 6 for most items).
218 //
219 wxSizerFlags pxSizerFlags::StdSpace()
220 {
221 return wxSizerFlags().Border( wxALL, StdPadding );
222 }
223
224 wxSizerFlags pxSizerFlags::StdCenter()
225 {
226 return wxSizerFlags().Align( wxALIGN_CENTER ).DoubleBorder();
227 }
228
229 wxSizerFlags pxSizerFlags::StdExpand()
230 {
231 return StdSpace().Expand();
232 }
233
234 // A good sizer flags setting for top-level static boxes or top-level picture boxes.
235 // Gives a generous border to the left, right, and bottom. Top border can be configured
236 // manually by using a spacer.
237 wxSizerFlags pxSizerFlags::TopLevelBox()
238 {
239 return wxSizerFlags().Border( wxLEFT | wxBOTTOM | wxRIGHT, StdPadding ).Expand();
240 }
241
242 // Flags intended for use on grouped StaticBox controls. These flags are ideal for
243 // StaticBoxes that are part of sub-panels or children of other static boxes, but may
244 // not be best for parent StaticBoxes on dialogs (left and right borders feel a bit
245 // "tight").
246 wxSizerFlags pxSizerFlags::SubGroup()
247 {
248 // Groups look better with a slightly smaller margin than standard.
249 // (basically this accounts for the group's frame)
250 return wxSizerFlags().Border( wxLEFT | wxBOTTOM | wxRIGHT, StdPadding-2 ).Expand();
251 }
252
253 // This force-aligns the std button sizer to the right, where (at least) us win32 platform
254 // users always expect it to be. Most likely Mac platforms expect it on the left side
255 // just because it's *not* where win32 sticks it. Too bad!
256 wxSizerFlags pxSizerFlags::StdButton()
257 {
258 return wxSizerFlags().Align( wxALIGN_RIGHT ).Border();
259 }
260
261 wxSizerFlags pxSizerFlags::Checkbox()
262 {
263 return StdExpand();
264 }
265
266 // --------------------------------------------------------------------------------------
267 // pxTextWrapper / pxTextWrapperBase Implementations
268 // --------------------------------------------------------------------------------------
269
270 pxTextWrapperBase& pxTextWrapperBase::Wrap( const wxWindow& win, const wxString& text, int widthMax )
271 {
272 if( text.IsEmpty() ) return *this;
273
274 const wxChar *lastSpace = NULL;
275 wxString line;
276 line.Alloc( text.Length()+12 );
277
278 const wxChar *lineStart = text.c_str();
279 for ( const wxChar *p = lineStart; ; p++ )
280 {
281 if ( IsStartOfNewLine() )
282 {
283 OnNewLine();
284
285 lastSpace = NULL;
286 line.clear();
287 lineStart = p;
288 }
289
290 if ( *p == L'\n' || *p == L'\0' )
291 {
292 DoOutputLine(line);
293
294 if ( *p == L'\0' )
295 break;
296 }
297 else // not EOL
298 {
299 if ( *p == L' ' )
300 lastSpace = p;
301
302 line += *p;
303
304 if ( widthMax >= 0 && lastSpace )
305 {
306 int width;
307 win.GetTextExtent(line, &width, NULL);
308
309 if ( width > widthMax )
310 {
311 // remove the last word from this line
312 line.erase(lastSpace - lineStart, p + 1 - lineStart);
313 DoOutputLine(line);
314
315 // go back to the last word of this line which we didn't
316 // output yet
317 p = lastSpace;
318 }
319 }
320 //else: no wrapping at all or impossible to wrap
321 }
322 }
323
324 return *this;
325 }
326
327 void pxTextWrapperBase::DoOutputLine(const wxString& line)
328 {
329 OnOutputLine(line);
330 m_linecount++;
331 m_eol = true;
332 }
333
334 // this function is a destructive inspector: when it returns true it also
335 // resets the flag to false so calling it again wouldn't return true any
336 // more
337 bool pxTextWrapperBase::IsStartOfNewLine()
338 {
339 if ( !m_eol )
340 return false;
341
342 m_eol = false;
343 return true;
344 }
345
346 pxTextWrapper& pxTextWrapper::Wrap( const wxWindow& win, const wxString& text, int widthMax )
347 {
348 _parent::Wrap( win, text, widthMax );
349 return *this;
350 }
351
352 void pxTextWrapper::OnOutputLine(const wxString& line)
353 {
354 m_text += line;
355 }
356
357 void pxTextWrapper::OnNewLine()
358 {
359 m_text += L'\n';
360 }
361
362 // --------------------------------------------------------------------------------------
363 // ScopedBusyCursor Implementations
364 // --------------------------------------------------------------------------------------
365
366 std::stack<BusyCursorType> ScopedBusyCursor::m_cursorStack;
367 BusyCursorType ScopedBusyCursor::m_defBusyType;
368
369 ScopedBusyCursor::ScopedBusyCursor( BusyCursorType busytype )
370 {
371 pxAssert( wxTheApp != NULL );
372
373 BusyCursorType curtype = Cursor_NotBusy;
374 if( !m_cursorStack.empty() )
375 curtype = m_cursorStack.top();
376
377 if( curtype < busytype )
378 SetManualBusyCursor( curtype=busytype );
379
380 m_cursorStack.push( curtype );
381 }
382
383 ScopedBusyCursor::~ScopedBusyCursor() throw()
384 {
385 if( !pxAssert( wxTheApp != NULL ) ) return;
386
387 if( !pxAssert( !m_cursorStack.empty() ) )
388 {
389 SetManualBusyCursor( m_defBusyType );
390 return;
391 }
392
393 BusyCursorType curtype = m_cursorStack.top();
394 m_cursorStack.pop();
395
396 if( m_cursorStack.empty() )
397 SetManualBusyCursor( m_defBusyType );
398 else if( m_cursorStack.top() != curtype )
399 SetManualBusyCursor( m_cursorStack.top() );
400 }
401
402 void ScopedBusyCursor::SetDefault( BusyCursorType busytype )
403 {
404 if( busytype == m_defBusyType ) return;
405 m_defBusyType = busytype;
406
407 if( m_cursorStack.empty() )
408 SetManualBusyCursor( busytype );
409 }
410
411 void ScopedBusyCursor::SetManualBusyCursor( BusyCursorType busytype )
412 {
413 switch( busytype )
414 {
415 case Cursor_NotBusy: wxSetCursor( wxNullCursor ); break;
416 case Cursor_KindaBusy: wxSetCursor( StockCursors.GetArrowWait() ); break;
417 case Cursor_ReallyBusy: wxSetCursor( *wxHOURGLASS_CURSOR ); break;
418 }
419 }
420
421 const wxCursor& MoreStockCursors::GetArrowWait()
422 {
423 if( !m_arrowWait )
424 m_arrowWait = new wxCursor( wxCURSOR_ARROWWAIT );
425 return *m_arrowWait;
426 }
427
428 MoreStockCursors StockCursors;
429
430 // --------------------------------------------------------------------------------------
431 // pxFormatToolTipText / pxSetToolTip
432 // --------------------------------------------------------------------------------------
433 // This is the preferred way to assign tooltips to wxWindow-based objects, as it performs the
434 // necessary text wrapping on platforms that need it. On windows tooltips are wrapped at 600
435 // pixels, or 66% of the screen width, whichever is smaller. GTK and MAC perform internal
436 // wrapping, so this function does a regular assignment there.
437
438 wxString pxFormatToolTipText( wxWindow* wind, const wxString& src )
439 {
440 // Windows needs manual tooltip word wrapping (sigh).
441 // GTK and Mac are a wee bit more clever (except in GTK tooltips don't show at all
442 // half the time because of some other bug .. sigh)
443
444 #ifdef __WXMSW__
445 if( wind == NULL ) return src; // Silently ignore nulls
446 int whee = wxGetDisplaySize().GetWidth() * 0.75;
447 return pxTextWrapper().Wrap( *wind, src, std::min( whee, 600 ) ).GetResult();
448 #else
449 return src;
450 #endif
451 }
452
453 void pxSetToolTip( wxWindow* wind, const wxString& src )
454 {
455 if( wind == NULL ) return; // Silently ignore nulls
456 wind->SetToolTip( pxFormatToolTipText(wind, src) );
457 }
458
459 void pxSetToolTip( wxWindow& wind, const wxString& src )
460 {
461 pxSetToolTip( &wind, src );
462 }
463
464
465 wxFont pxGetFixedFont( int ptsize, int weight )
466 {
467 return wxFont(
468 ptsize, wxMODERN, wxNORMAL, weight, false
469 #ifdef __WXMSW__
470 ,L"Lucida Console" // better than courier new (win32 only)
471 #endif
472 );
473 }
474 wxString pxGetAppName()
475 {
476 pxAssume( wxTheApp );
477 return wxTheApp->GetAppName();
478 }

  ViewVC Help
Powered by ViewVC 1.1.22