refactor types(#450)

This commit is contained in:
Jinhao 2019-06-26 05:05:05 +08:00
parent 8a0475c98c
commit 975993ff33
20 changed files with 687 additions and 772 deletions

View File

@ -24,10 +24,11 @@ namespace nana
{ {
namespace detail namespace detail
{ {
struct native_window_handle_impl{}; struct basic_window;
struct window_handle_impl{};
struct event_handle_impl{}; struct native_window_handle_impl;
struct native_drawable_impl{}; struct native_drawable_impl;
struct event_handle_impl;
} }
struct accel_key struct accel_key
@ -87,10 +88,11 @@ namespace nana
struct root_tag : public widget_tag{ static const flags value = flags::root; }; struct root_tag : public widget_tag{ static const flags value = flags::root; };
}// end namespace category }// end namespace category
using native_window_type = detail::native_window_handle_impl*; using window = detail::basic_window*; ///< The window handle type representing nana window objects
using window = detail::window_handle_impl*; ///< \see [What is window class ](https://sourceforge.net/p/nanapro/discussion/general/thread/bd0fabfb/) using native_window_type = detail::native_window_handle_impl*; ///< The native window handle type representing system native windows. E.g, HWND in windows, Window in X11
using event_handle = detail::event_handle_impl*;
using native_drawable_type = detail::native_drawable_impl*; using event_handle = detail::event_handle_impl*; ///< The event handle type representing nana window events
using native_drawable_type = detail::native_drawable_impl*; ///< The drawable handle type representing system native drawable objects. E.g. HDC in windows, Drawable in X11
struct keyboard struct keyboard

View File

@ -1,223 +0,0 @@
/*
* Effects Renderer
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/detail/effects_renderer.cpp
*/
#ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#include <nana/gui/effects.hpp>
#include <nana/paint/graphics.hpp>
#include <nana/paint/pixel_buffer.hpp>
#include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/window_layout.hpp>
namespace nana{
namespace detail
{
template<typename CoreWindow>
class edge_nimbus_renderer
{
edge_nimbus_renderer() = default;
public:
using core_window_t = CoreWindow;
using window_layer = ::nana::detail::window_layout;
using graph_reference = ::nana::paint::graphics&;
static edge_nimbus_renderer& instance()
{
static edge_nimbus_renderer object;
return object;
}
constexpr unsigned weight() const
{
return 2;
}
void erase(core_window_t* wd)
{
if (effects::edge_nimbus::none == wd->effect.edge_nimbus)
return;
core_window_t * root_wd = wd->root_widget;
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
for (auto i = nimbus.begin(); i != nimbus.end(); ++i)
{
if (i->window == wd)
{
auto pixels = weight();
rectangle r{wd->pos_root, wd->dimension};
r.x -= static_cast<int>(pixels);
r.y -= static_cast<int>(pixels);
r.width += static_cast<unsigned>(pixels << 1);
r.height += static_cast<unsigned>(pixels << 1);
root_wd->root_graph->paste(root_wd->root, r, r.x, r.y);
nimbus.erase(i);
break;
}
}
}
void render(core_window_t * wd, bool forced, const rectangle* update_area = nullptr)
{
bool copy_separately = true;
std::vector<std::pair<rectangle, core_window_t*>> rd_set;
if (wd->root_widget->other.attribute.root->effects_edge_nimbus.size())
{
auto root_wd = wd->root_widget;
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
auto focused = root_wd->other.attribute.root->focus;
const unsigned pixels = weight();
auto graph = root_wd->root_graph;
nana::rectangle r;
for(auto & action : nimbus)
{
if(_m_edge_nimbus(action.window, focused) && window_layer::read_visual_rectangle(action.window, r))
{
if (action.window == wd)
{
if (update_area)
::nana::overlap(*update_area, rectangle(r), r);
copy_separately = false;
}
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
if ((forced && (action.window == wd)) || (focused == action.window) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refreshed))
{
rd_set.emplace_back(r, action.window);
action.rendered = true;
}
}
else if(action.rendered)
{
action.rendered = false;
if (action.window == wd)
copy_separately = false;
::nana::rectangle erase_r(
action.window->pos_root.x - static_cast<int>(pixels),
action.window->pos_root.y - static_cast<int>(pixels),
static_cast<unsigned>(action.window->dimension.width + (pixels << 1)),
static_cast<unsigned>(action.window->dimension.height + (pixels << 1))
);
graph->paste(root_wd->root, erase_r, erase_r.x, erase_r.y);
}
}
}
if (copy_separately)
{
rectangle vr;
if (window_layer::read_visual_rectangle(wd, vr))
{
if (update_area)
::nana::overlap(*update_area, rectangle(vr), vr);
wd->root_graph->paste(wd->root, vr, vr.x, vr.y);
}
}
rectangle wd_r{ wd->pos_root, wd->dimension };
wd_r.pare_off(-static_cast<int>(this->weight()));
//Render
for (auto & rd : rd_set)
{
auto other_wd = rd.second;
if (other_wd != wd)
{
rectangle other_r{ other_wd->pos_root, other_wd->dimension };
other_r.pare_off(-static_cast<int>(this->weight()));
if (!overlapped(wd_r, other_r))
continue;
}
_m_render_edge_nimbus(other_wd, rd.first);
}
}
private:
/// Determines whether the effect will be rendered for the given window.
static bool _m_edge_nimbus(core_window_t * const wd, core_window_t * const focused_wd)
{
// Don't render the effect if the window is disabled.
if (wd->flags.enabled)
{
if ((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active)))
return true;
else if ((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered))
return true;
}
return false;
}
void _m_render_edge_nimbus(core_window_t* wd, const nana::rectangle & visual)
{
wd->flags.action_before = wd->flags.action;
auto r = visual;
r.pare_off(-static_cast<int>(weight()));
rectangle good_r;
if (overlap(r, rectangle{ wd->root_graph->size() }, good_r))
{
if ((good_r.x < wd->pos_root.x) || (good_r.y < wd->pos_root.y) ||
(good_r.right() > visual.right()) || (good_r.bottom() > visual.bottom()))
{
auto graph = wd->root_graph;
nana::paint::pixel_buffer pixbuf(graph->handle(), r);
pixel_argb_t px0, px1, px2, px3;
px0 = pixbuf.pixel(0, 0);
px1 = pixbuf.pixel(r.width - 1, 0);
px2 = pixbuf.pixel(0, r.height - 1);
px3 = pixbuf.pixel(r.width - 1, r.height - 1);
good_r.x = good_r.y = 1;
good_r.width = r.width - 2;
good_r.height = r.height - 2;
pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.95, false);
good_r.x = good_r.y = 0;
good_r.width = r.width;
good_r.height = r.height;
pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.4, false);
pixbuf.pixel(0, 0, px0);
pixbuf.pixel(r.width - 1, 0, px1);
pixbuf.pixel(0, r.height - 1, px2);
pixbuf.pixel(r.width - 1, r.height - 1, px3);
pixbuf.paste(wd->root, { r.x, r.y });
std::vector<typename window_layer::wd_rectangle> overlaps;
if(window_layer::read_overlaps(wd, visual, overlaps))
{
for(auto & wdr : overlaps)
graph->paste(wd->root, wdr.r, wdr.r.x, wdr.r.y);
}
}
else
wd->root_graph->paste(wd->root, visual, visual.x, visual.y);
}
}
};
}
}//end namespace nana
#endif

View File

