Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

app-helper.h

Go to the documentation of this file.
00001 /* 
00002  * Copyright 2000 Karl Nelson
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the Free
00016  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  *
00018  * UIInfo "huffs goat choad" but we will try to make the best of it.
00019  */
00020 
00021 #ifndef GNOMEMM_APP_HELPER_H
00022 #define GNOMEMM_APP_HELPER_H
00023 
00024 #include <new>
00025 #include <gtkmm/menushell.h>
00026 #include <gtkmm/toolbar.h>
00027 #include <gtkmm/accelgroup.h>
00028 #include <libgnomeuimm/ui-items-icon.h>
00029 #include <libgnomeui/gnome-app.h>
00030 #include <libgnomeui/gnome-app-helper.h>
00031 #include <vector>
00032 
00033 namespace Gnome
00034 {
00035 
00036 namespace UI
00037 {
00038 
00039 namespace Items
00040 {
00041 
00042 class Icon;
00043 
00044 /*******************************************************/
00045 // Info is the base of the UI item tree it represents broad types
00046 // of GUI items for construction later.
00047 
00048 template<class T_Info>
00049 class Array;
00050 
00051 class InfoData;
00052 
00053 /*** Derived GnomeUIInfo
00054  * Note: When deriving this, you must not add any fields or add any virtuals
00055  */
00056 class Info : protected GnomeUIInfo
00057 {
00058   friend class InfoData;
00059   friend class Array<Info>;
00060 
00061   // must not be dynamic
00062   void* operator new(size_t s);
00063 public:
00064   void* operator new(size_t s, void* v) {return ::operator new(s, v);}
00065 
00066   Info();
00067   Info(const Info& src);
00068   ~Info();
00069   Info& operator=(const Info& src);
00070 
00071   Gtk::Widget* get_widget();
00072   const Gtk::Widget* get_widget() const;
00073 
00074   enum Type
00075   {
00076     END = GNOME_APP_UI_ENDOFINFO,
00077     ITEM = GNOME_APP_UI_ITEM,
00078     TOGGLEITEM = GNOME_APP_UI_TOGGLEITEM,
00079     RADIOITEMS = GNOME_APP_UI_RADIOITEMS,
00080     SUBTREE = GNOME_APP_UI_SUBTREE,
00081     SEPARATOR = GNOME_APP_UI_SEPARATOR,
00082     HELP = GNOME_APP_UI_HELP,
00083     BUILDER = GNOME_APP_UI_BUILDER_DATA,
00084     CONFIGURABLE = GNOME_APP_UI_ITEM_CONFIGURABLE,
00085     SUBTREE_STOCK = GNOME_APP_UI_SUBTREE_STOCK
00086   };
00087   
00088   Type type() const;
00089 
00090   const gchar* debug_get_icon_info() const;
00091 
00092   typedef Gtk::Menu_Helpers::AccelKey AccelKey;
00093   void set_accel(AccelKey ak = AccelKey());
00094 
00095   typedef SigC::Slot0<void> Callback;
00096   typedef SigC::Slot1<void, Gtk::Widget*> CallbackWithWidget;
00097   
00098 protected:
00099   void init(Type type_);
00100   void init_cb(Type type_, const Icon& icon,
00101             const Glib::ustring& label, const Callback& cb,
00102             const Glib::ustring& tooltip);
00103   void init_cbw(Type type_, const Icon& icon,
00104             const Glib::ustring& label, const CallbackWithWidget& cb,
00105             const Glib::ustring& tooltip);
00106   void init_sub(Type type_, const Icon& icon,
00107             const Glib::ustring& label, const Array<Info>& sub,
00108             const Glib::ustring& tooltip);
00109   InfoData* init_common(Type type_, const Icon& icon_,
00110             const Glib::ustring& label_, const Glib::ustring& hint_);
00111 
00112   InfoData* get_data_();
00113   const InfoData* get_data_() const;
00114   
00115   void set_data_(InfoData* infodata);
00116 };
00117 
00118 
00119 
00120 
00121 
00122 
00123 // subtree or submenu
00124 class SubTree : public Info
00125 {
00126 protected:
00127   SubTree();
00128 public:
00129   SubTree(const Glib::ustring& label, const Array<Info>& uitree,
00130           const Glib::ustring& tip = Glib::ustring());
00131   SubTree(const Icon& icon, const Glib::ustring& label,
00132           const Array<Info>& uitree, const Glib::ustring& tip = Glib::ustring());
00133   ~SubTree();
00134 
00135   Array<Info>& get_uitree();
00136 };
00137 typedef SubTree Menu;
00138 
00139 
00140 
00141 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00142 // begin marker for C structures (not really for user use)
00143 class Begin : public Info
00144 {
00145 public:
00146   Begin();
00147 
00148 private:
00149   static GnomeUIBuilderData build_data_;
00150 };
00151 
00152 // end marker for C structures (not really for user use)
00153 class End : public Info
00154 {
00155 public:
00156   End();
00157 };
00158 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
00159 
00160 namespace Array_Helpers
00161 {
00162 
00163 template<class T>
00164 struct Traits
00165 {
00166   typedef typename T::const_iterator iterator;
00167   static iterator begin(const T& t) {return t.begin();}
00168   static iterator end(const T& t) {return t.end();}
00169 };
00170 
00171 // You must place an End() to use this type
00172 template<class T_Info>
00173 struct Traits<T_Info*>
00174 {
00175   typedef const T_Info* iterator;
00176   static iterator begin(const T_Info* t) {return t;}
00177   static iterator end( T_Info* t) {return t+64;} //64?
00178 };
00179 
00180 template<size_t N, class T_Info>
00181 struct Traits<T_Info[N]>
00182 {
00183   typedef const T_Info* iterator;
00184   static iterator begin(const T_Info* t) {return t;}
00185   static iterator end(const T_Info* t) {return &t[N];}
00186 };
00187 
00188 } /* namespace Array_Helpers */
00189 
00190 
00191 
00192 // Array converter class
00193 template<class T_Info>
00194 class Array 
00195 {
00196   //void* operator new (size_t s);  // not implemented
00197   Info* data_;
00198   Info* begin_;
00199   int size_;
00200 
00201   template <class I> void create(I b, I e);
00202 public:
00203   typedef T_Info value_type;
00204   typedef T_Info& reference_type;
00205   typedef T_Info* iterator;
00206   typedef T_Info* const const_iterator;
00207   typedef T_Info* const pointer;
00208   typedef T_Info* const const_pointer;
00209   typedef size_t size_type;
00210   typedef ptrdiff_t difference_type;
00211 
00212   Array& operator=(const Array& a)
00213   {
00214     if (this == &a)
00215       return *this;
00216 
00217     delete [] data_;
00218     data_ = 0;
00219     size_ = 0;
00220     
00221     create(a.begin(), a.end());
00222     return *this;
00223   }
00224 
00225   Array()
00226   : data_(0), begin_(0), size_(0)
00227   { create((T_Info*)0, (T_Info*)0); }
00228 
00229   Array(Array& a)
00230   : data_(0), begin_(0), size_(0)
00231   { create(a.begin(), a.end()); }
00232 
00233   template <class T>
00234   Array(const T& t)
00235   : data_(0), begin_(0), size_(0)
00236   { create(Array_Helpers::Traits<T>::begin(t),
00237            Array_Helpers::Traits<T>::end(t));
00238   }
00239 
00240   template <class I>
00241   Array(I b, I e)
00242   : data_(0), begin_(0), size_(0)
00243   { create(b, e); }
00244 
00245   ~Array()
00246   {
00247     delete [] data_;
00248     data_ = 0;
00249     size_ = 0;
00250   }
00251 
00252   size_t size() const { return size_; }
00253 
00254   iterator begin() const
00255   { return static_cast<T_Info*>(begin_); }
00256   
00257   iterator end() const
00258   { return static_cast<T_Info*>(begin_ + size_); }
00259   
00260   reference_type operator[](size_t n) const
00261   { return static_cast<T_Info&>(begin_[n]); }
00262   
00263 
00264   GnomeUIInfo* gobj() const
00265   //{ return static_cast<GnomeUIInfo*>(data_); }
00266   { return (GnomeUIInfo*)(data_); }
00267   
00268 };
00269 
00270 
00271 template <class T_Info>
00272 template <class I>
00273 void
00274 Array<T_Info>::create(I b, I e)
00275 {
00276 
00277   // NULL list
00278   if (b == e)
00279   {
00280     data_ = new End[1];
00281     return;
00282   }
00283 
00284   // determine number of Items
00285   for (I b2 = b ; b2 != e; ++b2, ++size_)
00286   {
00287     if (b2->type() == Info::END)
00288       break;
00289   }
00290 
00291   // must have a builder data on head
00292   if (b->type() != Info::BUILDER)
00293   {
00294     begin_ = data_ = new Info[size_+2]; //plus space for BEGIN and END.
00295     new (begin_) Begin(); //constructor without allocation.
00296     begin_++; //Hide Begin() element from outside, by keeping it before begin().
00297   }
00298   else
00299     begin_ = data_ = new Info[size_+1]; //plus space for END.
00300 
00301   // Copy data
00302   for (int i = 0; b != e; ++b, ++i)
00303   {
00304     new (&begin_[i]) T_Info(*b); //constructor without allocation.
00305   }
00306 
00307   new (&begin_[size_]) End(); //constructor without allocation.
00308 
00309   //At this point _size excludes the Begin() and End() GNOME internals elements,
00310   //so users of begin() and end() will never see them.
00311 }
00312 
00313 
00314 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00315 // This is a refcounted holder to deal with C interface badness
00316 // users don't need to deal with these unless they are making new Info types.
00317 //   This is probably refcounted because that's easier than copying in copy constructors, given that we can't
00318 //   add member data to the Info class.
00319 class InfoData
00320 {
00321 public:
00322   InfoData();
00323   InfoData(const Glib::ustring& label, const Glib::ustring& hint, const Icon& icon = Icon());
00324 
00325 private:
00326   InfoData(const InfoData&); //Prevent use of copy constructor.
00327 protected:
00328   virtual ~InfoData();
00329 
00330 public:
00331 
00332   void ref();
00333   void unref();
00334 
00335   virtual void connect(Info&);
00336 
00337   typedef SigC::Slot0<void> Callback;
00338   typedef SigC::Slot1<void, Gtk::Widget*> CallbackWithWidget;
00339 
00340   void set_callback(const Callback& callback);
00341   void set_callback(const CallbackWithWidget& callback);
00342   void set_subtree(const Array<Info>& subtree);
00343   Array<Info>& get_subtree();
00344 
00345 
00346   CallbackWithWidget callback_;
00347   Array<Info> subtree_;
00348   Glib::ustring label_;
00349   Glib::ustring hint_;
00350   Icon icon_;
00351 
00352 private:
00353   int ref_count_;
00354 };
00355 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
00356 
00357 
00361 Items::Array<Info> fill (Gtk::MenuShell                      &menu_shell,
00362                          const Items::Array<Info>            &info,
00363                          const Glib::RefPtr<Gtk::AccelGroup> &accel_group,
00364                          bool                                 uline_accels = true,
00365                          int                                  pos = 0);
00366 
00367 
00371 Items::Array<Info> fill (Gtk::Toolbar                        &toolbar, 
00372                          const Items::Array<Info>            &info,
00373                          const Glib::RefPtr<Gtk::AccelGroup> &accel_group);
00374 
00375 
00376 
00377 //: Utility functions for Gtk::MenuShell.
00378 //- These should really be member methods of Gtk::MenuShell,
00379 //- but they're part of gnomeui, not gtk, and they didn't subclass GtkMenuShell.
00380 //static Gtk::MenuShell* MenuShell_find_menu_pos(const Gtk::MenuShell& parent,
00381 //                                               const Glib::ustring &path,
00382 //                                               int& pos);
00383 
00384 //IGNORED gnome_app_fill_menu_with_data()
00385 //IGNORED gnome_app_fill_menu_custom()
00386 //IGNORED gnome_app_fill_toolbar_with_data()
00387 //IGNORED gnome_app_fill_toolbar_custom()
00388 
00389 } /* namespace Items */
00390 } /* namespace UI */
00391 } /* namespace Gnome */
00392 
00393 #endif //GNOMEMM_APP_HELPER_H

Generated on Tue Sep 2 16:10:51 2003 for libgnomeuimm by doxygen 1.3.2