+ const int height = DoGetBestClientHeight(width);
+
+ return height == wxDefaultCoord
+ ? GetBestSize().y
+ : height + DoGetBorderSize().y;
+}
+
+int wxWindowBase::GetBestWidth(int height) const
+{
+ const int width = DoGetBestClientWidth(height);
+
+ return width == wxDefaultCoord
+ ? GetBestSize().x
+ : width + DoGetBorderSize().x;
+}
+
+void wxWindowBase::SetMinSize(const wxSize& minSize)
+{
+ m_minWidth = minSize.x;
+ m_minHeight = minSize.y;
+
+ InvalidateBestSize();
+}
+
+void wxWindowBase::SetMaxSize(const wxSize& maxSize)
+{
+ m_maxWidth = maxSize.x;
+ m_maxHeight = maxSize.y;
+
+ InvalidateBestSize();
+}
+
+void wxWindowBase::SetInitialSize(const wxSize& size)
+{
+ // Set the min size to the size passed in. This will usually either be
+ // wxDefaultSize or the size passed to this window's ctor/Create function.
+ SetMinSize(size);
+
+ // Merge the size with the best size if needed
+ wxSize best = GetEffectiveMinSize();
+
+ // If the current size doesn't match then change it
+ if (GetSize() != best)
+ SetSize(best);
+}
+
+
+// by default the origin is not shifted
+wxPoint wxWindowBase::GetClientAreaOrigin() const
+{
+ return wxPoint(0,0);
+}
+
+wxSize wxWindowBase::ClientToWindowSize(const wxSize& size) const
+{
+ const wxSize diff(GetSize() - GetClientSize());
+
+ return wxSize(size.x == -1 ? -1 : size.x + diff.x,
+ size.y == -1 ? -1 : size.y + diff.y);
+}
+
+wxSize wxWindowBase::WindowToClientSize(const wxSize& size) const
+{
+ const wxSize diff(GetSize() - GetClientSize());
+
+ return wxSize(size.x == -1 ? -1 : size.x - diff.x,
+ size.y == -1 ? -1 : size.y - diff.y);
+}
+
+void wxWindowBase::SetWindowVariant( wxWindowVariant variant )
+{
+ if ( m_windowVariant != variant )
+ {
+ m_windowVariant = variant;
+
+ DoSetWindowVariant(variant);
+ }
+}
+
+void wxWindowBase::DoSetWindowVariant( wxWindowVariant variant )
+{
+ // 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:
+ size = wxRound(size * 3.0 / 4.0);
+ break;
+
+ case wxWINDOW_VARIANT_MINI:
+ size = wxRound(size * 2.0 / 3.0);
+ break;
+
+ case wxWINDOW_VARIANT_LARGE:
+ size = wxRound(size * 5.0 / 4.0);
+ break;
+
+ default:
+ wxFAIL_MSG(wxT("unexpected window variant"));
+ break;
+ }
+
+ font.SetPointSize(size);
+ SetFont(font);
+}
+
+void wxWindowBase::DoSetSizeHints( int minW, int minH,
+ int maxW, int maxH,
+ int WXUNUSED(incW), int WXUNUSED(incH) )
+{
+ wxCHECK_RET( (minW == wxDefaultCoord || maxW == wxDefaultCoord || minW <= maxW) &&
+ (minH == wxDefaultCoord || maxH == wxDefaultCoord || minH <= maxH),
+ wxT("min width/height must be less than max width/height!") );
+
+ m_minWidth = minW;
+ m_maxWidth = maxW;
+ m_minHeight = minH;
+ m_maxHeight = maxH;
+}
+
+
+#if WXWIN_COMPATIBILITY_2_8
+void wxWindowBase::SetVirtualSizeHints(int WXUNUSED(minW), int WXUNUSED(minH),
+ int WXUNUSED(maxW), int WXUNUSED(maxH))
+{
+}
+
+void wxWindowBase::SetVirtualSizeHints(const wxSize& WXUNUSED(minsize),
+ const wxSize& WXUNUSED(maxsize))
+{
+}
+#endif // WXWIN_COMPATIBILITY_2_8
+
+void wxWindowBase::DoSetVirtualSize( int x, int y )
+{
+ m_virtualSize = wxSize(x, y);
+}
+
+wxSize wxWindowBase::DoGetVirtualSize() const
+{
+ // we should use the entire client area so if it is greater than our
+ // virtual size, expand it to fit (otherwise if the window is big enough we
+ // wouldn't be using parts of it)
+ wxSize size = GetClientSize();
+ if ( m_virtualSize.x > size.x )
+ size.x = m_virtualSize.x;
+
+ if ( m_virtualSize.y >= size.y )
+ size.y = m_virtualSize.y;
+
+ return size;
+}
+
+void wxWindowBase::DoGetScreenPosition(int *x, int *y) const
+{
+ // screen position is the same as (0, 0) in client coords for non TLWs (and
+ // TLWs override this method)
+ if ( x )
+ *x = 0;
+ if ( y )
+ *y = 0;
+
+ ClientToScreen(x, y);
+}
+
+void wxWindowBase::SendSizeEvent(int flags)
+{
+ wxSizeEvent event(GetSize(), GetId());
+ event.SetEventObject(this);
+ if ( flags & wxSEND_EVENT_POST )
+ wxPostEvent(GetEventHandler(), event);
+ else
+ HandleWindowEvent(event);
+}
+
+void wxWindowBase::SendSizeEventToParent(int flags)
+{
+ wxWindow * const parent = GetParent();
+ if ( parent && !parent->IsBeingDeleted() )
+ parent->SendSizeEvent(flags);
+}
+
+bool wxWindowBase::HasScrollbar(int orient) const
+{
+ // if scrolling in the given direction is disabled, we can't have the
+ // corresponding scrollbar no matter what
+ if ( !CanScroll(orient) )
+ return false;
+
+ const wxSize sizeVirt = GetVirtualSize();
+ const wxSize sizeClient = GetClientSize();
+
+ return orient == wxHORIZONTAL ? sizeVirt.x > sizeClient.x
+ : sizeVirt.y > sizeClient.y;
+}
+
+// ----------------------------------------------------------------------------
+// show/hide/enable/disable the window
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::Show(bool show)
+{
+ if ( show != m_isShown )
+ {
+ m_isShown = show;
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool wxWindowBase::IsEnabled() const
+{
+ return IsThisEnabled() && (IsTopLevel() || !GetParent() || GetParent()->IsEnabled());
+}
+
+void wxWindowBase::NotifyWindowOnEnableChange(bool enabled)
+{
+ // Under some platforms there is no need to update the window state
+ // explicitly, it will become disabled when its parent is. On other ones we
+ // do need to disable all windows recursively though.
+#ifndef wxHAS_NATIVE_ENABLED_MANAGEMENT
+ DoEnable(enabled);
+#endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
+
+ OnEnabled(enabled);
+
+ // Disabling a top level window is typically done when showing a modal
+ // dialog and we don't need to disable its children in this case, they will
+ // be logically disabled anyhow (i.e. their IsEnabled() will return false)
+ // and the TLW won't accept any input for them. Moreover, explicitly
+ // disabling them would look ugly as the entire TLW would be greyed out
+ // whenever a modal dialog is shown and no native applications under any
+ // platform behave like this.
+ if ( IsTopLevel() && !enabled )
+ return;
+
+ // When disabling (or enabling back) a non-TLW window we need to
+ // recursively propagate the change of the state to its children, otherwise
+ // they would still show as enabled even though they wouldn't actually
+ // accept any input (at least under MSW where children don't accept input
+ // if any of the windows in their parent chain is enabled).
+ //
+ // Notice that we must do this even for wxHAS_NATIVE_ENABLED_MANAGEMENT
+ // platforms as we still need to call the children OnEnabled() recursively.
+ for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ wxWindowBase * const child = node->GetData();
+ if ( !child->IsTopLevel() && child->IsThisEnabled() )
+ child->NotifyWindowOnEnableChange(enabled);
+ }
+}
+
+bool wxWindowBase::Enable(bool enable)
+{
+ if ( enable == IsThisEnabled() )
+ return false;
+
+ m_isEnabled = enable;
+
+ // If we call DoEnable() from NotifyWindowOnEnableChange(), we don't need
+ // to do it from here.
+#ifdef wxHAS_NATIVE_ENABLED_MANAGEMENT
+ DoEnable(enable);
+#endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
+
+ NotifyWindowOnEnableChange(enable);
+
+ return true;
+}
+
+bool wxWindowBase::IsShownOnScreen() const
+{
+ // A window is shown on screen if it itself is shown and so are all its
+ // parents. But if a window is toplevel one, then its always visible on
+ // screen if IsShown() returns true, even if it has a hidden parent.
+ return IsShown() &&
+ (IsTopLevel() || GetParent() == NULL || GetParent()->IsShownOnScreen());
+}
+
+// ----------------------------------------------------------------------------
+// RTTI
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsTopLevel() const
+{
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+// Freeze/Thaw
+// ----------------------------------------------------------------------------
+
+void wxWindowBase::Freeze()
+{
+ if ( !m_freezeCount++ )
+ {
+ // physically freeze this window:
+ DoFreeze();
+
+ // and recursively freeze all children:
+ for ( wxWindowList::iterator i = GetChildren().begin();
+ i != GetChildren().end(); ++i )
+ {
+ wxWindow *child = *i;
+ if ( child->IsTopLevel() )
+ continue;
+
+ child->Freeze();
+ }
+ }
+}
+
+void wxWindowBase::Thaw()
+{
+ wxASSERT_MSG( m_freezeCount, "Thaw() without matching Freeze()" );
+
+ if ( !--m_freezeCount )
+ {
+ // recursively thaw all children:
+ for ( wxWindowList::iterator i = GetChildren().begin();
+ i != GetChildren().end(); ++i )
+ {
+ wxWindow *child = *i;
+ if ( child->IsTopLevel() )
+ continue;
+
+ child->Thaw();
+ }
+
+ // physically thaw this window:
+ DoThaw();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Dealing with parents and children.
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsDescendant(wxWindowBase* win) const
+{
+ // Iterate until we find this window in the parent chain or exhaust it.
+ while ( win )
+ {
+ if ( win == this )
+ return true;
+
+ // Stop iterating on reaching the top level window boundary.
+ if ( win->IsTopLevel() )
+ break;
+
+ win = win->GetParent();
+ }
+
+ return false;
+}
+
+void wxWindowBase::AddChild(wxWindowBase *child)
+{
+ wxCHECK_RET( child, wxT("can't add a NULL child") );
+
+ // this should never happen and it will lead to a crash later if it does
+ // because RemoveChild() will remove only one node from the children list
+ // and the other(s) one(s) will be left with dangling pointers in them
+ wxASSERT_MSG( !GetChildren().Find((wxWindow*)child), wxT("AddChild() called twice") );
+
+ GetChildren().Append((wxWindow*)child);
+ child->SetParent(this);
+
+ // adding a child while frozen will assert when thawed, so freeze it as if
+ // it had been already present when we were frozen
+ if ( IsFrozen() && !child->IsTopLevel() )
+ child->Freeze();
+}
+
+void wxWindowBase::RemoveChild(wxWindowBase *child)
+{
+ wxCHECK_RET( child, wxT("can't remove a NULL child") );
+
+ // removing a child while frozen may result in permanently frozen window
+ // if used e.g. from Reparent(), so thaw it
+ //
+ // NB: IsTopLevel() doesn't return true any more when a TLW child is being
+ // removed from its ~wxWindowBase, so check for IsBeingDeleted() too
+ if ( IsFrozen() && !child->IsBeingDeleted() && !child->IsTopLevel() )
+ child->Thaw();
+
+ GetChildren().DeleteObject((wxWindow *)child);
+ child->SetParent(NULL);
+}
+
+void wxWindowBase::SetParent(wxWindowBase *parent)
+{
+ // This assert catches typos which may result in using "this" instead of
+ // "parent" when creating the window. This doesn't happen often but when it
+ // does the results are unpleasant because the program typically just
+ // crashes when due to a stack overflow or something similar and this
+ // assert doesn't cost much (OTOH doing a more general check that the
+ // parent is not one of our children would be more expensive and probably
+ // not worth it).
+ wxASSERT_MSG( parent != this, wxS("Can't use window as its own parent") );
+
+ m_parent = (wxWindow *)parent;
+}
+
+bool wxWindowBase::Reparent(wxWindowBase *newParent)
+{
+ wxWindow *oldParent = GetParent();
+ if ( newParent == oldParent )
+ {
+ // nothing done
+ return false;
+ }
+
+ const bool oldEnabledState = IsEnabled();
+
+ // unlink this window from the existing parent.
+ if ( oldParent )
+ {
+ oldParent->RemoveChild(this);
+ }
+ else
+ {
+ wxTopLevelWindows.DeleteObject((wxWindow *)this);
+ }
+
+ // add it to the new one
+ if ( newParent )
+ {
+ newParent->AddChild(this);
+ }
+ else
+ {
+ wxTopLevelWindows.Append((wxWindow *)this);
+ }
+
+ // We need to notify window (and its subwindows) if by changing the parent
+ // we also change our enabled/disabled status.
+ const bool newEnabledState = IsEnabled();
+ if ( newEnabledState != oldEnabledState )
+ {
+ NotifyWindowOnEnableChange(newEnabledState);
+ }
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// event handler stuff
+// ----------------------------------------------------------------------------
+
+void wxWindowBase::SetEventHandler(wxEvtHandler *handler)
+{
+ wxCHECK_RET(handler != NULL, "SetEventHandler(NULL) called");
+
+ m_eventHandler = handler;
+}
+
+void wxWindowBase::SetNextHandler(wxEvtHandler *WXUNUSED(handler))
+{
+ // disable wxEvtHandler chain mechanism for wxWindows:
+ // wxWindow uses its own stack mechanism which doesn't mix well with wxEvtHandler's one
+
+ wxFAIL_MSG("wxWindow cannot be part of a wxEvtHandler chain");
+}
+void wxWindowBase::SetPreviousHandler(wxEvtHandler *WXUNUSED(handler))
+{
+ // we can't simply wxFAIL here as in SetNextHandler: in fact the last
+ // handler of our stack when is destroyed will be Unlink()ed and thus
+ // will call this function to update the pointer of this window...
+
+ //wxFAIL_MSG("wxWindow cannot be part of a wxEvtHandler chain");
+}
+
+void wxWindowBase::PushEventHandler(wxEvtHandler *handlerToPush)
+{
+ wxCHECK_RET( handlerToPush != NULL, "PushEventHandler(NULL) called" );
+
+ // the new handler is going to be part of the wxWindow stack of event handlers:
+ // it can't be part also of an event handler double-linked chain:
+ wxASSERT_MSG(handlerToPush->IsUnlinked(),
+ "The handler being pushed in the wxWindow stack shouldn't be part of "
+ "a wxEvtHandler chain; call Unlink() on it first");
+
+ wxEvtHandler *handlerOld = GetEventHandler();
+ wxCHECK_RET( handlerOld, "an old event handler is NULL?" );
+
+ // now use wxEvtHandler double-linked list to implement a stack:
+ handlerToPush->SetNextHandler(handlerOld);
+
+ if (handlerOld != this)
+ handlerOld->SetPreviousHandler(handlerToPush);
+
+ SetEventHandler(handlerToPush);
+
+#if wxDEBUG_LEVEL
+ // final checks of the operations done above:
+ wxASSERT_MSG( handlerToPush->GetPreviousHandler() == NULL,
+ "the first handler of the wxWindow stack should "
+ "have no previous handlers set" );
+ wxASSERT_MSG( handlerToPush->GetNextHandler() != NULL,
+ "the first handler of the wxWindow stack should "
+ "have non-NULL next handler" );
+
+ wxEvtHandler* pLast = handlerToPush;
+ while ( pLast && pLast != this )
+ pLast = pLast->GetNextHandler();
+ wxASSERT_MSG( pLast->GetNextHandler() == NULL,
+ "the last handler of the wxWindow stack should "
+ "have this window as next handler" );
+#endif // wxDEBUG_LEVEL
+}
+
+wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
+{
+ // we need to pop the wxWindow stack, i.e. we need to remove the first handler
+
+ wxEvtHandler *firstHandler = GetEventHandler();
+ wxCHECK_MSG( firstHandler != NULL, NULL, "wxWindow cannot have a NULL event handler" );
+ wxCHECK_MSG( firstHandler != this, NULL, "cannot pop the wxWindow itself" );
+ wxCHECK_MSG( firstHandler->GetPreviousHandler() == NULL, NULL,
+ "the first handler of the wxWindow stack should have no previous handlers set" );
+
+ wxEvtHandler *secondHandler = firstHandler->GetNextHandler();
+ wxCHECK_MSG( secondHandler != NULL, NULL,
+ "the first handler of the wxWindow stack should have non-NULL next handler" );
+
+ firstHandler->SetNextHandler(NULL);
+
+ // It is harmless but useless to unset the previous handler of the window
+ // itself as it's always NULL anyhow, so don't do this.
+ if ( secondHandler != this )
+ secondHandler->SetPreviousHandler(NULL);
+
+ // now firstHandler is completely unlinked; set secondHandler as the new window event handler
+ SetEventHandler(secondHandler);
+
+ if ( deleteHandler )
+ {
+ wxDELETE(firstHandler);
+ }
+
+ return firstHandler;
+}
+
+bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove)
+{
+ wxCHECK_MSG( handlerToRemove != NULL, false, "RemoveEventHandler(NULL) called" );
+ wxCHECK_MSG( handlerToRemove != this, false, "Cannot remove the window itself" );
+
+ if (handlerToRemove == GetEventHandler())
+ {
+ // removing the first event handler is equivalent to "popping" the stack
+ PopEventHandler(false);
+ return true;
+ }
+
+ // NOTE: the wxWindow event handler list is always terminated with "this" handler
+ wxEvtHandler *handlerCur = GetEventHandler()->GetNextHandler();
+ while ( handlerCur != this && handlerCur )
+ {
+ wxEvtHandler *handlerNext = handlerCur->GetNextHandler();
+
+ if ( handlerCur == handlerToRemove )
+ {
+ handlerCur->Unlink();
+
+ wxASSERT_MSG( handlerCur != GetEventHandler(),
+ "the case Remove == Pop should was already handled" );
+ return true;
+ }
+
+ handlerCur = handlerNext;
+ }
+
+ wxFAIL_MSG( wxT("where has the event handler gone?") );
+
+ return false;
+}
+
+bool wxWindowBase::HandleWindowEvent(wxEvent& event) const
+{
+ // SafelyProcessEvent() will handle exceptions nicely
+ return GetEventHandler()->SafelyProcessEvent(event);
+}
+
+// ----------------------------------------------------------------------------
+// colours, fonts &c
+// ----------------------------------------------------------------------------
+
+void wxWindowBase::InheritAttributes()
+{
+ const wxWindowBase * 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_inheritFont && !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_inheritFgCol && !m_hasFgCol )
+ SetForegroundColour(parent->GetForegroundColour());
+
+ // inheriting (solid) background colour is wrong as it totally breaks
+ // any kind of themed backgrounds
+ //
+ // instead, the controls should use the same background as their parent
+ // (ideally by not drawing it at all)
+#if 0
+ if ( parent->m_inheritBgCol && !m_hasBgCol )
+ SetBackgroundColour(parent->GetBackgroundColour());
+#endif // 0
+ }
+}
+
+/* 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);
+
+ // On Smartphone/PocketPC, wxSYS_COLOUR_WINDOW is a better reflection of
+ // the usual background colour than wxSYS_COLOUR_BTNFACE.
+ // It's a pity that wxSYS_COLOUR_WINDOW isn't always a suitable background
+ // colour on other platforms.
+
+#if defined(__WXWINCE__) && (defined(__SMARTPHONE__) || defined(__POCKETPC__))
+ attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+#else
+ attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
+#endif
+ return attrs;
+}
+
+wxColour wxWindowBase::GetBackgroundColour() const
+{
+ if ( !m_backgroundColour.IsOk() )
+ {
+ wxASSERT_MSG( !m_hasBgCol, wxT("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 surprising the applications written for older
+ // wxWidgets 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.IsOk() )
+ colBg = GetClassDefaultAttributes().colBg;
+
+ return colBg;
+ }
+ else
+ return m_backgroundColour;
+}
+
+wxColour wxWindowBase::GetForegroundColour() const
+{
+ // logic is the same as above
+ if ( !m_hasFgCol && !m_foregroundColour.IsOk() )
+ {
+ wxColour colFg = GetDefaultAttributes().colFg;
+
+ if ( !colFg.IsOk() )
+ colFg = GetClassDefaultAttributes().colFg;
+
+ return colFg;
+ }
+ else
+ return m_foregroundColour;
+}
+
+bool wxWindowBase::SetBackgroundStyle(wxBackgroundStyle style)
+{
+ // The checks below shouldn't be triggered if we're not really changing the
+ // style.
+ if ( style == m_backgroundStyle )
+ return true;
+
+ // Transparent background style can be only set before creation because of
+ // wxGTK limitation.
+ wxCHECK_MSG( (style != wxBG_STYLE_TRANSPARENT) || !GetHandle(),
+ false,
+ "wxBG_STYLE_TRANSPARENT style can only be set before "
+ "Create()-ing the window." );
+
+ // And once it is set, wxBG_STYLE_TRANSPARENT can't be unset.
+ wxCHECK_MSG( (m_backgroundStyle != wxBG_STYLE_TRANSPARENT) ||
+ (style == wxBG_STYLE_TRANSPARENT),
+ false,
+ "wxBG_STYLE_TRANSPARENT can't be unset once it was set." );
+
+ m_backgroundStyle = style;
+
+ return true;
+}
+
+bool wxWindowBase::IsTransparentBackgroundSupported(wxString *reason) const
+{
+ if ( reason )
+ *reason = _("This platform does not support background transparency.");
+
+ return false;
+}
+
+bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
+{
+ if ( colour == m_backgroundColour )
+ return false;
+
+ m_hasBgCol = colour.IsOk();
+
+ m_inheritBgCol = m_hasBgCol;
+ m_backgroundColour = colour;
+ SetThemeEnabled( !m_hasBgCol && !m_foregroundColour.IsOk() );
+ return true;
+}
+
+bool wxWindowBase::SetForegroundColour( const wxColour &colour )
+{
+ if (colour == m_foregroundColour )
+ return false;
+
+ m_hasFgCol = colour.IsOk();
+ m_inheritFgCol = m_hasFgCol;
+ m_foregroundColour = colour;
+ SetThemeEnabled( !m_hasFgCol && !m_backgroundColour.IsOk() );
+ return true;
+}
+
+bool wxWindowBase::SetCursor(const wxCursor& cursor)
+{
+ // setting an invalid cursor is ok, it means that we don't have any special
+ // cursor
+ if ( m_cursor.IsSameAs(cursor) )
+ {
+ // no change
+ return false;
+ }
+
+ m_cursor = cursor;
+
+ return true;
+}
+
+wxFont wxWindowBase::GetFont() const
+{
+ // logic is the same as in GetBackgroundColour()
+ if ( !m_font.IsOk() )
+ {
+ wxASSERT_MSG( !m_hasFont, wxT("we have invalid explicit font?") );
+
+ wxFont font = GetDefaultAttributes().font;
+ if ( !font.IsOk() )
+ font = GetClassDefaultAttributes().font;
+
+ return font;
+ }
+ else
+ return m_font;
+}
+
+bool wxWindowBase::SetFont(const wxFont& font)
+{
+ if ( font == m_font )
+ {
+ // no change
+ return false;
+ }
+
+ m_font = font;
+ m_hasFont = font.IsOk();
+ m_inheritFont = m_hasFont;
+
+ InvalidateBestSize();
+
+ return true;
+}
+
+#if wxUSE_PALETTE
+
+void wxWindowBase::SetPalette(const wxPalette& pal)
+{
+ m_hasCustomPalette = true;
+ m_palette = pal;
+
+ // VZ: can anyone explain me what do we do here?
+ wxWindowDC d((wxWindow *) this);
+ d.SetPalette(pal);
+}
+
+wxWindow *wxWindowBase::GetAncestorWithCustomPalette() const
+{
+ wxWindow *win = (wxWindow *)this;
+ while ( win && !win->HasCustomPalette() )
+ {
+ win = win->GetParent();
+ }
+
+ return win;
+}
+
+#endif // wxUSE_PALETTE
+
+#if wxUSE_CARET
+void wxWindowBase::SetCaret(wxCaret *caret)
+{
+ if ( m_caret )
+ {