@ -24,9 +24,13 @@
namespace nana namespace nana
{ {
namespace API
{
bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window.
}
namespace detail namespace detail
{ {
bool check_window(window);
void events_operation_register(event_handle); void events_operation_register(event_handle);
class event_interface class event_interface
@ -36,16 +40,16 @@ namespace nana
virtual void remove(event_handle) = 0; virtual void remove(event_handle) = 0;
}; };
class docker_interface class event_docker_interface
{ {
public: public:
virtual ~docker_interface() = default; virtual ~event_docker_interface() = default;
virtual event_interface* get_event() const = 0; virtual event_interface* get_event() const = 0;
}; };
struct docker_base struct docker_base
: public docker_interface : public event_docker_interface
{ {
event_interface * const event_ptr; event_interface * const event_ptr;
bool flag_deleted; bool flag_deleted;
@ -78,11 +82,11 @@ namespace nana
event_base * const evt_; event_base * const evt_;
}; };
event_handle _m_emplace(detail::docker_interface*, bool in_front); event_handle _m_emplace(detail::event_docker_interface*, bool in_front);
protected: protected:
unsigned emitting_count_{ 0 }; unsigned emitting_count_{ 0 };
bool deleted_flags_{ false }; bool deleted_flags_{ false };
std::vector<detail::docker_interface*> * dockers_{ nullptr }; std::vector<detail::event_docker_interface*> * dockers_{ nullptr };
}; };
}//end namespace detail }//end namespace detail
@ -228,7 +232,7 @@ namespace nana
d->invoke(arg); d->invoke(arg);
if (window_handle && (!detail::check_window(window_handle))) if (window_handle && (!::nana::API::is_window(window_handle)))
break; break;
} }
} }

View File

@ -10,7 +10,7 @@
* @file: nana/gui/detail/basic_window.cpp * @file: nana/gui/detail/basic_window.cpp
*/ */
#include <nana/gui/detail/basic_window.hpp> #include "basic_window.hpp"
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
namespace nana namespace nana

View File

@ -14,11 +14,11 @@
#ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP #ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP
#define NANA_GUI_DETAIL_BASIC_WINDOW_HPP #define NANA_GUI_DETAIL_BASIC_WINDOW_HPP
#include <nana/push_ignore_diagnostic> #include <nana/push_ignore_diagnostic>
#include "drawer.hpp" #include <nana/gui/detail/drawer.hpp>
#include "events_holder.hpp" #include <nana/gui/detail/events_holder.hpp>
#include "widget_geometrics.hpp" #include <nana/gui/detail/widget_geometrics.hpp>
#include "widget_content_measurer_interface.hpp" #include <nana/gui/detail/widget_content_measurer_interface.hpp>
#include "widget_notifier_interface.hpp" #include <nana/gui/detail/widget_notifier_interface.hpp>
#include <nana/basic_types.hpp> #include <nana/basic_types.hpp>
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <nana/gui/effects.hpp> #include <nana/gui/effects.hpp>

View File

@ -11,16 +11,17 @@
*/ */
#include "../../detail/platform_spec_selector.hpp" #include "../../detail/platform_spec_selector.hpp"
#include "basic_window.hpp"
#include "bedrock_types.hpp" #include "bedrock_types.hpp"
#include <nana/gui/detail/event_code.hpp> #include <nana/gui/detail/event_code.hpp>
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <sstream>
#include <nana/system/timepiece.hpp> #include <nana/system/timepiece.hpp>
#include <nana/gui/wvl.hpp> #include <nana/gui/wvl.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/element_store.hpp> #include <nana/gui/detail/element_store.hpp>
#include <sstream>
#include <algorithm> #include <algorithm>
namespace nana namespace nana
@ -64,11 +65,6 @@ namespace nana
namespace detail namespace detail
{ {
bool check_window(window wd)
{
return bedrock::instance().wd_manager().available(reinterpret_cast<window_manager::core_window_t*>(wd));
}
void events_operation_register(event_handle evt) void events_operation_register(event_handle evt)
{ {
bedrock::instance().evt_operation().register_evt(evt); bedrock::instance().evt_operation().register_evt(evt);
@ -171,7 +167,7 @@ namespace nana
arg_expose arg; arg_expose arg;
arg.exposed = exposed; arg.exposed = exposed;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
if (emit(event_code::expose, wd, arg, false, get_thread_context())) if (emit(event_code::expose, wd, arg, false, get_thread_context()))
{ {
//Get the window who has the activated caret //Get the window who has the activated caret
@ -203,7 +199,7 @@ namespace nana
if (wd) if (wd)
{ {
arg_move arg; arg_move arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.x = x; arg.x = x;
arg.y = y; arg.y = y;
emit(event_code::move, wd, arg, true, get_thread_context()); emit(event_code::move, wd, arg, true, get_thread_context());
@ -218,7 +214,7 @@ namespace nana
arg_mouse arg; arg_mouse arg;
arg.evt_code = event_code::mouse_leave; arg.evt_code = event_code::mouse_leave;
arg.window_handle = reinterpret_cast<window>(hovered); arg.window_handle = hovered;
arg.pos.x = arg.pos.y = 0; arg.pos.x = arg.pos.y = 0;
arg.left_button = arg.right_button = arg.mid_button = false; arg.left_button = arg.right_button = arg.mid_button = false;
arg.ctrl = arg.shift = false; arg.ctrl = arg.shift = false;
@ -234,7 +230,7 @@ namespace nana
auto focused = root_wd->other.attribute.root->focus; auto focused = root_wd->other.attribute.root->focus;
arg_focus arg; arg_focus arg;
arg.window_handle = reinterpret_cast<window>(focused); arg.window_handle = focused;
arg.getting = getting; arg.getting = getting;
arg.receiver = receiver; arg.receiver = receiver;
@ -416,7 +412,7 @@ namespace nana
wd->drawer.click(*arg, bForce__EmitInternal); wd->drawer.click(*arg, bForce__EmitInternal);
} }
if (bProcess__External_event) if (bProcess__External_event)
evts_ptr->click.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->click.emit(*arg, wd);
} }
} }
break; break;
@ -471,7 +467,7 @@ namespace nana
} }
if (bProcess__External_event) if (bProcess__External_event)
evt_addr->emit(*arg, reinterpret_cast<window>(wd)); evt_addr->emit(*arg, wd);
break; break;
} }
case event_code::mouse_wheel: case event_code::mouse_wheel:
@ -486,7 +482,7 @@ namespace nana
} }
if (bProcess__External_event) if (bProcess__External_event)
evts_ptr->mouse_wheel.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->mouse_wheel.emit(*arg, wd);
} }
break; break;
} }
@ -530,7 +526,7 @@ namespace nana
} }
if (bProcess__External_event) if (bProcess__External_event)
evt_addr->emit(*arg, reinterpret_cast<window>(wd)); evt_addr->emit(*arg, wd);
break; break;
} }
case event_code::expose: case event_code::expose:
@ -538,7 +534,7 @@ namespace nana
{ {
auto arg = dynamic_cast<const arg_expose*>(&event_arg); auto arg = dynamic_cast<const arg_expose*>(&event_arg);
if (arg) if (arg)
evts_ptr->expose.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->expose.emit(*arg, wd);
} }
break; break;
case event_code::focus: case event_code::focus:
@ -552,7 +548,7 @@ namespace nana
wd->drawer.focus(*arg, bForce__EmitInternal); wd->drawer.focus(*arg, bForce__EmitInternal);
} }
if (bProcess__External_event) if (bProcess__External_event)
evts_ptr->focus.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->focus.emit(*arg, wd);
} }
break; break;
} }
@ -567,7 +563,7 @@ namespace nana
wd->drawer.move(*arg, bForce__EmitInternal); wd->drawer.move(*arg, bForce__EmitInternal);
} }
if (bProcess__External_event) if (bProcess__External_event)
evts_ptr->move.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->move.emit(*arg, wd);
} }
break; break;
} }
@ -582,7 +578,7 @@ namespace nana
wd->drawer.resizing(*arg, bForce__EmitInternal); wd->drawer.resizing(*arg, bForce__EmitInternal);
} }
if (bProcess__External_event) if (bProcess__External_event)
evts_ptr->resizing.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->resizing.emit(*arg, wd);
} }
break; break;
} }
@ -597,7 +593,7 @@ namespace nana
wd->drawer.resized(*arg, bForce__EmitInternal); wd->drawer.resized(*arg, bForce__EmitInternal);
} }
if (bProcess__External_event) if (bProcess__External_event)
evts_ptr->resized.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->resized.emit(*arg, wd);
} }
break; break;
} }
@ -609,7 +605,7 @@ namespace nana
{ {
auto evt_root = dynamic_cast<events_root_extension*>(evts_ptr); auto evt_root = dynamic_cast<events_root_extension*>(evts_ptr);
if (evt_root) if (evt_root)
evt_root->unload.emit(*arg, reinterpret_cast<window>(wd)); evt_root->unload.emit(*arg, wd);
} }
} }
break; break;
@ -618,7 +614,7 @@ namespace nana
{ {
auto arg = dynamic_cast<const arg_destroy*>(&event_arg); auto arg = dynamic_cast<const arg_destroy*>(&event_arg);
if (arg) if (arg)
evts_ptr->destroy.emit(*arg, reinterpret_cast<window>(wd)); evts_ptr->destroy.emit(*arg, wd);
} }
break; break;
default: default:

