// Created: 13/07/98
// RCS-ID: $Id$
// Copyright: (c) wxWindows team
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
#endif // wxUSE_DRAG_AND_DROP
#if wxUSE_ACCESSIBILITY
- #include "wx/access.h"
+ #include "wx/access.h"
#endif
#if wxUSE_HELP
m_hasBgCol =
m_hasFgCol =
m_hasFont = FALSE;
+
+ m_isBeingDeleted = FALSE;
// no style bits
m_exStyle =
m_windowStyle = 0;
- // an optimization for the event processing: checking this flag is much
- // faster than using IsKindOf(CLASSINFO(wxWindow))
- m_isWindow = TRUE;
-
#if wxUSE_CONSTRAINTS
// no constraints whatsoever
m_constraints = (wxLayoutConstraints *) NULL;
const wxValidator& validator,
const wxString& name)
{
- // m_isWindow is set to TRUE in wxWindowBase::Init() as well as many other
- // member variables - check that it has been called (will catch the case
- // when a new ctor is added which doesn't call InitWindow)
- wxASSERT_MSG( m_isWindow, wxT("Init() must have been called before!") );
-
#if wxUSE_STATBOX
// wxGTK doesn't allow to create controls with static box as the parent so
// this will result in a crash when the program is ported to wxGTK so warn
_T("wxStaticBox can't be used as a window parent!") );
#endif // wxUSE_STATBOX
+ // ids are limited to 16 bits under MSW so if you care about portability,
+ // it's not a good idea to use ids out of this range (and negative ids are
+ // reserved for wxWindows own usage)
+ wxASSERT_MSG( id == wxID_ANY || (id >= 0 && id < 32767),
+ _T("invalid id value") );
+
// generate a new id if the user doesn't care about it
- m_windowId = id == -1 ? NewControlId() : id;
+ m_windowId = id == wxID_ANY ? NewControlId() : id;
SetName(name);
SetWindowStyleFlag(style);
int maxW, int maxH,
int WXUNUSED(incW), int WXUNUSED(incH))
{
+ // setting min width greater than max width leads to infinite loops under
+ // X11 and generally doesn't make any sense, so don't allow it
+ wxCHECK_RET( (minW == -1 || maxW == -1 || minW <= maxW) &&
+ (minH == -1 || maxH == -1 || minH <= maxH),
+ _T("min width/height must be less than max width/height!") );
+
m_minWidth = minW;
m_maxWidth = maxW;
m_minHeight = minH;
// do Update UI processing for child controls
// ----------------------------------------------------------------------------
-// TODO: should this be implemented for the child window rather
-// than the parent? Then you can override it e.g. for wxCheckBox
-// to do the Right Thing rather than having to assume a fixed number
-// of control classes.
-void wxWindowBase::UpdateWindowUI()
+void wxWindowBase::UpdateWindowUI(long flags)
{
-#if wxUSE_CONTROLS
wxUpdateUIEvent event(GetId());
event.m_eventObject = this;
if ( GetEventHandler()->ProcessEvent(event) )
{
- if ( event.GetSetEnabled() )
- Enable(event.GetEnabled());
+ DoUpdateWindowUI(event);
+ }
- if ( event.GetSetText() )
+ if (flags & wxUPDATE_UI_RECURSE)
+ {
+ wxWindowList::Node* node = GetChildren().GetFirst();
+ while (node)
{
- wxControl *control = wxDynamicCastThis(wxControl);
- if ( control )
- {
-#if wxUSE_TEXTCTRL
- wxTextCtrl *text = wxDynamicCast(control, wxTextCtrl);
- if ( text )
- {
- if ( event.GetText() != text->GetValue() )
- text->SetValue(event.GetText());
- }
- else
-#endif // wxUSE_TEXTCTRL
- {
- if ( event.GetText() != control->GetLabel() )
- control->SetLabel(event.GetText());
- }
- }
+ wxWindow* child = (wxWindow*) node->GetData();
+ child->UpdateWindowUI(flags);
+ node = node->GetNext();
}
+ }
+}
+// do the window-specific processing after processing the update event
+// TODO: take specific knowledge out of this function and
+// put in each control's base class. Unfortunately we don't
+// yet have base implementation files for wxCheckBox and wxRadioButton.
+void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
+{
+ if ( event.GetSetEnabled() )
+ Enable(event.GetEnabled());
+
+#if wxUSE_CONTROLS
+ if ( event.GetSetText() )
+ {
+ wxControl *control = wxDynamicCastThis(wxControl);
+ if ( control )
+ {
+ if ( event.GetText() != control->GetLabel() )
+ control->SetLabel(event.GetText());
+ }
#if wxUSE_CHECKBOX
wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
if ( checkbox )
radiobtn->SetValue(event.GetChecked());
}
#endif // wxUSE_RADIOBTN
+ }
+#endif
+}
+
+// call internal idle recursively
+void wxWindowBase::ProcessInternalIdle()
+{
+ OnInternalIdle();
+
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while (node)
+ {
+ wxWindow *child = node->GetData();
+ child->ProcessInternalIdle();
+ node = node->GetNext();
}
-#endif // wxUSE_CONTROLS
}
// ----------------------------------------------------------------------------
}
}
-// the default action is to populate dialog with data when it's created
+// the default action is to populate dialog with data when it's created,
+// and nudge the UI into displaying itself correctly in case
+// we've turned the wxUpdateUIEvents frequency down low.
void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
{
TransferDataToWindow();
+
+ // Update the UI at this point
+ UpdateWindowUI(wxUPDATE_UI_RECURSE);
}
// process Ctrl-Alt-mclick
#if wxUSE_ACCESSIBILITY
void wxWindowBase::SetAccessible(wxAccessible* accessible)
{
- if (m_accessible)
+ if (m_accessible && (accessible != m_accessible))
delete m_accessible;
m_accessible = accessible;
if (m_accessible)
// borders
// ----------------------------------------------------------------------------
-wxBorder wxWindowBase::GetBorder() const
+wxBorder wxWindowBase::GetBorder(long flags) const
{
- wxBorder border = (wxBorder)(m_windowStyle & wxBORDER_MASK);
+ wxBorder border = (wxBorder)(flags & wxBORDER_MASK);
if ( border == wxBORDER_DEFAULT )
{
border = GetDefaultBorder();
GetCapture());
}
+
+void wxWindowBase::SendDestroyEvent()
+{
+ wxWindowDestroyEvent event;
+ event.SetEventObject(this);
+ event.SetId(GetId());
+ GetEventHandler()->ProcessEvent(event);
+}
+
+// ----------------------------------------------------------------------------
+// event processing
+// ----------------------------------------------------------------------------
+
+#if wxUSE_VALIDATORS
+
+bool wxWindowBase::TryValidator(wxEvent& event)
+{
+ // Can only use the validator of the window which
+ // is receiving the event
+ if ( event.GetEventObject() == this )
+ {
+ wxValidator *validator = GetValidator();
+ if ( validator && validator->ProcessEvent(event) )
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+#endif // wxUSE_VALIDATORS
+
+bool wxWindowBase::TryParent(wxEvent& event)
+{
+ // Carry on up the parent-child hierarchy, but only if event is a command
+ // event: it wouldn't make sense for a parent to receive a child's size
+ // event, for example
+ if ( event.IsCommandEvent() )
+ {
+ // honour the requests to stop propagation at this window: this is
+ // used by the dialogs, for example, to prevent processing the events
+ // from the dialog controls in the parent frame which rarely, if ever,
+ // makes sense
+ if ( !(GetExtraStyle() & wxWS_EX_BLOCK_EVENTS) )
+ {
+ wxWindow *parent = GetParent();
+ if ( parent && !parent->IsBeingDeleted() )
+ return parent->GetEventHandler()->ProcessEvent(event);
+ }
+ }
+
+ return wxEvtHandler::TryParent(event);
+}
+
// ----------------------------------------------------------------------------
// global functions
// ----------------------------------------------------------------------------
if (!GetWindow())
return wxACC_FAIL;
- wxString title(GetWindow()->GetTitle());
+ wxString title;
+
+ // If a child, leave wxWindows to call the function on the actual
+ // child object.
+ if (childId > 0)
+ return wxACC_NOT_IMPLEMENTED;
+
+ // This will eventually be replaced by specialised
+ // accessible classes, one for each kind of wxWindows
+ // control or window.
+ if (GetWindow()->IsKindOf(CLASSINFO(wxButton)))
+ title = ((wxButton*) GetWindow())->GetLabel();
+ else
+ title = GetWindow()->GetName();
+
if (!title.IsEmpty())
{
*name = title;
if (!GetWindow())
return wxACC_FAIL;
+ wxString ht(GetWindow()->GetHelpText());
+ if (!ht.IsEmpty())
+ {
+ *description = ht;
+ return wxACC_OK;
+ }
return wxACC_NOT_IMPLEMENTED;
}
if (!GetWindow())
return wxACC_FAIL;
+ // If a child, leave wxWindows to call the function on the actual
+ // child object.
+ if (childId > 0)
+ return wxACC_NOT_IMPLEMENTED;
+
+ if (GetWindow()->IsKindOf(CLASSINFO(wxControl)))
+ return wxACC_NOT_IMPLEMENTED;
+#if wxUSE_STATUSBAR
+ if (GetWindow()->IsKindOf(CLASSINFO(wxStatusBar)))
+ return wxACC_NOT_IMPLEMENTED;
+#endif
+#if wxUSE_TOOLBAR
+ if (GetWindow()->IsKindOf(CLASSINFO(wxToolBar)))
+ return wxACC_NOT_IMPLEMENTED;
+#endif
+
+ //*role = wxROLE_SYSTEM_CLIENT;
+ *role = wxROLE_SYSTEM_CLIENT;
+ return wxACC_OK;
+
return wxACC_NOT_IMPLEMENTED;
}
if (!GetWindow())
return wxACC_FAIL;
+ // If a child, leave wxWindows to call the function on the actual
+ // child object.
+ if (childId > 0)
+ return wxACC_NOT_IMPLEMENTED;
+
+ if (GetWindow()->IsKindOf(CLASSINFO(wxControl)))
+ return wxACC_NOT_IMPLEMENTED;
+
+#if wxUSE_STATUSBAR
+ if (GetWindow()->IsKindOf(CLASSINFO(wxStatusBar)))
+ return wxACC_NOT_IMPLEMENTED;
+#endif
+#if wxUSE_TOOLBAR
+ if (GetWindow()->IsKindOf(CLASSINFO(wxToolBar)))
+ return wxACC_NOT_IMPLEMENTED;
+#endif
+
+ *state = 0;
+ return wxACC_OK;
+
return wxACC_NOT_IMPLEMENTED;
}