// headers
// ----------------------------------------------------------------------------
+#ifdef __GNUG__
+ #pragma implementation "windowbase.h"
+#endif
+
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
+#if wxUSE_CARET
+ #include "wx/caret.h"
+#endif // wxUSE_CARET
+
// ----------------------------------------------------------------------------
// static data
// ----------------------------------------------------------------------------
-int wxWindowBase::ms_lastControlId = 0;
+int wxWindowBase::ms_lastControlId = -200;
IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
void wxWindowBase::InitBase()
{
// no window yet, no parent nor children
-// m_widget = (WXWidget)0;
m_parent = (wxWindow *)NULL;
m_windowId = -1;
m_children.DeleteContents( FALSE ); // don't auto delete node data
// the default event handler is just this window
m_eventHandler = this;
+#if wxUSE_VALIDATORS
// no validator
m_windowValidator = (wxValidator *) NULL;
+#endif // wxUSE_VALIDATORS
// use the system default colours
wxSystemSettings settings;
#if wxUSE_TOOLTIPS
m_tooltip = (wxToolTip *)NULL;
#endif // wxUSE_TOOLTIPS
+
+#if wxUSE_CARET
+ m_caret = (wxCaret *)NULL;
+#endif // wxUSE_CARET
}
// common part of window creation process
// we weren't a dialog class
wxTopLevelWindows.DeleteObject(this);
- DestroyChildren();
+ wxASSERT_MSG( GetChildren().GetCount() == 0, _T("children not destroyed") );
+ // make sure that there are no dangling pointers left pointing to us
+ wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+ if ( panel )
+ {
+ if ( panel->GetLastFocus() == this )
+ {
+ panel->SetLastFocus((wxWindow *)NULL);
+ }
+ }
+
+#if wxUSE_CARET
+ if ( m_caret )
+ delete m_caret;
+#endif // wxUSE_CARET
+
+#if wxUSE_VALIDATORS
if ( m_windowValidator )
delete m_windowValidator;
+#endif // wxUSE_VALIDATORS
if ( m_clientObject )
delete m_clientObject;
bool wxWindowBase::DestroyChildren()
{
wxWindowList::Node *node;
- for ( node = GetChildren().GetFirst(); node; node = node->GetNext() )
+ for ( ;; )
{
+ // we iterate until the list becomes empty
+ node = GetChildren().GetFirst();
+ if ( !node )
+ break;
+
wxWindow *child = node->GetData();
- if ( child )
- {
- delete child;
- }
+
+ wxASSERT_MSG( child, _T("children list contains empty nodes") );
+
+ delete child;
+
+ wxASSERT_MSG( !GetChildren().Find(child),
+ _T("child didn't remove itself using RemoveChild()") );
}
return TRUE;
Move(new_x, new_y);
}
+// Center TopLevel windows over thier parent instead of the whole screen
+void wxWindowBase::CentreOnParent(int direction)
+{
+ wxPoint ppos;
+ wxSize psze;
+ wxSize wsze;
+ wxWindow* parent = GetParent();
+ int x, y;
+
+ if (!parent || !IsTopLevel()) {
+ Centre(direction);
+ return;
+ }
+
+ psze = parent->GetSize();
+ ppos = parent->ClientToScreen(wxPoint(0,0));
+ wsze = GetSize();
+
+ x = y = -1;
+
+ if (direction == wxBOTH || direction == wxHORIZONTAL)
+ x = ppos.x + (psze.x - wsze.x)/2;
+ if (direction == wxBOTH || direction == wxVERTICAL)
+ y = ppos.y + (psze.y - wsze.y)/2;
+
+ Move(x, y);
+}
+
// fits the window around the children
void wxWindowBase::Fit()
{
int maxX = 0,
maxY = 0;
- wxWindowList::Node *node = GetChildren().GetFirst();
- while ( node )
+ for ( wxWindowList::Node *node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext() )
{
wxWindow *win = node->GetData();
+ if ( win->IsTopLevel() )
+ {
+ // dialogs and frames lie in different top level windows - don't
+ // deal with them here
+ continue;
+ }
+
int wx, wy, ww, wh;
win->GetPosition(&wx, &wy);
win->GetSize(&ww, &wh);
maxX = wx + ww;
if ( wy + wh > maxY )
maxY = wy + wh;
-
- node = node->GetNext();
}
// leave a margin
return FALSE;
}
}
+// ----------------------------------------------------------------------------
+// RTTI
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsTopLevel() const
+{
+ return wxDynamicCast(this, wxFrame) || wxDynamicCast(this, wxDialog);
+}
// ----------------------------------------------------------------------------
// reparenting the window
return TRUE;
}
+#if wxUSE_CARET
+void wxWindowBase::SetCaret(wxCaret *caret)
+{
+ if ( m_caret )
+ {
+ delete m_caret;
+ }
+
+ m_caret = caret;
+
+ if ( m_caret )
+ {
+ wxASSERT_MSG( m_caret->GetWindow() == this,
+ _T("caret should be created associated to this window") );
+ }
+}
+#endif // wxUSE_CARET
+
+#if wxUSE_VALIDATORS
// ----------------------------------------------------------------------------
// validators
// ----------------------------------------------------------------------------
if ( m_windowValidator )
m_windowValidator->SetWindow(this) ;
}
+#endif // wxUSE_VALIDATORS
// ----------------------------------------------------------------------------
// update region testing
// dialog oriented functions
// ----------------------------------------------------------------------------
-void wxWindowBase::MakeModal(bool WXUNUSED(modal))
+void wxWindowBase::MakeModal(bool modal)
{
- wxFAIL_MSG("TODO");
+ // Disable all other windows
+ if ( IsTopLevel() )
+ {
+ wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
+ while (node)
+ {
+ wxWindow *win = node->GetData();
+ if (win != this)
+ win->Enable(!modal);
+
+ node = node->GetNext();
+ }
+ }
}
bool wxWindowBase::Validate()
{
+#if wxUSE_VALIDATORS
wxWindowList::Node *node;
for ( node = m_children.GetFirst(); node; node = node->GetNext() )
{
wxWindowBase *child = node->GetData();
wxValidator *validator = child->GetValidator();
- if ( validator && validator->Validate(this) )
+ if ( validator && !validator->Validate((wxWindow *)this) )
{
return FALSE;
}
}
+#endif // wxUSE_VALIDATORS
return TRUE;
}
bool wxWindowBase::TransferDataToWindow()
{
+#if wxUSE_VALIDATORS
wxWindowList::Node *node;
for ( node = m_children.GetFirst(); node; node = node->GetNext() )
{
return FALSE;
}
}
+#endif // wxUSE_VALIDATORS
return TRUE;
}
bool wxWindowBase::TransferDataFromWindow()
{
+#if wxUSE_VALIDATORS
wxWindowList::Node *node;
for ( node = m_children.GetFirst(); node; node = node->GetNext() )
{
return FALSE;
}
}
+#endif // wxUSE_VALIDATORS
return TRUE;
}
while (node)
{
wxWindow *child = node->GetData();
- if ( !child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)) )
+ if ( !child->IsTopLevel() )
{
wxLayoutConstraints *constr = child->GetConstraints();
if ( constr )
while (node)
{
wxWindow *win = node->GetData();
- if ( !win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)) )
+ if ( !win->IsTopLevel() )
win->ResetConstraints();
node = node->GetNext();
}
while (node)
{
wxWindow *win = node->GetData();
- if ( !win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)) )
+ if ( !win->IsTopLevel() )
win->SetConstraintSizes();
node = node->GetNext();
}
// this window.
void wxWindowBase::TransformSizerToActual(int *x, int *y) const
{
- if ( !m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog) ) ||
- m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
+ if ( !m_sizerParent || m_sizerParent->IsTopLevel() )
return;
int xp, yp;
if ( event.GetSetEnabled() )
Enable(event.GetEnabled());
- if ( event.GetSetText() && IsKindOf(CLASSINFO(wxControl)) )
- ((wxControl*)this)->SetLabel(event.GetText());
+ if ( event.GetSetText() )
+ {
+ wxControl *control = wxDynamicCast(this, wxControl);
+ if ( control )
+ control->SetLabel(event.GetText());
+ }
- if ( IsKindOf(CLASSINFO(wxCheckBox)) )
+#if wxUSE_CHECKBOX
+ wxCheckBox *checkbox = wxDynamicCast(this, wxCheckBox);
+ if ( checkbox )
{
if ( event.GetSetChecked() )
- ((wxCheckBox *)this)->SetValue(event.GetChecked());
+ checkbox->SetValue(event.GetChecked());
}
- // TODO No radio buttons in wxGTK yet
-#ifndef __WXGTK__
- else if ( IsKindOf(CLASSINFO(wxRadioButton)) )
+#endif // wxUSE_CHECKBOX
+
+#if wxUSE_RADIOBUTTON
+ wxRadioButton *radiobtn = wxDynamicCast(this, wxRadioButton);
+ if ( radiobtn )
{
if ( event.GetSetChecked() )
- ((wxRadioButton *) this)->SetValue(event.GetChecked());
+ radiobtn->SetValue(event.GetChecked());
}
-#endif // !wxGTK
+#endif // wxUSE_RADIOBUTTON
}
}
}