From b8e7b6738fe00529fdeae26e6cfea1ccc2a00a76 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 8 Apr 2004 12:11:22 +0000
Subject: [PATCH] 1. moved InheritAttributes() from wxControl to wxWindow 2.
 made it inherit only the attributes explicitly set for the parent 3.
 "explicitly set" means set with SetXXX(), not newly added SetDefaultXXX() 4.
 documented InheritAttributes(), ShouldInheritColours() and SetDefaultXXX()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26670 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/window.tex | 104 +++++++++++++++++++++++++++++++++++++--
 include/wx/control.h     |   4 --
 include/wx/window.h      |  57 +++++++++++++++------
 src/common/wincmn.cpp    |  25 ++++++++++
 4 files changed, 169 insertions(+), 21 deletions(-)

diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 1cf2671836..e9ed4dc011 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -781,6 +781,10 @@ 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.
 
+\wxheading{See also}
+
+\helpref{InheritAttributes}{wxwindowinheritattributes}
+
 
 \membersection{wxWindow::GetClientSize}\label{wxwindowgetclientsize}
 
@@ -1266,6 +1270,35 @@ Returns true if this window has the current mouse capture.
 Equivalent to calling \helpref{Show}{wxwindowshow}({\tt false}).
 
 
+\membersection{wxWindow::InheritAttributes}\label{wxwindowinheritattributes}
+
+\func{void}{InheritAttributes}{\void}
+
+This function is (or should be, in case of custom controls) called during
+window creation to intelligently set up the window visual attributes, that is
+the font and the foreground and background colours.
+
+By ``intelligently'' the following is meant: by default, all windows use their
+own \helpref{default}{wxwindowgetclassdefaultattributes} attributes. However
+if some of the parents attributes are explicitly (that is, using 
+\helpref{SetFont}{wxwindowsetfont} and not 
+\helpref{SetDefaultFont}{wxwindowsetdefaultfont}) changed \emph{and} if the
+corresponding attribute hadn't been explicitly set for this window itself,
+then this window takes the same value as used by the parent. In addition, if
+the window overrides \helpref{ShouldInheritColours}{wxwindowshouldinheritcolours} 
+to return \false, the colours will not be changed no matter what and only the
+font might.
+
+This rather complicated logic is necessary in order to accomodate the
+different usage scenarius. The most common one is when all default attributes
+are used and in this case, nothing should be inherited as in modern GUIs
+different controls use different fonts (and colours) than their siblings so
+they can't inherit the same value from the parent. However it was also deemed
+desirable to allow to simply change the attributes of all children at once by
+just changing the font or colour of their common parent, hence in this case we
+do inherit the parents attributes.
+
+
 \membersection{wxWindow::InitDialog}\label{wxwindowinitdialog}
 
 \func{void}{InitDialog}{\void}
@@ -2300,6 +2333,10 @@ from within wxWindow::OnSize functions.}
 
 Sets the background colour of the window.
 
+Please see \helpref{InheritAttributes}{wxwindowinheritattributes} for
+explanation of the difference between this method and 
+\helpref{SetDefaultBackgroundColour}{wxwindowsetdefaultbackgroundcolour}.
+
 \wxheading{Parameters}
 
 \docparam{colour}{The colour to be used as the background colour.}
