📄 wxflatnotebook.cpp
字号:
///////////////////////////////////////////////////////////////////////////////// Name: wxFlatNotebook.cpp // Purpose: generic implementation of flat style notebook class.// Author: Eran Ifrah <eranif@bezeqint.net>// Modified by: Priyank Bolia <soft@priyank.in>// Created: 30/12/2005// Modified: 01/01/2006// Copyright: Eran Ifrah (c)// Licence: wxWindows license <http://www.wxwidgets.org/licence3.txt>///////////////////////////////////////////////////////////////////////////////#include <wx/wxflatnotebook/wxflatnotebook.h>#include <wx/wxflatnotebook/renderer.h>#include <wx/wxflatnotebook/popup_dlg.h>#include <algorithm>#include <wx/tooltip.h>#include <wx/tipwin.h>#include <wx/arrimpl.cpp>#ifdef DEVELOPMENT# define FNB_LOG_MSG( msg ) { wxString logmsg; logmsg << msg; wxLogMessage( logmsg ); }#else# define FNB_LOG_MSG( msg ) { wxString logmsg; logmsg << msg; }#endif#ifdef DEVELOPMENT#include <map>wxString WhereToString( int where ){ static std::map<int, wxString> whereMap; static bool first = true; if( first ) { whereMap[wxFNB_TAB] = wxT("wxFNB_TAB"); whereMap[wxFNB_X] = wxT("wxFNB_X"); whereMap[wxFNB_TAB_X] = wxT("wxFNB_TAB_X"); whereMap[wxFNB_LEFT_ARROW] = wxT("wxFNB_LEFT_ARROW"); whereMap[wxFNB_RIGHT_ARROW] = wxT("wxFNB_RIGHT_ARROW"); whereMap[wxFNB_DROP_DOWN_ARROW] = wxT("wxFNB_DROP_DOWN_ARROW"); whereMap[wxFNB_NOWHERE] = wxT("wxFNB_NOWHERE"); first = false; } return whereMap[where];}#endif //-------------------------------------------------------------------// Provide user with a nice feedback when tab is being dragged//-------------------------------------------------------------------bool wxFNBDropSource::GiveFeedback(wxDragResult effect){ wxUnusedVar(effect); static_cast<wxPageContainer*>( m_win )->DrawDragHint(); return false;}IMPLEMENT_DYNAMIC_CLASS(wxFlatNotebookEvent, wxNotifyEvent)DEFINE_EVENT_TYPE(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGED)DEFINE_EVENT_TYPE(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGING)DEFINE_EVENT_TYPE(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSING)DEFINE_EVENT_TYPE(wxEVT_COMMAND_FLATNOTEBOOK_CONTEXT_MENU)DEFINE_EVENT_TYPE(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSED)IMPLEMENT_DYNAMIC_CLASS(wxFlatNotebook, wxPanel)WX_DEFINE_OBJARRAY(wxFlatNotebookImageList);WX_DEFINE_OBJARRAY(wxPageInfoArray)WX_DEFINE_OBJARRAY(wxWindowPtrArray)BEGIN_EVENT_TABLE(wxFlatNotebook, wxPanel)EVT_NAVIGATION_KEY(wxFlatNotebook::OnNavigationKey)END_EVENT_TABLE()wxFlatNotebook::wxFlatNotebook(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name): m_popupWin(NULL), m_sendPageChangeEvent(true){ m_bForceSelection = false; m_nPadding = 6; m_nFrom = 0; style |= wxTAB_TRAVERSAL; m_pages = NULL; wxPanel::Create(parent, id, pos, size, style, name); m_pages = new wxPageContainer(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style); Init();}wxFlatNotebook::~wxFlatNotebook(void){}void wxFlatNotebook::Init(){ m_pages->m_colorBorder = wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW)); m_mainSizer = new wxBoxSizer(wxVERTICAL); SetSizer(m_mainSizer); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE)); // Set default page height wxMemoryDC memDc; wxBitmap bmp(10, 10); memDc.SelectObject(bmp); int width, height;#ifdef __WXGTK__ // For GTK it seems that we must do this steps in order // for the tabs will get the proper height on initialization // on MSW, preforming these steps yields wierd results wxFont normalFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont boldFont = normalFont; boldFont.SetWeight(wxFONTWEIGHT_BOLD); memDc.SetFont( boldFont );#endif wxString stam = wxT("Tp"); // Temp data to get the text height; memDc.GetTextExtent(stam, &width, &height); int tabHeight = height + wxFNB_HEIGHT_SPACER; // We use 8 pixels as padding#ifdef __WXGTK__ // On GTK the tabs are should be larger tabHeight += 6;#endif m_pages->SetSizeHints(wxSize(-1, tabHeight)); // Add the tab container to the sizer m_mainSizer->Insert(0, m_pages, 0, wxEXPAND); m_mainSizer->Layout(); m_pages->m_nFrom = m_nFrom; m_pDropTarget = new wxFNBDropTarget<wxFlatNotebook>(this, &wxFlatNotebook::OnDropTarget); SetDropTarget(m_pDropTarget);}void wxFlatNotebook::SetActiveTabTextColour(const wxColour& textColour){ m_pages->m_activeTextColor = textColour;}wxDragResult wxFlatNotebook::OnDropTarget(wxCoord x, wxCoord y, int nTabPage, wxWindow * wnd_oldContainer){ return m_pages->OnDropTarget(x, y, nTabPage, wnd_oldContainer);}int wxFlatNotebook::GetPreviousSelection() const{ return m_pages->m_iPreviousActivePage;}bool wxFlatNotebook::AddPage(wxWindow* window, const wxString& caption, const bool selected, const int imgindex){ return InsertPage(m_windows.GetCount(), window, caption, selected, imgindex);}void wxFlatNotebook::SetImageList(wxFlatNotebookImageList * imglist){ m_pages->SetImageList(imglist);}wxFlatNotebookImageList * wxFlatNotebook::GetImageList(){ return m_pages->GetImageList();}bool wxFlatNotebook::InsertPage(size_t index, wxWindow* page, const wxString& text, bool select, const int imgindex){ // sanity check if (!page) return false; // reparent the window to us page->Reparent(this); if( !m_pages->IsShown() ) m_pages->Show(); index = FNB_MIN((unsigned int)index, (unsigned int)m_windows.GetCount()); // Insert tab bool bSelected = select || m_windows.empty(); int curSel = m_pages->GetSelection(); if(index <= m_windows.GetCount()) { m_windows.Insert(page, index); wxLogTrace(wxTraceMask(), wxT("New page inserted. Index = %i"), index); } else { m_windows.Add(page); wxLogTrace(wxTraceMask(), wxT("New page appended. Index = %i"), index); } if( !m_pages->InsertPage(index, page, text, bSelected, imgindex) ) return false; if((int)index <= curSel) curSel++; Freeze(); // Check if a new selection was made if(bSelected) { if(curSel >= 0) { // Remove the window from the main sizer m_mainSizer->Detach(m_windows[curSel]); m_windows[curSel]->Hide(); } m_pages->SetSelection(index); } else { // Hide the page page->Hide(); } m_mainSizer->Layout(); Thaw(); Refresh(); return true;}void wxFlatNotebook::SetSelection(size_t page){ if(page >= m_windows.GetCount()) return; // Support for disabed tabs if(!m_pages->GetEnabled(page) && m_windows.GetCount() > 1 && !m_bForceSelection) return; if( m_sendPageChangeEvent ) { // Allow the user to veto the selection int oldSelection = GetSelection(); wxFlatNotebookEvent event(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGING, GetId()); event.SetSelection( (int)page ); event.SetOldSelection( oldSelection ); event.SetEventObject( this ); if( !event.IsAllowed() ) { return; } } int curSel = m_pages->GetSelection(); // program allows the page change Freeze(); if(curSel >= 0) { // Remove the window from the main sizer m_mainSizer->Detach(m_windows[curSel]); m_windows[curSel]->Hide(); } if(m_windowStyle & wxFNB_BOTTOM) { m_mainSizer->Insert(0, m_windows[page], 1, wxEXPAND); } else { // We leave a space of 1 pixel around the window m_mainSizer->Add(m_windows[page], 1, wxEXPAND); } m_windows[page]->Show(); Thaw(); m_mainSizer->Layout(); if( page != (size_t)m_pages->m_iActivePage ) //there is a real poge changing m_pages->m_iPreviousActivePage = m_pages->m_iActivePage; m_pages->m_iActivePage = (int)page; m_pages->DoSetSelection(page); if( m_sendPageChangeEvent ) { // Fire event 'Page Changed' wxFlatNotebookEvent event(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGED, GetId()); event.SetSelection( (int)page ); event.SetEventObject( this ); GetEventHandler()->ProcessEvent(event); }}void wxFlatNotebook::DeletePage(size_t page, bool notify){ if(page >= m_windows.GetCount()) return; // Fire a closing event if( notify ) { wxFlatNotebookEvent event(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSING, GetId()); event.SetSelection((int)page); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); // The event handler allows it? if (!event.IsAllowed()) return; } Freeze(); // Delete the requested page wxWindow *pageRemoved = m_windows[page]; // If the page is the current window, remove it from the sizer // as well if((int)page == m_pages->GetSelection()) { m_mainSizer->Detach(pageRemoved); } // Remove it from the array as well m_windows.RemoveAt(page); // Now we can destroy it; in wxWidgets use Destroy instead of delete pageRemoved->Destroy(); Thaw(); m_pages->DoDeletePage(page); Refresh(); // Fire a closed event if( notify ) { wxFlatNotebookEvent closedEvent(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSED, GetId()); closedEvent.SetSelection((int)page); closedEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(closedEvent); }}bool wxFlatNotebook::DeleteAllPages(){ if(m_windows.empty()) return false; Freeze(); int i = 0; for(; i<(int)m_windows.GetCount(); i++) { delete m_windows[i]; } m_windows.Clear(); Thaw(); // Clear the container of the tabs as well m_pages->DeleteAllPages(); return true;}wxWindow* wxFlatNotebook::GetCurrentPage() const{ int sel = m_pages->GetSelection(); if(sel < 0) return NULL; return m_windows[sel];}wxWindow* wxFlatNotebook::GetPage(size_t page) const{ if(page >= m_windows.GetCount()) return NULL; return m_windows[page];}int wxFlatNotebook::GetPageIndex(wxWindow* win) const{ for (size_t i = 0; i < m_windows.GetCount(); ++i) { if (m_windows[i] == win) return (int)i; } return -1;}int wxFlatNotebook::GetSelection() const{ return m_pages->GetSelection();}void wxFlatNotebook::AdvanceSelection(bool bForward){ m_pages->AdvanceSelection(bForward);}int wxFlatNotebook::GetPageCount() const{ return (int)m_pages->GetPageCount();}void wxFlatNotebook::OnNavigationKey(wxNavigationKeyEvent& event){ if ( event.IsWindowChange() ) { if( HasFlag(wxFNB_SMART_TABS) ) { if( !m_popupWin ) { m_popupWin = new wxTabNavigatorWindow( this ); m_popupWin->ShowModal(); m_popupWin->Destroy(); m_popupWin = NULL; } else { // a dialog is already opened m_popupWin->OnNavigationKey( event ); return; } } else { // change pages AdvanceSelection(event.GetDirection()); } } else { // pass to the parent if ( GetParent() ) { event.SetCurrentFocus(this); GetParent()->ProcessEvent(event); } }}bool wxFlatNotebook::GetPageShapeAngle(int page_index, unsigned int * result){ if(page_index < 0 || page_index >= (int)m_pages->m_pagesInfoVec.GetCount()) return false; *result = m_pages->m_pagesInfoVec[page_index].GetTabAngle(); return true;}void wxFlatNotebook::SetPageShapeAngle(int page_index, unsigned int angle){ if(page_index < 0 || page_index >= (int)m_pages->m_pagesInfoVec.GetCount()) return; if(angle > 15) return; m_pages->m_pagesInfoVec[page_index].SetTabAngle(angle);}void wxFlatNotebook::SetAllPagesShapeAngle(unsigned int angle){ if(angle > 15) return; for(unsigned int i = 0; i < m_pages->m_pagesInfoVec.GetCount(); i++) { m_pages->m_pagesInfoVec[i].SetTabAngle(angle); } Refresh();}wxSize wxFlatNotebook::GetPageBestSize(){ return m_pages->GetClientSize();}bool wxFlatNotebook::SetPageText(size_t page, const wxString& text){ bool bVal = m_pages->SetPageText(page, text); m_pages->Refresh(); return bVal;}void wxFlatNotebook::SetPadding(const wxSize& padding){ m_nPadding = padding.GetWidth();}void wxFlatNotebook::SetWindowStyleFlag(long style){ wxPanel::SetWindowStyleFlag(style); if(m_pages) { // For changing the tab position (i.e. placing them top/bottom) // refreshing the tab container is not enough m_sendPageChangeEvent = false; SetSelection(m_pages->m_iActivePage); m_sendPageChangeEvent = true; }}bool wxFlatNotebook::RemovePage(size_t page, bool notify){ if(page >= m_windows.GetCount()) return false; // Fire a closing event if( notify ) { wxFlatNotebookEvent event(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSING, GetId()); event.SetSelection((int)page); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); // The event handler allows it? if (!event.IsAllowed()) return false; } Freeze(); // Remove the requested page wxWindow *pageRemoved = m_windows[page]; // If the page is the current window, remove it from the sizer // as well if((int)page == m_pages->GetSelection()) { m_mainSizer->Detach(pageRemoved); } // Remove it from the array as well m_windows.RemoveAt(page); Thaw(); m_pages->DoDeletePage(page); // Fire a closed event if( notify ) { wxFlatNotebookEvent closedEvent(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSED, GetId()); closedEvent.SetSelection((int)page); closedEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(closedEvent); } return true;}void wxFlatNotebook::SetRightClickMenu(wxMenu* menu){ m_pages->m_pRightClickMenu = menu;}wxString wxFlatNotebook::GetPageText(size_t page){ return m_pages->GetPageText(page);}void wxFlatNotebook::SetGradientColors(const wxColour& from, const wxColour& to, const wxColour& border){ m_pages->m_colorFrom = from; m_pages->m_colorTo = to; m_pages->m_colorBorder = border;}void wxFlatNotebook::SetGradientColorFrom(const wxColour& from){ m_pages->m_colorFrom = from;}void wxFlatNotebook::SetGradientColorTo(const wxColour& to){ m_pages->m_colorTo = to;}void wxFlatNotebook::SetGradientColorBorder(const wxColour& border){ m_pages->m_colorBorder = border;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -