From 1b69c815746d9ca7cbfcbe96423e2021ed3fbdb2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 1 Apr 2004 00:05:13 +0000 Subject: [PATCH] added Get(Class)DefaultAttributes() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26522 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/control.tex | 9 +- docs/latex/wx/window.tex | 46 +++++++++++ include/wx/window.h | 72 ++++++++++++---- src/common/wincmn.cpp | 170 +++++++++++++++++++++++++++----------- 4 files changed, 229 insertions(+), 68 deletions(-) diff --git a/docs/latex/wx/control.tex b/docs/latex/wx/control.tex index 8cf69429ac..75c4e5f975 100644 --- a/docs/latex/wx/control.tex +++ b/docs/latex/wx/control.tex @@ -1,9 +1,9 @@ \section{\class{wxControl}}\label{wxcontrol} -This is the base class for a control or `widget'. +This is the base class for a control or ``widget''. -A control is generally a small window which processes user input and/or displays one or more item -of data. +A control is generally a small window which processes user input and/or +displays one or more item of data. \wxheading{Derived from} @@ -21,18 +21,21 @@ of data. \latexignore{\rtfignore{\wxheading{Members}}} + \membersection{wxControl::Command}\label{wxcontrolcommand} \func{void}{Command}{\param{wxCommandEvent\& }{event}} Simulates the effect of the user issuing a command to the item. See \helpref{wxCommandEvent}{wxcommandevent}. + \membersection{wxControl::GetLabel}\label{wxcontrolgetlabel} \func{wxString\&}{GetLabel}{\void} Returns the control's text. + \membersection{wxControl::SetLabel}\label{wxcontrolsetlabel} \func{void}{SetLabel}{\param{const wxString\& }{label}} diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex index 3e6abfa4bb..d7d86c9631 100644 --- a/docs/latex/wx/window.tex +++ b/docs/latex/wx/window.tex @@ -755,6 +755,33 @@ Returns the average character width for this window. Returns a reference to the list of the window's children. +\membersection{wxControl::GetClassDefaultAttributes}\label{wxwindowgetclassdefaultattributes} + +\func{static wxVisualAttributes}{GetClassDefaultAttributes}{\param{wxWindowVariant}{ variant = \texttt{wxWINDOW\_VARIANT\_NORMAL}}} + +Returns the default font and colours which are used by the control. This is +useful if you want to use the same font or colour in your own control as in a +standard control -- which is a much better idea than hard coding specific +colours or fonts which might look completely out of place on the users +system, especially if it uses themes. + +The \arg{variant} parameter is only relevant under Mac currently and is +ignore under other platforms. Under Mac, it will change the size of the +returned font. See \helpref{wxWindow::SetWindowVariant}{wxwindowsetwindowvariant} +for more about this. + +This static method is ``overridden'' in many derived classes and so calling, +for example, \helpref{wxButton}::GetClassDefaultAttributes() will typically +return the values appropriate for a button which will be normally different +from those returned by, say, \helpref{wxListCtrl}::GetClassDefaultAttributes(). + +The \texttt{wxVisualAttributes} structure has at least the fields +\texttt{font}, \texttt{colFg} and \texttt{colBg}. All of them may be invalid +if it was not possible to determine the default control appearance or, +especially for the background colour, if the field doesn't make sense as is +the case for \texttt{colBg} for the controls with themed background. + + \membersection{wxWindow::GetClientSize}\label{wxwindowgetclientsize} \constfunc{void}{GetClientSize}{\param{int* }{width}, \param{int* }{height}} @@ -815,6 +842,25 @@ Return the cursor associated with this window. \helpref{wxWindow::SetCursor}{wxwindowsetcursor} +\membersection{wxControl::GetDefaultAttributes}\label{wxwindowgetdefaultattributes} + +\constfunc{virtual wxVisualAttributes}{GetDefaultAttributes}{\void} + +Currently this is the same as calling +\helpref{GetClassDefaultAttributes}{wxwindowgetclassdefaultattributes}(\helpref{GetWindowVariant}{wxwindowgetwindowvariant}()). + +One advantage of using this function compared to the static version is that +the call is automatically dispatched to the correct class (as usual with +virtual functions) and you don't have to specify the class name explicitly. + +The other one is that in the future this function could return different +results, for example it might return a different font for an ``Ok'' button +than for a generic button if the users GUI is configured to show such buttons +in bold font. Of course, the down side is that it is impossible to call this +function without actually having an object to apply it to whereas the static +version can be used without having to create an object first. + + \membersection{wxWindow::GetDropTarget}\label{wxwindowgetdroptarget} \constfunc{wxDropTarget*}{GetDropTarget}{\void} diff --git a/include/wx/window.h b/include/wx/window.h index bd26e0c557..662c0e53e0 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -73,6 +73,35 @@ class WXDLLEXPORT wxWindow; class WXDLLEXPORT wxAccessible; #endif +// ---------------------------------------------------------------------------- +// helper stuff used by wxWindow +// ---------------------------------------------------------------------------- + +// struct containing all the visual attributes of a control +struct WXDLLEXPORT wxVisualAttributes +{ + // the font used for control label/text inside it + wxFont font; + + // the foreground colour + wxColour colFg; + + // the background colour, may be wxNullColour if the controls background + // colour is not solid + wxColour colBg; +}; + +// different window variants, on platforms like eg mac uses different +// rendering sizes +enum wxWindowVariant +{ + wxWINDOW_VARIANT_NORMAL, // Normal size + wxWINDOW_VARIANT_SMALL, // Smaller size (about 25 % smaller than normal) + wxWINDOW_VARIANT_MINI, // Mini size (about 33 % smaller than normal) + wxWINDOW_VARIANT_LARGE, // Large size (about 25 % larger than normal) + wxWINDOW_VARIANT_MAX +}; + // ---------------------------------------------------------------------------- // (pseudo)template list classes // ---------------------------------------------------------------------------- @@ -96,16 +125,6 @@ WXDLLEXPORT_DATA(extern wxWindowList) wxTopLevelWindows; // temporarily switches event handlers). // ---------------------------------------------------------------------------- -// different window variants, on platforms like eg mac uses different rendering sizes - -enum wxWindowVariant -{ - wxWINDOW_VARIANT_NORMAL, // Normal size - wxWINDOW_VARIANT_SMALL, // Smaller size (about 25 % smaller than normal ) - wxWINDOW_VARIANT_MINI, // Mini size (about 33 % smaller than normal ) - wxWINDOW_VARIANT_LARGE, // Large size (about 25 % larger than normal ) -}; - class WXDLLEXPORT wxWindowBase : public wxEvtHandler { public: @@ -648,13 +667,28 @@ public: // colours, fonts and cursors // -------------------------- + // get the default attributes for the controls of this class: we + // provide a virtual function which can be used to query the default + // attributes of an existing control and a static function which can + // be used even when no existing object of the given class is + // available, but which won't return any styles specific to this + // particular control, of course (e.g. "Ok" button might have + // different -- bold for example -- font) + virtual wxVisualAttributes GetDefaultAttributes() const + { + return GetClassDefaultAttributes(GetWindowVariant()); + } + + static wxVisualAttributes + GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); + // set/retrieve the window colours (system defaults are used by // default): Set functions return true if colour was changed virtual bool SetBackgroundColour( const wxColour &colour ); virtual bool SetForegroundColour( const wxColour &colour ); - wxColour GetBackgroundColour() const { return m_backgroundColour; } - wxColour GetForegroundColour() const { return m_foregroundColour; } + wxColour GetBackgroundColour() const; + wxColour GetForegroundColour() const; // set/retrieve the cursor for this window (SetCursor() returns true // if the cursor was really changed) @@ -665,8 +699,8 @@ public: // set/retrieve the font for the window (SetFont() returns true if the // font really changed) virtual bool SetFont( const wxFont &font ) = 0; - const wxFont& GetFont() const { return m_font; } - wxFont& GetFont() { return m_font; } + const wxFont& GetFont() const { return DoGetFont(); } + wxFont& GetFont() { return DoGetFont(); } #if wxUSE_CARET // associate a caret with the window @@ -979,8 +1013,9 @@ protected: // visual window attributes wxCursor m_cursor; - wxFont m_font; - wxColour m_backgroundColour, m_foregroundColour; + wxFont m_font; // see m_hasFont + wxColour m_backgroundColour, // m_hasBgCol + m_foregroundColour; // m_hasFgCol #if wxUSE_CARET wxCaret *m_caret; @@ -1152,13 +1187,16 @@ protected: virtual void DoSetWindowVariant( wxWindowVariant variant ) ; private: - // contains the last id generated by NewControlId static int ms_lastControlId; // the stack of windows which have captured the mouse static struct WXDLLEXPORT wxWindowNext *ms_winCaptureNext; + // implementation of both const and non-const versions of GetFont() + wxFont& DoGetFont() const; + + DECLARE_ABSTRACT_CLASS(wxWindowBase) DECLARE_NO_COPY_CLASS(wxWindowBase) DECLARE_EVENT_TABLE() diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 5f892e172d..25a98cc3d2 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -133,24 +133,12 @@ wxWindowBase::wxWindowBase() m_windowValidator = (wxValidator *) NULL; #endif // wxUSE_VALIDATORS - // use the system default colours - m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); - m_foregroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - - // don't set the font here for wxMSW as we don't call WM_SETFONT here and - // so the font is *not* really set - but calls to SetFont() later won't do - // anything because m_font appears to be already set! -#ifndef __WXMSW__ - m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); -#endif // __WXMSW__ - - // the colours/fonts are default for now + // the colours/fonts are default for now, so leave m_font, + // m_backgroundColour and m_foregroundColour uninitialized and set those m_hasBgCol = m_hasFgCol = m_hasFont = false; - m_isBeingDeleted = false; - // no style bits m_exStyle = m_windowStyle = 0; @@ -186,16 +174,19 @@ wxWindowBase::wxWindowBase() #endif m_virtualSize = wxDefaultSize; - + m_minVirtualWidth = m_minVirtualHeight = m_maxVirtualWidth = m_maxVirtualHeight = -1; - m_windowVariant = wxWINDOW_VARIANT_NORMAL ; + m_windowVariant = wxWINDOW_VARIANT_NORMAL; // Whether we're using the current theme for this window (wxGTK only for now) m_themeEnabled = false; + + // VZ: this one shouldn't exist... + m_isBeingDeleted = false; } // common part of window creation process @@ -625,37 +616,47 @@ void wxWindowBase::SetSizeHints(int minW, int minH, void wxWindowBase::SetWindowVariant( wxWindowVariant variant ) { - if ( m_windowVariant == variant ) - return ; - - m_windowVariant = variant ; + if ( m_windowVariant != variant ) + { + m_windowVariant = variant; - DoSetWindowVariant( variant ) ; - return ; + DoSetWindowVariant(variant); + } } void wxWindowBase::DoSetWindowVariant( wxWindowVariant variant ) { - wxFont font = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT ) ; - int size = font.GetPointSize() ; + // adjust the font height to correspond to our new variant (notice that + // we're only called if something really changed) + wxFont font = GetFont(); + int size = font.GetPointSize(); switch ( variant ) { - case wxWINDOW_VARIANT_NORMAL : - break ; - case wxWINDOW_VARIANT_SMALL : - font.SetPointSize( size * 3 / 4 ) ; - break ; - case wxWINDOW_VARIANT_MINI : - font.SetPointSize( size * 2 / 3 ) ; - break ; - case wxWINDOW_VARIANT_LARGE : - font.SetPointSize( size * 5 / 4 ) ; - break ; + case wxWINDOW_VARIANT_NORMAL: + break; + + case wxWINDOW_VARIANT_SMALL: + size *= 3; + size /= 4; + break; + + case wxWINDOW_VARIANT_MINI: + size *= 2; + size /= 3; + break; + + case wxWINDOW_VARIANT_LARGE: + size *= 5; + size /= 4; + break; + default: wxFAIL_MSG(_T("unexpected window variant")); - break ; + break; } - SetFont( font ) ; + + font.SetPointSize(size); + SetFont(font); } void wxWindowBase::SetVirtualSizeHints( int minW, int minH, @@ -866,9 +867,64 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler) } // ---------------------------------------------------------------------------- -// cursors, fonts &c +// colours, fonts &c // ---------------------------------------------------------------------------- +/* static */ wxVisualAttributes +wxWindowBase::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) +{ + // it is important to return valid values for all attributes from here, + // GetXXX() below rely on this + wxVisualAttributes attrs; + attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + + return attrs; +} + +wxColour wxWindowBase::GetBackgroundColour() const +{ + if ( !m_backgroundColour.Ok() ) + { + wxASSERT_MSG( !m_hasBgCol, _T("we have invalid explicit bg colour?") ); + + // get our default background colour + wxColour colBg = GetDefaultAttributes().colBg; + + // we must return some valid colour to avoid redoing this every time + // and also to avoid surprizing the applications written for older + // wxWindows versions where GetBackgroundColour() always returned + // something -- so give them something even if it doesn't make sense + // for this window (e.g. it has a themed background) + if ( !colBg.Ok() ) + colBg = GetClassDefaultAttributes().colBg; + + // cache it for the next call + wxConstCast(this, wxWindowBase)->m_backgroundColour = colBg; + } + + return m_backgroundColour; +} + +wxColour wxWindowBase::GetForegroundColour() const +{ + // logic is the same as above + if ( !m_hasFgCol && !m_foregroundColour.Ok() ) + { + wxASSERT_MSG( !m_hasFgCol, _T("we have invalid explicit fg colour?") ); + + wxColour colFg = GetDefaultAttributes().colFg; + + if ( !colFg.Ok() ) + colFg = GetClassDefaultAttributes().colFg; + + wxConstCast(this, wxWindowBase)->m_foregroundColour = colFg; + } + + return m_foregroundColour; +} + bool wxWindowBase::SetBackgroundColour( const wxColour &colour ) { if ( !colour.Ok() || (colour == m_backgroundColour) ) @@ -908,18 +964,36 @@ bool wxWindowBase::SetCursor(const wxCursor& cursor) return true; } +wxFont& wxWindowBase::DoGetFont() const +{ + // logic is the same as in GetBackgroundColour() + if ( !m_font.Ok() ) + { + wxASSERT_MSG( !m_hasFont, _T("we have invalid explicit font?") ); + + wxFont font = GetDefaultAttributes().font; + if ( !font.Ok() ) + font = GetClassDefaultAttributes().font; + + wxConstCast(this, wxWindowBase)->m_font = font; + } + + // cast is here for non-const GetFont() convenience + return wxConstCast(this, wxWindowBase)->m_font; +} + bool wxWindowBase::SetFont(const wxFont& font) { - // don't try to set invalid font, always fall back to the default - const wxFont& fontOk = font.Ok() ? font : *wxSWISS_FONT; + if ( !font.Ok() ) + return false; - if ( fontOk == m_font ) + if ( font == m_font ) { // no change return false; } - m_font = fontOk; + m_font = font; m_hasFont = true; @@ -982,7 +1056,7 @@ void wxWindowBase::SetValidator(const wxValidator& validator) m_windowValidator = (wxValidator *)validator.Clone(); if ( m_windowValidator ) - m_windowValidator->SetWindow(this) ; + m_windowValidator->SetWindow(this); } #endif // wxUSE_VALIDATORS @@ -1505,7 +1579,7 @@ void wxWindowBase::SetSizer(wxSizer *sizer, bool deleteOld) { if ( sizer == m_windowSizer) return; - + if ( deleteOld ) delete m_windowSizer; @@ -1906,9 +1980,9 @@ wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) int charHeight = GetCharHeight(); wxPoint pt2(-1, -1); if (pt.x != -1) - pt2.x = (int) ((pt.x * 4) / charWidth) ; + pt2.x = (int) ((pt.x * 4) / charWidth); if (pt.y != -1) - pt2.y = (int) ((pt.y * 8) / charHeight) ; + pt2.y = (int) ((pt.y * 8) / charHeight); return pt2; } @@ -1919,9 +1993,9 @@ wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) int charHeight = GetCharHeight(); wxPoint pt2(-1, -1); if (pt.x != -1) - pt2.x = (int) ((pt.x * charWidth) / 4) ; + pt2.x = (int) ((pt.x * charWidth) / 4); if (pt.y != -1) - pt2.y = (int) ((pt.y * charHeight) / 8) ; + pt2.y = (int) ((pt.y * charHeight) / 8); return pt2; }