@@ -2415,6 +2452,45 @@ explicitly. When setting both a wxLayoutConstraints and a \helpref{wxSizer}{wxsi
 sizer will have effect.
 
 
+\membersection{wxWindow::SetDefaultBackgroundColour}\label{wxwindowsetdefaultbackgroundcolour}
+
+\func{void}{SetDefaultBackgroundColour}{\param{const wxColour\& }{colour}}
+
+Sets the background colour of the window but prevents it from being inherited
+by the children of this window.
+
+\wxheading{See also}
+
+\helpref{SetBackgroundColour}{wxwindowsetbackgroundcolour},\rtfsp
+\helpref{InheritAttributes}{wxwindowinheritattributes}
+
+
+\membersection{wxWindow::SetDefaultFont}\label{wxwindowsetdefaultfont}
+
+\func{void}{SetDefaultBackgroundColour}{\param{const wxColour\& }{colour}}
+
+Sets the font of the window but prevents it from being inherited by the
+children of this window.
+
+\wxheading{See also}
+
+\helpref{SetFont}{wxwindowsetfont},\rtfsp
+\helpref{InheritAttributes}{wxwindowinheritattributes}
+
+
+\membersection{wxWindow::SetDefaultForegroundColour}\label{wxwindowsetdefaultforegroundcolour}
+
+\func{void}{SetDefaultForegroundColour}{\param{const wxColour\& }{colour}}
+
+Sets the foreground colour of the window but prevents it from being inherited
+by the children of this window.
+
+\wxheading{See also}
+
+\helpref{SetForegroundColour}{wxwindowsetforegroundcolour},\rtfsp
+\helpref{InheritAttributes}{wxwindowinheritattributes}
+
+
 \membersection{wxWindow::SetDropTarget}\label{wxwindowsetdroptarget}
 
 \func{void}{SetDropTarget}{\param{wxDropTarget*}{ target}}
@@ -2523,7 +2599,11 @@ can be overridden to do something in addition to this in the derived classes.
 
 \func{void}{SetFont}{\param{const wxFont\& }{font}}
 
-Sets the font for this window.
+Sets the font for this window. This function should not be called for the
+parent window if you don't want its font to be inherited by its children,
+use \helpref{SetDefaultFont}{wxwindowsetdefaultfont} instead in this case and
+see \helpref{InheritAttributes}{wxwindowinheritattributes} for more
+explanations.
 
 \wxheading{Parameters}
 
@@ -2531,7 +2611,8 @@ Sets the font for this window.
 
 \wxheading{See also}
 
-\helpref{wxWindow::GetFont}{wxwindowgetfont}
+\helpref{wxWindow::GetFont}{wxwindowgetfont},\\
+\helpref{InheritAttributes}{wxwindowinheritattributes}
 
 
 \membersection{wxWindow::SetForegroundColour}\label{wxwindowsetforegroundcolour}
@@ -2540,6 +2621,10 @@ Sets the font for this window.
 
 Sets the foreground colour of the window.
 
+Please see \helpref{InheritAttributes}{wxwindowinheritattributes} for
+explanation of the difference between this method and 
+\helpref{SetDefaultForegroundColour}{wxwindowsetdefaultforegroundcolour}.
+
 \wxheading{Parameters}
 
 \docparam{colour}{The colour to be used as the foreground colour.}
@@ -2558,7 +2643,8 @@ their parent windows.
 
 \helpref{wxWindow::GetForegroundColour}{wxwindowgetforegroundcolour},\rtfsp
 \helpref{wxWindow::SetBackgroundColour}{wxwindowsetbackgroundcolour},\rtfsp
-\helpref{wxWindow::GetBackgroundColour}{wxwindowgetbackgroundcolour}
+\helpref{wxWindow::GetBackgroundColour}{wxwindowgetbackgroundcolour},\rtfsp
+\helpref{wxWindow::ShouldInheritColours}{wxwindowshouldinheritcolours}
 
 
 \membersection{wxWindow::SetHelpText}\label{wxwindowsethelptext}
@@ -3054,6 +3140,18 @@ By default the controls use the normal size, of course, but this function can
 be used to change this.
 
 
+\membersection{wxWindow::ShouldInheritColours}\label{wxwindowshouldinheritcolours}
+
+\func{virtual bool}{ShouldInheritColours}{\void}
+
+Return \true from here to allow the colours of this window to be changed by 
+\helpref{InheritAttributes}{wxwindowinheritattributes}, returning \false
+forbids inheriting them from the parent window.
+
+The base class version returns \false, but this method is overridden in 
+\helpref{wxControl}{wxcontrol} where it returns \true.
+
+
 \membersection{wxWindow::Show}\label{wxwindowshow}
 
 \func{virtual bool}{Show}{\param{bool}{ show = {\tt true}}}
diff --git a/include/wx/control.h b/include/wx/control.h
index ecde84ec8f..62ea97b1b3 100644
--- a/include/wx/control.h
+++ b/include/wx/control.h
@@ -74,10 +74,6 @@ protected:
                        const wxValidator& validator,
                        const wxString& name);
 
-    // this function is obsolete, it is only kept for backwards compatibility,
-    // do *not* use it
-    void InheritAttributes() { }
-
     // initialize the common fields of wxCommandEvent
     void InitCommandEvent(wxCommandEvent& event) const;
 
diff --git a/include/wx/window.h b/include/wx/window.h
index b2e14d4151..63b37aedc4 100644
--- a/include/wx/window.h
+++ b/include/wx/window.h
@@ -439,6 +439,10 @@ public:
         // make the window modal (all other windows unresponsive)
     virtual void MakeModal(bool modal = true);
 
