Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

background_wnd/background_wnd.hpp

00001 // background_wnd.hpp
00002 
00003 // Copyright (C) 2004 Steven Weiß (steven11@gmx.de)
00004 //
00005 // Permission to copy, use, sell and distribute this software is granted
00006 // provided this copyright notice appears in all copies.
00007 // Permission to modify the code and to distribute modified code is granted
00008 // provided this copyright notice appears in all copies, and a notice
00009 // that the code was modified is included with the copyright notice.
00010 //
00011 // This software is provided "as is" without express or implied warranty,
00012 // and with no claim as to its suitability for any purpose.
00013 
00014 // version history in version.txt
00015 
00016 
00017 #pragma once
00018 #include <background_wnd/painter_holder.hpp>
00019 #include <background_wnd/detail/memory_dc.hpp>
00020 #include <win32gui/window.hpp>                    // win32gui
00021 
00022 
00023 namespace win32 { namespace gui {
00024 
00025 
00026 struct background_wnd_handler;            // forward-declarations
00027 
00028 
00029 // ============================================================================================================= //
00030 // background_wnd
00031 
00032 class background_wnd : public wnd_extend<window_base, background_wnd>
00033 {
00034 private:
00035     struct painter_info;
00036 
00037      typedef boost::shared_ptr<painter_info> PainterInfoPtr;
00038      typedef std::vector<PainterInfoPtr> PainterColl;
00039      typedef PainterColl::iterator      iterator;
00040      typedef PainterColl::const_iterator const_iterator;
00041 
00042 public:
00043      // exceptions
00044      typedef bg_wnd::general_exception<background_wnd, 0> index_invalid;
00045      typedef bg_wnd::general_exception<background_wnd, 1> invalid_painter_cast;
00046 
00047 
00048      // c'tor
00049      background_wnd();
00050 
00051      // add and remove painters
00052      unsigned add_painter(const painter_base& painter);
00053      void delete_painter(unsigned idx);
00054      void delete_all_painters();
00055 
00056      // direct access to painters
00057      painter_base& get_painter(unsigned idx) const;
00058      std::vector<unsigned> get_indices() const;
00059 
00060      // drawing rectangle
00061      void drawing_rect(unsigned idx, const rectangle& rc);
00062      rectangle drawing_rect(unsigned idx) const;
00063 
00064      // visibility state and transparency
00065      bool is_painter_visible(unsigned idx) const;
00066      void show_painter(unsigned idx, bool bVisible);
00067      void transparency(unsigned idx, unsigned transparency);
00068      unsigned transparency(unsigned idx) const;
00069      void redraw_on_changes(bool bRedraw);
00070      bool redraw_on_changes() const;
00071      void redraw_painters();
00072 
00073      // z-order
00074      void zorder_to_front(unsigned idx);
00075      void zorder_to_back(unsigned idx);
00076      void zorder_forward(unsigned idx);
00077      void zorder_backward(unsigned idx);
00078 
00079      // background-color of window
00080      void bk_color(COLORREF cr);
00081      COLORREF bk_color() const;
00082 
00083 public:
00084      // template-memberfunctions
00085 
00087      template <class Painter> unsigned add_painter()
00088      {
00089           return add_raw_painter(new Painter());
00090      }
00091 
00096      template <class Painter> unsigned add_painter(typename Painter::param0 param)
00097      {
00098           return add_raw_painter(new Painter(param));
00099      }
00100 
00105      template <class Painter> unsigned add_painter(typename Painter::param0 param0, typename Painter::param1 param1)
00106      {
00107           return add_raw_painter(new Painter(param0, param1));
00108      }
00109 
00116      template <class Painter> Painter& get_painter(unsigned idx) const
00117      {
00118           try {
00119                return find_painter_info(idx).get_painter<Painter> ();
00120           }
00121           catch (painter_holder::invalid_painter_cast&) {
00122                throw invalid_painter_cast(*this);           // throw our own exception ;-)
00123           }
00124      }
00125 
00126 protected:
00127      // interface for derived classes
00128      bg_wnd::memory_dc& get_mem_dc();
00129      const bg_wnd::memory_dc& get_mem_dc() const;
00130 
00131 private:
00132      // painter access
00133      unsigned add_raw_painter(painter_base* pPainter);
00134      iterator find_painter_info_iterator(unsigned idx) const;
00135      painter_info& find_painter_info(unsigned idx) const;
00136 
00137      // memory dc and painting functions
00138      void create_mem_dc(HDC hDC);
00139     void redraw_mem_dc();
00140     void redraw_one_painter(PainterInfoPtr pInfo, const rectangle& rc_painter);
00141      rectangle get_actual_drawing_rect(PainterInfoPtr pInfo) const;
00142      static bool is_overlapped(const rectangle& rc, const std::vector<rectangle>& rects);
00143      bool is_partially_visible(const_iterator it_painter, const rectangle& rc_painter) const;
00144 
00145 
00146      // struct with additional information about a painter
00147      struct painter_info : painter_holder
00148     {
00149         painter_info(unsigned idx, painter_base* pPainter)
00150             : idx_(idx), painter_holder(pPainter), bVisible_(true), transparency_(255)
00151         {}
00152 
00153           unsigned       idx_;
00154         rectangle        rc_drawing_;
00155         bool             bVisible_;
00156           unsigned       transparency_;
00157     };
00158 
00159     friend struct background_wnd_handler;
00160 
00161     mutable PainterColl coll_painters_;
00162      bg_wnd::memory_dc mem_dc_;
00163      COLORREF  cr_bkgnd_;
00164      bool   bRedraw_on_changes_;
00165      unsigned  next_index_;
00166 };
00167 
00168 
00169 // ========================================================================================================== //
00170 // background_wnd_by_key
00171 
00172 // thx to John Torjo for his suggestions about a separation of background_wnd and a keyed background_wnd
00173 
00186 template <class Key>
00187 class background_wnd_by_key : private wnd_extend<background_wnd, background_wnd_by_key>,
00188                                      public  wnd_extend<window_base, background_wnd_by_key>
00189 {
00190      typedef std::map<Key, unsigned>    KeyMap;
00191      typedef background_wnd_by_key<Key> self;
00192      typedef background_wnd Base;
00193 
00194      KeyMap map_keys_;
00195 public:
00196      typedef Key key_type;
00197 
00198      // exceptions
00199      typedef bg_wnd::general_exception<self, 0> key_already_used;
00200      typedef bg_wnd::general_exception<self, 1> key_invalid;
00201      typedef bg_wnd::general_exception<self, 2> invalid_painter_cast;
00202 
00203 
00204      // add and remove painters
00205      void add_painter(const key_type& key, painter_base& painter)
00206      {
00207           check_key_invalid(key);
00208           unsigned idx = Base::add_painter(painter);
00209           insert_key(key, idx);
00210      }
00211 
00212      template <class Painter> void add_painter(const key_type& key)
00213      {
00214           check_key_invalid(key);
00215           unsigned idx = Base::add_painter<Painter> ();
00216           insert_key(key, idx);
00217      }
00218 
00219      template <class Painter> void add_painter(const key_type& key, typename Painter::param0 param)
00220      {
00221           check_key_invalid(key);
00222           unsigned idx = Base::add_painter<Painter> (param);
00223           insert_key(key, idx);
00224      }
00225 
00226      template <class Painter> void add_painter(const key_type& key, typename Painter::param0 param0, typename Painter::param1 param1)
00227      {
00228           check_key_invalid(key);
00229           unsigned idx = Base::add_painter<Painter> (param0, param1);
00230           insert_key(key, idx);
00231      }
00232 
00233      void delete_painter(const key_type& key)
00234      {
00235           Base::delete_painter(key_index(key));
00236           map_keys_.erase(key);
00237      }
00238 
00239      void delete_all_painters()
00240      {
00241           Base::delete_all_painters();
00242           map_keys_.clear();
00243      }
00244 
00245      // direct access to painters
00246      painter_base& get_painter(const key_type& key) const
00247      {
00248           return Base::get_painter(key_index(key));
00249      }
00250 
00251      template <class Painter> Painter& get_painter(const key_type& key) const
00252      {
00253           try {
00254                return Base::get_painter<Painter> (key_index(key));
00255           }
00256           catch (Base::invalid_painter_cast&) {
00257                throw invalid_painter_cast(*this);           // throw our own exception ;-)
00258           }
00259      }
00260 
00261      std::vector<key_type> get_keys() const
00262      {
00263           std::vector<key_type> keys;
00264           keys.reserve(map_keys_.size());
00265           for (KeyMap::const_iterator it = map_keys_.begin(); it != map_keys_.end(); ++it)
00266                keys.push_back(it->first);
00267           return keys;
00268      }
00269 
00270      // drawing rectangle
00271      void drawing_rect(const key_type& key, const rectangle& rc)
00272      {
00273           Base::drawing_rect(key_index(key), rc);
00274      }
00275 
00276      rectangle drawing_rect(const key_type& key) const
00277      {
00278           return Base::drawing_rect(key_index(key));
00279      }
00280 
00281      // visibility state and transparency
00282      bool is_painter_visible(const key_type& key) const
00283      {
00284           return Base::is_painter_visible(key_index(key));
00285      }
00286 
00287      void show_painter(const key_type& key, bool bVisible)
00288      {
00289           Base::show_painter(key_index(key), bVisible);
00290      }
00291 
00292      void transparency(const key_type& key, unsigned transparency)
00293      {
00294           Base::transparency(key_index(key), transparency);
00295      }
00296 
00297      unsigned transparency(const key_type& key) const
00298      {
00299           return Base::transparency(key_index(key));
00300      }
00301 
00302      void redraw_on_changes(bool bRedraw)
00303      {
00304           Base::redraw_on_changes(bRedraw);
00305      }
00306 
00307      bool redraw_on_changes() const
00308      {
00309           return Base::redraw_on_changes();
00310      }
00311 
00312      // z-order
00313      void zorder_to_front(const key_type& key)
00314      {
00315           Base::zorder_to_front(key_index(key));
00316      }
00317 
00318      void zorder_to_back(const key_type& key)
00319      {
00320           Base::zorder_to_back(key_index(key));
00321      }
00322 
00323      void zorder_forward(const key_type& key)
00324      {
00325           Base::zorder_forward(key_index(key));
00326      }
00327 
00328      void zorder_backward(const key_type& key)
00329      {
00330           Base::zorder_backward(key_index(key));
00331      }
00332 
00333      // background-color of window
00334      void bk_color(COLORREF cr)
00335      {
00336           Base::bk_color(cr);
00337      }
00338 
00339      COLORREF bk_color() const
00340      {
00341           return Base::bk_color();
00342      }
00343 
00344 protected:
00345      bg_wnd::memory_dc& get_mem_dc()
00346      {
00347           return Base::get_mem_dc();
00348      }
00349 
00350      const bg_wnd::memory_dc& get_mem_dc() const
00351      {
00352           return Base::get_mem_dc();
00353      }
00354 
00355 
00356 private:
00357      void insert_key(const key_type& key, unsigned idx)
00358      {
00359           try {
00360                map_keys_.insert( KeyMap::value_type(key, idx) );
00361           }
00362           catch (...) {
00363                Base::delete_painter(idx);
00364                throw;
00365           }
00366      }
00367 
00368      void check_key_invalid(const key_type& key) const
00369      {
00370           if (map_keys_.find(key) != map_keys_.end())
00371                throw key_already_used(*this);
00372      }
00373 
00374      unsigned key_index(const key_type& key) const
00375      {
00376           KeyMap::const_iterator it = map_keys_.find(key);
00377           if (it == map_keys_.end())
00378                throw key_invalid(*this);
00379           return it->second;
00380      }
00381 };
00382 
00383 
00384 } }  // namespace win32::gui



by Steven Weiss. You can contact me at steven11@gmx.de.