View File

@ -143,7 +143,7 @@ namespace detail
void bedrock::flush_surface(core_window_t* wd, bool forced, const rectangle* update_area) void bedrock::flush_surface(core_window_t* wd, bool forced, const rectangle* update_area)
{ {
wd->drawer.map(reinterpret_cast<window>(wd), forced, update_area); wd->drawer.map(wd, forced, update_area);
} }
//inc_window //inc_window
@ -255,7 +255,7 @@ namespace detail
void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt) void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt)
{ {
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.button = ::nana::mouse::any_button; arg.button = ::nana::mouse::any_button;
int mask_state = 0; int mask_state = 0;
@ -308,7 +308,7 @@ namespace detail
void assign_arg(arg_focus& arg, basic_window* wd, native_window_type recv, bool getting) void assign_arg(arg_focus& arg, basic_window* wd, native_window_type recv, bool getting)
{ {
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.receiver = recv; arg.receiver = recv;
arg.getting = getting; arg.getting = getting;
arg.focus_reason = arg_focus::reason::general; arg.focus_reason = arg_focus::reason::general;
@ -317,7 +317,7 @@ namespace detail
void assign_arg(arg_wheel& arg, basic_window* wd, const XEvent& evt) void assign_arg(arg_wheel& arg, basic_window* wd, const XEvent& evt)
{ {
arg.evt_code = event_code::mouse_wheel; arg.evt_code = event_code::mouse_wheel;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
if (ButtonRelease == evt.type && (evt.xbutton.button == Button4 || evt.xbutton.button == Button5)) if (ButtonRelease == evt.type && (evt.xbutton.button == Button4 || evt.xbutton.button == Button5))
{ {
arg.evt_code = event_code::mouse_wheel; arg.evt_code = event_code::mouse_wheel;
@ -371,12 +371,12 @@ namespace detail
if(msgwd) if(msgwd)
{ {
arg_dropfiles arg; arg_dropfiles arg;
arg.window_handle = reinterpret_cast<window>(msgwd); arg.window_handle = msgwd;
arg.files.swap(*msg.u.mouse_drop.files); arg.files.swap(*msg.u.mouse_drop.files);
delete msg.u.mouse_drop.files; delete msg.u.mouse_drop.files;
arg.pos.x = msg.u.mouse_drop.x - msgwd->pos_root.x; arg.pos.x = msg.u.mouse_drop.x - msgwd->pos_root.x;
arg.pos.y = msg.u.mouse_drop.y - msgwd->pos_root.y; arg.pos.y = msg.u.mouse_drop.y - msgwd->pos_root.y;
msgwd->annex.events_ptr->mouse_dropfiles.emit(arg, reinterpret_cast<window>(msgwd)); msgwd->annex.events_ptr->mouse_dropfiles.emit(arg, msgwd);
brock.wd_manager().do_lazy_refresh(msgwd, false); brock.wd_manager().do_lazy_refresh(msgwd, false);
} }
break; break;
@ -539,15 +539,15 @@ namespace detail
auto shr_wd = wd_manager.find_shortkey(native_window, arg.key); auto shr_wd = wd_manager.find_shortkey(native_window, arg.key);
if(shr_wd) if(shr_wd)
{ {
arg.window_handle = reinterpret_cast<window>(shr_wd); arg.window_handle = shr_wd;
brock.emit(event_code::shortkey, shr_wd, arg, true, &context); brock.emit(event_code::shortkey, shr_wd, arg, true, &context);
} }
continue; continue;
} }
arg.evt_code = event_code::key_char; arg.evt_code = event_code::key_char;
arg.window_handle = reinterpret_cast<window>(msgwd); arg.window_handle = msgwd;
msgwd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwd)); msgwd->annex.events_ptr->key_char.emit(arg, msgwd);
if(arg.ignore == false && wd_manager.available(msgwd)) if(arg.ignore == false && wd_manager.available(msgwd))
draw_invoker(&drawer::key_char, msgwd, arg, &context); draw_invoker(&drawer::key_char, msgwd, arg, &context);
} }
@ -789,7 +789,7 @@ namespace detail
{ {
msgwnd->set_action(mouse_action::hovered); msgwnd->set_action(mouse_action::hovered);
click_arg.window_handle = reinterpret_cast<window>(msgwnd); click_arg.window_handle = msgwnd;
draw_invoker(&drawer::click, msgwnd, click_arg, &context); draw_invoker(&drawer::click, msgwnd, click_arg, &context);
} }
} }
@ -807,16 +807,16 @@ namespace detail
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
if(click_arg.window_handle) if(click_arg.window_handle)
evt_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); evt_ptr->click.emit(click_arg, msgwnd);
if (wd_manager.available(msgwnd)) if (wd_manager.available(msgwnd))
{ {
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
evt_ptr->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd)); evt_ptr->mouse_up.emit(arg, msgwnd);
} }
} }
else if(click_arg.window_handle) else if(click_arg.window_handle)
msgwnd->annex.events_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->click.emit(click_arg, msgwnd);
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
@ -940,7 +940,7 @@ namespace detail
//Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed. //Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed.
::nana::rectangle update_area(xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.width, xevent.xexpose.height); ::nana::rectangle update_area(xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.width, xevent.xexpose.height);
if (!update_area.empty()) if (!update_area.empty())
msgwnd->drawer.map(reinterpret_cast<window>(msgwnd), true, &update_area); msgwnd->drawer.map(msgwnd, true, &update_area);
} }
} }
break; break;
@ -1030,7 +1030,7 @@ namespace detail
arg.mid_button = false; arg.mid_button = false;
arg.pos.x = 0; arg.pos.x = 0;
arg.pos.y = 0; arg.pos.y = 0;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
msgwnd->set_action(mouse_action::pressed); msgwnd->set_action(mouse_action::pressed);
@ -1052,7 +1052,7 @@ namespace detail
bool focused = (brock.focus() == msgwnd); bool focused = (brock.focus() == msgwnd);
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_press; arg.evt_code = event_code::key_press;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
arg.key = os_code; arg.key = os_code;
brock.get_key_state(arg); brock.get_key_state(arg);
@ -1074,7 +1074,7 @@ namespace detail
arg.ignore = false; arg.ignore = false;
arg.key = os_code; arg.key = os_code;
arg.evt_code = event_code::key_press; arg.evt_code = event_code::key_press;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
brock.emit(event_code::key_press, msgwnd, arg, true, &context); brock.emit(event_code::key_press, msgwnd, arg, true, &context);
@ -1130,7 +1130,7 @@ namespace detail
arg_click click_arg; arg_click click_arg;
click_arg.mouse_args = nullptr; click_arg.mouse_args = nullptr;
click_arg.window_handle = reinterpret_cast<window>(msgwnd); click_arg.window_handle = msgwnd;
arg_mouse arg; arg_mouse arg;
arg.alt = false; arg.alt = false;
@ -1141,7 +1141,7 @@ namespace detail
arg.mid_button = false; arg.mid_button = false;
arg.pos.x = 0; arg.pos.x = 0;
arg.pos.y = 0; arg.pos.y = 0;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
@ -1155,7 +1155,7 @@ namespace detail
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_release; arg.evt_code = event_code::key_release;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
arg.key = os_code; arg.key = os_code;
brock.get_key_state(arg); brock.get_key_state(arg);
@ -1181,7 +1181,7 @@ namespace detail
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_release; arg.evt_code = event_code::key_release;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
arg.key = os_code; arg.key = os_code;
brock.get_key_state(arg); brock.get_key_state(arg);
@ -1208,7 +1208,7 @@ namespace detail
if(msgwnd->flags.enabled && (atoms.wm_delete_window == static_cast<Atom>(xclient.data.l[0]))) if(msgwnd->flags.enabled && (atoms.wm_delete_window == static_cast<Atom>(xclient.data.l[0])))
{ {
arg_unload arg; arg_unload arg;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.cancel = false; arg.cancel = false;
brock.emit(event_code::unload, msgwnd, arg, true, &context); brock.emit(event_code::unload, msgwnd, arg, true, &context);
if(false == arg.cancel) if(false == arg.cancel)
@ -1262,7 +1262,7 @@ namespace detail
core_window_t * owner = 0; core_window_t * owner = 0;
if(condition_wd && is_modal) if(condition_wd && is_modal)
{ {
native_window_type modal = reinterpret_cast<core_window_t*>(condition_wd)->root; native_window_type modal = condition_wd->root;
owner_native = native_interface::get_window(modal, window_relationship::owner); owner_native = native_interface::get_window(modal, window_relationship::owner);
if(owner_native) if(owner_native)
{ {
@ -1273,7 +1273,7 @@ namespace detail
} }
} }
nana::detail::platform_spec::instance().msg_dispatch(condition_wd ? reinterpret_cast<core_window_t*>(condition_wd)->root : 0); nana::detail::platform_spec::instance().msg_dispatch(condition_wd ? condition_wd->root : 0);
if(owner_native) if(owner_native)
{ {

View File

@ -311,7 +311,7 @@ namespace detail
} }
} }
else else
wd->drawer.map(reinterpret_cast<window>(wd), forced, update_area); wd->drawer.map(wd, forced, update_area);
} }
void interior_helper_for_menu(MSG& msg, native_window_type menu_window) void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
@ -367,7 +367,7 @@ namespace detail
MSG msg; MSG msg;
if (condition_wd) if (condition_wd)
{ {
HWND native_handle = reinterpret_cast<HWND>(reinterpret_cast<core_window_t*>(condition_wd)->root); HWND native_handle = reinterpret_cast<HWND>(condition_wd->root);
if (is_modal) if (is_modal)
{ {
HWND owner = ::GetWindow(native_handle, GW_OWNER); HWND owner = ::GetWindow(native_handle, GW_OWNER);
@ -466,7 +466,7 @@ namespace detail
void assign_arg(nana::arg_mouse& arg, basic_window* wd, unsigned msg, const parameter_decoder& pmdec) void assign_arg(nana::arg_mouse& arg, basic_window* wd, unsigned msg, const parameter_decoder& pmdec)
{ {
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
bool set_key_state = true; bool set_key_state = true;
switch (msg) switch (msg)
@ -530,7 +530,7 @@ namespace detail
void assign_arg(arg_wheel& arg, basic_window* wd, const parameter_decoder& pmdec) void assign_arg(arg_wheel& arg, basic_window* wd, const parameter_decoder& pmdec)
{ {
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.evt_code = event_code::mouse_wheel; arg.evt_code = event_code::mouse_wheel;
POINT point = { pmdec.mouse.x, pmdec.mouse.y }; POINT point = { pmdec.mouse.x, pmdec.mouse.y };
@ -985,7 +985,7 @@ namespace detail
msgwnd->set_action(mouse_action::hovered); msgwnd->set_action(mouse_action::hovered);
if ((::nana::mouse::left_button == arg.button) && (pressed_wd == msgwnd)) if ((::nana::mouse::left_button == arg.button) && (pressed_wd == msgwnd))
{ {
click_arg.window_handle = reinterpret_cast<window>(msgwnd); click_arg.window_handle = msgwnd;
draw_invoker(&drawer::click, msgwnd, click_arg, &context); draw_invoker(&drawer::click, msgwnd, click_arg, &context);
} }
} }
@ -997,16 +997,16 @@ namespace detail
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
if (click_arg.window_handle) if (click_arg.window_handle)
retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); retain->click.emit(click_arg, msgwnd);
if (wd_manager.available(msgwnd)) if (wd_manager.available(msgwnd))
{ {
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
retain->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd)); retain->mouse_up.emit(arg, msgwnd);
} }
} }
else if (click_arg.window_handle) else if (click_arg.window_handle)
retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); retain->click.emit(click_arg, msgwnd);
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
@ -1176,9 +1176,9 @@ namespace detail
dropfiles.pos = pos; dropfiles.pos = pos;
wd_manager.calc_window_point(msgwnd, dropfiles.pos); wd_manager.calc_window_point(msgwnd, dropfiles.pos);
dropfiles.window_handle = reinterpret_cast<window>(msgwnd); dropfiles.window_handle = msgwnd;
msgwnd->annex.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->mouse_dropfiles.emit(dropfiles, msgwnd);
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
} }
@ -1232,7 +1232,7 @@ namespace detail
static_cast<unsigned>(r->bottom - r->top - msgwnd->extra_height)); static_cast<unsigned>(r->bottom - r->top - msgwnd->extra_height));
arg_resizing arg; arg_resizing arg;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.width = size_before.width; arg.width = size_before.width;
arg.height = size_before.height; arg.height = size_before.height;
@ -1285,7 +1285,7 @@ namespace detail
//Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed. //Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed.
::nana::rectangle update_area(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); ::nana::rectangle update_area(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top);
if (!update_area.empty()) if (!update_area.empty())
msgwnd->drawer.map(reinterpret_cast<window>(msgwnd), true, &update_area); msgwnd->drawer.map(msgwnd, true, &update_area);
} }
::EndPaint(root_window, &ps); ::EndPaint(root_window, &ps);
} }
@ -1300,7 +1300,7 @@ namespace detail
arg.evt_code = event_code::shortkey; arg.evt_code = event_code::shortkey;
arg.key = static_cast<wchar_t>(wParam < 0x61 ? wParam + 0x61 - 0x41 : wParam); arg.key = static_cast<wchar_t>(wParam < 0x61 ? wParam + 0x61 - 0x41 : wParam);
arg.ctrl = arg.shift = false; arg.ctrl = arg.shift = false;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
brock.emit(event_code::shortkey, msgwnd, arg, true, &context); brock.emit(event_code::shortkey, msgwnd, arg, true, &context);
def_window_proc = false; def_window_proc = false;
@ -1316,7 +1316,7 @@ namespace detail
bool focused = (brock.focus() == msgwnd); bool focused = (brock.focus() == msgwnd);
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_press; arg.evt_code = event_code::key_press;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
arg.key = static_cast<wchar_t>(wParam); arg.key = static_cast<wchar_t>(wParam);
brock.get_key_state(arg); brock.get_key_state(arg);
@ -1344,7 +1344,7 @@ namespace detail
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_release; arg.evt_code = event_code::key_release;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
arg.key = static_cast<wchar_t>(wParam); arg.key = static_cast<wchar_t>(wParam);
brock.get_key_state(arg); brock.get_key_state(arg);
@ -1397,7 +1397,7 @@ namespace detail
arg.mid_button = false; arg.mid_button = false;
arg.pos.x = 0; arg.pos.x = 0;
arg.pos.y = 0; arg.pos.y = 0;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
msgwnd->set_action(mouse_action::pressed); msgwnd->set_action(mouse_action::pressed);
@ -1412,7 +1412,7 @@ namespace detail
{ {
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_press; arg.evt_code = event_code::key_press;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.ignore = false; arg.ignore = false;
arg.key = translate_virtual_key(wParam); arg.key = translate_virtual_key(wParam);
brock.get_key_state(arg); brock.get_key_state(arg);
@ -1443,12 +1443,12 @@ namespace detail
{ {
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_char; arg.evt_code = event_code::key_char;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.key = static_cast<wchar_t>(wParam); arg.key = static_cast<wchar_t>(wParam);
brock.get_key_state(arg); brock.get_key_state(arg);
arg.ignore = false; arg.ignore = false;
msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->key_char.emit(arg, msgwnd);
if ((false == arg.ignore) && wd_manager.available(msgwnd)) if ((false == arg.ignore) && wd_manager.available(msgwnd))
draw_invoker(&drawer::key_char, msgwnd, arg, &context); draw_invoker(&drawer::key_char, msgwnd, arg, &context);
@ -1476,7 +1476,7 @@ namespace detail
arg_click click_arg; arg_click click_arg;
click_arg.mouse_args = nullptr; click_arg.mouse_args = nullptr;
click_arg.window_handle = reinterpret_cast<window>(msgwnd); click_arg.window_handle = msgwnd;
arg_mouse arg; arg_mouse arg;
arg.alt = false; arg.alt = false;
@ -1487,7 +1487,7 @@ namespace detail
arg.mid_button = false; arg.mid_button = false;
arg.pos.x = 0; arg.pos.x = 0;
arg.pos.y = 0; arg.pos.y = 0;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
@ -1500,7 +1500,7 @@ namespace detail
{ {
arg_keyboard keyboard_arg; arg_keyboard keyboard_arg;
keyboard_arg.evt_code = event_code::key_release; keyboard_arg.evt_code = event_code::key_release;
keyboard_arg.window_handle = reinterpret_cast<window>(msgwnd); keyboard_arg.window_handle = msgwnd;
keyboard_arg.key = translate_virtual_key(wParam); keyboard_arg.key = translate_virtual_key(wParam);
brock.get_key_state(keyboard_arg); brock.get_key_state(keyboard_arg);
keyboard_arg.ignore = false; keyboard_arg.ignore = false;
@ -1521,7 +1521,7 @@ namespace detail
case WM_CLOSE: case WM_CLOSE:
{ {
arg_unload arg; arg_unload arg;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = msgwnd;
arg.cancel = false; arg.cancel = false;
brock.emit(event_code::unload, msgwnd, arg, true, &context); brock.emit(event_code::unload, msgwnd, arg, true, &context);
if (!arg.cancel) if (!arg.cancel)
@ -1742,9 +1742,6 @@ namespace detail
void bedrock::undefine_state_cursor(core_window_t * wd, thread_context* thrd) void bedrock::undefine_state_cursor(core_window_t * wd, thread_context* thrd)
{ {
if (nullptr == thrd)
thrd = get_thread_context(wd->thread_id);
HCURSOR rev_handle = ::LoadCursor(nullptr, IDC_ARROW); HCURSOR rev_handle = ::LoadCursor(nullptr, IDC_ARROW);
if (!wd_manager().available(wd)) if (!wd_manager().available(wd))
{ {
@ -1753,6 +1750,9 @@ namespace detail
return; return;
} }
if (nullptr == thrd)
thrd = get_thread_context(wd->thread_id);
wd->root_widget->other.attribute.root->state_cursor = nana::cursor::arrow; wd->root_widget->other.attribute.root->state_cursor = nana::cursor::arrow;
wd->root_widget->other.attribute.root->state_cursor_window = nullptr; wd->root_widget->other.attribute.root->state_cursor_window = nullptr;

View File

@ -10,11 +10,11 @@
* @file: nana/gui/detail/drawer.cpp * @file: nana/gui/detail/drawer.cpp
*/ */
#include "basic_window.hpp"
#include "effects_renderer.hpp"
#include <nana/config.hpp> #include <nana/config.hpp>
#include <nana/gui/detail/bedrock.hpp> #include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/drawer.hpp> #include <nana/gui/detail/drawer.hpp>
#include <nana/gui/detail/effects_renderer.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include "dynamic_drawing_object.hpp" #include "dynamic_drawing_object.hpp"
#if defined(NANA_X11) #if defined(NANA_X11)
@ -23,8 +23,6 @@
namespace nana namespace nana
{ {
typedef detail::edge_nimbus_renderer<detail::bedrock::core_window_t> edge_nimbus_renderer_t;
//class drawer_trigger //class drawer_trigger
void drawer_trigger::attached(widget_reference, graph_reference){} void drawer_trigger::attached(widget_reference, graph_reference){}
void drawer_trigger::detached(){} //none-const void drawer_trigger::detached(){} //none-const
@ -360,7 +358,7 @@ namespace nana
#endif #endif
} }
edge_nimbus_renderer_t::instance().render(iwd, forced, update_area); edge_nimbus_renderer::instance().render(iwd, forced, update_area);
if(owns_caret) if(owns_caret)
{ {
@ -475,4 +473,192 @@ namespace nana
return data_impl_->mth_state[pos]; return data_impl_->mth_state[pos];
} }
}//end namespace detail }//end namespace detail
namespace detail
{
//class edge_nimbus_renderer
edge_nimbus_renderer& edge_nimbus_renderer::instance()
{
static edge_nimbus_renderer object;
return object;
}
void edge_nimbus_renderer::erase(basic_window* wd)
{
if (effects::edge_nimbus::none == wd->effect.edge_nimbus)
return;
auto root_wd = wd->root_widget;
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
for (auto i = nimbus.begin(); i != nimbus.end(); ++i)
{
if (i->window == wd)
{
auto pixels = weight();
rectangle r{ wd->pos_root, wd->dimension };
r.x -= static_cast<int>(pixels);
r.y -= static_cast<int>(pixels);
r.width += static_cast<unsigned>(pixels << 1);
r.height += static_cast<unsigned>(pixels << 1);
root_wd->root_graph->paste(root_wd->root, r, r.x, r.y);
nimbus.erase(i);
break;
}
}
}
void edge_nimbus_renderer::render(basic_window* wd, bool forced, const rectangle* update_area)
{
bool copy_separately = true;
std::vector<std::pair<rectangle, basic_window*>> rd_set;
if (wd->root_widget->other.attribute.root->effects_edge_nimbus.size())
{
auto root_wd = wd->root_widget;
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
auto focused = root_wd->other.attribute.root->focus;
const unsigned pixels = weight();
auto graph = root_wd->root_graph;
nana::rectangle r;
for (auto & action : nimbus)
{
if (_m_edge_nimbus(action.window, focused) && window_layer::read_visual_rectangle(action.window, r))
{
if (action.window == wd)
{
if (update_area)
::nana::overlap(*update_area, rectangle(r), r);
copy_separately = false;
}
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
if ((forced && (action.window == wd)) || (focused == action.window) || !action.rendered || (action.window->other.upd_state == basic_window::update_state::refreshed))
{
rd_set.emplace_back(r, action.window);
action.rendered = true;
}
}
else if (action.rendered)
{
action.rendered = false;
if (action.window == wd)
copy_separately = false;
::nana::rectangle erase_r(
action.window->pos_root.x - static_cast<int>(pixels),
action.window->pos_root.y - static_cast<int>(pixels),
static_cast<unsigned>(action.window->dimension.width + (pixels << 1)),
static_cast<unsigned>(action.window->dimension.height + (pixels << 1))
);
graph->paste(root_wd->root, erase_r, erase_r.x, erase_r.y);
}
}
}
if (copy_separately)
{
rectangle vr;
if (window_layer::read_visual_rectangle(wd, vr))
{
if (update_area)
::nana::overlap(*update_area, rectangle(vr), vr);
wd->root_graph->paste(wd->root, vr, vr.x, vr.y);
}
}
rectangle wd_r{ wd->pos_root, wd->dimension };
wd_r.pare_off(-static_cast<int>(this->weight()));
//Render
for (auto & rd : rd_set)
{
auto other_wd = rd.second;
if (other_wd != wd)
{
rectangle other_r{ other_wd->pos_root, other_wd->dimension };
other_r.pare_off(-static_cast<int>(this->weight()));
if (!overlapped(wd_r, other_r))
continue;
}
_m_render_edge_nimbus(other_wd, rd.first);
}
}
/// Determines whether the effect will be rendered for the given window.
bool edge_nimbus_renderer::_m_edge_nimbus(basic_window * const wd, basic_window * const focused_wd)
{
// Don't render the effect if the window is disabled.
if (wd->flags.enabled)
{
if ((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active)))
return true;
else if ((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered))
return true;
}
return false;
}
void edge_nimbus_renderer::_m_render_edge_nimbus(basic_window* wd, const nana::rectangle & visual)
{
wd->flags.action_before = wd->flags.action;
auto r = visual;
r.pare_off(-static_cast<int>(weight()));
rectangle good_r;
if (overlap(r, rectangle{ wd->root_graph->size() }, good_r))
{
if ((good_r.x < wd->pos_root.x) || (good_r.y < wd->pos_root.y) ||
(good_r.right() > visual.right()) || (good_r.bottom() > visual.bottom()))
{
auto graph = wd->root_graph;
nana::paint::pixel_buffer pixbuf(graph->handle(), r);
pixel_argb_t px0, px1, px2, px3;
px0 = pixbuf.pixel(0, 0);
px1 = pixbuf.pixel(r.width - 1, 0);
px2 = pixbuf.pixel(0, r.height - 1);
px3 = pixbuf.pixel(r.width - 1, r.height - 1);
good_r.x = good_r.y = 1;
good_r.width = r.width - 2;
good_r.height = r.height - 2;
pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.95, false);
good_r.x = good_r.y = 0;
good_r.width = r.width;
good_r.height = r.height;
pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.4, false);
pixbuf.pixel(0, 0, px0);
pixbuf.pixel(r.width - 1, 0, px1);
pixbuf.pixel(0, r.height - 1, px2);
pixbuf.pixel(r.width - 1, r.height - 1, px3);
pixbuf.paste(wd->root, { r.x, r.y });
std::vector<typename window_layer::wd_rectangle> overlaps;
if (window_layer::read_overlaps(wd, visual, overlaps))
{
for (auto & wdr : overlaps)
graph->paste(wd->root, wdr.r, wdr.r.x, wdr.r.y);
}
}
else
wd->root_graph->paste(wd->root, visual, visual.x, visual.y);
}
}
//end class edge_nimbus_renderer
}//end namespace detail
}//end namespace nana }//end namespace nana

View File

@ -0,0 +1,52 @@
/*
* Effects Renderer
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/detail/effects_renderer.cpp
*/
#ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#include "basic_window.hpp"
#include <nana/gui/effects.hpp>
#include <nana/paint/graphics.hpp>
#include <nana/paint/pixel_buffer.hpp>
#include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/window_layout.hpp>
namespace nana{
namespace detail
{
/// Effect edige nimbus renderer
class edge_nimbus_renderer
{
edge_nimbus_renderer() = default;
public:
using window_layer = ::nana::detail::window_layout;
using graph_reference = ::nana::paint::graphics&;
static edge_nimbus_renderer& instance();
constexpr unsigned weight() const
{
return 2;
}
void erase(basic_window* wd);
void render(basic_window* wd, bool forced, const rectangle* update_area = nullptr);
private:
/// Determines whether the effect will be rendered for the given window.
static bool _m_edge_nimbus(basic_window * const wd, basic_window * const focused_wd);
void _m_render_edge_nimbus(basic_window* wd, const nana::rectangle & visual);
};
}
}//end namespace nana
#endif

View File

@ -26,9 +26,7 @@ namespace nana
auto i = handles_.find(evt); auto i = handles_.find(evt);
if (i != handles_.end()) if (i != handles_.end())
{ reinterpret_cast<detail::event_docker_interface*>(evt)->get_event()->remove(evt);
reinterpret_cast<detail::docker_interface*>(evt)->get_event()->remove(evt);
}
} }
//end namespace events_operation //end namespace events_operation
@ -80,35 +78,33 @@ namespace nana
void event_base::remove(event_handle evt) void event_base::remove(event_handle evt)
{ {
internal_scope_guard lock; internal_scope_guard lock;
if (dockers_)
for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i)
{ {
for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i) if (reinterpret_cast<detail::event_docker_interface*>(evt) == *i)
{ {
if (reinterpret_cast<detail::docker_interface*>(evt) == *i) //Checks whether this event is working now.
if (emitting_count_)
{ {
//Checks whether this event is working now. static_cast<docker_base*>(*i)->flag_deleted = true;
if (emitting_count_) deleted_flags_ = true;
{
static_cast<docker_base*>(*i)->flag_deleted = true;
deleted_flags_ = true;
}
else
{
bedrock::instance().evt_operation().cancel(evt);
dockers_->erase(i);
delete reinterpret_cast<detail::docker_interface*>(evt);
}
break;
} }
else
{
bedrock::instance().evt_operation().cancel(evt);
dockers_->erase(i);
delete reinterpret_cast<detail::event_docker_interface*>(evt);
}
return;
} }
} }
} }
event_handle event_base::_m_emplace(detail::docker_interface* docker_ptr, bool in_front) event_handle event_base::_m_emplace(detail::event_docker_interface* docker_ptr, bool in_front)
{ {
internal_scope_guard lock; internal_scope_guard lock;
if (nullptr == dockers_) if (nullptr == dockers_)
dockers_ = new std::vector<detail::docker_interface*>; dockers_ = new std::vector<detail::event_docker_interface*>;
auto evt = reinterpret_cast<event_handle>(docker_ptr); auto evt = reinterpret_cast<event_handle>(docker_ptr);

View File

@ -15,8 +15,8 @@
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP #define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
#include <nana/push_ignore_diagnostic> #include <nana/push_ignore_diagnostic>
#include "basic_window.hpp"
#include <nana/gui/detail/inner_fwd.hpp> #include <nana/gui/detail/inner_fwd.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include <nana/paint/graphics.hpp> #include <nana/paint/graphics.hpp>
#include <map> #include <map>

View File

@ -11,8 +11,8 @@
* *
*/ */
#include "basic_window.hpp"
#include <nana/gui/detail/window_layout.hpp> #include <nana/gui/detail/window_layout.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <algorithm> #include <algorithm>
@ -286,7 +286,7 @@ namespace nana
} }
if (wd->effect.bground) if (wd->effect.bground)
wd->effect.bground->take_effect(reinterpret_cast<window>(wd), glass_buffer); wd->effect.bground->take_effect(wd, glass_buffer);
} }
void window_layout::_m_paste_children(core_window_t* wd, bool have_refreshed, bool req_refresh_children, const nana::rectangle& parent_rect, nana::paint::graphics& graph, const nana::point& graph_rpos) void window_layout::_m_paste_children(core_window_t* wd, bool have_refreshed, bool req_refresh_children, const nana::rectangle& parent_rect, nana::paint::graphics& graph, const nana::point& graph_rpos)

