// -*- c++ -*-
//  Generated by gtkmmproc from ./../menushell.gen_h -- DO NOT MODIFY!
#ifndef _GTKMM_MENUSHELL_H
#define _GTKMM_MENUSHELL_H

/* $Id: menushell.gen_h,v 1.82 2001/07/15 13:33:38 murrayc Exp $ */

/* menushell.h
 *
 * Copyright (C) 1998-1999 The Gtk-- 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 <gdk/gdkkeysyms.h>
#include <gtk/gtkmenushell.h>
#include <gtk--/container.h>
#include <gtk--/menuitem.h>
#include <gtk--/radiomenuitem.h>
#include <gtk--/checkmenuitem.h>
#include <gtk--/tearoffmenuitem.h>

namespace Gtk {
class MenuShell;
class MenuShell_Class;
}
namespace Gtk { Gtk::MenuShell *wrap (GtkMenuShell *o); }
namespace Gtk
{

class Menu;
class MenuShell;
class Window;

namespace Menu_Helpers
{
/*********************************************************************
***** Accelerator Key
*********************************************************************/
  static const guint SHIFT  = 1<<15;
  static const guint LOCK   = 1<<16;
  static const guint CTL    = 1<<17;
  static const guint MOD1   = 1<<18;
  static const guint MOD2   = 1<<19;
  static const guint MOD3   = 1<<20;
  static const guint MOD4   = 1<<21;
  static const guint MOD5   = 1<<22;
  static const guint RELEASE= 1<<28;
  static const guint ALT    = 1<<18;

  static const guint KEY_MASK = 0xFFFF;
  static const guint MOD_MASK = 0xFF0000;

  struct AccelKey
    {
      guint key_;

      guint key() { return key_&KEY_MASK; }
      guint mod() { return (key_&MOD_MASK) >> 15; }
      string abrev();

      AccelKey(): key_(GDK_VoidSymbol) {}
      AccelKey(guint s): key_(s) {}
      AccelKey(const string &s);
      AccelKey(const char* s);

      private:
        void parse(string s);
    };


/*********************************************************************
***** Menu Properties
*********************************************************************/

  // input class (MenuItem-Factory)
  class Element
  {
  protected:
    MenuItem *child_;

  public:
    Element(MenuItem* child)
      : child_(child)
    {}
    Element(MenuItem& child)
      : child_(&child)
    {}

    virtual ~Element();

    friend class MenuList;


  protected:
    // connects a callback to the activate signal
    void set_callback(SigC::Slot0<void> callback,
                      const string &accel_signal);

    // creates a label and sets up for navigation and accelerator
    void set_navigation(const string& str,
                        const AccelKey& accel_key=AccelKey());

    virtual void create_child_menu_item();

    MenuItem *get_child() const { return child_; }

    virtual void init(const string &label,
                      SigC::Slot0<void> callback,
                      const string &accel_signal,
                      const AccelKey &key = AccelKey());

    virtual void init(const string &label,
                      Gtk::Menu& submenu,
                      const AccelKey &key = AccelKey());
  };

  class MenuElem : public Element
  {
  public:
    MenuElem(MenuItem& child)
      : Element(&child)
    {}

    //: create a labeled, non-accelerated menuitem with a callback
    MenuElem(const string &label, SigC::Slot0<void> callback = 0,
             const string &accel_signal = "activate") ;

    //: create a labeled, accelerated menuitem with a callback
    MenuElem(const string &label, const AccelKey &key,
             SigC::Slot0<void> callback = 0,
             const string &accel_signal = "activate");

    //: create a labeled, non-accelerated menuitem with a submenu
    MenuElem(const string &label, Gtk::Menu& submenu);

    //: create a labeled, accelerated menuitem with a submenu
    MenuElem(const string &label, const AccelKey &key, Gtk::Menu& submenu);

  };

  class SeparatorElem : public Element
  {
  public:
    SeparatorElem(void);
  };

  class CheckMenuElem : public Element
  {
  public:
    CheckMenuElem(CheckMenuItem& child)
      : Element(&child)
    {}

    //: create a labeled, non-accelerated menuitem with a callback
    CheckMenuElem(const string &label, SigC::Slot0<void> callback = 0,
                  const string &accel_signal = "toggled") ;

    //: create a labeled, accelerated checkmenuitem with a callback
    CheckMenuElem(const string &label, const AccelKey &key,
                  SigC::Slot0<void> callback = 0,
                  const string &accel_signal = "toggled");

  protected:
    virtual void create_child_menu_item();
  };


  class RadioMenuElem : public Element
  {
  public:
    RadioMenuElem(RadioMenuItem& child)
      : Element(&child), gr_(0)
    {}

    //: create a labeled, non-accelerated menuitem with a callback
    RadioMenuElem(RadioMenuItem::Group&, const string &label,
                  SigC::Slot0<void> callback = 0,
                  const string &accel_signal = "toggled");

    //: create a labeled, accelerated checkmenuitem with a callback
    RadioMenuElem(RadioMenuItem::Group&, const string &label,
                  const AccelKey &key,
                  SigC::Slot0<void> callback = 0,
                  const string &accel_signal = "toggled");

  protected:
    virtual void create_child_menu_item();
    RadioMenuItem::Group *gr_;
  };

  class TearoffMenuElem : public Element
  {
  public:
    TearoffMenuElem(TearoffMenuItem& child)
      : Element(&child)
    {}

    //: create a non-accelerated tearoffmenuitem with a callback
    TearoffMenuElem(SigC::Slot0<void> callback = 0,
                    const string &accel_signal = "activate") ;

    //: create accelerated tearoffmenuitem with a callback
    TearoffMenuElem(const AccelKey &key,
                    SigC::Slot0<void> callback = 0,
                    const string &accel_signal = "activate");

  protected:
    virtual void create_child_menu_item();
    virtual void init(SigC::Slot0<void> callback,
                      const string &accel_signal,
                      const AccelKey &accel_key = AccelKey());
  };


