X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0da1f1c4cc2fd8e8b6774b8e20b941bee759075f..603cfe42185349e119ba4c69bd56a79998babcc4:/src/propgrid/manager.cpp diff --git a/src/propgrid/manager.cpp b/src/propgrid/manager.cpp index accb791fb8..2030ec2ea3 100644 --- a/src/propgrid/manager.cpp +++ b/src/propgrid/manager.cpp @@ -6,7 +6,7 @@ // Created: 2005-01-14 // RCS-ID: $Id$ // Copyright: (c) Jaakko Salli -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx/wx.h". @@ -76,7 +76,7 @@ const char wxPropertyGridManagerNameStr[] = "wxPropertyGridManager"; // Categoric Mode Icon -static const char* gs_xpm_catmode[] = { +static const char* const gs_xpm_catmode[] = { "16 16 5 1", ". c none", "B c black", @@ -102,7 +102,7 @@ static const char* gs_xpm_catmode[] = { }; // Alphabetic Mode Icon -static const char* gs_xpm_noncatmode[] = { +static const char* const gs_xpm_noncatmode[] = { "16 16 5 1", ". c none", "B c black", @@ -128,7 +128,7 @@ static const char* gs_xpm_noncatmode[] = { }; // Default Page Icon. -static const char* gs_xpm_defpage[] = { +static const char* const gs_xpm_defpage[] = { "16 16 5 1", ". c none", "B c black", @@ -209,18 +209,197 @@ void wxPropertyGridPage::SetSplitterPosition( int splitterPos, int col ) void wxPropertyGridPage::DoSetSplitterPosition( int pos, int splitterColumn, - bool allPages, - bool fromAutoCenter ) + int flags ) { - if ( allPages && m_manager->GetPageCount() ) + if ( (flags & wxPG_SPLITTER_ALL_PAGES) && m_manager->GetPageCount() ) m_manager->SetSplitterPosition( pos, splitterColumn ); else wxPropertyGridPageState::DoSetSplitterPosition( pos, splitterColumn, - allPages, - fromAutoCenter ); + flags ); } +// ----------------------------------------------------------------------- +// wxPGHeaderCtrl +// ----------------------------------------------------------------------- + +#if wxUSE_HEADERCTRL + +class wxPGHeaderCtrl : public wxHeaderCtrl +{ +public: + wxPGHeaderCtrl(wxPropertyGridManager* manager) : + wxHeaderCtrl() + { + m_manager = manager; + EnsureColumnCount(2); + + // Seed titles with defaults + m_columns[0]->SetTitle(_("Property")); + m_columns[1]->SetTitle(_("Value")); + } + + virtual ~wxPGHeaderCtrl() + { + for (unsigned int i=0; iGetColumnWidth(idx); + int colMinWidth = page->GetColumnMinWidth(idx); + if ( idx == 0 ) + { + wxPropertyGrid* pg = m_manager->GetGrid(); + int margin = pg->GetMarginWidth(); + + // Compensate for the internal border + margin += (pg->GetSize().x - pg->GetClientSize().x) / 2; + + colWidth += margin; + colMinWidth += margin; + } + *pMinWidth = colMinWidth; + return colWidth; + } + + void OnPageChanged(const wxPropertyGridPage* page) + { + m_page = page; + OnPageUpdated(); + } + + void OnPageUpdated() + { + // Get column info from the page + const wxPropertyGridPage* page = m_page; + unsigned int colCount = page->GetColumnCount(); + EnsureColumnCount(colCount); + + for ( unsigned int i=0; iSetWidth(colWidth); + colInfo->SetMinWidth(colMinWidth); + } + + SetColumnCount(colCount); + } + + void OnColumWidthsChanged() + { + const wxPropertyGridPage* page = m_page; + unsigned int colCount = page->GetColumnCount(); + + for ( unsigned int i=0; iSetWidth(colWidth); + colInfo->SetMinWidth(colMinWidth); + UpdateColumn(i); + } + } + + virtual const wxHeaderColumn& GetColumn(unsigned int idx) const + { + return *m_columns[idx]; + } + + void SetColumnTitle(unsigned int idx, const wxString& title) + { + EnsureColumnCount(idx+1); + m_columns[idx]->SetTitle(title); + } + +private: + void EnsureColumnCount(unsigned int count) + { + while ( m_columns.size() < count ) + { + wxHeaderColumnSimple* colInfo = new wxHeaderColumnSimple(""); + m_columns.push_back(colInfo); + } + } + + void OnSetColumnWidth(int col, int colWidth) + { + wxPropertyGrid* pg = m_manager->GetGrid(); + + // Compensate for the internal border + int x = -((pg->GetSize().x - pg->GetClientSize().x) / 2); + + for ( int i=0; iGetWidth(); + + x += colWidth; + + pg->DoSetSplitterPosition(x, col, + wxPG_SPLITTER_REFRESH | + wxPG_SPLITTER_FROM_EVENT); + } + + virtual bool ProcessEvent( wxEvent& event ) + { + if ( event.IsKindOf(CLASSINFO(wxHeaderCtrlEvent)) ) + { + wxHeaderCtrlEvent& hcEvent = + static_cast(event); + + wxPropertyGrid* pg = m_manager->GetGrid(); + int col = hcEvent.GetColumn(); + int evtType = event.GetEventType(); + + if ( evtType == wxEVT_COMMAND_HEADER_RESIZING ) + { + int colWidth = hcEvent.GetWidth(); + + OnSetColumnWidth(col, colWidth); + + pg->SendEvent(wxEVT_PG_COL_DRAGGING, + NULL, NULL, 0, + (unsigned int)col); + + return true; + } + else if ( evtType == wxEVT_COMMAND_HEADER_BEGIN_RESIZE ) + { + // Never allow column resize if layout is static + if ( m_manager->HasFlag(wxPG_STATIC_SPLITTER) ) + hcEvent.Veto(); + // Allow application to veto dragging + else if ( pg->SendEvent(wxEVT_PG_COL_BEGIN_DRAG, + NULL, NULL, 0, + (unsigned int)col) ) + hcEvent.Veto(); + + return true; + } + else if ( evtType == wxEVT_COMMAND_HEADER_END_RESIZE ) + { + pg->SendEvent(wxEVT_PG_COL_END_DRAG, + NULL, NULL, 0, + (unsigned int)col); + + return true; + } + } + + return wxHeaderCtrl::ProcessEvent(event); + } + + wxPropertyGridManager* m_manager; + const wxPropertyGridPage* m_page; + wxVector m_columns; +}; + +#endif // wxUSE_HEADERCTRL + // ----------------------------------------------------------------------- // wxPropertyGridManager // ----------------------------------------------------------------------- @@ -232,12 +411,6 @@ void wxPropertyGridPage::DoSetSplitterPosition( int pos, IMPLEMENT_CLASS(wxPropertyGridManager, wxPanel) -#define ID_ADVTOOLBAR_OFFSET 1 -#define ID_ADVHELPCAPTION_OFFSET 2 -#define ID_ADVHELPCONTENT_OFFSET 3 -//#define ID_ADVBUTTON_OFFSET 4 -#define ID_ADVTBITEMSBASE_OFFSET 5 // Must be last. - // ----------------------------------------------------------------------- BEGIN_EVENT_TABLE(wxPropertyGridManager, wxPanel) @@ -309,6 +482,10 @@ void wxPropertyGridManager::Init1() #if wxUSE_TOOLBAR m_pToolbar = NULL; +#endif +#if wxUSE_HEADERCTRL + m_pHeaderCtrl = NULL; + m_showHeader = false; #endif m_pTxtHelpCaption = NULL; m_pTxtHelpContent = NULL; @@ -325,6 +502,9 @@ void wxPropertyGridManager::Init1() m_nextDescBoxSize = -1; + m_categorizedModeToolId = -1; + m_alphabeticModeToolId = -1; + m_extraHeight = 0; m_dragStatus = 0; m_onSplitter = 0; @@ -372,8 +552,6 @@ void wxPropertyGridManager::Init2( int style ) if ( baseId < 0 ) baseId = wxPG_MAN_ALTERNATE_BASE_ID; - m_baseId = baseId; - #ifdef __WXMAC__ // Smaller controls on Mac SetWindowVariant(wxWINDOW_VARIANT_SMALL); @@ -407,20 +585,16 @@ void wxPropertyGridManager::Init2( int style ) m_pPropGrid->SetExtraStyle(wxPG_EX_INIT_NOCAT); - m_nextTbInd = baseId+ID_ADVTBITEMSBASE_OFFSET + 2; - - // Connect to property grid onselect event. // NB: Even if wxID_ANY is used, this doesn't connect properly in wxPython // (see wxPropertyGridManager::ProcessEvent). - Connect(m_pPropGrid->GetId()/*wxID_ANY*/, - wxEVT_PG_SELECTED, - wxPropertyGridEventHandler(wxPropertyGridManager::OnPropertyGridSelect) ); + Connect(m_pPropGrid->GetId(), + wxEVT_PG_SELECTED, + wxPropertyGridEventHandler(wxPropertyGridManager::OnPropertyGridSelect)); - // Connect to toolbar button events. - Connect(baseId+ID_ADVTBITEMSBASE_OFFSET,baseId+ID_ADVTBITEMSBASE_OFFSET+50, - wxEVT_COMMAND_TOOL_CLICKED, - wxCommandEventHandler(wxPropertyGridManager::OnToolbarClick) ); + Connect(m_pPropGrid->GetId(), + wxEVT_PG_COL_DRAGGING, + wxPropertyGridEventHandler(wxPropertyGridManager::OnPGColDrag)); // Optional initial controls. m_width = -12345; @@ -436,8 +610,7 @@ wxPropertyGridManager::~wxPropertyGridManager() END_MOUSE_CAPTURE //m_pPropGrid->ClearSelection(); - delete m_pPropGrid; - m_pPropGrid = NULL; + wxDELETE(m_pPropGrid); size_t i; for ( i=0; i= 0 ) - m_pToolbar->ToggleTool( nextPage->m_id, true ); + m_pToolbar->ToggleTool( nextPage->m_toolId, true ); else - m_pToolbar->ToggleTool( prevPage->m_id, false ); + m_pToolbar->ToggleTool( prevPage->m_toolId, false ); } #endif +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnPageChanged(nextPage); +#endif + return true; } @@ -690,9 +868,6 @@ void wxPropertyGridManager::Clear() for ( i=(int)GetPageCount()-1; i>=0; i-- ) RemovePage(i); - // Reset toolbar ids - m_nextTbInd = m_baseId+ID_ADVTBITEMSBASE_OFFSET + 2; - m_pPropGrid->Thaw(); } @@ -733,6 +908,11 @@ void wxPropertyGridManager::SetColumnCount( int colCount, int page ) GetPageState(page)->SetColumnCount( colCount ); GetGrid()->Refresh(); + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnPageUpdated(); +#endif } // ----------------------------------------------------------------------- @@ -806,14 +986,14 @@ wxPropertyGridPage* wxPropertyGridManager::InsertPage( int index, state->InitNonCatMode(); } - if ( label.length() ) + if ( !label.empty() ) { wxASSERT_MSG( !pageObj->m_label.length(), wxT("If page label is given in constructor, empty label must be given in AddPage")); pageObj->m_label = label; } - pageObj->m_id = m_nextTbInd; + pageObj->m_toolId = -1; if ( !HasFlag(wxPG_SPLITTER_AUTO_CENTER) ) pageObj->m_dontCenterSplitter = true; @@ -836,14 +1016,23 @@ wxPropertyGridPage* wxPropertyGridManager::InsertPage( int index, m_pToolbar->GetToolsCount() < 3 ) m_pToolbar->AddSeparator(); + wxToolBarToolBase* tool; + if ( &bmp != &wxNullBitmap ) - m_pToolbar->AddTool(m_nextTbInd,label,bmp,label,wxITEM_RADIO); - //m_pToolbar->InsertTool(index+3,m_nextTbInd,bmp); + tool = m_pToolbar->AddTool(wxID_ANY, label, bmp, + label, wxITEM_RADIO); else - m_pToolbar->AddTool(m_nextTbInd,label,wxBitmap( (const char**)gs_xpm_defpage ), - label,wxITEM_RADIO); + tool = m_pToolbar->AddTool(wxID_ANY, label, + wxBitmap(gs_xpm_defpage), + label, wxITEM_RADIO); + + pageObj->m_toolId = tool->GetId(); - m_nextTbInd++; + // Connect to toolbar button events. + Connect(pageObj->m_toolId, + wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEventHandler( + wxPropertyGridManager::OnToolbarClick)); m_pToolbar->Realize(); } @@ -899,6 +1088,31 @@ bool wxPropertyGridManager::IsPageModified( size_t index ) const // ----------------------------------------------------------------------- +#if wxUSE_HEADERCTRL +void wxPropertyGridManager::ShowHeader(bool show) +{ + if ( show != m_showHeader) + { + m_showHeader = show; + RecreateControls(); + } +} +#endif + +// ----------------------------------------------------------------------- + +#if wxUSE_HEADERCTRL +void wxPropertyGridManager::SetColumnTitle( int idx, const wxString& title ) +{ + if ( !m_pHeaderCtrl ) + ShowHeader(); + + m_pHeaderCtrl->SetColumnTitle(idx, title); +} +#endif + +// ----------------------------------------------------------------------- + bool wxPropertyGridManager::IsPropertySelected( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) @@ -1110,6 +1324,15 @@ void wxPropertyGridManager::RecalculatePositions( int width, int height ) } #endif + // Header comes after the tool bar +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + { + m_pHeaderCtrl->SetSize(0, propgridY, width, -1); + propgridY += m_pHeaderCtrl->GetSize().y; + } +#endif + // Help box. if ( m_pTxtHelpCaption ) { @@ -1231,10 +1454,6 @@ void wxPropertyGridManager::RecreateControls() if ( was_shown ) Show ( false ); - wxWindowID baseId = m_pPropGrid->GetId(); - if ( baseId < 0 ) - baseId = wxPG_MAN_ALTERNATE_BASE_ID; - #if wxUSE_TOOLBAR if ( m_windowStyle & wxPG_TOOLBAR ) { @@ -1245,8 +1464,9 @@ void wxPropertyGridManager::RecreateControls() if (GetExtraStyle() & wxPG_EX_NO_TOOLBAR_DIVIDER) toolBarFlags |= wxTB_NODIVIDER; - m_pToolbar = new wxToolBar(this,baseId+ID_ADVTOOLBAR_OFFSET, - wxDefaultPosition,wxDefaultSize, + m_pToolbar = new wxToolBar(this, wxID_ANY, + wxDefaultPosition, + wxDefaultSize, toolBarFlags); m_pToolbar->SetToolBitmapSize(wxSize(16, 15)); @@ -1273,32 +1493,62 @@ void wxPropertyGridManager::RecreateControls() { wxString desc1(_("Categorized Mode")); wxString desc2(_("Alphabetic Mode")); - m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+0, - desc1,wxBitmap ( (const char**)gs_xpm_catmode ), - desc1,wxITEM_RADIO); - m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+1, - desc2,wxBitmap ( (const char**)gs_xpm_noncatmode ), - desc2,wxITEM_RADIO); + + wxToolBarToolBase* tool; + + tool = m_pToolbar->AddTool(wxID_ANY, + desc1, + wxBitmap(gs_xpm_catmode), + desc1, + wxITEM_RADIO); + m_categorizedModeToolId = tool->GetId(); + + tool = m_pToolbar->AddTool(wxID_ANY, + desc2, + wxBitmap(gs_xpm_noncatmode), + desc2, + wxITEM_RADIO); + m_alphabeticModeToolId = tool->GetId(); + m_pToolbar->Realize(); + + Connect(m_categorizedModeToolId, + wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEventHandler( + wxPropertyGridManager::OnToolbarClick)); + Connect(m_alphabeticModeToolId, + wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEventHandler( + wxPropertyGridManager::OnToolbarClick)); + } + else + { + m_categorizedModeToolId = -1; + m_alphabeticModeToolId = -1; } } - if ( (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) ) + if ( (GetExtraStyle() & wxPG_EX_MODE_BUTTONS) ) { // Toggle correct mode button. // TODO: This doesn't work in wxMSW (when changing, // both items will get toggled). - int toggle_but_on_ind = ID_ADVTBITEMSBASE_OFFSET+0; - int toggle_but_off_ind = ID_ADVTBITEMSBASE_OFFSET+1; + int toggle_but_on_ind; + int toggle_but_off_ind; if ( m_pPropGrid->m_pState->IsInNonCatMode() ) { - toggle_but_on_ind++; - toggle_but_off_ind--; + toggle_but_on_ind = m_alphabeticModeToolId; + toggle_but_off_ind = m_categorizedModeToolId; + } + else + { + toggle_but_on_ind = m_categorizedModeToolId; + toggle_but_off_ind = m_alphabeticModeToolId; } - m_pToolbar->ToggleTool(baseId+toggle_but_on_ind,true); - m_pToolbar->ToggleTool(baseId+toggle_but_off_ind,false); + m_pToolbar->ToggleTool(toggle_but_on_ind, true); + m_pToolbar->ToggleTool(toggle_but_off_ind, false); } } @@ -1311,6 +1561,31 @@ void wxPropertyGridManager::RecreateControls() } #endif +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + { + wxPGHeaderCtrl* hc; + + if ( !m_pHeaderCtrl ) + { + hc = new wxPGHeaderCtrl(this); + hc->Create(this, wxID_ANY); + m_pHeaderCtrl = hc; + } + else + { + m_pHeaderCtrl->Show(); + } + + m_pHeaderCtrl->OnPageChanged(GetCurrentPage()); + } + else + { + if ( m_pHeaderCtrl ) + m_pHeaderCtrl->Hide(); + } +#endif + if ( m_windowStyle & wxPG_DESCRIPTION ) { // Has help box. @@ -1319,7 +1594,7 @@ void wxPropertyGridManager::RecreateControls() if ( !m_pTxtHelpCaption ) { m_pTxtHelpCaption = new wxStaticText(this, - baseId+ID_ADVHELPCAPTION_OFFSET, + wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, @@ -1330,7 +1605,7 @@ void wxPropertyGridManager::RecreateControls() if ( !m_pTxtHelpContent ) { m_pTxtHelpContent = new wxStaticText(this, - baseId+ID_ADVHELPCONTENT_OFFSET, + wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, @@ -1403,69 +1678,60 @@ bool wxPropertyGridManager::EnsureVisible( wxPGPropArg id ) void wxPropertyGridManager::OnToolbarClick( wxCommandEvent &event ) { int id = event.GetId(); - if ( id >= 0 ) - { - int baseId = m_pPropGrid->GetId(); - if ( baseId < 0 ) - baseId = wxPG_MAN_ALTERNATE_BASE_ID; - if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 0 ) ) + if ( id == m_categorizedModeToolId ) + { + // Categorized mode. + if ( m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES ) { - // Categorized mode. - if ( m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES ) - { - if ( !m_pPropGrid->HasInternalFlag(wxPG_FL_CATMODE_AUTO_SORT) ) - m_pPropGrid->m_windowStyle &= ~wxPG_AUTO_SORT; - m_pPropGrid->EnableCategories( true ); - } + if ( !m_pPropGrid->HasInternalFlag(wxPG_FL_CATMODE_AUTO_SORT) ) + m_pPropGrid->m_windowStyle &= ~wxPG_AUTO_SORT; + m_pPropGrid->EnableCategories( true ); } - else if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 1 ) ) + } + else if ( id == m_alphabeticModeToolId ) + { + // Alphabetic mode. + if ( !(m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES) ) { - // Alphabetic mode. - if ( !(m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES) ) - { - if ( m_pPropGrid->HasFlag(wxPG_AUTO_SORT) ) - m_pPropGrid->SetInternalFlag(wxPG_FL_CATMODE_AUTO_SORT); - else - m_pPropGrid->ClearInternalFlag(wxPG_FL_CATMODE_AUTO_SORT); + if ( m_pPropGrid->HasFlag(wxPG_AUTO_SORT) ) + m_pPropGrid->SetInternalFlag(wxPG_FL_CATMODE_AUTO_SORT); + else + m_pPropGrid->ClearInternalFlag(wxPG_FL_CATMODE_AUTO_SORT); - m_pPropGrid->m_windowStyle |= wxPG_AUTO_SORT; - m_pPropGrid->EnableCategories( false ); - } + m_pPropGrid->m_windowStyle |= wxPG_AUTO_SORT; + m_pPropGrid->EnableCategories( false ); } - else - { - // Page Switching. + } + else + { + // Page Switching. - int index = -1; - size_t i; - wxPropertyGridPage* pdc; + int index = -1; + size_t i; + wxPropertyGridPage* pdc; - // Find page with given id. - for ( i=0; im_toolId == id ) { - pdc = m_arrPages[i]; - if ( pdc->m_id == id ) - { - index = i; - break; - } + index = i; + break; } + } - wxASSERT( index >= 0 ); - - if ( DoSelectPage( index ) ) - { - - // Event dispatching must be last. - m_pPropGrid->SendEvent( wxEVT_PG_PAGE_CHANGED, NULL ); - - } - else - { - // TODO: Depress the old button on toolbar. - } + wxASSERT( index >= 0 ); + if ( DoSelectPage( index ) ) + { + // Event dispatching must be last. + m_pPropGrid->SendEvent( wxEVT_PG_PAGE_CHANGED, NULL ); + } + else + { + // TODO: Depress the old button on toolbar. } } } @@ -1557,6 +1823,11 @@ void wxPropertyGridManager::SetSplitterLeft( bool subProps, bool allPages ) if ( highest > 0 ) m_pPropGrid->SetSplitterPosition( highest ); } + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif } // ----------------------------------------------------------------------- @@ -1573,6 +1844,19 @@ void wxPropertyGridManager::OnPropertyGridSelect( wxPropertyGridEvent& event ) // ----------------------------------------------------------------------- +void +wxPropertyGridManager::OnPGColDrag( wxPropertyGridEvent& WXUNUSED(event) ) +{ +#if wxUSE_HEADERCTRL + if ( !m_showHeader ) + return; + + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif +} + +// ----------------------------------------------------------------------- + void wxPropertyGridManager::OnResize( wxSizeEvent& WXUNUSED(event) ) { int width, height; @@ -1737,9 +2021,28 @@ void wxPropertyGridManager::SetSplitterPosition( int pos, int splitterColumn ) for ( i=0; iDoSetSplitterPosition( pos, splitterColumn, false ); - page->m_isSplitterPreSet = true; + page->DoSetSplitterPosition( pos, splitterColumn, + wxPG_SPLITTER_REFRESH ); } + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif +} + +// ----------------------------------------------------------------------- + +void wxPropertyGridManager::SetPageSplitterPosition( int page, + int pos, + int column ) +{ + GetPage(page)->DoSetSplitterPosition( pos, column ); + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif } // -----------------------------------------------------------------------