Merged revisions 6293,6296-6306,6308 via svnmerge from
[ardour.git] / libs / gtkmm2 / gtk / src / notebook.hg
1 /* $Id: notebook.hg,v 1.14 2006/07/05 16:59:28 murrayc Exp $ */
2
3 /* notebook.h
4  * 
5  * Copyright (C) 1998-2002 The gtkmm Development Team
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <gtkmm/container.h>
23 #include <gtkmm/label.h>
24 //#include <gtk/gtknotebook.h>
25 #include <glibmm/helperlist.h>
26
27 _DEFS(gtkmm,gtk)
28 _PINCLUDE(gtkmm/private/container_p.h)
29 #m4 _CONVERSION(guint,PositionType,`$2($3)')
30
31 #ifndef DOXYGEN_SHOULD_SKIP_THIS
32 extern "C"
33 {
34   typedef struct _GtkNotebookPage GtkNotebookPage;
35 }
36 #endif //DOXYGEN_SHOULD_SKIP_THIS
37
38 namespace Gtk
39 {
40
41 _CC_INCLUDE(gtk/gtktypebuiltins.h)
42 _WRAP_ENUM(NotebookTab, GtkNotebookTab)
43
44
45 class Notebook;
46
47 namespace Notebook_Helpers
48 {
49 /*********************************************************************
50 ***** Elem classes
51 *********************************************************************/
52
53 class Page;
54
55 /* Since the data stored in GtkNotebook's GList is inaccessible
56  * the iterator "PageIterator" has to hold a pointer to the Notebook
57  * that owns the list. "Page" (the value_type of "PageList")
58  * inherits "PageIterator" privately and uses Notebook-API-functions
59  * to retrieve and manipulate data.
60  *
61  * Note that PageIterator uses g_list_* functions just to step through
62  * the children and test for iterator equality instead of simply using
63  * the child index number. This is done because even if you use a
64  * child index number, you would still have to use g_list_length() to
65  * retrieve the number of elements.  And using an element index results
66  * in iterators not staying valid on insertion/removal. This would only
67  * lead to fragile and unexpected behaviour.
68  * (Thanks for this explanation, Daniel!)
69  */
70 class PageIterator
71 {
72 public:
73   typedef std::bidirectional_iterator_tag iterator_category;
74   typedef size_t size_type;
75   typedef ptrdiff_t difference_type;
76
77   typedef Page        value_type;
78   typedef const Page* pointer;
79   typedef const Page& reference;
80
81   PageIterator(Gtk::Notebook* parent, GList* node) : node_(node), parent_(parent) {}
82   PageIterator()                                   : node_(0),    parent_(0)      {}
83
84   bool equal(const PageIterator& other) const;
85   operator bool() const;
86
87   PageIterator&      operator++();
88   const PageIterator operator++(int);
89
90   PageIterator&      operator--();
91   const PageIterator operator--(int);
92
93   inline reference operator*()  const;
94   inline pointer   operator->() const;
95
96 protected:
97   GList*         node_;
98   Gtk::Notebook* parent_;
99
100   friend class Gtk::Notebook_Helpers::Page;
101 };
102
103 /** @relates Gtk::Notebook_Helpers::PageIterator */
104 inline bool operator==(const PageIterator& lhs, const PageIterator& rhs)
105   { return lhs.equal(rhs); }
106
107 /** @relates Gtk::Notebook_Helpers::PageIterator */
108 inline bool operator!=(const PageIterator& lhs, const PageIterator& rhs)
109   { return !lhs.equal(rhs); }
110
111
112 // Page is the output class
113 class Page : public PageIterator
114 {
115 protected:
116   Page();
117 private:
118   Page& operator=(const Page&);
119
120 public:
121   int get_page_num() const;
122   Widget* get_child() const;
123   Widget* get_tab_label() const;
124   void set_tab_label(Widget& tab_label);
125   void set_tab_label_text(const Glib::ustring& tab_text);
126   Glib::ustring get_tab_label_text() const;
127   Widget* get_menu_label() const;
128   void set_menu_label(Widget& menu_label);
129   void set_menu_label_text(const Glib::ustring& menu_text);
130   Glib::ustring get_menu_label_text() const;
131   void query_tab_label_packing(bool& expand, bool& fill, PackType& pack_type);
132   void set_tab_label_packing(bool expand, bool fill, PackType pack_type);
133 };
134
135
136 // Element is the input class
137 class PageList;
138
139 class Element
140 {
141 public:
142   Element(Widget* child, Widget* tab, Widget* menu);
143   Element(Widget& child, Widget& tab, Widget& menu);
144   explicit Element(Widget& child);
145
146 protected:
147   friend class PageList;
148   Widget* child_;
149   Widget* tab_;
150   Widget* menu_;
151 };
152
153 // Just a widget without a tab
154 typedef Element WidgetElem;
155
156 struct TabElem : public Element
157 {
158   TabElem(Widget& child, Widget& tab);
159   TabElem(Widget& child, const Glib::ustring& label, bool mnemonic = false);
160 };
161
162 struct MenuElem : public Element
163 {
164   MenuElem(Widget& child, Widget& menu);
165 };
166
167 /*********************************************************************
168 ***** List properties
169 *********************************************************************/
170
171 /** An STL-style container for pages in a Gtk::Notebook.
172  *
173  */
174 class PageList
175 {
176 public:
177   PageList();
178   explicit PageList(GtkNotebook* gparent);
179   PageList(const PageList& src);
180
181   PageList& operator=(const PageList& src);
182
183   typedef Page  value_type;
184   typedef Page& reference;
185   typedef const Page& const_reference;
186
187   typedef PageIterator iterator;
188   typedef Glib::List_ConstIterator<iterator> const_iterator;
189   typedef Glib::List_ReverseIterator<iterator> reverse_iterator;
190   typedef Glib::List_ConstIterator<reverse_iterator> const_reverse_iterator;
191
192   typedef const Element element_type;
193
194   typedef size_t difference_type;
195   typedef size_t size_type;
196
197   inline GtkNotebook* gparent()
198     { return gparent_; }
199   inline const GtkNotebook* gparent() const
200     { return gparent_; }
201
202   size_type size() const;
203
204   size_type max_size() const;
205   bool empty() const;
206
207   inline iterator begin()
208     { return begin_(); }
209   inline iterator end()
210     { return end_(); }
211
212   inline const_iterator begin() const
213     { return const_iterator(begin_()); }
214   inline const_iterator end() const
215     { return const_iterator(end_()); }
216
217   inline reverse_iterator rbegin()
218     { return reverse_iterator(end_()); }
219   inline reverse_iterator rend()
220     { return reverse_iterator(begin_()); }
221
222   inline const_reverse_iterator rbegin() const
223     { return const_reverse_iterator(reverse_iterator(end_())); }
224   inline const_reverse_iterator rend() const
225     { return const_reverse_iterator(reverse_iterator(begin_())); }
226
227   value_type front() const;
228   value_type back() const;
229
230   value_type operator[](size_type l) const;
231
232   iterator insert(iterator position, element_type& e); //custom-implemented.
233
234   template <class InputIterator>
235   inline void insert(iterator position, InputIterator first, InputIterator last)
236   {
237     for(;first != last; ++first)
238       position = insert(position, *first);
239   }
240
241   inline void push_front(element_type& e)
242     { insert(begin(), e); }
243   inline void push_back(element_type& e)
244     { insert(end(), e); }
245
246   void erase(iterator start, iterator stop);
247   iterator erase(iterator);
248   void remove(const_reference child);
249   void remove(Widget& w);
250
251   void reorder(iterator loc, iterator page); // Non-standard
252
253   iterator find(int num);
254   iterator find(const_reference c);
255   iterator find(Widget& w);
256   iterator find(GtkNotebookPage* t);
257
258   inline void pop_front()
259     { erase(begin()); }
260   inline void pop_back()
261     { erase(--end()); }
262
263   void clear();
264
265 protected:
266   iterator begin_() const;
267   iterator end_() const;
268
269   GtkNotebook* gparent_;
270 };
271
272 } /* Notebook_Helpers */
273
274 /** Container which shows one of its children at a time, in tabbed windows.
275  *
276  * The Gtk::Notebook widget is a Gtk::Container whose children are pages that
277  * can be switched between using tab labels along one edge. 
278  *
279  * You can use the PageList returned by pages() as any normal STL container
280  * to manipulate the pages.
281  *
282  * @ingroup Widgets
283  * @ingroup Containers
284  */
285 class Notebook : public Container
286 {
287   _CLASS_GTKOBJECT(Notebook,GtkNotebook,GTK_NOTEBOOK,Gtk::Container,GtkContainer)
288   _IGNORE(gtk_notebook_set_homogeneous_tabs, gtk_notebook_set_tab_border, gtk_notebook_set_tab_hborder, gtk_notebook_set_tab_vborder)
289 public:
290   typedef Notebook_Helpers::PageList PageList;
291
292   _CTOR_DEFAULT
293
294   _WRAP_METHOD(int prepend_page(Widget& child, Widget& tab_label), gtk_notebook_prepend_page)
295   int prepend_page(Widget& child);
296
297   int prepend_page(Widget& child, const Glib::ustring& tab_label, bool use_mnemonic = false);
298   _WRAP_METHOD(int prepend_page(Widget& child, Widget& tab_label, Widget& menu_label), gtk_notebook_prepend_page_menu)
299   //Ignore the possible-0 menu_label version of this method. It would have the same signature as another method.
300  
301   int prepend_page(Widget& child, const Glib::ustring& tab_label, const Glib::ustring& menu_label, bool use_mnemonic);
302
303   _WRAP_METHOD(int append_page(Widget& child, Widget& tab_label), gtk_notebook_append_page)
304   int append_page(Widget& child);
305   int append_page(Widget& child, const Glib::ustring& tab_label, bool use_mnemonic = false);
306
307   _WRAP_METHOD(int append_page(Widget& child, Widget& tab_label, Widget& menu_label), gtk_notebook_append_page_menu)
308   //Ignore the possible-0 menu_label version of this method. It would have the same signature as another method.
309   
310   int append_page(Widget& child, const Glib::ustring& tab_label, const Glib::ustring& menu_label, bool use_mnemonic = false);
311
312   _WRAP_METHOD(int insert_page(Widget& child, Widget& tab_label, int position), gtk_notebook_insert_page)
313   int insert_page(Widget& child, int position);
314  
315   int insert_page(Widget& child, const Glib::ustring& tab_label, int position, bool use_mnemonic = false);
316   _WRAP_METHOD(int insert_page(Widget& child, Widget& tab_label, Widget& menu_label, int position), gtk_notebook_insert_page_menu)
317   //Ignore the possible-0 menu_label version of this method. It would have the same signature as another method.
318  
319   int insert_page(Widget& child, const Glib::ustring& tab_label, const Glib::ustring& menu_label, int position, bool use_mnemonic = false);
320
321   _WRAP_METHOD(void remove_page(int page_num = 0), gtk_notebook_remove_page)
322   void remove_page(Widget& child);
323
324   /** For instance,
325    * Notebook* on_window_creation(Widget* page, int x, int y);
326    */
327   typedef sigc::slot<Notebook*, Widget*, int, int> SlotWindowCreation;
328
329   static void set_window_creation_hook(const SlotWindowCreation& slot);
330   _IGNORE(gtk_notebook_set_window_creation_hook)
331
332   _WRAP_METHOD(void set_group_id(int group_id), gtk_notebook_set_group_id, deprecated)
333   _WRAP_METHOD(int get_group_id() const, gtk_notebook_get_group_id, deprecated)
334
335   //TODO: Use something nicer than void*/gpointer?
336   _WRAP_METHOD(void set_group(void* group), gtk_notebook_set_group)
337   _WRAP_METHOD(void* get_group(), gtk_notebook_get_group)
338   _WRAP_METHOD(const void* get_group() const, gtk_notebook_get_group, constversion)
339
340   _WRAP_METHOD(int get_current_page() const, gtk_notebook_get_current_page)
341   _WRAP_METHOD(Widget* get_nth_page(int page_num), gtk_notebook_get_nth_page)
342   _WRAP_METHOD(const Widget* get_nth_page(int page_num) const, gtk_notebook_get_nth_page, constversion)
343   _WRAP_METHOD(int get_n_pages(), gtk_notebook_get_n_pages, deprecated "Use the const method.")
344   _WRAP_METHOD(int get_n_pages() const, gtk_notebook_get_n_pages)
345   /*Widget* get_current_page();*/ /*inconsistency with set_current_page*/
346   _WRAP_METHOD(int page_num(const Widget& child), gtk_notebook_page_num, deprecated "Use the const method.")
347   _WRAP_METHOD(int page_num(const Widget& child) const, gtk_notebook_page_num)
348
349   _WRAP_METHOD(void set_current_page(int page_num), gtk_notebook_set_current_page)
350   _WRAP_METHOD(void next_page(), gtk_notebook_next_page)
351   _WRAP_METHOD(void prev_page(), gtk_notebook_prev_page)
352
353   _WRAP_METHOD(void set_show_border(bool show_border = true), gtk_notebook_set_show_border)
354
355   _WRAP_METHOD(bool get_show_border() const, gtk_notebook_get_show_border)
356   _WRAP_METHOD(void set_show_tabs(bool show_tabs = true), gtk_notebook_set_show_tabs)
357   _WRAP_METHOD(bool get_show_tabs() const, gtk_notebook_get_show_tabs)
358
359
360   _WRAP_METHOD(void set_tab_pos(PositionType pos), gtk_notebook_set_tab_pos)
361   _WRAP_METHOD(PositionType get_tab_pos() const, gtk_notebook_get_tab_pos)
362
363   _WRAP_METHOD(void set_scrollable(bool scrollable = true), gtk_notebook_set_scrollable)
364   _WRAP_METHOD(bool get_scrollable() const, gtk_notebook_get_scrollable)
365
366   _WRAP_METHOD(void popup_enable(), gtk_notebook_popup_enable)
367
368   _WRAP_METHOD(void popup_disable(), gtk_notebook_popup_disable)
369
370
371   _WRAP_METHOD(Widget* get_tab_label(Widget& child), gtk_notebook_get_tab_label)
372   _WRAP_METHOD(const Widget* get_tab_label(Widget& child) const, gtk_notebook_get_tab_label, constversion)
373   _WRAP_METHOD(void set_tab_label(Widget& child, Widget& tab_label), gtk_notebook_set_tab_label)
374   _WRAP_METHOD(void set_tab_label_text(Widget& child, const Glib::ustring& tab_text), gtk_notebook_set_tab_label_text)
375   _WRAP_METHOD(Glib::ustring get_tab_label_text(Widget& child) const, gtk_notebook_get_tab_label_text)
376   _WRAP_METHOD(Widget* get_menu_label(Widget& child), gtk_notebook_get_menu_label)
377   _WRAP_METHOD(const Widget* get_menu_label(Widget& child) const, gtk_notebook_get_menu_label, constversion)
378   _WRAP_METHOD(void set_menu_label(Widget& child, Widget& menu_label), gtk_notebook_set_menu_label)
379   _WRAP_METHOD(void set_menu_label_text(Widget& child, const Glib::ustring& menu_text), gtk_notebook_set_menu_label_text)
380   _WRAP_METHOD(Glib::ustring get_menu_label_text(Widget& child) const, gtk_notebook_get_menu_label_text)
381   void query_tab_label_packing(Widget& child, bool& expand, bool& fill, PackType& pack_type);
382   _IGNORE(gtk_notebook_query_tab_label_packing)
383   _WRAP_METHOD(void set_tab_label_packing(Widget& child, bool expand, bool fill, PackType pack_type), gtk_notebook_set_tab_label_packing)
384   _WRAP_METHOD(void reorder_child(Widget& child, int position), gtk_notebook_reorder_child)
385
386   _WRAP_METHOD(bool get_tab_reorderable(Widget& child) const, gtk_notebook_get_tab_reorderable)
387   _WRAP_METHOD(void set_tab_reorderable(Widget& child, bool reorderable = true), gtk_notebook_set_tab_reorderable)
388   _WRAP_METHOD(bool get_tab_detachable(Widget& child) const, gtk_notebook_get_tab_detachable)
389   _WRAP_METHOD(void set_tab_detachable(Widget& child, bool detachable = true), gtk_notebook_set_tab_detachable)
390
391
392   PageList::iterator get_current();
393
394   PageList& pages();
395   const PageList& pages() const;
396
397   _WRAP_SIGNAL(void switch_page(GtkNotebookPage* page, guint page_num), "switch_page")
398   _WRAP_SIGNAL(void page_reordered(Widget* page, guint page_num), "page_reordered", no_default_handler)
399   _WRAP_SIGNAL(void page_removed(Widget* page, guint page_num), "page_removed", no_default_handler)
400   _WRAP_SIGNAL(void page_added(Widget* page, guint page_num), "page_added", no_default_handler)
401
402
403   //Key-binding signals:
404   _IGNORE_SIGNAL("move_focus_out")
405   _IGNORE_SIGNAL("select_page")
406   _IGNORE_SIGNAL("focus_tab")
407   _IGNORE_SIGNAL("change_current_page")
408   _IGNORE_SIGNAL("reorder_tab")
409
410   //This doesn't seem generally useful:
411   _IGNORE_SIGNAL("create-window")
412
413
414   _WRAP_PROPERTY("tab-pos", PositionType)
415   _WRAP_PROPERTY("show-tabs", bool)
416   _WRAP_PROPERTY("show-border", bool)
417   _WRAP_PROPERTY("scrollable", bool)
418   _WRAP_PROPERTY("tab-border", guint)
419   _WRAP_PROPERTY("tab-hborder", guint)
420   _WRAP_PROPERTY("tab-vborder", guint)
421   _WRAP_PROPERTY("page", int)
422   _WRAP_PROPERTY("enable-popup", bool)
423   _WRAP_PROPERTY("homogeneous", bool)
424
425 protected:
426 #ifndef DOXYGEN_SHOULD_SKIP_THIS
427   mutable PageList pages_proxy_;
428 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
429 };
430
431
432 #ifndef DOXYGEN_SHOULD_SKIP_THIS
433
434 namespace Notebook_Helpers
435 {
436
437 /**** PageIterator **************************************************/
438
439 inline
440 PageIterator::reference PageIterator::operator*() const 
441
442   return static_cast<const Page&>(*this);
443 }
444
445 inline
446 PageIterator::pointer PageIterator::operator->() const
447
448   return static_cast<const Page*>(this);
449 }
450
451 } /* Notebook_Helpers */
452
453 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
454
455 } /* namespace Gtk */
456