/*********************************************************************
***** List properties
*********************************************************************/

  class MenuList
    {
      public:
        typedef MenuItem*                       value_type;
        typedef value_type &                       reference;
        typedef const value_type &                 const_reference;

        typedef G_List_Cpp_Iterator<GtkMenuItem,MenuItem>        iterator;
        typedef G_List_ConstIterator<iterator>     const_iterator;
        typedef G_List_ReverseIterator<iterator>   reverse_iterator;
        typedef G_List_ConstIterator<reverse_iterator>   const_reverse_iterator;

        typedef size_t                             difference_type;
        typedef size_t                             size_type;

      private:
        friend class Gtk::MenuShell;
        Gtk::MenuShell *parent_;
        explicit MenuList(MenuShell* parent): parent_(parent) {}

        GList*& glist() const;      // front of list

        iterator begin_() const;
        iterator end_() const;

      public:
        ~MenuList() {}

        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_())); }

        size_type size(void) const;
        inline size_type max_size(void) { return size_type(-1); }
        inline bool empty(void) { return glist() == 0; }

        iterator insert(iterator position, const Element& e);
        template <class InputIterator>
        inline void insert(iterator position, InputIterator first, InputIterator last)
          { for (;first!=last;++first) position=insert(position,*first); }

        inline void push_front(const Element& e) { insert(begin(), e); }
        inline void push_back(const Element& e)  { insert(end(), e); }
        inline void pop_front()                  { erase(begin()); }
        inline void pop_back()                   { erase(--end()); }

        void clear();

        iterator erase(iterator);
        void erase(iterator start, iterator stop);
        void remove(const_reference);

        void remove(Widget& w);

        value_type front() const     { return *begin(); }
        value_type back() const      { return *(--end()); }

        // This is order n. (use at own risk)
        value_type operator[](size_type l) const;

     };

};

//: A base class for menu objects.
//- A {\class Gtk::MenuShell} is the abstract base class used to derive the
//- {\class Gtk::Menu} and {\class Gtk::MenuBar} subclasses.
//-
//- A {\class Gtk::MenuShell} is a container of {\class Gtk::MenuItem}
//- objects arranged in a list which can be navigated, selected, and
//- activated by the user to perform application functions. A
//- {\class Gtk::MenuItem} can have a submenu associated with it, allowing
//- for nested hierarchical menus.
class MenuShell : public Container
{

public:
  typedef MenuShell          CppObjectType;
  typedef MenuShell_Class    CppClassType;
  typedef GtkMenuShell           BaseObjectType;
  typedef GtkMenuShellClass      BaseClassType;

private:
  friend class MenuShell_Class;
  static CppClassType menu_shell_class;

  MenuShell(const MenuShell&);
  MenuShell& operator=(const MenuShell&); // not implemented

protected:
  void   initialize_class();
  explicit MenuShell(GtkMenuShell *castitem);

public:
  static GtkType get_type();
  GtkMenuShell* gtkobj()             { return (GtkMenuShell*)(gtkobject); }
  const GtkMenuShell* gtkobj() const { return (GtkMenuShell*)(gtkobject); }
  static bool isA(Object *checkcast);

  // Hook for proxies
  static const char* const signal_names[];

  virtual ~MenuShell();

private:

public:

  typedef Menu_Helpers::AccelKey AccelKey;
  typedef Menu_Helpers::MenuList MenuList;
  friend class Menu_Helpers::MenuList;

  //: (deprecated) append a MenuItem

  void append(Gtk::MenuItem& menu_item);

  //: (deprecated) prepend a MenuItem

  void prepend(Gtk::MenuItem& menu_item);

  //: (deprecated) insert a MenuItem

  void insert(Gtk::MenuItem& menu_item,gint position);

  //: Selects the menu item from the menu shell.
  //- menu_item: The {\class Gtk::MenuItem} to select.

  void select_item(Gtk::MenuItem& menu_item);


  void deselect();

  //: Activates the menu item within the menu shell.
  //- menu_item: The GtkMenuItem to activate.
  //-
  //- force_deactivate: If TRUE, force the deactivation of the menu shell after the menu item is activated.

  void activate_item(Gtk::MenuItem& menu_item,bool force_deactivate);

  //: This signal is emitted when a menu shell is deactivated.

  //: This signal is emitted when a selection has been completed within a menu shell.

  //: An action signal which moves the current menu item in the direction specified by direction.

  //: An action signal that activates the current menu item within the menu shell.

  //: An action signal which cancels the selection within the menu shell.
  //: Causes the {GtkMenuShell::selection-done} signal to be emitted.


  MenuList& items()
    {return reinterpret_cast<MenuList&>(menu_shell_self); }
  const MenuList& items() const
    {return reinterpret_cast<const MenuList&>(menu_shell_self); }

  //: assign the menu to a window
  //- Use this function to assign a popup menu to act as keyboard
  //- accelerators for a window.  A popup menu is one which acts
  //- without a parent.
  //-
  //- This function has no gtk+ equivelent.  In gtk+, you create
  //- an accelerator group and then create items with the group
  //- then later assign the group to the window.  To automate this
  //- and save passing arround the group, assignment of accelerators
  //- is held off until you assign the menu to its window.
  //-
  //- It is not necessary to call this on menubars as they perform this
  //- automatically.
  void accelerate(Gtk::Window&);

  // returns 0 is widget is not yet realized or accelerated
  Gtk::AccelGroup* get_accel_group() const {return nav_group_;}

protected:

  MenuShell(void);

protected:
  virtual void realize_impl();
  virtual gint event_impl(GdkEvent*);

  AccelGroup* nav_group_;

public:

  union
    {
      CppObjectType * menu_shell_self;
      Gtk::EmitProxySignal0<void,CppObjectType,BaseObjectType,0,&gtk_menu_shell_deactivate> deactivate;
      Gtk::ProxySignal0<void,CppObjectType,BaseObjectType,1> selection_done;
      Gtk::ProxySignal1<void,GtkMenuDirectionType,CppObjectType,BaseObjectType,2> move_current;
      Gtk::ProxySignal1<void,gboolean,CppObjectType,BaseObjectType,3> activate_current;
      Gtk::ProxySignal0<void,CppObjectType,BaseObjectType,4> cancel;
    };

protected:
  // impl functions
    virtual void deactivate_impl();
    virtual void selection_done_impl();
    virtual void move_current_impl(GtkMenuDirectionType p0);
    virtual void activate_current_impl(gboolean p0);
    virtual void cancel_impl();

};


}

//+ PROPERTIES(Gtk_MenuShell)
//. name: children
//. type: GList*
//. get:
//. set:
//. desc:

//. name: active_menu_item
//. type: Gtk_Widget*
//. get:
//. set:
//. desc:

//. name: parent_menu_shell
//. type: Gtk_Widget*
//. get:
//. set:
//. desc:

//. name: active
//. type: guint:1
//. get:
//. set:
//. desc:

//. name: have_grab
//. type: guint:1
//. get:
//. set:
//. desc:

//. name: have_xgrab
//. type: guint:1
//. get:
//. set:
//. desc:

//. name: button
//. type: guint:2
//. get:
//. set:
//. desc:

//. name: ignore_leave
//. type: guint:1
//. get:
//. set:
//. desc:

//. name: menu_flag
//. type: guint:1
//. get:
//. set:
//. desc:

//. name: ignore_enter
//. type: guint:1
//. get:
//. set:
//. desc:

//. name: activate_time
//. type: guint32
//. get:
//. set:
//. desc:

#endif