View File

@ -18,7 +18,8 @@
#include <nana/gui/detail/window_layout.hpp> #include <nana/gui/detail/window_layout.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/effects_renderer.hpp>
#include "effects_renderer.hpp"
#include "window_register.hpp" #include "window_register.hpp"
#include "inner_fwd_implement.hpp" #include "inner_fwd_implement.hpp"
@ -587,7 +588,7 @@ namespace detail
{ {
auto &brock = bedrock::instance(); auto &brock = bedrock::instance();
arg_unload arg; arg_unload arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.cancel = false; arg.cancel = false;
brock.emit(event_code::unload, wd, arg, true, brock.get_thread_context()); brock.emit(event_code::unload, wd, arg, true, brock.get_thread_context());
if (false == arg.cancel) if (false == arg.cancel)
@ -758,7 +759,7 @@ namespace detail
auto &brock = bedrock::instance(); auto &brock = bedrock::instance();
arg_move arg; arg_move arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.x = x; arg.x = x;
arg.y = y; arg.y = y;
@ -812,7 +813,7 @@ namespace detail
wd->other.upd_state = basic_window::update_state::request_refresh; wd->other.upd_state = basic_window::update_state::request_refresh;
arg_move arg; arg_move arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.x = r.x; arg.x = r.x;
arg.y = r.y; arg.y = r.y;
brock.emit(event_code::move, wd, arg, true, brock.get_thread_context()); brock.emit(event_code::move, wd, arg, true, brock.get_thread_context());
@ -846,7 +847,7 @@ namespace detail
native_interface::move_window(wd->root, root_r); native_interface::move_window(wd->root, root_r);
arg_resized arg; arg_resized arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.width = root_r.width; arg.width = root_r.width;
arg.height = root_r.height; arg.height = root_r.height;
brock.emit(event_code::resized, wd, arg, true, brock.get_thread_context()); brock.emit(event_code::resized, wd, arg, true, brock.get_thread_context());
@ -875,7 +876,7 @@ namespace detail
if (sz != wd->dimension) if (sz != wd->dimension)
{ {
arg_resizing arg; arg_resizing arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.border = window_border::none; arg.border = window_border::none;
arg.width = sz.width; arg.width = sz.width;
arg.height = sz.height; arg.height = sz.height;
@ -970,7 +971,7 @@ namespace detail
} }
arg_resized arg; arg_resized arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.width = sz.width; arg.width = sz.width;
arg.height = sz.height; arg.height = sz.height;
brock.emit(event_code::resized, wd, arg, ask_update, brock.get_thread_context()); brock.emit(event_code::resized, wd, arg, ask_update, brock.get_thread_context());
@ -1177,7 +1178,7 @@ namespace detail
prev_focus->annex.caret_ptr->activate(false); prev_focus->annex.caret_ptr->activate(false);
arg.getting = false; arg.getting = false;
arg.window_handle = reinterpret_cast<window>(prev_focus); arg.window_handle = prev_focus;
arg.receiver = wd->root; arg.receiver = wd->root;
arg.focus_reason = arg_focus::reason::general; arg.focus_reason = arg_focus::reason::general;
brock.emit(event_code::focus, prev_focus, arg, true, brock.get_thread_context()); brock.emit(event_code::focus, prev_focus, arg, true, brock.get_thread_context());
@ -1194,7 +1195,7 @@ namespace detail
if(wd->annex.caret_ptr) if(wd->annex.caret_ptr)
wd->annex.caret_ptr->activate(true); wd->annex.caret_ptr->activate(true);
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
arg.getting = true; arg.getting = true;
arg.receiver = wd->root; arg.receiver = wd->root;
arg.focus_reason = reason; arg.focus_reason = reason;
@ -1444,7 +1445,7 @@ namespace detail
if (impl_->wd_register.available(wd)) if (impl_->wd_register.available(wd))
{ {
//the root runtime must exist, because the wd is valid. Otherse, it's bug of library //the root runtime must exist, because the wd is valid. Otherse, it's bug of library
return root_runtime(wd->root)->shortkeys.make(reinterpret_cast<window>(wd), key); return root_runtime(wd->root)->shortkeys.make(wd, key);
} }
return false; return false;
} }
@ -1458,7 +1459,7 @@ namespace detail
auto root_rt = root_runtime(wd->root); auto root_rt = root_runtime(wd->root);
if (root_rt) if (root_rt)
{ {
root_rt->shortkeys.umake(reinterpret_cast<window>(wd)); root_rt->shortkeys.umake(wd);
if (with_children) if (with_children)
{ {
for (auto child : wd->children) for (auto child : wd->children)
@ -1475,7 +1476,7 @@ namespace detail
std::lock_guard<mutex_type> lock(mutex_); std::lock_guard<mutex_type> lock(mutex_);
auto object = root_runtime(native_window); auto object = root_runtime(native_window);
if(object) if(object)
return reinterpret_cast<core_window_t*>(object->shortkeys.find(key)); return object->shortkeys.find(key);
} }
return nullptr; return nullptr;
} }
@ -1598,10 +1599,8 @@ namespace detail
if (!established) if (!established)
{ {
using effect_renderer = detail::edge_nimbus_renderer<basic_window>;
//remove the window from edge nimbus effect when it is destroying //remove the window from edge nimbus effect when it is destroying
effect_renderer::instance().erase(wd); edge_nimbus_renderer::instance().erase(wd);
} }
else if (pa_root_attr != root_attr) else if (pa_root_attr != root_attr)
{ {
@ -1705,13 +1704,11 @@ namespace detail
wd->annex.caret_ptr = nullptr; wd->annex.caret_ptr = nullptr;
} }
using effect_renderer = detail::edge_nimbus_renderer<basic_window>;
//remove the window from edge nimbus effect when it is destroying //remove the window from edge nimbus effect when it is destroying
effect_renderer::instance().erase(wd); edge_nimbus_renderer::instance().erase(wd);
arg_destroy arg; arg_destroy arg;
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = wd;
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context()); brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
//Delete the children widgets. //Delete the children widgets.
@ -1770,7 +1767,7 @@ namespace detail
//The root_rt must exist, because wd is valid. Otherwise, it's a bug of the library. //The root_rt must exist, because wd is valid. Otherwise, it's a bug of the library.
auto root_rt = root_runtime(wd->root); auto root_rt = root_runtime(wd->root);
auto pkeys = root_rt->shortkeys.keys(reinterpret_cast<window>(wd)); auto pkeys = root_rt->shortkeys.keys(wd);
if (pkeys) if (pkeys)
{ {
for (auto key : *pkeys) for (auto key : *pkeys)

View File

@ -1,7 +1,7 @@
#ifndef NANA_WINDOW_REGISTER_HEADER_INCLUDED #ifndef NANA_WINDOW_REGISTER_HEADER_INCLUDED
#define NANA_WINDOW_REGISTER_HEADER_INCLUDED #define NANA_WINDOW_REGISTER_HEADER_INCLUDED
#include <nana/gui/detail/basic_window.hpp> #include "basic_window.hpp"
#include <set> #include <set>
#include <vector> #include <vector>
#include <algorithm> //std::find #include <algorithm> //std::find

View File

@ -13,9 +13,9 @@
#include <nana/gui/dragdrop.hpp> #include <nana/gui/dragdrop.hpp>
#include <nana/gui/programming_interface.hpp> #include <nana/gui/programming_interface.hpp>
#include <nana/gui/detail/bedrock.hpp> #include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include "detail/basic_window.hpp"
#include <map> #include <map>
#include <set> #include <set>
@ -961,8 +961,7 @@ namespace nana
if (API::is_window(window_handle)) if (API::is_window(window_handle))
{ {
dragging = true; dragging = true;
auto real_wd = reinterpret_cast<detail::basic_window*>(window_handle); window_handle->other.dnd_state = dragdrop_status::not_ready;
real_wd->other.dnd_state = dragdrop_status::not_ready;
} }
API::release_capture(window_handle); API::release_capture(window_handle);
@ -1000,9 +999,7 @@ namespace nana
if (arg.is_left_button() && API::is_window(impl_->window_handle)) if (arg.is_left_button() && API::is_window(impl_->window_handle))
{ {
impl_->dragging = ((!impl_->predicate) || impl_->predicate()); impl_->dragging = ((!impl_->predicate) || impl_->predicate());
impl_->window_handle->other.dnd_state = dragdrop_status::ready;
auto real_wd = reinterpret_cast<detail::basic_window*>(impl_->window_handle);
real_wd->other.dnd_state = dragdrop_status::ready;
} }
}); });
@ -1010,14 +1007,13 @@ namespace nana
if (!(arg.is_left_button() && impl_->dragging && API::is_window(arg.window_handle))) if (!(arg.is_left_button() && impl_->dragging && API::is_window(arg.window_handle)))
return; return;
auto real_wd = reinterpret_cast<detail::basic_window*>(arg.window_handle); arg.window_handle->other.dnd_state = dragdrop_status::in_progress;
real_wd->other.dnd_state = dragdrop_status::in_progress;
std::unique_ptr<dragdrop_service::dropdata_type> dropdata{new dragdrop_service::dropdata_type}; std::unique_ptr<dragdrop_service::dropdata_type> dropdata{new dragdrop_service::dropdata_type};
auto has_dropped = dragdrop_service::instance().dragdrop(arg.window_handle, dropdata.get(), nullptr); auto has_dropped = dragdrop_service::instance().dragdrop(arg.window_handle, dropdata.get(), nullptr);
real_wd->other.dnd_state = dragdrop_status::not_ready; arg.window_handle->other.dnd_state = dragdrop_status::not_ready;
impl_->dragging = false; impl_->dragging = false;
if (has_dropped) if (has_dropped)
@ -1116,9 +1112,7 @@ namespace nana
if (arg.is_left_button() && API::is_window(impl_->source_handle)) if (arg.is_left_button() && API::is_window(impl_->source_handle))
{ {
impl_->dragging = ((!impl_->predicate) || impl_->predicate()); impl_->dragging = ((!impl_->predicate) || impl_->predicate());
impl_->source_handle->other.dnd_state = dragdrop_status::ready;
auto real_wd = reinterpret_cast<detail::basic_window*>(impl_->source_handle);
real_wd->other.dnd_state = dragdrop_status::ready;
} }
}); });
@ -1126,13 +1120,9 @@ namespace nana
if (!(arg.is_left_button() && impl_->dragging && API::is_window(arg.window_handle))) if (!(arg.is_left_button() && impl_->dragging && API::is_window(arg.window_handle)))
return; return;
auto real_wd = reinterpret_cast<detail::basic_window*>(arg.window_handle); arg.window_handle->other.dnd_state = dragdrop_status::in_progress;
real_wd->other.dnd_state = dragdrop_status::in_progress;
impl_->make_drop(); impl_->make_drop();
arg.window_handle->other.dnd_state = dragdrop_status::not_ready;
real_wd->other.dnd_state = dragdrop_status::not_ready;
impl_->dragging = false; impl_->dragging = false;
}); });
} }

View File

@ -10,9 +10,9 @@
* @file: nana/gui/drawing.cpp * @file: nana/gui/drawing.cpp
*/ */
#include "detail/basic_window.hpp"
#include <nana/gui/drawing.hpp> #include <nana/gui/drawing.hpp>
#include <nana/gui/programming_interface.hpp> #include <nana/gui/programming_interface.hpp>
#include <nana/gui/detail/basic_window.hpp>
namespace nana namespace nana
{ {
@ -22,11 +22,9 @@ namespace nana
{ {
namespace namespace
{ {
using core_window_t = detail::basic_window;
inline detail::drawer& get_drawer(window wd) inline detail::drawer& get_drawer(window wd)
{ {
return reinterpret_cast<core_window_t*>(wd)->drawer; return wd->drawer;
} }
} }
} }
@ -38,7 +36,7 @@ namespace nana
if (!API::is_window(wd)) if (!API::is_window(wd))
throw std::invalid_argument("drawing: invalid window parameter"); throw std::invalid_argument("drawing: invalid window parameter");
if (reinterpret_cast<restrict::core_window_t*>(wd)->is_draw_through()) if (wd->is_draw_through())
throw std::invalid_argument("drawing: the window is draw_through enabled"); throw std::invalid_argument("drawing: the window is draw_through enabled");
} }
@ -46,7 +44,7 @@ namespace nana
bool drawing::empty() const bool drawing::empty() const
{ {
return API::empty_window(handle_) || reinterpret_cast<restrict::core_window_t*>(handle_)->root_graph->empty(); return API::empty_window(handle_) || handle_->root_graph->empty();
} }
void drawing::update() const void drawing::update() const