+
+    // (primitive) theming support
+    // ---------------------------
+
     virtual void SetThemeEnabled(bool enableTheme) { m_themeEnabled = enableTheme; }
     virtual bool GetThemeEnabled() const { return m_themeEnabled; }
 
@@ -450,10 +454,6 @@ public:
     virtual void ApplyParentThemeBackground(const wxColour& WXUNUSED(bg))
         { /* do nothing */ }
     
-        // returns true if this window should inherit its parent colours on
-        // creation
-    virtual bool ShouldInheritColours() const { return false; }
-
 
     // focus and keyboard handling
     // ---------------------------
@@ -697,25 +697,42 @@ public:
     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 );
-
+        // default): SetXXX() functions return true if colour was changed,
+        // SetDefaultXXX() reset the "m_hasXXX" flag after setting the value
+        // to prevent it from being inherited by our children
+    virtual bool SetBackgroundColour(const wxColour& colour);
+    void SetDefaultBackgroundColour(const wxColour& colour)
+    {
+        if ( SetBackgroundColour(colour) )
+            m_hasBgCol = false;
+    }
     wxColour GetBackgroundColour() const;
+
+    virtual bool SetForegroundColour(const wxColour& colour);
+    void SetDefaultForegroundColour(const wxColour& colour)
+    {
+        if ( SetForegroundColour(colour) )
+            m_hasFgCol = false;
+    }
     wxColour GetForegroundColour() const;
 
+        // set/retrieve the font for the window (SetFont() returns true if the
+        // font really changed)
+    virtual bool SetFont(const wxFont& font) = 0;
+    void SetDefaultFont(const wxFont& font)
+    {
+        if ( SetFont(font) )
+            m_hasFont = false;
+    }
+    const wxFont& GetFont() const { return DoGetFont(); }
+    wxFont& GetFont() { return DoGetFont(); }
+
         // set/retrieve the cursor for this window (SetCursor() returns true
         // if the cursor was really changed)
     virtual bool SetCursor( const wxCursor &cursor );
     const wxCursor& GetCursor() const { return m_cursor; }
     wxCursor& GetCursor() { return m_cursor; }
 
-        // 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 DoGetFont(); }
-    wxFont& GetFont() { return DoGetFont(); }
-
 #if wxUSE_CARET
         // associate a caret with the window
     void SetCaret(wxCaret *caret);
@@ -987,6 +1004,18 @@ protected:
     virtual bool TryValidator(wxEvent& event);
     virtual bool TryParent(wxEvent& event);
 
+    // inherit the parents visual attributes if they had been explicitly set
+    // by the user (i.e. we don't inherit default attributes) and if we don't
+    // have our own explicitly set
+    virtual void InheritAttributes();
+
+    // returns false from here if this window doesn't want to inherit the
+    // parents colours even if InheritAttributes() would normally do it
+    //
+    // this just provides a simple way to customize InheritAttributes()
+    // behaviour in the most common case
+    virtual bool ShouldInheritColours() const { return false; }
+
 
 #if wxUSE_CONSTRAINTS
     // satisfy the constraints for the windows but don't set the window sizes
diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp
index 465635a87c..031974f072 100644
--- a/src/common/wincmn.cpp
+++ b/src/common/wincmn.cpp
@@ -888,6 +888,31 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler)
 // colours, fonts &c
 // ----------------------------------------------------------------------------
 
+void wxWindowBase::InheritAttributes()
+{
+    const wxWindow * const parent = GetParent();
+    if ( !parent )
+        return;
+
+    // we only inherit attributes which had been explicitly set for the parent
+    // which ensures that this only happens if the user really wants it and
+    // not by default which wouldn't make any sense in modern GUIs where the
+    // controls don't all use the same fonts (nor colours)
+    if ( parent->m_hasFont && !m_hasFont )
+        SetFont(parent->GetFont());
+
+    // in addition, there is a possibility to explicitly forbid inheriting
+    // colours at each class level by overriding ShouldInheritColours()
+    if ( ShouldInheritColours() )
+    {
+        if ( parent->m_hasFgCol && !m_hasFgCol )
+            SetForegroundColour(parent->GetForegroundColour());
+
+        if ( parent->m_hasBgCol && !m_hasBgCol )
+            SetBackgroundColour(parent->GetBackgroundColour());
+    }
+}
+
 /* static */ wxVisualAttributes
 wxWindowBase::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 {
-- 
2.50.0

