]> git.saurik.com Git - wxWidgets.git/commitdiff
MSW wxNotebook implementation
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 9 Jul 1998 20:19:33 +0000 (20:19 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 9 Jul 1998 20:19:33 +0000 (20:19 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@213 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/notebook.cpp [new file with mode: 0644]

diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp
new file mode 100644 (file)
index 0000000..24f673d
--- /dev/null
@@ -0,0 +1,480 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        msw/notebook.cpp
+// Purpose:     implementation of wxNotebook
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     11.06.98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// TODO: 
+// 1) keyboard interface for changing pages ([Shift]+Ctrl-Tab)
+// 2) using OnSize() for showing pages for the first time works, but it surely
+//    us ugly
+// 3) I'm not sure that setting fonts works
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+#ifdef __GNUG__
+  #pragma implementation "notebook.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+  #pragma hdrstop
+#endif
+
+// wxWindows
+#ifndef WX_PRECOMP
+  #include  <wx/string.h>
+#endif  // WX_PRECOMP
+
+#include  <wx/log.h>
+#include  <wx/imaglist.h>
+#include  <wx/notebook.h>
+
+#include  <wx/msw/private.h>
+
+// Windows standard headers
+#ifndef   __WIN95__
+  #error  "wxNotebook is not supported under Windows 3.1"
+#endif    //Win95
+
+#ifdef __GNUWIN32__
+  #include "wx/msw/gnuwin32/extra.h"
+#else   //!GnuWin32
+  #include <commctrl.h>
+#endif
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+// check that the page index is valid
+#define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
+
+// hide the ugly cast
+#define m_hwnd    (HWND)GetHWND()
+
+// ----------------------------------------------------------------------------
+// event table
+// ----------------------------------------------------------------------------
+
+#if !USE_SHARED_LIBRARIES
+  BEGIN_EVENT_TABLE(wxNotebook, wxControl)
+    EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
+
+    EVT_SIZE(wxNotebook::OnSize)
+    EVT_SET_FOCUS(wxNotebook::OnSetFocus)
+    EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
+  END_EVENT_TABLE()
+
+  IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
+  IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent)
+#endif
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxNotebook construction
+// ----------------------------------------------------------------------------
+
+// common part of all ctors
+void wxNotebook::Init()
+{
+  m_pImageList = NULL;
+  m_nSelection = -1;
+}
+
+// default for dynamic class
+wxNotebook::wxNotebook()
+{
+  Init();
+}
+
+// the same arguments as for wxControl
+wxNotebook::wxNotebook(wxWindow *parent,
+                       const wxWindowID id, 
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       const long style,
+                       const wxString& name)
+{
+  Init();
+
+  Create(parent, id, pos, size, style, name);
+}
+
+// Create() function
+bool wxNotebook::Create(wxWindow *parent,
+                        const wxWindowID id, 
+                        const wxPoint& pos,
+                        const wxSize& size,
+                        const long style,
+                        const wxString& name)
+{
+  // base init
+  SetName(name);
+  SetParent(parent);
+
+  m_windowId = id == -1 ? NewControlId() : id;
+
+  // colors and font
+  m_backgroundColour = wxColour(GetSysColor(COLOR_BTNFACE));
+  m_foregroundColour = *wxBLACK ;
+
+  m_defaultForegroundColour = *wxBLACK ;
+  m_defaultBackgroundColour = wxColour(GetSysColor(COLOR_BTNFACE));
+
+  // style
+  m_windowStyle = style;
+
+  long tabStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | TCS_TABS;
+  if ( m_windowStyle & wxTC_MULTILINE )
+    tabStyle |= TCS_MULTILINE;
+  if ( m_windowStyle & wxBORDER )
+    tabStyle &= WS_BORDER;
+
+  // create the tab control.
+  m_hWnd = (WXHWND)CreateWindowEx
+    (
+      0,                                      // extended style
+      WC_TABCONTROL,                          // class name for the tab control
+      "",                                     // no caption
+      tabStyle,                               // style
+      pos.x, pos.y, size.x, size.y,           // size and position
+      (HWND)parent->GetHWND(),                // parent window
+      (HMENU)m_windowId,                      // child id
+      wxGetInstance(),                        // current instance
+      NULL                                    // no class data
+    );
+
+  if ( m_hWnd == 0 ) {
+    wxLogSysError("Can't create the notebook control");
+    return FALSE;
+  }
+
+  if ( parent != NULL ) 
+    parent->AddChild(this);
+  
+  SubclassWin(m_hWnd);
+
+  return TRUE;
+}
+
+// dtor
+wxNotebook::~wxNotebook()
+{
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook accessors
+// ----------------------------------------------------------------------------
+int wxNotebook::GetPageCount() const
+{
+  // consistency check
+  wxASSERT( (int)m_aPages.Count() == TabCtrl_GetItemCount(m_hwnd) );
+
+  return m_aPages.Count();
+}
+
+int wxNotebook::GetRowCount() const
+{
+  return TabCtrl_GetRowCount(m_hwnd);
+}
+
+int wxNotebook::SetSelection(int nPage)
+{
+  wxASSERT( IS_VALID_PAGE(nPage) );
+
+  ChangePage(m_nSelection, nPage);
+
+  return TabCtrl_SetCurSel(m_hwnd, nPage);
+}
+
+void wxNotebook::AdvanceSelection(bool bForward)
+{
+  int nSel = GetSelection();
+  int nMax = GetPageCount() - 1;
+  if ( bForward )
+    SetSelection(nSel == nMax ? 0 : nSel + 1);
+  else
+    SetSelection(nSel == 0 ? nMax : nSel - 1);
+}
+
+bool wxNotebook::SetPageText(int nPage, const wxString& strText)
+{
+  wxASSERT( IS_VALID_PAGE(nPage) );
+
+  TC_ITEM tcItem;
+  tcItem.mask = TCIF_TEXT;
+  tcItem.pszText = (char *)strText.c_str();
+
+  return TabCtrl_SetItem(m_hwnd, nPage, &tcItem) != 0;
+}
+
+wxString wxNotebook::GetPageText(int nPage) const
+{
+  wxASSERT( IS_VALID_PAGE(nPage) );
+
+  char buf[256];
+  TC_ITEM tcItem;
+  tcItem.mask = TCIF_TEXT;
+  tcItem.pszText = buf;
+  tcItem.cchTextMax = WXSIZEOF(buf);
+
+  wxString str;
+  if ( TabCtrl_GetItem(m_hwnd, nPage, &tcItem) )
+    str = tcItem.pszText;
+
+  return str;
+}
+
+int wxNotebook::GetPageImage(int nPage) const
+{
+  wxASSERT( IS_VALID_PAGE(nPage) );
+
+  TC_ITEM tcItem;
+  tcItem.mask = TCIF_IMAGE;
+
+  return TabCtrl_GetItem(m_hwnd, nPage, &tcItem) ? tcItem.iImage : -1;
+}
+
+bool wxNotebook::SetPageImage(int nPage, int nImage)
+{
+  wxASSERT( IS_VALID_PAGE(nPage) );
+
+  TC_ITEM tcItem;
+  tcItem.mask = TCIF_IMAGE;
+  tcItem.iImage = nImage;
+
+  return TabCtrl_SetItem(m_hwnd, nPage, &tcItem) != 0;
+}
+
+void wxNotebook::SetImageList(wxImageList* imageList)
+{ 
+  m_pImageList = imageList;
+  TabCtrl_SetImageList(m_hwnd, (HIMAGELIST)imageList->GetHIMAGELIST());
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook operations
+// ----------------------------------------------------------------------------
+
+// remove one page from the notebook
+bool wxNotebook::DeletePage(int nPage)
+{
+  wxCHECK( IS_VALID_PAGE(nPage), FALSE );
+
+  TabCtrl_DeleteItem(m_hwnd, nPage);
+
+  delete m_aPages[nPage];
+  m_aPages.Remove(nPage);
+
+  return TRUE;
+}
+
+// remove all pages
+bool wxNotebook::DeleteAllPages()
+{
+  TabCtrl_DeleteAllItems(m_hwnd);
+
+  int nPageCount = GetPageCount();
+  int nPage;
+  for ( nPage = 0; nPage < nPageCount; nPage++ )
+    delete m_aPages[nPage];
+
+  m_aPages.Clear();
+
+  return TRUE;
+}
+
+// add a page to the notebook
+bool wxNotebook::AddPage(wxNotebookPage *pPage,
+                         const wxString& strText,
+                         bool bSelect,
+                         int imageId)
+{
+  return InsertPage(GetPageCount(), pPage, strText, bSelect, imageId);
+}
+
+// same as AddPage() but does it at given position
+bool wxNotebook::InsertPage(int nPage,
+                            wxNotebookPage *pPage,
+                            const wxString& strText,
+                            bool bSelect,
+                            int imageId)
+{
+  wxASSERT( pPage != NULL );
+  wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
+
+  // add the tab to the control
+  TC_ITEM tcItem;
+  tcItem.mask    = TCIF_TEXT | TCIF_IMAGE;
+  tcItem.pszText = (char *)strText.c_str();
+  tcItem.iImage  = imageId;
+
+  if ( TabCtrl_InsertItem(m_hwnd, nPage, &tcItem) == -1 ) {
+    wxLogError("Can't create the notebook page '%s'.", strText.c_str());
+    return 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 
+  // still no selection
+  if ( bSelect )
+    m_nSelection = nPage;
+  else if ( m_nSelection == -1 )
+    m_nSelection = 0;
+
+  // don't show pages by default (we'll need to adjust their size first)
+  HWND hwnd = (HWND)pPage->GetHWND();
+  SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE);
+
+  return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook callbacks
+// ----------------------------------------------------------------------------
+
+// @@@ OnSize() is used for setting the font when it's called for the first
+//     time because doing it in ::Create() doesn't work (for unknown reasons)
+void wxNotebook::OnSize(wxSizeEvent& event)
+{
+  static bool s_bFirstTime = TRUE;
+  if ( s_bFirstTime ) {
+    SendMessage((HWND)m_hwnd, WM_SETFONT,
+                (WPARAM)GetStockObject(DEFAULT_GUI_FONT),
+                MAKELPARAM(TRUE, 0));
+    s_bFirstTime = FALSE;
+  }
+
+  // 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);
+
+  event.Skip();
+}
+
+void wxNotebook::OnSelChange(wxNotebookEvent& event)
+{
+  // is it our tab control?
+  if ( event.GetEventObject() == this )
+    ChangePage(event.GetOldSelection(), event.GetSelection());
+
+  // we want to give others a chance to process this message as well
+  event.Skip();
+}
+
+void wxNotebook::OnSetFocus(wxFocusEvent& event)
+{
+  // set focus to the currently selected page if any
+  if ( m_nSelection != -1 )
+    m_aPages[m_nSelection]->SetFocus();
+
+  event.Skip();
+}
+
+void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
+{
+  if ( event.IsWindowChange() ) {
+    // change pages
+    AdvanceSelection(event.GetDirection());
+  }
+  else {
+    // pass to the parent
+    if ( GetParent() ) {
+      event.SetCurrentFocus(this);
+      GetParent()->ProcessEvent(event);
+    }
+  }
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook base class virtuals
+// ----------------------------------------------------------------------------
+void wxNotebook::Command(wxCommandEvent& event)
+{
+  wxFAIL_MSG("wxNotebook::Command not implemented");
+}
+
+bool wxNotebook::MSWNotify(const WXWPARAM wParam, const WXLPARAM lParam)
+{
+  wxNotebookEvent event(wxEVT_NULL, m_windowId, 
+                        TabCtrl_GetCurSel(m_hwnd), m_nSelection);
+
+  NMHDR* hdr = (NMHDR *)lParam;
+  switch ( hdr->code ) {
+    case TCN_SELCHANGE:
+      event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
+      break;
+
+    case TCN_SELCHANGING:
+      event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING);
+      break;
+
+    default :
+      return wxControl::MSWNotify(wParam, lParam);
+  }
+
+  event.SetEventObject(this);
+  event.SetInt(LOWORD(wParam));
+
+  return ProcessEvent(event);
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook helper functions
+// ----------------------------------------------------------------------------
+
+// hide the currently active panel and show the new one
+void wxNotebook::ChangePage(int nOldSel, int nSel)
+{
+  wxASSERT( nOldSel != nSel ); // impossible
+
+  if ( nOldSel != -1 ) {
+    m_aPages[nOldSel]->Show(FALSE);
+  }
+
+  wxNotebookPage *pPage = m_aPages[nSel];
+  FitPage(pPage);
+  pPage->Show(TRUE);
+
+  // set focus to the currently selected page
+  wxWindow *win = m_aPages[nSel];
+  if ( win->IsKindOf(CLASSINFO(wxPanel)) ) {
+    wxList *children = win->GetChildren();
+    if ( children->First() != NULL );
+      win = (wxWindow *)children->First()->Data();
+  }
+  win->SetFocus();
+
+  m_nSelection = nSel;
+}
+
+// fit the notebook page to the tab control's display area
+void wxNotebook::FitPage(wxNotebookPage *pPage)
+{
+  RECT rc;
+  rc.left = rc.top = 0;
+  GetSize((int *)&rc.right, (int *)&rc.bottom);
+
+  TabCtrl_AdjustRect(m_hwnd, FALSE, &rc);
+  pPage->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
+}
\ No newline at end of file