/* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2009 PCSX2 Dev Team * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with PCSX2. * If not, see . */ #pragma once #if wxUSE_GUI #include "Dependencies.h" #include "ScopedPtr.h" #include #include class pxStaticText; class pxStaticHeading; class pxCheckBox; class wxSpinCtrl; #define wxSF wxSizerFlags() // -------------------------------------------------------------------------------------- // pxAlignment / pxStretchType // -------------------------------------------------------------------------------------- // These are full blown class types instead of enumerations because wxSizerFlags has an // implicit conversion from integer (silly design flaw creating more work for me!) // struct pxAlignmentType { enum { Centre, Center = Centre, Middle, Left, Right, Top, Bottom }; int intval; wxSizerFlags Apply( wxSizerFlags flags=wxSizerFlags() ) const; wxSizerFlags operator& ( const wxSizerFlags& _flgs ) const { return Apply( _flgs ); } wxSizerFlags Border( int dir, int padding ) const { return Apply().Border( dir, padding ); } wxSizerFlags Proportion( int prop ) const { return Apply().Proportion( intval ); } operator wxSizerFlags() const { return Apply(); } }; struct pxStretchType { enum { Shrink, Expand, Shaped, ReserveHidden, FixedMinimum }; int intval; wxSizerFlags Apply( wxSizerFlags flags=wxSizerFlags() ) const; wxSizerFlags operator& ( const wxSizerFlags& _flgs ) const { return Apply( _flgs ); } wxSizerFlags Border( int dir, int padding ) const { return Apply().Border( dir, padding ); } wxSizerFlags Proportion( int prop ) const { return Apply().Proportion( intval ); } operator wxSizerFlags() const { return Apply(); } }; static __forceinline wxSizerFlags pxProportion( int prop ) { return wxSizerFlags( prop ); } static __forceinline wxSizerFlags pxBorder( int dir, int pad ) { return wxSizerFlags().Border( dir, pad ); } class pxStretchSpacer { public: int proportion; pxStretchSpacer( int prop=0 ) { proportion = prop; } }; extern const pxAlignmentType pxCentre, // Horizontal centered alignment pxCenter, pxMiddle, // vertical centered alignment pxAlignLeft, pxAlignRight, pxAlignTop, pxAlignBottom; extern const pxStretchType pxShrink, pxExpand, pxShaped, pxReserveHidden, pxFixedMinimum; // -------------------------------------------------------------------------------------- // pxWindowAndFlags // -------------------------------------------------------------------------------------- // This struct is a go-between for combining windows and sizer flags in "neat" fashion. // To create the struct, use the | operator, like so: // // myPanel | wxSizerFlags().Expand() // // Implementation Note: This struct is a template as it allows us to use a special // version of the += operator that retains the type information of the window, in case // the window implements its own += overloads (one example is pxStaticText). Without the // template, the type of the window would only be known as "wxWindow" when it's added to the // sizer, and would thus fail to invoke the correct operator overload. // template< typename WinType > struct pxWindowAndFlags { WinType* window; wxSizerFlags flags; }; extern wxSizerFlags operator& ( const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2 ); template< typename WinType > pxWindowAndFlags operator | ( WinType* _win, const wxSizerFlags& _flgs ) { pxWindowAndFlags result = { _win, _flgs }; return result; } template< typename WinType > pxWindowAndFlags operator | ( WinType& _win, const wxSizerFlags& _flgs ) { pxWindowAndFlags result = { &_win, _flgs }; return result; } // -------------------------------------------------------------------------------------- // wxSizer Operator += .. a wxSizer.Add() Substitute // -------------------------------------------------------------------------------------- // This set of operators is the *recommended* method for adding windows to sizers, not just // because it's a lot prettier but also because it allows controls like pxStaticText to over- // ride default sizerflags behavior. // // += operator works on either sizers, wxDialogs or wxPanels. In the latter case, the window // is added to the dialog/panel's toplevel sizer (wxPanel.GetSizer() is used). If the panel // has no sizer set via SetSizer(), an assertion is generated. // extern void operator+=( wxSizer& target, wxWindow* src ); extern void operator+=( wxSizer& target, wxSizer* src ); extern void operator+=( wxSizer& target, wxWindow& src ); extern void operator+=( wxSizer& target, wxSizer& src ); extern void operator+=( wxSizer* target, wxWindow& src ); extern void operator+=( wxSizer* target, wxSizer& src ); extern void operator+=( wxSizer& target, int spacer ); extern void operator+=( wxWindow& target, int spacer ); extern void operator+=( wxSizer& target, const pxStretchSpacer& spacer ); extern void operator+=( wxWindow& target, const pxStretchSpacer& spacer ); // ---------------------------------------------------------------------------- // Important: This template is needed in order to retain window type information and // invoke the proper overloaded version of += (which is used by pxStaticText and other // classes to perform special actions when added to sizers). template< typename WinType > void operator+=( wxWindow& target, WinType* src ) { if( !pxAssert( target.GetSizer() != NULL ) ) return; *target.GetSizer() += src; } template< typename WinType > void operator+=( wxWindow& target, WinType& src ) { if( !pxAssert( target.GetSizer() != NULL ) ) return; *target.GetSizer() += src; } template< typename WinType > void operator+=( wxWindow& target, const pxWindowAndFlags& src ) { if( !pxAssert( target.GetSizer() != NULL ) ) return; *target.GetSizer() += src; } template< typename WinType > void operator+=( wxSizer& target, const pxWindowAndFlags& src ) { target.Add( src.window, src.flags ); } // ---------------------------------------------------------------------------- // Pointer Versions! (note that C++ requires one of the two operator params be a // "poper" object type (non-pointer), so that's why some of these are missing. template< typename WinType > void operator+=( wxWindow* target, WinType& src ) { if( !pxAssert( target != NULL ) ) return; if( !pxAssert( target->GetSizer() != NULL ) ) return; *target->GetSizer() += src; } template< typename WinType > void operator+=( wxWindow* target, const pxWindowAndFlags& src ) { if( !pxAssert( target != NULL ) ) return; if( !pxAssert( target->GetSizer() != NULL ) ) return; *target->GetSizer() += src; } template< typename WinType > void operator+=( wxSizer* target, const pxWindowAndFlags& src ) { if( !pxAssert( target != NULL ) ) return; target->Add( src.window, src.flags ); } // ---------------------------------------------------------------------------- // wxGuiTools.h // // This file is meant to contain utility classes for users of the wxWidgets library. // All classes in this file are dependent on wxBase and wxCore libraries! Meaning // you will have to use wxCore header files and link against wxCore (GUI) to build // them. For tools which require only wxBase, see wxBaseTools.h // ---------------------------------------------------------------------------- namespace pxSizerFlags { static const int StdPadding = 5; extern wxSizerFlags StdSpace(); extern wxSizerFlags StdCenter(); extern wxSizerFlags StdExpand(); extern wxSizerFlags TopLevelBox(); extern wxSizerFlags SubGroup(); extern wxSizerFlags StdButton(); extern wxSizerFlags Checkbox(); }; // -------------------------------------------------------------------------------------- // wxDialogWithHelpers // -------------------------------------------------------------------------------------- class wxDialogWithHelpers : public wxDialog { DECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers) protected: bool m_hasContextHelp; int m_idealWidth; wxBoxSizer* m_extraButtonSizer; public: wxDialogWithHelpers(); wxDialogWithHelpers(wxWindow* parent, const wxString& title, bool hasContextHelp=false, bool resizable=false ); wxDialogWithHelpers(wxWindow* parent, const wxString& title, wxOrientation orient); virtual ~wxDialogWithHelpers() throw(); void Init(); void AddOkCancel( wxSizer& sizer, bool hasApply=false ); virtual void SmartCenterFit(); virtual int ShowModal(); virtual bool Show( bool show=true ); virtual pxStaticText* Text( const wxString& label ); virtual pxStaticHeading* Heading( const wxString& label ); virtual wxDialogWithHelpers& SetIdealWidth( int newWidth ) { m_idealWidth = newWidth; return *this; } int GetIdealWidth() const { return m_idealWidth; } bool HasIdealWidth() const { return m_idealWidth != wxDefaultCoord; } protected: void OnActivate(wxActivateEvent& evt); void OnOkCancel(wxCommandEvent& evt); void OnCloseWindow(wxCloseEvent& event); }; // -------------------------------------------------------------------------------------- // wxPanelWithHelpers // -------------------------------------------------------------------------------------- // Overview of Helpers provided by this class: // * Simpler constructors that have wxID, position, and size parameters removed (We never // use them in pcsx2) // // * Automatic 'primary box sizer' creation, assigned via SetSizer() -- use GetSizer() // to retrieve it, or use the "*this += window;" syntax to add windows directly to it. // // * Built-in support for StaticBoxes (aka groupboxes). Create one at construction with // a wxString label, or add one "after the fact" using AddFrame. // // * Propagates IdealWidth settings from parenting wxPanelWithHelpers classes, and auto- // matically adjusts the width based on the sizer type (groupsizers get truncated to // account for borders). // class wxPanelWithHelpers : public wxPanel { DECLARE_DYNAMIC_CLASS_NO_COPY(wxPanelWithHelpers) protected: int m_idealWidth; public: wxPanelWithHelpers( wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel ); wxPanelWithHelpers( wxWindow* parent, wxOrientation orient ); wxPanelWithHelpers( wxWindow* parent, const wxPoint& pos, const wxSize& size=wxDefaultSize ); explicit wxPanelWithHelpers( wxWindow* parent=NULL ); wxPanelWithHelpers* AddFrame( const wxString& label, wxOrientation orient=wxVERTICAL ); pxStaticText* Text( const wxString& label ); pxStaticHeading* Heading( const wxString& label ); // TODO : Propagate to children? wxPanelWithHelpers& SetIdealWidth( int width ) { m_idealWidth = width; return *this; } int GetIdealWidth() const { return m_idealWidth; } bool HasIdealWidth() const { return m_idealWidth != wxDefaultCoord; } protected: void Init(); }; // -------------------------------------------------------------------------------------- // pxTextWrapperBase // -------------------------------------------------------------------------------------- // this class is used to wrap the text on word boundary: wrapping is done by calling // OnStartLine() and OnOutputLine() functions. This class by itself can be used as a // line counting tool, but produces no formatted text output. // // [class "borrowed" from wxWidgets private code, made public, and renamed to avoid possible // conflicts with future editions of wxWidgets which might make it public. Why this isn't // publicly available already in wxBase I'll never know-- air] // class pxTextWrapperBase { protected: bool m_eol; int m_linecount; public: virtual ~pxTextWrapperBase() throw() { } pxTextWrapperBase() { m_eol = false; m_linecount = 0; } // win is used for getting the font, text is the text to wrap, width is the // max line width or -1 to disable wrapping pxTextWrapperBase& Wrap( const wxWindow& win, const wxString& text, int widthMax ); int GetLineCount() const { return m_linecount; } protected: // line may be empty virtual void OnOutputLine(const wxString& line) { } // called at the start of every new line (except the very first one) virtual void OnNewLine() { } void DoOutputLine(const wxString& line); bool IsStartOfNewLine(); }; // -------------------------------------------------------------------------------------- // pxTextWrapper // -------------------------------------------------------------------------------------- // This class extends pxTextWrapperBase and adds the ability to retrieve the formatted // result of word wrapping. // class pxTextWrapper : public pxTextWrapperBase { typedef pxTextWrapperBase _parent; protected: wxString m_text; public: pxTextWrapper() : pxTextWrapperBase() { } virtual ~pxTextWrapper() throw() { } const wxString& GetResult() const { return m_text; } pxTextWrapper& Wrap( const wxWindow& win, const wxString& text, int widthMax ); protected: virtual void OnOutputLine(const wxString& line); virtual void OnNewLine(); }; // -------------------------------------------------------------------------------------- // MoreStockCursors // -------------------------------------------------------------------------------------- // Because (inexplicably) the ArrowWait cursor isn't in wxWidgets stock list. // class MoreStockCursors { protected: ScopedPtr m_arrowWait; public: MoreStockCursors() { } virtual ~MoreStockCursors() throw() { } const wxCursor& GetArrowWait(); }; enum BusyCursorType { Cursor_NotBusy, Cursor_KindaBusy, Cursor_ReallyBusy, }; extern MoreStockCursors StockCursors; // -------------------------------------------------------------------------------------- // ScopedBusyCursor // -------------------------------------------------------------------------------------- // ... because wxWidgets wxBusyCursor doesn't really do proper nesting (doesn't let me // override a partially-busy cursor with a really busy one) class ScopedBusyCursor { protected: static std::stack m_cursorStack; static BusyCursorType m_defBusyType; public: ScopedBusyCursor( BusyCursorType busytype ); virtual ~ScopedBusyCursor() throw(); static void SetDefault( BusyCursorType busytype ); static void SetManualBusyCursor( BusyCursorType busytype ); }; // -------------------------------------------------------------------------------------- // pxFitToDigits // -------------------------------------------------------------------------------------- // Fits a given text or spinner control to the number of digits requested, since by default // they're usually way over-sized. extern void pxFitToDigits( wxWindow* win, int digits ); extern void pxFitToDigits( wxSpinCtrl* win, int digits ); extern wxTextCtrl* CreateNumericalTextCtrl( wxWindow* parent, int digits ); ////////////////////////////////////////////////////////////////////////////////////////////// extern bool pxDialogExists( const wxString& name ); extern bool pxIsValidWindowPosition( const wxWindow& window, const wxPoint& windowPos ); extern wxRect wxGetDisplayArea(); extern wxString pxFormatToolTipText( wxWindow* wind, const wxString& src ); extern void pxSetToolTip( wxWindow* wind, const wxString& src ); extern void pxSetToolTip( wxWindow& wind, const wxString& src ); extern wxFont pxGetFixedFont( int ptsize=8, int weight=wxNORMAL ); #endif