X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0d57be459406c2830f6abc9d99ae99166c6d133b..44c4a3348693414bace13852e50d926c1aa9f08b:/src/motif/notebook.cpp diff --git a/src/motif/notebook.cpp b/src/motif/notebook.cpp index c93dbba6f9..4523b93e05 100644 --- a/src/motif/notebook.cpp +++ b/src/motif/notebook.cpp @@ -24,6 +24,10 @@ #include #include #include +#include + +#include +#include // ---------------------------------------------------------------------------- // macros @@ -39,10 +43,12 @@ #if !USE_SHARED_LIBRARIES BEGIN_EVENT_TABLE(wxNotebook, wxControl) EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange) - EVT_SIZE(wxNotebook::OnSize) + EVT_PAINT(wxNotebook::OnPaint) + EVT_MOUSE_EVENTS(wxNotebook::OnMouseEvent) EVT_SET_FOCUS(wxNotebook::OnSetFocus) EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey) + EVT_IDLE(wxNotebook::OnIdle) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl) @@ -60,6 +66,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent) // common part of all ctors void wxNotebook::Init() { + m_tabView = (wxNotebookTabView*) NULL; m_pImageList = NULL; m_nSelection = -1; } @@ -93,24 +100,22 @@ bool wxNotebook::Create(wxWindow *parent, { // base init SetName(name); - SetParent(parent); m_windowId = id == -1 ? NewControlId() : id; - // style - m_windowStyle = style; + // It's like a normal window... + if (!wxWindow::Create(parent, id, pos, size, style, name)) + return FALSE; - if ( parent != NULL ) - parent->AddChild(this); - - // TODO + SetTabView(new wxNotebookTabView(this)); - return FALSE; + return TRUE; } // dtor wxNotebook::~wxNotebook() { + delete m_tabView; } // ---------------------------------------------------------------------------- @@ -129,9 +134,14 @@ int wxNotebook::GetRowCount() const int wxNotebook::SetSelection(int nPage) { + if (nPage == -1) + return 0; + wxASSERT( IS_VALID_PAGE(nPage) ); - ChangePage(m_nSelection, nPage); + wxNotebookPage* pPage = GetPage(nPage); + + m_tabView->SetTabSelection((int) (long) pPage); // TODO return 0; @@ -151,7 +161,14 @@ bool wxNotebook::SetPageText(int nPage, const wxString& strText) { wxASSERT( IS_VALID_PAGE(nPage) ); - // TODO + wxNotebookPage* page = GetPage(nPage); + if (page) + { + m_tabView->SetTabText((int) (long) page, strText); + Refresh(); + return TRUE; + } + return FALSE; } @@ -159,8 +176,11 @@ wxString wxNotebook::GetPageText(int nPage) const { wxASSERT( IS_VALID_PAGE(nPage) ); - // TODO - return wxString(""); + wxNotebookPage* page = ((wxNotebook*)this)->GetPage(nPage); + if (page) + return m_tabView->GetTabText((int) (long) page); + else + return wxEmptyString; } int wxNotebook::GetPageImage(int nPage) const @@ -189,23 +209,117 @@ void wxNotebook::SetImageList(wxImageList* imageList) // wxNotebook operations // ---------------------------------------------------------------------------- -// remove one page from the notebook +// remove one page from the notebook and delete it bool wxNotebook::DeletePage(int nPage) { wxCHECK( IS_VALID_PAGE(nPage), FALSE ); - // TODO: delete native widget page + if (m_nSelection != -1) + { + m_aPages[m_nSelection]->Show(FALSE); + m_aPages[m_nSelection]->Lower(); + } + + wxNotebookPage* pPage = GetPage(nPage); + m_tabView->RemoveTab((int) (long) pPage); delete m_aPages[nPage]; m_aPages.Remove(nPage); + if (m_aPages.GetCount() == 0) + { + m_nSelection = -1; + m_tabView->SetTabSelection(-1, FALSE); + } + else if (m_nSelection > -1) + { + m_nSelection = -1; + m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE); + if (m_nSelection != 0) + ChangePage(-1, 0); + } + + RefreshLayout(FALSE); + + return TRUE; +} + +bool wxNotebook::DeletePage(wxNotebookPage* page) +{ + int pagePos = FindPagePosition(page); + if (pagePos > -1) + return DeletePage(pagePos); + else + return FALSE; +} + +// remove one page from the notebook +bool wxNotebook::RemovePage(int nPage) +{ + wxCHECK( IS_VALID_PAGE(nPage), FALSE ); + + m_aPages[nPage]->Show(FALSE); + // m_aPages[nPage]->Lower(); + + wxNotebookPage* pPage = GetPage(nPage); + m_tabView->RemoveTab((int) (long) pPage); + + m_aPages.Remove(nPage); + + if (m_aPages.GetCount() == 0) + { + m_nSelection = -1; + m_tabView->SetTabSelection(-1, TRUE); + } + else if (m_nSelection > -1) + { + // Only change the selection if the page we + // deleted was the selection. + if (nPage == m_nSelection) + { + m_nSelection = -1; + // Select the first tab. Generates a ChangePage. + m_tabView->SetTabSelection((int) (long) GetPage(0), TRUE); + } + else + { + // We must adjust which tab we think is selected. + // If greater than the page we deleted, it must be moved down + // a notch. + if (m_nSelection > nPage) + m_nSelection -- ; + } + } + + RefreshLayout(FALSE); + return TRUE; } +bool wxNotebook::RemovePage(wxNotebookPage* page) +{ + int pagePos = FindPagePosition(page); + if (pagePos > -1) + return RemovePage(pagePos); + else + return FALSE; +} + +// Find the position of the wxNotebookPage, -1 if not found. +int wxNotebook::FindPagePosition(wxNotebookPage* page) const +{ + int nPageCount = GetPageCount(); + int nPage; + for ( nPage = 0; nPage < nPageCount; nPage++ ) + if (m_aPages[nPage] == page) + return nPage; + return -1; +} + // remove all pages bool wxNotebook::DeleteAllPages() { - // TODO: delete native widget pages + m_tabView->ClearTabs(TRUE); int nPageCount = GetPageCount(); int nPage; @@ -236,17 +350,25 @@ bool wxNotebook::InsertPage(int nPage, wxASSERT( pPage != NULL ); wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE ); - // TODO: insert native widget page + m_tabView->AddTab((int) (long) pPage, strText); + if (!bSelect) + pPage->Show(FALSE); // save the pointer to the page m_aPages.Insert(pPage, nPage); - // some page must be selected: either this one or the first one if there is + if (bSelect) + { + // This will cause ChangePage to be called, via OnSelPage + m_tabView->SetTabSelection((int) (long) pPage, TRUE); + } + + // some page must be selected: either this one or the first one if there is // still no selection - if ( bSelect ) - m_nSelection = nPage; - else if ( m_nSelection == -1 ) - m_nSelection = 0; + if ( m_nSelection == -1 ) + ChangePage(-1, 0); + + RefreshLayout(FALSE); return TRUE; } @@ -265,35 +387,103 @@ void wxNotebook::OnSize(wxSizeEvent& event) s_bFirstTime = FALSE; } - // TODO: all this may or may not be necessary for your platform - - // emulate page change (it's esp. important to do it first time because - // otherwise our page would stay invisible) - int nSel = m_nSelection; - m_nSelection = -1; - SetSelection(nSel); - - // fit the notebook page to the tab control's display area - int w, h; - GetSize(&w, &h); - - unsigned int nCount = m_aPages.Count(); - for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) { - wxNotebookPage *pPage = m_aPages[nPage]; - pPage->SetSize(0, 0, w, h); - if ( pPage->GetAutoLayout() ) - pPage->Layout(); - } + RefreshLayout(); // Processing continues to next OnSize event.Skip(); } +// This was supposed to cure the non-display of the notebook +// until the user resizes the window. +// What's going on? +void wxNotebook::OnIdle(wxIdleEvent& event) +{ + static bool s_bFirstTime = TRUE; + if ( s_bFirstTime ) { + /* + wxSize sz(GetSize()); + sz.x ++; + SetSize(sz); + sz.x --; + SetSize(sz); + */ + + /* + wxSize sz(GetSize()); + wxSizeEvent sizeEvent(sz, GetId()); + sizeEvent.SetEventObject(this); + GetEventHandler()->ProcessEvent(sizeEvent); + Refresh(); + */ + s_bFirstTime = FALSE; + } + event.Skip(); +} + +// Implementation: calculate the layout of the view rect +// and resize the children if required +bool wxNotebook::RefreshLayout(bool force) +{ + if (m_tabView) + { + wxRect oldRect = m_tabView->GetViewRect(); + + int cw, ch; + GetClientSize(& cw, & ch); + + int tabHeight = m_tabView->GetTotalTabHeight(); + wxRect rect; + rect.x = 4; + rect.y = tabHeight + 4; + rect.width = cw - 8; + rect.height = ch - 4 - rect.y ; + + m_tabView->SetViewRect(rect); + + m_tabView->Layout(); + + // Need to do it a 2nd time to get the tab height with + // the new view width, since changing the view width changes the + // tab layout. + tabHeight = m_tabView->GetTotalTabHeight(); + rect.x = 4; + rect.y = tabHeight + 4; + rect.width = cw - 8; + rect.height = ch - 4 - rect.y ; + + m_tabView->SetViewRect(rect); + + m_tabView->Layout(); + + if (!force && (rect == oldRect)) + return FALSE; + + // fit the notebook page to the tab control's display area + + unsigned int nCount = m_aPages.Count(); + for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) { + wxNotebookPage *pPage = m_aPages[nPage]; + if (pPage->IsShown()) + { + wxRect clientRect = GetAvailableClientSize(); + pPage->SetSize(clientRect.x, clientRect.y, clientRect.width, clientRect.height); + if ( pPage->GetAutoLayout() ) + pPage->Layout(); + } + } + Refresh(); + } + return TRUE; +} + void wxNotebook::OnSelChange(wxNotebookEvent& event) { // is it our tab control? if ( event.GetEventObject() == this ) - ChangePage(event.GetOldSelection(), event.GetSelection()); + { + if (event.GetSelection() != m_nSelection) + ChangePage(event.GetOldSelection(), event.GetSelection()); + } // we want to give others a chance to process this message as well event.Skip(); @@ -352,31 +542,112 @@ void wxNotebook::Command(wxCommandEvent& event) // hide the currently active panel and show the new one void wxNotebook::ChangePage(int nOldSel, int nSel) { + // cout << "ChangePage: " << nOldSel << ", " << nSel << "\n"; wxASSERT( nOldSel != nSel ); // impossible if ( nOldSel != -1 ) { m_aPages[nOldSel]->Show(FALSE); + m_aPages[nOldSel]->Lower(); } wxNotebookPage *pPage = m_aPages[nSel]; + + wxRect clientRect = GetAvailableClientSize(); + pPage->SetSize(clientRect.x, clientRect.y, clientRect.width, clientRect.height); + pPage->Show(TRUE); + pPage->Raise(); pPage->SetFocus(); + Refresh(); + m_nSelection = nSel; } -void wxNotebook::ChangeFont() +void wxNotebook::ChangeFont(bool keepOriginalSize) { - // TODO + wxWindow::ChangeFont(keepOriginalSize); } void wxNotebook::ChangeBackgroundColour() { - // TODO + wxWindow::ChangeBackgroundColour(); } void wxNotebook::ChangeForegroundColour() { - // TODO + wxWindow::ChangeForegroundColour(); +} + +void wxNotebook::OnMouseEvent(wxMouseEvent& event) +{ + if (m_tabView) + m_tabView->OnEvent(event); } +void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event) ) +{ + wxPaintDC dc(this); + if (m_tabView) + m_tabView->Draw(dc); +} + +wxRect wxNotebook::GetAvailableClientSize() +{ + int cw, ch; + GetClientSize(& cw, & ch); + + int tabHeight = m_tabView->GetTotalTabHeight(); + + // TODO: these margins should be configurable. + wxRect rect; + rect.x = 6; + rect.y = tabHeight + 6; + rect.width = cw - 12; + rect.height = ch - 4 - rect.y ; + + return rect; +} + +/* + * wxNotebookTabView + */ + +IMPLEMENT_CLASS(wxNotebookTabView, wxTabView) + +wxNotebookTabView::wxNotebookTabView(wxNotebook *notebook, long style): wxTabView(style) +{ + m_notebook = notebook; + + m_notebook->SetTabView(this); + + SetWindow(m_notebook); +} + +wxNotebookTabView::~wxNotebookTabView(void) +{ +} + +// Called when a tab is activated +void wxNotebookTabView::OnTabActivate(int activateId, int deactivateId) +{ + if (!m_notebook) + return; + + wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_notebook->GetId()); + + // Translate from wxTabView's ids (which aren't position-dependent) + // to wxNotebook's (which are). + wxNotebookPage* pActive = (wxNotebookPage*) activateId; + wxNotebookPage* pDeactive = (wxNotebookPage*) deactivateId; + + int activatePos = m_notebook->FindPagePosition(pActive); + int deactivatePos = m_notebook->FindPagePosition(pDeactive); + + event.SetEventObject(m_notebook); + event.SetSelection(activatePos); + event.SetOldSelection(deactivatePos); + m_notebook->GetEventHandler()->ProcessEvent(event); +} + +