📄 wxflatnotebook.cpp
字号:
int iLastVisiblePage = GetLastVisibleTab(); return iPage <= iLastVisiblePage && iPage >= m_nFrom;}void wxPageContainer::DoDeletePage(size_t page){ // Remove the page from the vector wxFlatNotebook* book = (wxFlatNotebook*)GetParent(); m_pagesInfoVec.RemoveAt(page); // Thanks to Yiaanis AKA Mandrav if (m_iActivePage >= (int)page) { m_iActivePage--; m_iPreviousActivePage = -1; } // The delete page was the last first on the array, // but the book still has more pages, so we set the // active page to be the first one (0) if(m_iActivePage < 0 && !m_pagesInfoVec.empty()) { m_iPreviousActivePage = -1; m_iActivePage = 0; } // Refresh the tabs if(m_iActivePage >= 0) { book->m_bForceSelection = true; book->SetSelection(m_iActivePage); book->m_bForceSelection = false; } if(m_pagesInfoVec.empty()) { // Erase the page container drawings wxClientDC dc(this); dc.Clear(); }}void wxPageContainer::DeleteAllPages(){ m_iActivePage = -1; m_iPreviousActivePage = -1; m_nFrom = 0; m_pagesInfoVec.Clear(); // Erase the page container drawings wxClientDC dc(this); dc.Clear();}void wxPageContainer::OnMouseMove(wxMouseEvent& event){ if (!m_pagesInfoVec.empty() && IsShown()) { const int xButtonStatus = m_nXButtonStatus; const int xTabButtonStatus = m_nTabXButtonStatus; const int rightButtonStatus = m_nRightButtonStatus; const int leftButtonStatus = m_nLeftButtonStatus; const int dropDownButtonStatus = m_nArrowDownButtonStatus; long style = GetParent()->GetWindowStyleFlag(); m_nXButtonStatus = wxFNB_BTN_NONE; m_nRightButtonStatus = wxFNB_BTN_NONE; m_nLeftButtonStatus = wxFNB_BTN_NONE; m_nTabXButtonStatus = wxFNB_BTN_NONE; m_nArrowDownButtonStatus = wxFNB_BTN_NONE; wxPageInfo pgInfo; int tabIdx; int where = HitTest(event.GetPosition(), pgInfo, tabIdx); switch ( where ) { case wxFNB_X: if (event.LeftIsDown()) { m_nXButtonStatus = (m_nLeftClickZone==wxFNB_X) ? wxFNB_BTN_PRESSED : wxFNB_BTN_NONE; } else { m_nXButtonStatus = wxFNB_BTN_HOVER; } break; case wxFNB_DROP_DOWN_ARROW: if (event.LeftIsDown()) { m_nArrowDownButtonStatus = (m_nLeftClickZone == wxFNB_DROP_DOWN_ARROW) ? wxFNB_BTN_PRESSED : wxFNB_BTN_NONE; } else { m_nArrowDownButtonStatus = wxFNB_BTN_HOVER; } break; case wxFNB_TAB_X: if (event.LeftIsDown()) { m_nTabXButtonStatus = (m_nLeftClickZone==wxFNB_TAB_X) ? wxFNB_BTN_PRESSED : wxFNB_BTN_NONE; } else { m_nTabXButtonStatus = wxFNB_BTN_HOVER; } break; case wxFNB_RIGHT_ARROW: if (event.LeftIsDown()) { m_nRightButtonStatus = (m_nLeftClickZone==wxFNB_RIGHT_ARROW) ? wxFNB_BTN_PRESSED : wxFNB_BTN_NONE; } else { m_nRightButtonStatus = wxFNB_BTN_HOVER; } break; case wxFNB_LEFT_ARROW: if (event.LeftIsDown()) { m_nLeftButtonStatus = (m_nLeftClickZone==wxFNB_LEFT_ARROW) ? wxFNB_BTN_PRESSED : wxFNB_BTN_NONE; } else { m_nLeftButtonStatus = wxFNB_BTN_HOVER; } break; case wxFNB_TAB: // Call virtual method for showing tooltip ShowTabTooltip(tabIdx); if(!GetEnabled((size_t)tabIdx)) { // Set the cursor to be 'No-entry' ::wxSetCursor(wxCURSOR_NO_ENTRY); } // Support for drag and drop if(event.Dragging() && !(style & wxFNB_NODRAG)) { wxFNBDragInfo draginfo(this, tabIdx); wxFNBDragInfoDataObject dataobject(wxDataFormat(wxT("wxFNB"))); dataobject.SetData(sizeof(wxFNBDragInfo), &draginfo); wxFNBDropSource dragSource(this); dragSource.SetData(dataobject); dragSource.DoDragDrop(wxDrag_DefaultMove); } break; default: m_nTabXButtonStatus = wxFNB_BTN_NONE; break; } const bool bRedrawX = m_nXButtonStatus != xButtonStatus; const bool bRedrawDropArrow = m_nArrowDownButtonStatus != dropDownButtonStatus; const bool bRedrawRight = m_nRightButtonStatus != rightButtonStatus; const bool bRedrawLeft = m_nLeftButtonStatus != leftButtonStatus; const bool bRedrawTabX = m_nTabXButtonStatus != xTabButtonStatus; wxFNBRendererPtr render = wxFNBRendererMgrST::Get()->GetRenderer( GetParent()->GetWindowStyleFlag() ); if (bRedrawX || bRedrawRight || bRedrawLeft || bRedrawTabX || bRedrawDropArrow) { wxClientDC dc(this); if (bRedrawX) { render->DrawX(this, dc); } if (bRedrawLeft) { render->DrawLeftArrow(this, dc); } if (bRedrawRight) { render->DrawRightArrow(this, dc); } if (bRedrawTabX) { FNB_LOG_MSG( wxT("Refreshing Tab 'X' button with status=") << m_nTabXButtonStatus << wxT(" and tabIdx=") << tabIdx ); render->DrawTabX(this, dc, pgInfo.GetXRect(), tabIdx, m_nTabXButtonStatus); } if (bRedrawDropArrow) { render->DrawDropDownArrow(this, dc); } } } event.Skip();}int wxPageContainer::GetLastVisibleTab(){ int i; if( m_nFrom < 0) return -1; for(i=m_nFrom; i<(int)m_pagesInfoVec.GetCount(); i++) { if(m_pagesInfoVec[i].GetPosition() == wxPoint(-1, -1)) break; } return (i-1);}int wxPageContainer::GetNumTabsCanScrollLeft(){ int i; // Reserved area for the buttons (<>x) wxRect rect = GetClientRect(); int clientWidth = rect.width; int posx = ((wxFlatNotebook *)m_pParent)->m_nPadding, numTabs = 0, tabHeight, tabWidth; wxClientDC dc(this); // Incase we have error prevent crash if(m_nFrom < 0) return 0; long style = GetParent()->GetWindowStyleFlag(); wxFNBRendererPtr render = wxFNBRendererMgrST::Get()->GetRenderer(style); tabHeight = render->CalcTabHeight(this); for(i=m_nFrom; i>=0; i--) { tabWidth = render->CalcTabWidth(this, i, tabHeight); if(posx + tabWidth + render->GetButtonsAreaLength(this) >= clientWidth) break; numTabs++; posx += tabWidth; } return numTabs;}bool wxPageContainer::IsDefaultTabs(){ long style = GetParent()->GetWindowStyleFlag(); bool res = (style & wxFNB_VC71) || (style & wxFNB_FANCY_TABS) || (style & wxFNB_VC8); return !res;}void wxPageContainer::AdvanceSelection(bool bForward){ int nSel = GetSelection(); if(nSel < 0) return; int nMax = (int)GetPageCount() - 1; if ( bForward ) SetSelection(nSel == nMax ? 0 : nSel + 1); else SetSelection(nSel == 0 ? nMax : nSel - 1);}void wxPageContainer::OnMouseLeave(wxMouseEvent& event){ m_nLeftButtonStatus = wxFNB_BTN_NONE; m_nXButtonStatus = wxFNB_BTN_NONE; m_nRightButtonStatus = wxFNB_BTN_NONE; m_nTabXButtonStatus = wxFNB_BTN_NONE; m_nArrowDownButtonStatus = wxFNB_BTN_NONE; long style = GetParent()->GetWindowStyleFlag(); wxFNBRendererPtr render = wxFNBRendererMgrST::Get()->GetRenderer(style); wxClientDC dc(this); render->DrawX(this, dc); render->DrawLeftArrow(this, dc); render->DrawRightArrow(this, dc); if(GetSelection() != -1 && IsTabVisible((size_t)GetSelection())) { render->DrawTabX(this, dc, m_pagesInfoVec[GetSelection()].GetXRect(), GetSelection(), m_nTabXButtonStatus); } event.Skip();}void wxPageContainer::OnMouseEnterWindow(wxMouseEvent& event){ m_nLeftButtonStatus = wxFNB_BTN_NONE; m_nXButtonStatus = wxFNB_BTN_NONE; m_nRightButtonStatus = wxFNB_BTN_NONE; m_nLeftClickZone = wxFNB_BTN_NONE; m_nArrowDownButtonStatus = wxFNB_BTN_NONE; event.Skip();}void wxPageContainer::ShowTabTooltip(int tabIdx){ wxWindow *pWindow = ((wxFlatNotebook *)m_pParent)->GetPage(tabIdx); if( pWindow ) { wxString label(pWindow->GetLabel()); if (! label.IsEmpty()) { SetToolTip(label); } }}void wxPageContainer::SetPageImageIndex(size_t page, int imgindex){ if(page < m_pagesInfoVec.GetCount()) { m_pagesInfoVec[page].SetImageIndex(imgindex); Refresh(); }}int wxPageContainer::GetPageImageIndex(size_t page){ if(page < m_pagesInfoVec.GetCount()) { return m_pagesInfoVec[page].GetImageIndex(); } return -1;}wxDragResult wxPageContainer::OnDropTarget(wxCoord x, wxCoord y, int nTabPage, wxWindow * wnd_oldContainer){ // Disable drag'n'drop for disabled tab if(!((wxPageContainer *)wnd_oldContainer)->m_pagesInfoVec[nTabPage].GetEnabled()) return wxDragCancel; wxLogTrace(wxTraceMask(), _("Old Page Index = %i"), nTabPage); wxPageContainer * oldContainer = (wxPageContainer *)wnd_oldContainer; int nIndex = -1; wxPageInfo pgInfo; int where = HitTest(wxPoint(x, y), pgInfo, nIndex); wxLogTrace(wxTraceMask(), _("OnDropTarget: index by HitTest = %i"), nIndex); wxFlatNotebook * oldNotebook = (wxFlatNotebook *)oldContainer->GetParent(); wxFlatNotebook * newNotebook = (wxFlatNotebook *)GetParent(); if(oldNotebook == newNotebook) { if(nTabPage >= 0) { switch(where) { case wxFNB_TAB: MoveTabPage(nTabPage, nIndex); break; case wxFNB_NOWHERE: { } break; default: break; } } } else if ( GetParent()->GetWindowStyleFlag() & wxFNB_ALLOW_FOREIGN_DND ) {#if defined(__WXMSW__) || defined(__WXGTK__) if(nTabPage >= 0) { wxWindow * window = oldNotebook->GetPage(nTabPage); if(window) { wxString caption = oldContainer->GetPageText(nTabPage); // Pass the image to the new container // incase that the new container (this) does not have image list we dont pass the image // to the new notebook int newIndx( wxNOT_FOUND ); if( m_ImageList ) { int imageindex = oldContainer->GetPageImageIndex(nTabPage); if( imageindex >= 0 ) { wxBitmap bmp( (*oldContainer->GetImageList())[imageindex] ); m_ImageList->Add( bmp ); newIndx = static_cast<int>(m_ImageList->GetCount() - 1); } } oldNotebook->RemovePage( nTabPage ); window->Reparent( newNotebook ); newNotebook->InsertPage(nIndex, window, caption, true, newIndx); } }#endif } return wxDragMove;}void wxPageContainer::MoveTabPage(int nMove, int nMoveTo){ if(nMove == nMoveTo) return; else if(nMoveTo < (int)((wxFlatNotebook *)m_pParent)->m_windows.GetCount()) nMoveTo++; m_pParent->Freeze(); // Remove the window from the main sizer int nCurSel = ((wxFlatNotebook *)m_pParent)->m_pages->GetSelection(); ((wxFlatNotebook *)m_pParent)->m_mainSizer->Detach(((wxFlatNotebook *)m_pParent)->m_windows[nCurSel]); ((wxFlatNotebook *)m_pParent)->m_windows[nCurSel]->Hide(); wxWindow *pWindow = ((wxFlatNotebook *)m_pParent)->m_windows[nMove]; ((wxFlatNotebook *)m_pParent)->m_windows.RemoveAt(nMove); ((wxFlatNotebook *)m_pParent)->m_windows.Insert(pWindow, nMoveTo-1); wxPageInfo pgInfo = m_pagesInfoVec[nMove]; m_pagesInfoVec.RemoveAt( nMove ); m_pagesInfoVec.Insert(pgInfo, nMoveTo - 1); // Add the page according to the style wxBoxSizer* pSizer = ((wxFlatNotebook *)m_pParent)->m_mainSizer; long style = GetParent()->GetWindowStyleFlag(); if(style & wxFNB_BOTTOM) { pSizer->Insert(0, pWindow, 1, wxEXPAND); } else { // We leave a space of 1 pixel around the window pSizer->Add(pWindow, 1, wxEXPAND); } pWindow->Show(); pSizer->Layout(); m_iActivePage = nMoveTo-1; m_iPreviousActivePage = -1; DoSetSelection(m_iActivePage); Refresh(); m_pParent->Thaw();}bool wxPageContainer::CanFitToScreen(size_t page){ // Incase the from is greater than page, // we need to reset the m_nFrom, so in order // to force the caller to do so, we return false if(m_nFrom > (int)page) return false; long style = GetParent()->GetWindowStyleFlag(); wxFNBRendererPtr render = wxFNBRendererMgrST::Get()->GetRenderer(style); std::vector<wxRect> vTabInfo; render->NumberTabsCanFit( this, vTabInfo ); if(static_cast<int>(page) - m_nFrom >= static_cast<int>( vTabInfo.size() )) return false; return true;}int wxPageContainer::GetNumOfVisibleTabs(){ int i=m_nFrom; int counter = 0; for(; i<(int)m_pagesInfoVec.GetCount(); i++, ++counter) { if(m_pagesInfoVec[i].GetPosition() == wxPoint(-1, -1)) break; } return counter;}bool wxPageContainer::GetEnabled(size_t page){ if(page >= m_pagesInfoVec.GetCount()) return true; // Seems strange, but this is the default return m_pagesInfoVec[page].GetEnabled();}void wxPageContainer::Enable(size_t page, bool enabled){ if(page >= m_pagesInfoVec.GetCount()) return ; m_pagesInfoVec[page].Enable(enabled); return;}wxColor wxPageContainer::GetSingleLineBorderColor(){ if(HasFlag(wxFNB_FANCY_TABS)) return m_colorFrom; return *wxWHITE;}bool wxPageContainer::HasFlag(int flag){ long style = GetParent()->GetWindowStyleFlag(); bool res = style & flag ? true : false; return res;}void wxPageContainer::ClearFlag(int flag){ long style = GetParent()->GetWindowStyleFlag(); style &= ~( flag ); wxWindowBase::SetWindowStyleFlag(style);}bool wxPageContainer::TabHasImage(int tabIdx){ if(m_ImageList) return m_pagesInfoVec[tabIdx].GetImageIndex() != -1; return false;}void wxPageContainer::OnLeftDClick(wxMouseEvent& event){ wxPageInfo pgInfo; int tabIdx; int where = HitTest(event.GetPosition(), pgInfo, tabIdx); switch(where) { case wxFNB_TAB: if(HasFlag(wxFNB_DCLICK_CLOSES_TABS)) { { DeletePage((size_t)tabIdx); break; } } case wxFNB_X: { OnLeftDown(event); break; } default: event.Skip(); break; }}void wxPageContainer::PopupTabsMenu(){ wxMenu popupMenu; for(size_t i=0; i<m_pagesInfoVec.GetCount(); i++) { wxPageInfo pi = m_pagesInfoVec[i]; wxMenuItem *item = new wxMenuItem(&popupMenu, static_cast<int>(i), pi.GetCaption(), pi.GetCaption(), wxITEM_NORMAL); // This code is commented, since there is an alignment problem with wx2.6.3 & Menus// if( TabHasImage(static_cast<int>(i)) )// item->SetBitmaps( (*m_ImageList)[pi.GetImageIndex()] ); popupMenu.Append( item ); } // connect an event handler to our menu popupMenu.Connect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxPageContainer::OnTabMenuSelection), NULL, this); PopupMenu( &popupMenu );}void wxPageContainer::OnTabMenuSelection(wxCommandEvent &event){ int selection = event.GetId(); static_cast<wxFlatNotebook*>(m_pParent)->SetSelection( (size_t)selection );}// Draw small arrow at the place that the tab will be placedvoid wxPageContainer::DrawDragHint(){ // get the index of tab that will be replaced with the dragged tab wxPageInfo info; int tabIdx; wxPoint pt = ::wxGetMousePosition(); wxPoint client_pt = ScreenToClient(pt); HitTest(client_pt, info, tabIdx); wxFNBRendererMgrST::Get()->GetRenderer( GetParent()->GetWindowStyleFlag() )->DrawDragHint(this, tabIdx);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -