tom_usenet <to********@hotmail.com> writes:
On Thu, 18 Dec 2003 16:51:34 +0000, Roger Leigh
<${******@invalid.whinlatter.uklinux.net.invalid > wrote:
Jeffrey Schwab <je******@comcast.net> writes:
typename menu_list::const_iterator cur;
Thanks, that works just fine!
Is it possible to declare this as a type, rather than using typename
each time?
You only have to use typename when using a member of a dependent type
that is also a type. So it only applies to code inside a template
definition. e.g. this is fine
ObjectOptionMenu<int>::menu_list::const_iterator i;
I see.
I tried putting
typename menu_list::const_iterator;
just after the typedefs, but that doesn't work.
I'd rather the users of the class didn't need to use typename--is
there any way to achieve this?
The users of which class? How do they use it?
I wasn't aware of exactly how typename worked. This question is
wrong--I meant code using the ObjectOptionMenu<> class, but since they
don't need to use typename anyway, it's a non-issue.
For anyone else having problems with templates (and default
parameters), my working code follows:
// object-based option menu -*- C++ -*-
// $Id: objectoptionmenu.h,v 1.2 2003/12/14 16:14:54 roger Exp $
//
// Copyright (C) 2003 Roger Leigh.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////
#ifndef GTKMM_RLEXTRA_OBJECTOPTIONMENU_H
#define GTKMM_RLEXTRA_OBJECTOPTIONMENU_H
#include <cassert>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <gtkmm/optionmenu.h>
#include <gtkmm/menu.h>
#include <libglademm/xml.h>
namespace Gtkmm
{
template<typename T>
class ObjectOptionMenuDescribeObject
{
public:
typedef T object_type;
std::string operator () (const object_type& object) const
{
std::ostringstream desc;
desc << object;
return desc.str();
}
};
template<typename T>
class ObjectOptionMenuItem : public Gtk::MenuItem
{
public:
typedef T object_type;
ObjectOptionMenuItem(const object_type& object,
const Glib::ustring& label):
Gtk::MenuItem(label),
m_object(object)
{}
virtual ~ObjectOptionMenuItem()
{}
const object_type& get_object() const
{
return m_object;
}
private:
object_type m_object;
};
template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
class ObjectOptionMenu : public Gtk::OptionMenu
{
public:
typedef T object_type;
typedef D description_func;
typedef std::vector<object_type> menu_list;
ObjectOptionMenu():
describe_object(),
m_options(),
m_menu()
{
}
ObjectOptionMenu(const menu_list& list):
describe_object(),
m_options(),
m_menu()
{
add_menu(list);
}
/**
* Constructor for initialisation from a Glade interface description.
* @param cobject the GTK+ C object.
* @param xml_interface the Glade XML interface.
*/
explicit ObjectOptionMenu(BaseObjectType* cobject,
const Glib::RefPtr<Gnome::Glade::Xml>& xml_interface):
describe_object(),
m_options(),
m_menu()
{}
virtual ~ObjectOptionMenu()
{}
void set_menu(const menu_list& list)
{
std::cerr << "ObjectOptionMenu::add_menu()" << std::endl;
remove_menu();
for (typename menu_list::const_iterator cur = list.begin();
cur != list.end();
++cur)
{
m_options.push_back(*cur);
Gtk::MenuItem *menu_item =
manage(new ObjectOptionMenuItem<object_type>(*cur, describe_object(*cur)));
m_menu.append(*menu_item);
}
Gtk::OptionMenu::set_menu(m_menu);
Gtk::OptionMenu::set_history(0);
}
void remove_menu()
{
m_options.clear();
Gtk::OptionMenu::remove_menu();
m_menu.items().clear();
}
const object_type* get_history() const
{
int selected = Gtk::OptionMenu::get_history();
const Gtk::MenuItem& menu_item = get_menu()->items()[selected];
const Gtk::MenuItem* menu_item_ptr = &menu_item;
const ObjectOptionMenuItem<object_type> *object_menu_item =
dynamic_cast<const ObjectOptionMenuItem<object_type>* >(menu_item_ptr);
if (object_menu_item != NULL)
return &object_menu_item->get_object();
return NULL;
}
void set_history(const object_type& object)
{
Gtk::MenuShell::MenuList& menu_list = get_menu()->items();
Gtk::MenuShell::MenuList::size_type size = menu_list.size();
for (Gtk::MenuShell::MenuList::size_type cur = 0;
cur < size;
++cur)
{
const Gtk::MenuItem& menu_item = menu_list[cur];
const Gtk::MenuItem* menu_item_ptr = &menu_item;
const ObjectOptionMenuItem<object_type> *object_menu_item =
dynamic_cast<const ObjectOptionMenuItem<object_type>* >(menu_item_ptr);
if (object_menu_item != NULL)
{
if (object == object_menu_item->get_object())
{
Gtk::OptionMenu::set_history(cur);
return;
}
}
}
Gtk::OptionMenu::set_history(0);
}
void on_changed()
{
std::cerr << "OptionMenu::on_changed()" << std::endl;
std::cerr << " There are " << m_menu.items().size() << " items" << std::endl;
if (get_history() != NULL)
std::cerr << " Currently selected: " << describe_object(*get_history()) << std::endl;
else
std::cerr << " Nothing currently selected" << std::endl;
}
protected:
description_func describe_object;
menu_list m_options;
Gtk::Menu m_menu;
}; // class OptionMenu
}; // namespace Gtkmm
#endif // GTKMM_RLEXTRA_OBJECTOPTIONMENU_H
--
Roger Leigh
Printing on GNU/Linux?
http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.