00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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>
00021
00022
00023 namespace win32 { namespace gui {
00024
00025
00026 struct background_wnd_handler;
00027
00028
00029
00030
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
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
00049 background_wnd();
00050
00051
00052 unsigned add_painter(const painter_base& painter);
00053 void delete_painter(unsigned idx);
00054 void delete_all_painters();
00055
00056
00057 painter_base& get_painter(unsigned idx) const;
00058 std::vector<unsigned> get_indices() const;
00059
00060
00061 void drawing_rect(unsigned idx, const rectangle& rc);
00062 rectangle drawing_rect(unsigned idx) const;
00063
00064
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
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
00080 void bk_color(COLORREF cr);
00081 COLORREF bk_color() const;
00082
00083 public:
00084
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);
00123 }
00124 }
00125
00126 protected:
00127
00128 bg_wnd::memory_dc& get_mem_dc();
00129 const bg_wnd::memory_dc& get_mem_dc() const;
00130
00131 private:
00132
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
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
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
00171
00172
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
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
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
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);
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
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
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
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
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 } }