File diff suppressed because it is too large Load Diff

View File

@ -9,18 +9,18 @@
* *
* @file: nana/gui/state_cursor.cpp * @file: nana/gui/state_cursor.cpp
*/ */
#include "detail/basic_window.hpp"
#include <nana/gui/state_cursor.hpp> #include <nana/gui/state_cursor.hpp>
#include <nana/gui/detail/bedrock.hpp> #include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include <nana/gui/detail/window_manager.hpp> #include <nana/gui/detail/window_manager.hpp>
namespace nana namespace nana
{ {
state_cursor::state_cursor(window handle, cursor cur) state_cursor::state_cursor(window wd, cursor cur)
: handle_(handle) : handle_(wd)
{ {
auto & brock = detail::bedrock::instance(); auto & brock = detail::bedrock::instance();
auto wd = reinterpret_cast<detail::basic_window*>(handle);
if (brock.wd_manager().available(wd)) if (brock.wd_manager().available(wd))
brock.define_state_cursor(wd, cur, nullptr); brock.define_state_cursor(wd, cur, nullptr);
else else
@ -39,10 +39,9 @@ namespace nana
{ {
if (handle_) if (handle_)
{ {
nana::internal_scope_guard lock;
auto & brock = detail::bedrock::instance(); auto & brock = detail::bedrock::instance();
auto wd = reinterpret_cast<detail::basic_window*>(handle_); brock.undefine_state_cursor(handle_, nullptr);
if (brock.wd_manager().available(wd))
brock.undefine_state_cursor(wd, nullptr);
} }
handle_ = rhs.handle_; handle_ = rhs.handle_;
rhs.handle_ = nullptr; rhs.handle_ = nullptr;
@ -54,10 +53,9 @@ namespace nana
{ {
if (handle_) if (handle_)
{ {
nana::internal_scope_guard lock;
auto & brock = detail::bedrock::instance(); auto & brock = detail::bedrock::instance();
auto wd = reinterpret_cast<detail::basic_window*>(handle_); brock.undefine_state_cursor(handle_, nullptr);
if (brock.wd_manager().available(wd))
brock.undefine_state_cursor(wd, nullptr);
} }
} }
} }

View File

@ -29,7 +29,7 @@ namespace nana
{ {
void form_loader_private::insert_form(::nana::widget* p) void form_loader_private::insert_form(::nana::widget* p)
{ {
bedrock::instance().manage_form_loader(reinterpret_cast<basic_window*>(p->handle()), true); bedrock::instance().manage_form_loader(p->handle(), true);
} }
} }