diff options
author | Daniel Burrows <dburrows@debian.org> | 2010-04-29 21:58:07 -0700 |
---|---|---|
committer | Daniel Burrows <dburrows@debian.org> | 2010-04-29 21:58:07 -0700 |
commit | e5dff91d2e5a4d6b31ca3111338c53047e6ad647 (patch) | |
tree | 224ad3e11c73aa7864d8b35a5d0a9f654133adfb /src/gtk | |
parent | 53de7492a5969c63ac23eb4d40f2788fda8675f8 (diff) | |
download | aptitude-e5dff91d2e5a4d6b31ca3111338c53047e6ad647.tar.gz |
Tidy up the area code and factor out generic stuff into generic/util.
Several changes rolled into this:
* Provide an interface for an append-only list that can emit signals
when stuff is appended or removed. (TODO: index-based operations?)
* Pull out code with no GTK+ dependencies for possible reuse.
Includes the dynamic_list and dynamic_list_impl (above), as well
as progress_info and enumerators.
Diffstat (limited to 'src/gtk')
-rw-r--r-- | src/gtk/toplevel/area.cc | 202 | ||||
-rw-r--r-- | src/gtk/toplevel/area.h | 166 |
2 files changed, 57 insertions, 311 deletions
diff --git a/src/gtk/toplevel/area.cc b/src/gtk/toplevel/area.cc index 37e4baf4..cd2b3b5b 100644 --- a/src/gtk/toplevel/area.cc +++ b/src/gtk/toplevel/area.cc @@ -19,74 +19,20 @@ #include "area.h" -#include <boost/enable_shared_from_this.hpp> -#include <boost/make_shared.hpp> - -#include <cwidget/generic/util/eassert.h> - -#include <boost/multi_index_container.hpp> -#include <boost/multi_index/hashed_index.hpp> -#include <boost/multi_index/mem_fun.hpp> -#include <boost/multi_index/sequenced_index.hpp> +#include <generic/util/dynamic_list_impl.h> #include <gtkmm/window.h> using namespace boost::multi_index; +using aptitude::util::dynamic_list; +using aptitude::util::dynamic_list_impl; +using aptitude::util::enumerator; +using aptitude::util::iterator_enumerator_with_keepalive; +using aptitude::util::progress_info; + namespace gui { - /** \brief An enumerator over a range of STL iterators. */ - template<typename ForwardIter> - class iterator_enumerator : public enumerator<typename ForwardIter::value_type> - { - ForwardIter begin, end; - bool first; - - public: - iterator_enumerator(ForwardIter _begin, ForwardIter _end) - : begin(_begin), end(_end), first(true) - { - } - - typename ForwardIter::value_type get_current() - { - eassert(!first); - eassert(begin != end); - - return *begin; - } - - bool advance() - { - if(begin == end) - return false; - - if(first) - first = false; - else - ++begin; - - return true; - } - }; - - /** \brief An enumerator over an iterator range that holds a strong - * shared reference to an object (presumably the one containing the - * iterators). - */ - template<typename ForwardIter, typename T> - class iterator_enumerator_with_keepalive : public iterator_enumerator<ForwardIter> - { - boost::shared_ptr<T> keptalive; - - public: - iterator_enumerator_with_keepalive(ForwardIter begin, ForwardIter end, - boost::shared_ptr<T> _keptalive) - : iterator_enumerator<ForwardIter>(begin, end), - keptalive(_keptalive) - { - } - }; /** \brief Implements the static area list. */ class area_list_impl : public area_list, public boost::enable_shared_from_this<area_list_impl> @@ -104,12 +50,23 @@ namespace gui return static_cast<int>(areas.size()); } - boost::shared_ptr<enumerator<boost::shared_ptr<area_info> > > get_areas() - { - return boost::make_shared<iterator_enumerator_with_keepalive<std::vector<boost::shared_ptr<area_info> >::const_iterator, area_list_impl> >(areas.begin(), areas.end(), shared_from_this()); - } + typedef enumerator<boost::shared_ptr<area_info> > + area_enumerator; + + boost::shared_ptr<area_enumerator> get_areas(); }; + boost::shared_ptr<area_list_impl::area_enumerator> + area_list_impl::get_areas() + { + typedef iterator_enumerator_with_keepalive<std::vector< + boost::shared_ptr<area_info> >::const_iterator, area_list_impl> + real_area_enumerator; + + return boost::make_shared<real_area_enumerator>(areas.begin(), areas.end(), shared_from_this()); + } + + boost::shared_ptr<area_list> create_area_list(const std::vector<boost::shared_ptr<area_info> > &areas) { return boost::make_shared<area_list_impl>(areas); @@ -120,40 +77,12 @@ namespace gui std::string name; std::string description; Glib::RefPtr<Gdk::Pixbuf> icon; - // Note: I don't recall whether hash<> is defined for shared - // pointers -- if it is, I could just use identity<> below instead - // of mem_fun<>. - class tab_hash_tag; - class tab_list_tag; - typedef multi_index_container< - boost::shared_ptr<tab_info>, - indexed_by< - hashed_unique<tag<tab_hash_tag>, - const_mem_fun<boost::shared_ptr<tab_info>, tab_info *, - &boost::shared_ptr<tab_info>::get> >, - sequenced<tag<tab_list_tag> > > - > tab_collection; - - typedef tab_collection::index<tab_hash_tag>::type tab_hash; - typedef tab_collection::index<tab_list_tag>::type tab_list; - - - class notification_hash_tag; - class notification_list_tag; - typedef multi_index_container< - boost::shared_ptr<notification_info>, - indexed_by< - hashed_unique<tag<notification_hash_tag>, - const_mem_fun<boost::shared_ptr<notification_info>, notification_info *, - &boost::shared_ptr<notification_info>::get> >, - sequenced<tag<notification_list_tag> > > - > notification_collection; - - typedef notification_collection::index<notification_hash_tag>::type notification_hash; - typedef notification_collection::index<notification_list_tag>::type notification_list; - - tab_collection tabs; - notification_collection notifications; + + typedef dynamic_list_impl<boost::shared_ptr<tab_info> > tabs_list_impl; + typedef dynamic_list_impl<boost::shared_ptr<notification_info> > notifications_list_impl; + + boost::shared_ptr<tabs_list> tabs; + boost::shared_ptr<notifications_list> notifications; public: area_info_impl(const std::string &_name, @@ -161,82 +90,17 @@ namespace gui const Glib::RefPtr<Gdk::Pixbuf> &_icon) : name(_name), description(_description), - icon(_icon) + icon(_icon), + tabs(tabs_list_impl::create()), + notifications(notifications_list_impl::create()) { } std::string get_name() { return name; } std::string get_description() { return description; } Glib::RefPtr<Gdk::Pixbuf> get_icon() { return icon; } - - boost::shared_ptr<tab_enumerator> get_tabs() - { - const tab_list &tabs_ordered = tabs.get<tab_list_tag>(); - - return boost::make_shared<iterator_enumerator_with_keepalive<tab_list::const_iterator, area_info_impl> >(tabs_ordered.begin(), tabs_ordered.end(), shared_from_this()); - } - - void append_tab(const boost::shared_ptr<tab_info> &tab) - { - tab_hash &tabs_hashed = tabs.get<tab_hash_tag>(); - - if(tabs_hashed.find(tab.get()) == tabs_hashed.end()) - { - tab_list &tabs_ordered = tabs.get<tab_list_tag>(); - - tabs_ordered.push_back(tab); - signal_tab_appended(tab); - } - } - - void remove_tab(const boost::shared_ptr<tab_info> &tab) - { - tab_hash &tabs_hashed = tabs.get<tab_hash_tag>(); - - tab_hash::iterator found = tabs_hashed.find(tab.get()); - - if(found != tabs_hashed.end()) - { - tabs_hashed.erase(found); - signal_tab_removed(tab); - } - } - - - - - boost::shared_ptr<notification_enumerator> get_notifications() - { - const notification_list ¬ifications_ordered = notifications.get<notification_list_tag>(); - - return boost::make_shared<iterator_enumerator_with_keepalive<notification_list::const_iterator, area_info_impl> >(notifications_ordered.begin(), notifications_ordered.end(), shared_from_this()); - } - - void append_notification(const boost::shared_ptr<notification_info> ¬ification) - { - notification_hash ¬ifications_hashed = notifications.get<notification_hash_tag>(); - - if(notifications_hashed.find(notification.get()) == notifications_hashed.end()) - { - notification_list ¬ifications_ordered = notifications.get<notification_list_tag>(); - - notifications_ordered.push_back(notification); - signal_notification_appended(notification); - } - } - - void remove_notification(const boost::shared_ptr<notification_info> ¬ification) - { - notification_hash ¬ifications_hashed = notifications.get<notification_hash_tag>(); - - notification_hash::iterator found = notifications_hashed.find(notification.get()); - - if(found != notifications_hashed.end()) - { - notifications_hashed.erase(found); - signal_notification_removed(notification); - } - } + boost::shared_ptr<tabs_list> get_tabs() { return tabs; } + boost::shared_ptr<notifications_list> get_notifications() { return notifications; } }; boost::shared_ptr<area_info> create_area_info(const std::string &name, diff --git a/src/gtk/toplevel/area.h b/src/gtk/toplevel/area.h index a5c3fe65..a5591ed1 100644 --- a/src/gtk/toplevel/area.h +++ b/src/gtk/toplevel/area.h @@ -20,6 +20,10 @@ #ifndef AREA_H #define AREA_H +#include <generic/util/dynamic_list.h> +#include <generic/util/enumerator.h> +#include <generic/util/progress_info.h> + #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> @@ -55,87 +59,6 @@ namespace gui class tab_info; - /** \brief Data types related to progress information. */ - // @{ - - /** \brief The type of progress information being stored. - */ - enum progress_type - { - /** \brief There is no progress information. */ - progress_type_none, - /** \brief There is only a progress pulse. */ - progress_type_pulse, - /** \brief Full progress information is available. */ - progress_type_bar - }; - - class progress_info - { - progress_type type; - double progress_fraction; - std::string progress_status; - - progress_info(double _progress_fraction, - std::string _progress_status) - : type(progress_type_bar), - progress_fraction(_progress_fraction), - progress_status(_progress_status) - { - } - - progress_info(progress_type _type) - : type(_type), progress_fraction(0) - { - } - - public: - static progress_info none() - { - return progress_info(progress_type_none); - } - - static progress_info pulse() - { - return progress_info(progress_type_pulse); - } - - static progress_info bar(double fraction, - const std::string &status) - { - return progress_info(fraction, status); - } - }; - - // @} - - /** \brief Utility class to allow generic iteration over a list. - * - * Unlike an iterator, instantiations of this class can be used - * without the definition of the concrete object being visible to - * the user. Like Java and .NET iterators, these iterators start - * "before" the list being iterated over and must be advanced to - * the first entry. - */ - template<typename T> - class enumerator - { - public: - virtual ~enumerator() {} - - typedef T value_type; - - /** \brief Get the value at the current position. */ - virtual T get_current() = 0; - - /** \brief Advance to the next entry in the list. - * - * \return \b true if there was another entry, or \b false if we - * reached the end of the list. - */ - virtual bool advance() = 0; - }; - /** \brief The abstract description of a static collection of areas. * * It would be possible, and attractive from one point of view, to @@ -153,7 +76,11 @@ namespace gui virtual int get_size() = 0; - virtual boost::shared_ptr<enumerator<boost::shared_ptr<area_info> > > get_areas() = 0; + typedef aptitude::util::enumerator<boost::shared_ptr<area_info> > + areas_enumerator; + + /** \brief Enumerate the list areas contained in this list. */ + virtual boost::shared_ptr<areas_enumerator> get_areas() = 0; }; /** \brief Create an immutable area list from an STL vector of @@ -178,62 +105,17 @@ namespace gui /** \brief Get the icon of this area. */ virtual Glib::RefPtr<Gdk::Pixbuf> get_icon() = 0; + public: + typedef aptitude::util::dynamic_list<boost::shared_ptr<tab_info> > + tabs_list; - typedef enumerator<boost::shared_ptr<tab_info> > tab_enumerator; - - /** \brief Enumerate the tabs in this area. - * - * To get a consistent picture of the tabs, the caller should - * enumerate them before any other process adds or removes a tab. - * Typically this means enumerating them in a tight loop. - */ - virtual boost::shared_ptr<tab_enumerator> get_tabs() = 0; - - /** \brief Append a tab to this area's tab list. */ - virtual void append_tab(const boost::shared_ptr<tab_info> &tab) = 0; - - /** \brief Remove a tab from this area's tab list. */ - virtual void remove_tab(const boost::shared_ptr<tab_info> &tab) = 0; - - - - - typedef enumerator<boost::shared_ptr<notification_info> > notification_enumerator; - - /** \brief Enumerate the notifications in this area. - * - * To get a consistent picture of the notifications, the caller - * should enumerate them before any other process adds or removes - * a notification. Typically this means enumerating them in a - * tight loop. - */ - virtual boost::shared_ptr<notification_enumerator> get_notifications() = 0; - - /** \brief Append a notification to this area's notification list. */ - virtual void append_notification(const boost::shared_ptr<notification_info> ¬ification) = 0; - - /** \brief Remove a notification from this area's notification list. */ - virtual void remove_notification(const boost::shared_ptr<notification_info> ¬ification) = 0; - - - /** \brief Signals */ - // @{ - - /** \brief Emitted after a tab is appended to the area's tab list. */ - sigc::signal<void, boost::shared_ptr<tab_info> > signal_tab_appended; - - /** \brief Emitted after a tab is removed from the area's tab list. */ - sigc::signal<void, boost::shared_ptr<tab_info> > signal_tab_removed; - - - - /** \brief Emitted after a notification is appended to the area's notification list. */ - sigc::signal<void, boost::shared_ptr<notification_info> > signal_notification_appended; - - /** \brief Emitted after a notification is removed from the area's notification list. */ - sigc::signal<void, boost::shared_ptr<notification_info> > signal_notification_removed; + typedef aptitude::util::dynamic_list<boost::shared_ptr<notification_info> > + notifications_list; - // @} + /** \brief Get the tabs associated with this area. */ + virtual boost::shared_ptr<tabs_list> get_tabs() = 0; + /** \brief Get the notifications associated with this area. */ + virtual boost::shared_ptr<notifications_list> get_notifications() = 0; }; boost::shared_ptr<area_info> create_area_info(const std::string &name, @@ -280,13 +162,13 @@ namespace gui virtual Glib::RefPtr<Gdk::Pixbuf> get_icon() = 0; /** \brief Get any progress information associated with this tab. */ - virtual progress_info get_progress() = 0; + virtual aptitude::util::progress_info get_progress() = 0; /** \brief Update the progress information associated with this tab. * * Invokes signal_progress_changed() as a side-effect. */ - virtual void set_progress(const progress_info &info) = 0; + virtual void set_progress(const aptitude::util::progress_info &info) = 0; /** \brief Get the main widget of this tab. */ virtual Gtk::Widget *get_widget() = 0; @@ -314,7 +196,7 @@ namespace gui sigc::signal<void, std::string, Gtk::Window *> signal_tooltip_changed; /** \brief Emitted when the progress information changes. */ - sigc::signal<void, progress_info> signal_progress_changed; + sigc::signal<void, aptitude::util::progress_info> signal_progress_changed; /** \brief Emitted when the tab becomes active or inactive. * @@ -362,14 +244,14 @@ namespace gui /** \brief Retrieve the progress display associated with this * notification. */ - virtual progress_info get_progress() = 0; + virtual aptitude::util::progress_info get_progress() = 0; /** \brief Update the progress display associated with this * notification. * * Invokes signal_progress_changed as a side-effect. */ - virtual void set_progress(const progress_info &progress) = 0; + virtual void set_progress(const aptitude::util::progress_info &progress) = 0; /** \brief Signals */ @@ -377,7 +259,7 @@ namespace gui // @{ /** \brief Emitted when the progress information changes. */ - sigc::signal<void, progress_info> signal_progress_changed; + sigc::signal<void, aptitude::util::progress_info> signal_progress_changed; /** \brief Emitted when the user clicks the notification. */ sigc::signal<void> signal_clicked; |