draw-through
it is possible to render with OpenGL/DX by using draw-through.
This commit is contained in:
parent
7496fea110
commit
f67dbdb14b
@ -25,6 +25,7 @@ namespace nana
|
|||||||
struct native_window_handle_impl{};
|
struct native_window_handle_impl{};
|
||||||
struct window_handle_impl{};
|
struct window_handle_impl{};
|
||||||
struct event_handle_impl{};
|
struct event_handle_impl{};
|
||||||
|
struct native_drawable_impl{};
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class checkstate
|
enum class checkstate
|
||||||
@ -66,6 +67,7 @@ namespace nana
|
|||||||
using native_window_type = detail::native_window_handle_impl*;
|
using native_window_type = detail::native_window_handle_impl*;
|
||||||
using window = detail::window_handle_impl*; ///< \see [What is window class ](https://sourceforge.net/p/nanapro/discussion/general/thread/bd0fabfb/)
|
using window = detail::window_handle_impl*; ///< \see [What is window class ](https://sourceforge.net/p/nanapro/discussion/general/thread/bd0fabfb/)
|
||||||
using event_handle = detail::event_handle_impl*;
|
using event_handle = detail::event_handle_impl*;
|
||||||
|
using native_drawable_type = detail::native_drawable_impl*;
|
||||||
|
|
||||||
|
|
||||||
struct keyboard
|
struct keyboard
|
||||||
|
@ -74,7 +74,7 @@ namespace detail
|
|||||||
struct basic_window
|
struct basic_window
|
||||||
: public events_holder
|
: public events_holder
|
||||||
{
|
{
|
||||||
typedef std::vector<basic_window*> container;
|
using container = std::vector<basic_window*>;
|
||||||
|
|
||||||
struct root_context
|
struct root_context
|
||||||
{
|
{
|
||||||
@ -119,6 +119,8 @@ namespace detail
|
|||||||
bool is_ancestor_of(const basic_window* wd) const;
|
bool is_ancestor_of(const basic_window* wd) const;
|
||||||
bool visible_parents() const;
|
bool visible_parents() const;
|
||||||
bool belong_to_lazy() const;
|
bool belong_to_lazy() const;
|
||||||
|
|
||||||
|
bool is_draw_through() const; ///< Determines whether it is a draw-through window.
|
||||||
public:
|
public:
|
||||||
//Override event_holder
|
//Override event_holder
|
||||||
bool set_events(const std::shared_ptr<general_events>&) override;
|
bool set_events(const std::shared_ptr<general_events>&) override;
|
||||||
@ -206,6 +208,8 @@ namespace detail
|
|||||||
#endif
|
#endif
|
||||||
cursor state_cursor{nana::cursor::arrow};
|
cursor state_cursor{nana::cursor::arrow};
|
||||||
basic_window* state_cursor_window{ nullptr };
|
basic_window* state_cursor_window{ nullptr };
|
||||||
|
|
||||||
|
std::function<void()> draw_through; ///< A draw through renderer for root widgets.
|
||||||
};
|
};
|
||||||
|
|
||||||
const category::flags category;
|
const category::flags category;
|
||||||
|
@ -67,6 +67,7 @@ namespace detail
|
|||||||
bool whether_keyboard_shortkey() const;
|
bool whether_keyboard_shortkey() const;
|
||||||
|
|
||||||
element_store& get_element_store() const;
|
element_store& get_element_store() const;
|
||||||
|
void map_through_widgets(core_window_t*, native_drawable_type);
|
||||||
public:
|
public:
|
||||||
void event_expose(core_window_t *, bool exposed);
|
void event_expose(core_window_t *, bool exposed);
|
||||||
void event_move(core_window_t*, int x, int y);
|
void event_move(core_window_t*, int x, int y);
|
||||||
|
@ -115,7 +115,8 @@ namespace API
|
|||||||
|
|
||||||
void window_icon_default(const paint::image&);
|
void window_icon_default(const paint::image&);
|
||||||
void window_icon(window, const paint::image&);
|
void window_icon(window, const paint::image&);
|
||||||
bool empty_window(window); ///< Determines whether a window is existing.
|
bool empty_window(window); ///< Determines whether a window is existing.
|
||||||
|
bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window.
|
||||||
void enable_dropfiles(window, bool);
|
void enable_dropfiles(window, bool);
|
||||||
|
|
||||||
/// \brief Retrieves the native window of a Nana.GUI window.
|
/// \brief Retrieves the native window of a Nana.GUI window.
|
||||||
@ -176,6 +177,9 @@ namespace API
|
|||||||
void bring_top(window, bool activated);
|
void bring_top(window, bool activated);
|
||||||
bool set_window_z_order(window wd, window wd_after, z_order_action action_if_no_wd_after);
|
bool set_window_z_order(window wd, window wd_after, z_order_action action_if_no_wd_after);
|
||||||
|
|
||||||
|
void draw_through(window, std::function<void()>);
|
||||||
|
void map_through_widgets(window, native_drawable_type);
|
||||||
|
|
||||||
nana::size window_size(window);
|
nana::size window_size(window);
|
||||||
void window_size(window, const size&);
|
void window_size(window, const size&);
|
||||||
bool window_rectangle(window, rectangle&);
|
bool window_rectangle(window, rectangle&);
|
||||||
|
@ -401,6 +401,16 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return *scheme_;
|
return *scheme_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_through(std::function<void()> draw_fn)
|
||||||
|
{
|
||||||
|
API::draw_through(handle(), draw_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_through_widgets(native_drawable_type drawable)
|
||||||
|
{
|
||||||
|
API::map_through_widgets(handle(), drawable);
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
DrawerTrigger& get_drawer_trigger()
|
DrawerTrigger& get_drawer_trigger()
|
||||||
{
|
{
|
||||||
|
@ -292,6 +292,13 @@ namespace nana
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool basic_window::is_draw_through() const
|
||||||
|
{
|
||||||
|
if (::nana::category::flags::root == this->other.category)
|
||||||
|
return static_cast<bool>(other.attribute.root->draw_through);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r)
|
void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r)
|
||||||
{
|
{
|
||||||
pos_owner = pos_root = r;
|
pos_owner = pos_root = r;
|
||||||
|
@ -1265,6 +1265,15 @@ namespace detail
|
|||||||
brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
|
brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
|
||||||
break;
|
break;
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
|
if (msgwnd->is_draw_through())
|
||||||
|
{
|
||||||
|
msgwnd->other.attribute.root->draw_through();
|
||||||
|
|
||||||
|
::PAINTSTRUCT ps;
|
||||||
|
::BeginPaint(root_window, &ps);
|
||||||
|
::EndPaint(root_window, &ps);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
::PAINTSTRUCT ps;
|
::PAINTSTRUCT ps;
|
||||||
::HDC dc = ::BeginPaint(root_window, &ps);
|
::HDC dc = ::BeginPaint(root_window, &ps);
|
||||||
@ -1581,6 +1590,26 @@ namespace detail
|
|||||||
return impl_->estore;
|
return impl_->estore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bedrock::map_through_widgets(core_window_t* wd, native_drawable_type drawable)
|
||||||
|
{
|
||||||
|
#if defined(NANA_WINDOWS)
|
||||||
|
auto graph_context = reinterpret_cast<HDC>(wd->root_graph->handle()->context);
|
||||||
|
|
||||||
|
for (auto child : wd->children)
|
||||||
|
{
|
||||||
|
if (!child->visible) continue;
|
||||||
|
|
||||||
|
if (::nana::category::flags::widget == child->other.category)
|
||||||
|
{
|
||||||
|
::BitBlt(reinterpret_cast<HDC>(drawable), child->pos_root.x, child->pos_root.y, static_cast<int>(child->dimension.width), static_cast<int>(child->dimension.height),
|
||||||
|
graph_context, child->pos_root.x, child->pos_root.y, SRCCOPY);
|
||||||
|
}
|
||||||
|
else if (::nana::category::flags::lite_widget == child->other.category)
|
||||||
|
map_through_widgets(child, drawable);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool bedrock::emit(event_code evt_code, core_window_t* wd, const arg_mouse& arg, bool ask_update, thread_context* thrd)
|
bool bedrock::emit(event_code evt_code, core_window_t* wd, const arg_mouse& arg, bool ask_update, thread_context* thrd)
|
||||||
{
|
{
|
||||||
if (evt_code != arg.evt_code)
|
if (evt_code != arg.evt_code)
|
||||||
|
@ -674,7 +674,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
if (impl_->wd_register.available(wd))
|
if (impl_->wd_register.available(wd) && !wd->is_draw_through())
|
||||||
{
|
{
|
||||||
//Copy the root buffer that wd specified into DeviceContext
|
//Copy the root buffer that wd specified into DeviceContext
|
||||||
#if defined(NANA_LINUX)
|
#if defined(NANA_LINUX)
|
||||||
@ -738,7 +738,7 @@ namespace detail
|
|||||||
if (false == impl_->wd_register.available(wd))
|
if (false == impl_->wd_register.available(wd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(wd->visible)
|
if(wd->visible && (!wd->is_draw_through()))
|
||||||
{
|
{
|
||||||
if (wd->visible_parents())
|
if (wd->visible_parents())
|
||||||
{
|
{
|
||||||
|
@ -20,19 +20,27 @@ namespace nana
|
|||||||
//@brief: This name is only visible for this compiling-unit
|
//@brief: This name is only visible for this compiling-unit
|
||||||
namespace restrict
|
namespace restrict
|
||||||
{
|
{
|
||||||
typedef detail::bedrock::core_window_t core_window_t;
|
namespace
|
||||||
extern detail::bedrock& bedrock;
|
|
||||||
|
|
||||||
inline detail::drawer& get_drawer(window wd)
|
|
||||||
{
|
{
|
||||||
return reinterpret_cast<core_window_t*>(wd)->drawer;
|
using core_window_t = detail::bedrock::core_window_t;
|
||||||
|
|
||||||
|
inline detail::drawer& get_drawer(window wd)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<core_window_t*>(wd)->drawer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//class drawing
|
//class drawing
|
||||||
drawing::drawing(window wd)
|
drawing::drawing(window wd)
|
||||||
:handle_(wd)
|
:handle_(wd)
|
||||||
{}
|
{
|
||||||
|
if (!API::is_window(wd))
|
||||||
|
throw std::invalid_argument("drawing: invalid window parameter");
|
||||||
|
|
||||||
|
if (reinterpret_cast<restrict::core_window_t*>(wd)->is_draw_through())
|
||||||
|
throw std::invalid_argument("drawing: the window is draw_through enabled");
|
||||||
|
}
|
||||||
|
|
||||||
drawing::~drawing(){} //Just for polymorphism
|
drawing::~drawing(){} //Just for polymorphism
|
||||||
|
|
||||||
|
@ -349,6 +349,11 @@ namespace API
|
|||||||
return (restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd)) == false);
|
return (restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd)) == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_window(window wd)
|
||||||
|
{
|
||||||
|
return restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd));
|
||||||
|
}
|
||||||
|
|
||||||
void enable_dropfiles(window wd, bool enb)
|
void enable_dropfiles(window wd, bool enb)
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
@ -564,6 +569,27 @@ namespace API
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_through(window wd, std::function<void()> draw_fn)
|
||||||
|
{
|
||||||
|
auto iwd = reinterpret_cast<restrict::core_window_t*>(wd);
|
||||||
|
internal_scope_guard lock;
|
||||||
|
if (!restrict::bedrock.wd_manager.available(iwd))
|
||||||
|
throw std::invalid_argument("draw_through: invalid window parameter");
|
||||||
|
|
||||||
|
if (::nana::category::flags::root != iwd->other.category)
|
||||||
|
throw std::invalid_argument("draw_through: the window is not a root widget");
|
||||||
|
|
||||||
|
iwd->other.attribute.root->draw_through.swap(draw_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_through_widgets(window wd, native_drawable_type drawable)
|
||||||
|
{
|
||||||
|
auto iwd = reinterpret_cast<::nana::detail::basic_window*>(wd);
|
||||||
|
internal_scope_guard lock;
|
||||||
|
if (restrict::bedrock.wd_manager.available(iwd) && iwd->is_draw_through() )
|
||||||
|
restrict::bedrock.map_through_widgets(iwd, drawable);
|
||||||
|
}
|
||||||
|
|
||||||
nana::size window_size(window wd)
|
nana::size window_size(window wd)
|
||||||
{
|
{
|
||||||
nana::rectangle r;
|
nana::rectangle r;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user