/* $Id: notebook.hg,v 1.14 2006/07/05 16:59:28 murrayc Exp $ */ /* notebook.h * * Copyright (C) 1998-2002 The gtkmm Development Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include //#include #include _DEFS(gtkmm,gtk) _PINCLUDE(gtkmm/private/container_p.h) #m4 _CONVERSION(guint,PositionType,`$2($3)') #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { typedef struct _GtkNotebookPage GtkNotebookPage; } #endif //DOXYGEN_SHOULD_SKIP_THIS namespace Gtk { _CC_INCLUDE(gtk/gtktypebuiltins.h) _WRAP_ENUM(NotebookTab, GtkNotebookTab) class Notebook; namespace Notebook_Helpers { /********************************************************************* ***** Elem classes *********************************************************************/ class Page; /* Since the data stored in GtkNotebook's GList is inaccessible * the iterator "PageIterator" has to hold a pointer to the Notebook * that owns the list. "Page" (the value_type of "PageList") * inherits "PageIterator" privately and uses Notebook-API-functions * to retrieve and manipulate data. * * Note that PageIterator uses g_list_* functions just to step through * the children and test for iterator equality instead of simply using * the child index number. This is done because even if you use a * child index number, you would still have to use g_list_length() to * retrieve the number of elements. And using an element index results * in iterators not staying valid on insertion/removal. This would only * lead to fragile and unexpected behaviour. * (Thanks for this explanation, Daniel!) */ class PageIterator { public: typedef std::bidirectional_iterator_tag iterator_category; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef Page value_type; typedef const Page* pointer; typedef const Page& reference; PageIterator(Gtk::Notebook* parent, GList* node) : node_(node), parent_(parent) {} PageIterator() : node_(0), parent_(0) {} bool equal(const PageIterator& other) const; operator bool() const; PageIterator& operator++(); const PageIterator operator++(int); PageIterator& operator--(); const PageIterator operator--(int); inline reference operator*() const; inline pointer operator->() const; protected: GList* node_; Gtk::Notebook* parent_; friend class Gtk::Notebook_Helpers::Page; }; /** @relates Gtk::Notebook_Helpers::PageIterator */ inline bool operator==(const PageIterator& lhs, const PageIterator& rhs) { return lhs.equal(rhs); } /** @relates Gtk::Notebook_Helpers::PageIterator */ inline bool operator!=(const PageIterator& lhs, const PageIterator& rhs) { return !lhs.equal(rhs); } // Page is the output class class Page : public PageIterator { protected: Page(); private: Page& operator=(const Page&); public: int get_page_num() const; Widget* get_child() const; Widget* get_tab_label() const; void set_tab_label(Widget& tab_label); void set_tab_label_text(const Glib::ustring& tab_text); Glib::ustring get_tab_label_text() const; Widget* get_menu_label() const; void set_menu_label(Widget& menu_label); void set_menu_label_text(const Glib::ustring& menu_text); Glib::ustring get_menu_label_text() const; void query_tab_label_packing(bool& expand, bool& fill, PackType& pack_type); void set_tab_label_packing(bool expand, bool fill, PackType pack_type); }; // Element is the input class class PageList; class Element { public: Element(Widget* child, Widget* tab, Widget* menu); Element(Widget& child, Widget& tab, Widget& menu); explicit Element(Widget& child); protected: friend class PageList; Widget* child_; Widget* tab_; Widget* menu_; }; // Just a widget without a tab typedef Element WidgetElem; struct TabElem : public Element { TabElem(Widget& child, Widget& tab); TabElem(Widget& child, const Glib::ustring& label, bool mnemonic = false); }; struct MenuElem : public Element { MenuElem(Widget& child, Widget& menu); }; /********************************************************************* ***** List properties *********************************************************************/ /** An STL-style container for pages in a Gtk::Notebook. * */ class PageList { public: PageList(); explicit PageList(GtkNotebook* gparent); PageList(const PageList& src); PageList& operator=(const PageList& src); typedef Page value_type; typedef Page& reference; typedef const Page& const_reference; typedef PageIterator iterator; typedef Glib::List_ConstIterator const_iterator; typedef Glib::List_ReverseIterator reverse_iterator; typedef Glib::List_ConstIterator const_reverse_iterator; typedef const Element element_type; typedef size_t difference_type; typedef size_t size_type; inline GtkNotebook* gparent() { return gparent_; } inline const GtkNotebook* gparent() const { return gparent_; } size_type size() const; size_type max_size() const; bool empty() const; inline iterator begin() { return begin_(); } inline iterator end() { return end_(); } inline const_iterator begin() const { return const_iterator(begin_()); } inline const_iterator end() const { return const_iterator(end_()); } inline reverse_iterator rbegin() { return reverse_iterator(end_()); } inline reverse_iterator rend() { return reverse_iterator(begin_()); } inline const_reverse_iterator rbegin() const { return const_reverse_iterator(reverse_iterator(end_())); } inline const_reverse_iterator rend() const { return const_reverse_iterator(reverse_iterator(begin_())); } value_type front() const; value_type back() const; value_type operator[](size_type l) const; iterator insert(iterator position, element_type& e); //custom-implemented. template inline void insert(iterator position, InputIterator first, InputIterator last) { for(;first != last; ++first) position = insert(position, *first); } inline void push_front(element_type& e) { insert(begin(), e); } inline void push_back(element_type& e) { insert(end(), e); } void erase(iterator start, iterator stop); iterator erase(iterator); void remove(const_reference child); void remove(Widget& w); void reorder(iterator loc, iterator page); // Non-standard iterator find(int num); iterator find(const_reference c); iterator find(Widget& w); iterator find(GtkNotebookPage* t); inline void pop_front() { erase(begin()); } inline void pop_back() { erase(--end()); } void clear(); protected: iterator begin_() const; iterator end_() const; GtkNotebook* gparent_; }; } /* Notebook_Helpers */ /** Container which shows one of its children at a time, in tabbed windows. * * The Gtk::Notebook widget is a Gtk::Container whose children are pages that * can be switched between using tab labels along one edge. * * You can use the PageList returned by pages() as any normal STL container * to manipulate the pages. * * @ingroup Widgets * @ingroup Containers */ class Notebook : public Container { _CLASS_GTKOBJECT(Notebook,GtkNotebook,GTK_NOTEBOOK,Gtk::Container,GtkContainer) _IGNORE(gtk_notebook_set_homogeneous_tabs, gtk_notebook_set_tab_border, gtk_notebook_set_tab_hborder, gtk_notebook_set_tab_vborder) public: typedef Notebook_Helpers::PageList PageList; _CTOR_DEFAULT _WRAP_METHOD(int prepend_page(Widget& child, Widget& tab_label), gtk_notebook_prepend_page) int prepend_page(Widget& child); int prepend_page(Widget& child, const Glib::ustring& tab_label, bool use_mnemonic = false); _WRAP_METHOD(int prepend_page(Widget& child, Widget& tab_label, Widget& menu_label), gtk_notebook_prepend_page_menu) //Ignore the possible-0 menu_label version of this method. It would have the same signature as another method. int prepend_page(Widget& child, const Glib::ustring& tab_label, const Glib::ustring& menu_label, bool use_mnemonic); _WRAP_METHOD(int append_page(Widget& child, Widget& tab_label), gtk_notebook_append_page) int append_page(Widget& child); int append_page(Widget& child, const Glib::ustring& tab_label, bool use_mnemonic = false); _WRAP_METHOD(int append_page(Widget& child, Widget& tab_label, Widget& menu_label), gtk_notebook_append_page_menu) //Ignore the possible-0 menu_label version of this method. It would have the same signature as another method. int append_page(Widget& child, const Glib::ustring& tab_label, const Glib::ustring& menu_label, bool use_mnemonic = false); _WRAP_METHOD(int insert_page(Widget& child, Widget& tab_label, int position), gtk_notebook_insert_page) int insert_page(Widget& child, int position); int insert_page(Widget& child, const Glib::ustring& tab_label, int position, bool use_mnemonic = false); _WRAP_METHOD(int insert_page(Widget& child, Widget& tab_label, Widget& menu_label, int position), gtk_notebook_insert_page_menu) //Ignore the possible-0 menu_label version of this method. It would have the same signature as another method. int insert_page(Widget& child, const Glib::ustring& tab_label, const Glib::ustring& menu_label, int position, bool use_mnemonic = false); _WRAP_METHOD(void remove_page(int page_num = 0), gtk_notebook_remove_page) void remove_page(Widget& child); /** For instance, * Notebook* on_window_creation(Widget* page, int x, int y); */ typedef sigc::slot SlotWindowCreation; static void set_window_creation_hook(const SlotWindowCreation& slot); _IGNORE(gtk_notebook_set_window_creation_hook) _WRAP_METHOD(void set_group_id(int group_id), gtk_notebook_set_group_id, deprecated) _WRAP_METHOD(int get_group_id() const, gtk_notebook_get_group_id, deprecated) //TODO: Use something nicer than void*/gpointer? _WRAP_METHOD(void set_group(void* group), gtk_notebook_set_group) _WRAP_METHOD(void* get_group(), gtk_notebook_get_group) _WRAP_METHOD(const void* get_group() const, gtk_notebook_get_group, constversion) _WRAP_METHOD(int get_current_page() const, gtk_notebook_get_current_page) _WRAP_METHOD(Widget* get_nth_page(int page_num), gtk_notebook_get_nth_page) _WRAP_METHOD(const Widget* get_nth_page(int page_num) const, gtk_notebook_get_nth_page, constversion) _WRAP_METHOD(int get_n_pages(), gtk_notebook_get_n_pages, deprecated "Use the const method.") _WRAP_METHOD(int get_n_pages() const, gtk_notebook_get_n_pages) /*Widget* get_current_page();*/ /*inconsistency with set_current_page*/ _WRAP_METHOD(int page_num(const Widget& child), gtk_notebook_page_num, deprecated "Use the const method.") _WRAP_METHOD(int page_num(const Widget& child) const, gtk_notebook_page_num) _WRAP_METHOD(void set_current_page(int page_num), gtk_notebook_set_current_page) _WRAP_METHOD(void next_page(), gtk_notebook_next_page) _WRAP_METHOD(void prev_page(), gtk_notebook_prev_page) _WRAP_METHOD(void set_show_border(bool show_border = true), gtk_notebook_set_show_border) _WRAP_METHOD(bool get_show_border() const, gtk_notebook_get_show_border) _WRAP_METHOD(void set_show_tabs(bool show_tabs = true), gtk_notebook_set_show_tabs) _WRAP_METHOD(bool get_show_tabs() const, gtk_notebook_get_show_tabs) _WRAP_METHOD(void set_tab_pos(PositionType pos), gtk_notebook_set_tab_pos) _WRAP_METHOD(PositionType get_tab_pos() const, gtk_notebook_get_tab_pos) _WRAP_METHOD(void set_scrollable(bool scrollable = true), gtk_notebook_set_scrollable) _WRAP_METHOD(bool get_scrollable() const, gtk_notebook_get_scrollable) _WRAP_METHOD(void popup_enable(), gtk_notebook_popup_enable) _WRAP_METHOD(void popup_disable(), gtk_notebook_popup_disable) _WRAP_METHOD(Widget* get_tab_label(Widget& child), gtk_notebook_get_tab_label) _WRAP_METHOD(const Widget* get_tab_label(Widget& child) const, gtk_notebook_get_tab_label, constversion) _WRAP_METHOD(void set_tab_label(Widget& child, Widget& tab_label), gtk_notebook_set_tab_label) _WRAP_METHOD(void set_tab_label_text(Widget& child, const Glib::ustring& tab_text), gtk_notebook_set_tab_label_text) _WRAP_METHOD(Glib::ustring get_tab_label_text(Widget& child) const, gtk_notebook_get_tab_label_text) _WRAP_METHOD(Widget* get_menu_label(Widget& child), gtk_notebook_get_menu_label) _WRAP_METHOD(const Widget* get_menu_label(Widget& child) const, gtk_notebook_get_menu_label, constversion) _WRAP_METHOD(void set_menu_label(Widget& child, Widget& menu_label), gtk_notebook_set_menu_label) _WRAP_METHOD(void set_menu_label_text(Widget& child, const Glib::ustring& menu_text), gtk_notebook_set_menu_label_text) _WRAP_METHOD(Glib::ustring get_menu_label_text(Widget& child) const, gtk_notebook_get_menu_label_text) void query_tab_label_packing(Widget& child, bool& expand, bool& fill, PackType& pack_type); _IGNORE(gtk_notebook_query_tab_label_packing) _WRAP_METHOD(void set_tab_label_packing(Widget& child, bool expand, bool fill, PackType pack_type), gtk_notebook_set_tab_label_packing) _WRAP_METHOD(void reorder_child(Widget& child, int position), gtk_notebook_reorder_child) _WRAP_METHOD(bool get_tab_reorderable(Widget& child) const, gtk_notebook_get_tab_reorderable) _WRAP_METHOD(void set_tab_reorderable(Widget& child, bool reorderable = true), gtk_notebook_set_tab_reorderable) _WRAP_METHOD(bool get_tab_detachable(Widget& child) const, gtk_notebook_get_tab_detachable) _WRAP_METHOD(void set_tab_detachable(Widget& child, bool detachable = true), gtk_notebook_set_tab_detachable) PageList::iterator get_current(); PageList& pages(); const PageList& pages() const; _WRAP_SIGNAL(void switch_page(GtkNotebookPage* page, guint page_num), "switch_page") _WRAP_SIGNAL(void page_reordered(Widget* page, guint page_num), "page_reordered", no_default_handler) _WRAP_SIGNAL(void page_removed(Widget* page, guint page_num), "page_removed", no_default_handler) _WRAP_SIGNAL(void page_added(Widget* page, guint page_num), "page_added", no_default_handler) //Key-binding signals: _IGNORE_SIGNAL("move_focus_out") _IGNORE_SIGNAL("select_page") _IGNORE_SIGNAL("focus_tab") _IGNORE_SIGNAL("change_current_page") _IGNORE_SIGNAL("reorder_tab") //This doesn't seem generally useful: _IGNORE_SIGNAL("create-window") _WRAP_PROPERTY("tab-pos", PositionType) _WRAP_PROPERTY("show-tabs", bool) _WRAP_PROPERTY("show-border", bool) _WRAP_PROPERTY("scrollable", bool) _WRAP_PROPERTY("tab-border", guint) _WRAP_PROPERTY("tab-hborder", guint) _WRAP_PROPERTY("tab-vborder", guint) _WRAP_PROPERTY("page", int) _WRAP_PROPERTY("enable-popup", bool) _WRAP_PROPERTY("homogeneous", bool) protected: #ifndef DOXYGEN_SHOULD_SKIP_THIS mutable PageList pages_proxy_; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ }; #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace Notebook_Helpers { /**** PageIterator **************************************************/ inline PageIterator::reference PageIterator::operator*() const { return static_cast(*this); } inline PageIterator::pointer PageIterator::operator->() const { return static_cast(this); } } /* Notebook_Helpers */ #endif /* DOXYGEN_SHOULD_SKIP_THIS */ } /* namespace Gtk */