change the implementation of pat::cloneable

This commit is contained in:
Jinhao
2015-08-17 01:37:56 +08:00
parent c1e9ea3daf
commit 4323977908
10 changed files with 183 additions and 77 deletions

View File

@@ -27,19 +27,35 @@ namespace nana
namespace element
{
class element_interface
namespace detail
{
class element_abstract
{
public:
using graph_reference = paint::graphics&;
using graph_reference = ::nana::paint::graphics&;
virtual ~element_abstract() = default;
};
virtual ~element_interface() = default;
class factory_abstract
{
public:
virtual ~factory_abstract() = default;
virtual void destroy(element_abstract *);
};
}
class element_interface
: public detail::element_abstract
{
public:
virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state) = 0;
};
class crook_interface
: public detail::element_abstract
{
public:
using graph_reference = paint::graphics&;
using state = checkstate;
struct data
@@ -48,24 +64,20 @@ namespace nana
bool radio;
};
virtual ~crook_interface() = default;
virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state, const data&) = 0;
};
class border_interface
: public detail::element_abstract
{
public:
using graph_reference = paint::graphics&;
virtual ~border_interface() = default;
virtual bool draw(graph_reference, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle&, element_state, unsigned weight) = 0;
};
class arrow_interface
: public detail::element_abstract
{
public:
using graph_reference = paint::graphics&;
virtual ~arrow_interface() = default;
virtual bool draw(graph_reference, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle&, element_state, direction) = 0;
};
@@ -74,10 +86,10 @@ namespace nana
public:
template<typename ElementInterface>
struct factory_interface
: public detail::factory_abstract
{
virtual ~factory_interface(){}
virtual ElementInterface* create() const = 0;
virtual void destroy(ElementInterface*) const = 0;
};
template<typename Element, typename ElementInterface>
@@ -85,17 +97,12 @@ namespace nana
: public factory_interface<ElementInterface>
{
public:
typedef factory_interface<ElementInterface> interface_type;
using interface_type = factory_interface<ElementInterface>;
ElementInterface * create() const override
{
return (new Element);
}
void destroy(ElementInterface * p) const override
{
delete p;
}
};
void add_arrow(const std::string&, const pat::cloneable<factory_interface<arrow_interface>>&);

View File

@@ -14,7 +14,7 @@
#define NANA_GUI_WIDGET_SCROLL_HPP
#include "widget.hpp"
#include <nana/paint/gadget.hpp>
//#include <nana/paint/gadget.hpp> //deprecated
#include <nana/gui/timer.hpp>
namespace nana

View File

@@ -14,7 +14,7 @@
#ifndef NANA_GUI_WIDGET_TABBAR_HPP
#define NANA_GUI_WIDGET_TABBAR_HPP
#include "widget.hpp"
#include "../../paint/gadget.hpp"
//#include "../../paint/gadget.hpp" //deprecated
#include <nana/pat/cloneable.hpp>
#include <nana/any.hpp>

View File

@@ -19,7 +19,7 @@
#define NANA_GUI_WIDGETS_TREEBOX_HPP
#include "widget.hpp"
#include "detail/compset.hpp"
#include <nana/paint/gadget.hpp>
//#include <nana/paint/gadget.hpp> //deprecated
#include "detail/tree_cont.hpp"
#include <nana/gui/timer.hpp>
#include <nana/any.hpp>

View File

@@ -21,36 +21,38 @@ namespace nana{ namespace pat{
namespace detail
{
/*
template<typename T>
class cloneable_interface
class cloneable_interface //deprecated
{
public:
typedef T interface_t;
using interface_t = T;
typedef cloneable_interface cloneable_t;
virtual ~cloneable_interface() = default;
virtual interface_t& refer() = 0;
virtual const interface_t& refer() const = 0;
virtual cloneable_t* clone() const = 0;
virtual void self_delete() const = 0;
};
*/
/*
template<typename T, typename SuperOfT>
class cloneable_wrapper
: public cloneable_interface<SuperOfT>
: public cloneable_interface<SuperOfT> //deprecated
{
public:
typedef T value_t;
typedef typename cloneable_interface<SuperOfT>::interface_t interface_t;
using value_type = T;
using interface_t = typename cloneable_interface<SuperOfT>::interface_t;
cloneable_wrapper()
{}
cloneable_wrapper() = default;
cloneable_wrapper(const value_t& obj)
cloneable_wrapper(const value_type& obj)
:object_(obj)
{}
cloneable_wrapper(value_t&& rv)
cloneable_wrapper(value_type&& rv)
:object_(std::move(rv))
{}
@@ -66,17 +68,17 @@ namespace nana{ namespace pat{
virtual interface_t& refer() override
{
return object_;
return value_obj_;
}
virtual const interface_t& refer() const override
{
return object_;
return value_obj_;
}
virtual cloneable_interface<interface_t>* clone() const override
{
return (new cloneable_wrapper(object_));
return (new cloneable_wrapper{ value_obj_ });
}
virtual void self_delete() const override
@@ -84,28 +86,87 @@ namespace nana{ namespace pat{
(delete this);
}
private:
value_t object_;
value_type value_obj_;
};
*/
class cloneable_interface
{
public:
virtual ~cloneable_interface() = default;
virtual void * get() = 0;
virtual cloneable_interface* clone() const = 0;
virtual void self_delete() const = 0;
};
struct cloneable_interface_deleter
{
void operator()(cloneable_interface * p)
{
if (p)
p->self_delete();
}
};
template<typename T>
class cloneable_wrapper
: public cloneable_interface
{
public:
using value_type = T;
cloneable_wrapper() = default;
cloneable_wrapper(const value_type& obj)
:value_obj_(obj)
{}
cloneable_wrapper(value_type&& rv)
:value_obj_(std::move(rv))
{}
/*
template<typename U>
cloneable_wrapper(const U& u) //deprecated
: object_(u)
{}
template<typename U>
cloneable_wrapper(U&& u)
: object_(std::move(u))
{}
*/
private:
//Implement cloneable_interface
virtual void* get() override
{
return &value_obj_;
}
virtual cloneable_interface* clone() const override
{
return (new cloneable_wrapper{ value_obj_ });
}
virtual void self_delete() const override
{
(delete this);
}
private:
value_type value_obj_;
};
}//end namespace detail
template<typename Base, bool Mutable = false>
class cloneable
{
using base_t = Base;
using interface_t = detail::cloneable_interface < base_t > ;
using cloneable_interface = detail::cloneable_interface;
using const_base_ptr = typename std::conditional<Mutable, base_t*, const base_t*>::type;
using const_base_ref = typename std::conditional<Mutable, base_t&, const base_t&>::type;
struct deleter
{
void operator()(interface_t * p)
{
if(p)
p->self_delete();
}
};
template<typename OtherBase, bool OtherMutable> friend class cloneable;
struct inner_bool
{
@@ -125,16 +186,16 @@ namespace nana{ namespace pat{
template<typename T, typename member_enabled<T>::type* = nullptr>
cloneable(T&& t)
: cwrapper_(new detail::cloneable_wrapper<typename std::remove_cv<typename std::remove_reference<T>::type>::type, base_t>(std::forward<T>(t)), deleter()),
fast_ptr_(&(cwrapper_->refer()))
: cwrapper_(new detail::cloneable_wrapper<typename std::remove_cv<typename std::remove_reference<T>::type>::type>(std::forward<T>(t)), detail::cloneable_interface_deleter()),
fast_ptr_(reinterpret_cast<typename std::remove_cv<typename std::remove_reference<T>::type>::type*>(cwrapper_->get()))
{}
cloneable(const cloneable& r)
{
if(r.cwrapper_)
{
cwrapper_ = std::shared_ptr<interface_t>(r.cwrapper_->clone(), deleter());
fast_ptr_ = &(cwrapper_->refer());
cwrapper_ = std::move(std::shared_ptr<cloneable_interface>(r.cwrapper_->clone(), detail::cloneable_interface_deleter{}));
fast_ptr_ = reinterpret_cast<base_t*>(cwrapper_->get());
}
}
@@ -145,12 +206,27 @@ namespace nana{ namespace pat{
r.fast_ptr_ = nullptr;
}
template<typename OtherBase, typename std::enable_if<std::is_base_of<base_t, OtherBase>::value>::type* = nullptr>
cloneable(const cloneable<OtherBase, Mutable>& other)
{
if (other)
{
char* value_ptr = reinterpret_cast<char*>(other.cwrapper_->get());
char* base_ptr = reinterpret_cast<char*>(other.fast_ptr_);
auto ptr_diff = std::distance(base_ptr, value_ptr);
cwrapper_.reset(other.cwrapper_->clone(), detail::cloneable_interface_deleter{});
fast_ptr_ = reinterpret_cast<OtherBase*>(reinterpret_cast<char*>(cwrapper_->get()) - ptr_diff);
}
}
cloneable & operator=(const cloneable& r)
{
if((this != &r) && r.cwrapper_)
{
cwrapper_ = std::shared_ptr<interface_t>(r.cwrapper_->clone(), deleter());
fast_ptr_ = &(cwrapper_->refer());
cwrapper_ = std::shared_ptr<cloneable_interface>(r.cwrapper_->clone(), detail::cloneable_interface_deleter());
fast_ptr_ = reinterpret_cast<base_t*>(cwrapper_->get());
}
return *this;
}
@@ -159,10 +235,8 @@ namespace nana{ namespace pat{
{
if(this != &r)
{
cwrapper_ = r.cwrapper_;
cwrapper_ = std::move(r.cwrapper_);
fast_ptr_ = r.fast_ptr_;
r.cwrapper_.reset();
r.fast_ptr_ = nullptr;
}
return *this;
@@ -204,7 +278,7 @@ namespace nana{ namespace pat{
return (fast_ptr_ ? &inner_bool::true_stand : nullptr);
}
private:
std::shared_ptr<interface_t> cwrapper_;
std::shared_ptr<cloneable_interface> cwrapper_;
base_t * fast_ptr_{nullptr};
};

View File

@@ -28,6 +28,14 @@ namespace nana
//Element definitions
namespace element
{
namespace detail
{
void factory_abstract::destroy(element_abstract* ptr)
{
delete ptr;
}
}
class crook
: public crook_interface
{
@@ -592,8 +600,9 @@ namespace nana
class element_object
: nana::noncopyable, nana::nonmovable
{
typedef ElementInterface element_t;
typedef pat::cloneable<element::provider::factory_interface<element_t>> factory_interface;
using element_type = ElementInterface;
using factory_interface = pat::cloneable<element::provider::factory_interface<element_type>>; //deprecated
//using factory_interface = pat::cloneable<element::detail::factory_abstract>;
public:
~element_object()
@@ -608,7 +617,8 @@ namespace nana
auto keep_e = element_ptr_;
factory_ = rhs;
element_ptr_ = factory_->create();
element_ptr_ = factory_->create(); //deprecated
//element_ptr_ = static_cast<element_type*>(static_cast<element::provider::factory_interface<element_type>&>(*factory_).create());
if(nullptr == factory_ || nullptr == element_ptr_)
{
@@ -624,22 +634,27 @@ namespace nana
spare_.emplace_back(keep_e, keep_f);
}
element_t * const * cite() const
element_type * const * cite() const
{
return &element_ptr_;
}
private:
factory_interface factory_; //Keep the factory for destroying the element
element_t * element_ptr_{nullptr};
std::vector<std::pair<element_t*, factory_interface>> spare_;
element_type * element_ptr_{nullptr};
std::vector<std::pair<element_type*, factory_interface>> spare_;
};
class element_manager
: nana::noncopyable, nana::nonmovable
{
//VC2012 does not support alias declaration.
//template<typename E> using factory_interface = element::provider::factory_interface<E>;
/*
template<typename ElementInterface> //deprecated
struct item
{
element_object<ElementInterface> * employee;
std::map<std::string, std::shared_ptr<element_object<ElementInterface>>> table;
};
*/
template<typename ElementInterface>
struct item
{
@@ -1047,19 +1062,21 @@ namespace nana
namespace element
{
using brock = ::nana::detail::bedrock;
void set_bground(const char* name, const pat::cloneable<element_interface>& obj)
{
detail::bedrock::instance().get_element_store().bground(name, obj);
brock::instance().get_element_store().bground(name, obj);
}
void set_bground(const char* name, pat::cloneable<element_interface> && obj)
{
detail::bedrock::instance().get_element_store().bground(name, std::move(obj));
brock::instance().get_element_store().bground(name, std::move(obj));
}
//class cite
cite_bground::cite_bground(const char* name)
: ref_ptr_(detail::bedrock::instance().get_element_store().bground(name))
: ref_ptr_(brock::instance().get_element_store().bground(name))
{
}
@@ -1073,7 +1090,7 @@ namespace nana
void cite_bground::set(const char* name)
{
holder_.reset();
ref_ptr_ = detail::bedrock::instance().get_element_store().bground(name);
ref_ptr_ = brock::instance().get_element_store().bground(name);
}
bool cite_bground::draw(graph_reference dst, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const nana::rectangle& r, element_state state)

View File

@@ -14,7 +14,7 @@
#include <nana/gui/widgets/categorize.hpp>
#include <nana/gui/widgets/float_listbox.hpp>
#include <nana/gui/element.hpp>
#include <nana/paint/gadget.hpp>
//#include <nana/paint/gadget.hpp> //deprecated
#include <nana/gui/widgets/detail/tree_cont.hpp>
#include <stdexcept>

View File

@@ -11,7 +11,7 @@
*/
#include <nana/gui/widgets/checkbox.hpp>
#include <nana/paint/gadget.hpp>
//#include <nana/paint/gadget.hpp> //deprecated
#include <nana/paint/text_renderer.hpp>
#include <nana/gui/element.hpp>
#include <algorithm>

View File

@@ -12,7 +12,7 @@
#include <nana/gui/widgets/date_chooser.hpp>
#include <nana/gui/element.hpp>
#include <nana/paint/gadget.hpp>
//#include <nana/paint/gadget.hpp> //deprecated
#include <nana/system/platform.hpp>
#include <sstream>

View File

@@ -112,12 +112,16 @@ namespace nana
clr = { 0xF0, 0xF0, 0xF0 };
}
graph.rectangle(r, true, bgcolor_);
nana::paint::gadget::cross(graph, x, y, 14, 6, clr);
facade<element::cross> cross;
cross.draw(graph, {}, clr, { x, y, 14, 6 }, element_state::normal);
//nana::paint::gadget::cross(graph, x, y, 14, 6, clr); //deprecated
}
virtual void close(graph_reference graph, const nana::rectangle& r, state_t sta)
{
nana::paint::gadget::close_16_pixels(graph, r.x + (r.width - 16) / 2, r.y + (r.height - 16) / 2, 1, colors::black);
//nana::paint::gadget::close_16_pixels(graph, r.x + (r.width - 16) / 2, r.y + (r.height - 16) / 2, 1, colors::black); //deprecated
facade<element::x_icon> x_icon;
x_icon.draw(graph, {}, colors::black, { r.x + static_cast<int>(r.width - 16) / 2, r.y + static_cast<int>(r.height - 16) / 2, 16, 16 }, element_state::normal);
if(item_renderer::highlight == sta)
graph.rectangle(r, false, {0xa0, 0xa0, 0xa0});
}
@@ -140,24 +144,28 @@ namespace nana
else if (!active)
clr = ::nana::color{ 0x92, 0x99, 0xA4 };
gadget::close_16_pixels(graph, r.x - (16 - r.width) / 2, r.y - (16 - r.height) / 2, 1, clr);
//gadget::close_16_pixels(graph, r.x - (16 - r.width) / 2, r.y - (16 - r.height) / 2, 1, clr); //deprecated
facade<element::x_icon> x_icon;
x_icon.draw(graph, {}, colors::black, { r.x + static_cast<int>(r.width - 16) / 2, r.y + static_cast<int>(r.height - 16) / 2, 16, 16 }, element_state::normal);
}
virtual void back(graph_reference graph, const nana::rectangle& r, state_t sta)
{
using namespace nana::paint::gadget;
//using namespace nana::paint::gadget; //deprecated
_m_draw_arrow(graph, r, sta, direction::west);
}
virtual void next(graph_reference graph, const nana::rectangle& r, state_t sta)
{
using namespace nana::paint::gadget;
//using namespace nana::paint::gadget; //deprecated
_m_draw_arrow(graph, r, sta, direction::east);
}
virtual void list(graph_reference graph, const nana::rectangle& r, state_t sta)
{
using namespace nana::paint::gadget;
//using namespace nana::paint::gadget; //deprecated
_m_draw_arrow(graph, r, sta, direction::south);
}
private: