optimize generated binary size

This commit is contained in:
Jinhao 2016-02-18 01:01:55 +08:00
parent 0ed51a7a21
commit d3120cbf35
15 changed files with 274 additions and 285 deletions

View File

@ -95,9 +95,9 @@ namespace std
namespace nana namespace nana
{ {
/// Checks whether a specified text is utf8 encoding /// Checks whether a specified text is utf8 encoding
bool is_utf8(const char* str, unsigned len); bool is_utf8(const char* str, std::size_t len);
void throw_not_utf8(const std::string& text); void throw_not_utf8(const std::string& text);
void throw_not_utf8(const char*, unsigned len); void throw_not_utf8(const char*, std::size_t len);
void throw_not_utf8(const char*); void throw_not_utf8(const char*);
const std::string& to_utf8(const std::string&); const std::string& to_utf8(const std::string&);

View File

@ -1,7 +1,7 @@
/* /*
* A Bedrock Implementation * A Bedrock Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -78,8 +78,8 @@ namespace detail
void define_state_cursor(core_window_t*, nana::cursor, thread_context*); void define_state_cursor(core_window_t*, nana::cursor, thread_context*);
void undefine_state_cursor(core_window_t*, thread_context*); void undefine_state_cursor(core_window_t*, thread_context*);
widget_colors& get_scheme_template(scheme_factory_base&&); widget_colors& get_scheme_template(scheme_factory_interface&&);
widget_colors* make_scheme(scheme_factory_base&&); widget_colors* make_scheme(scheme_factory_interface&&);
events_operation& evt_operation(); events_operation& evt_operation();
window_manager& wd_manager(); window_manager& wd_manager();

View File

@ -1,7 +1,7 @@
/* /*
* Color Schemes * Color Schemes
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -19,20 +19,21 @@ namespace nana
{ {
namespace detail namespace detail
{ {
class scheme_factory_base class scheme_factory_interface
{ {
public: public:
struct factory_identifier{}; struct factory_identifier{};
virtual ~scheme_factory_base() = default; virtual ~scheme_factory_interface() = default;
virtual factory_identifier* get_id() const = 0; virtual factory_identifier* get_id() const = 0;
virtual widget_colors* create() = 0; virtual widget_colors* create() = 0;
virtual widget_colors* create(widget_colors&) = 0; virtual widget_colors* create(widget_colors&) = 0;
}; };
template<typename Scheme> template<typename Scheme>
class scheme_factory class scheme_factory
: public scheme_factory_base : public scheme_factory_interface
{ {
private: private:
factory_identifier* get_id() const override factory_identifier* get_id() const override
@ -54,7 +55,7 @@ namespace nana
}; };
template<typename Scheme> template<typename Scheme>
scheme_factory_base::factory_identifier scheme_factory<Scheme>::fid_; scheme_factory_interface::factory_identifier scheme_factory<Scheme>::fid_;
class color_schemes class color_schemes
{ {
@ -69,8 +70,8 @@ namespace nana
color_schemes(); color_schemes();
~color_schemes(); ~color_schemes();
scheme& scheme_template(scheme_factory_base&&); scheme& scheme_template(scheme_factory_interface&&);
scheme* create(scheme_factory_base&&); scheme* create(scheme_factory_interface&&);
private: private:
implement * impl_; implement * impl_;
}; };

View File

@ -4,6 +4,7 @@
#include <nana/gui/detail/general_events.hpp> #include <nana/gui/detail/general_events.hpp>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
#include <memory>
#if defined(STD_THREAD_NOT_SUPPORTED) #if defined(STD_THREAD_NOT_SUPPORTED)
#include <nana/std_mutex.hpp> #include <nana/std_mutex.hpp>

View File

@ -17,7 +17,6 @@
#include "internal_scope_guard.hpp" #include "internal_scope_guard.hpp"
#include <type_traits> #include <type_traits>
#include <functional> #include <functional>
#include <memory>
#include <vector> #include <vector>
namespace nana namespace nana
@ -67,7 +66,7 @@ namespace nana
protected: protected:
//class emit_counter is a RAII helper for emitting count //class emit_counter is a RAII helper for emitting count
//It is used for avoiding a try{}catch block which is required for some finial works when //It is used for avoiding a try{}catch block which is required for some finial works when
//event handlers throw exceptions. //event handlers throw exceptions. Precondition event_base.dockers_ != nullptr.
class emit_counter class emit_counter
{ {
public: public:
@ -77,12 +76,10 @@ namespace nana
event_base * const evt_; event_base * const evt_;
}; };
//event_handle _m_emplace(::std::unique_ptr<detail::docker_interface>& docker_ptr, bool in_front);
event_handle _m_emplace(detail::docker_interface*, bool in_front); event_handle _m_emplace(detail::docker_interface*, bool in_front);
protected: protected:
unsigned emitting_count_{ 0 }; unsigned emitting_count_{ 0 };
bool deleted_flags_{ false }; bool deleted_flags_{ false };
//std::unique_ptr<std::vector<std::unique_ptr<detail::docker_interface>>> dockers_;
std::vector<detail::docker_interface*> * dockers_{ nullptr }; std::vector<detail::docker_interface*> * dockers_{ nullptr };
}; };
}//end namespace detail }//end namespace detail
@ -172,27 +169,26 @@ namespace nana
emit_counter ec(this); emit_counter ec(this);
auto& dockers = *dockers_;
const auto dockers_len = dockers_->size();
//The dockers may resize when a new event handler is created by a calling handler. //The dockers may resize when a new event handler is created by a calling handler.
//Traverses with position can avaid crash error which caused by a iterator which becomes invalid. //Traverses with position can avaid crash error which caused by a iterator which becomes invalid.
for (std::size_t pos = 0; pos < dockers_len; ++pos)
auto i = dockers_->data();
auto const end = i + dockers_->size();
for (; i != end; ++i)
{ {
auto docker_ptr = static_cast<docker*>(dockers[pos]); if (static_cast<docker*>(*i)->flag_deleted)
if (docker_ptr->flag_deleted)
continue; continue;
docker_ptr->invoke(arg); static_cast<docker*>(*i)->invoke(arg);
if (arg.propagation_stopped()) if (arg.propagation_stopped())
{ {
for (++pos; pos < dockers_len; ++pos) for (++i; i != end; ++i)
{ {
auto docker_ptr = static_cast<docker*>(dockers[pos]); if (!static_cast<docker*>(*i)->unignorable || static_cast<docker*>(*i)->flag_deleted)
if (!docker_ptr->unignorable || docker_ptr->flag_deleted)
continue; continue;
docker_ptr->invoke(arg); static_cast<docker*>(*i)->invoke(arg);
} }
break; break;
} }
@ -274,7 +270,7 @@ namespace nana
}; };
} }
}; };
template<typename Ret, typename Arg2> template<typename Ret, typename Arg2>
struct factory < std::function<Ret(Arg2)>, false> struct factory < std::function<Ret(Arg2)>, false>
{ {

View File

@ -1,7 +1,7 @@
/* /*
* Elements of GUI Gadgets * Elements of GUI Gadgets
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -88,7 +88,6 @@ namespace nana
struct factory_interface struct factory_interface
: public detail::factory_abstract : public detail::factory_abstract
{ {
virtual ~factory_interface(){}
virtual ElementInterface* create() const = 0; virtual ElementInterface* create() const = 0;
}; };

View File

@ -46,7 +46,7 @@ namespace API
{ {
namespace detail namespace detail
{ {
::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_base&&); ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_interface&&);
} }
void effects_edge_nimbus(window, effects::edge_nimbus); void effects_edge_nimbus(window, effects::edge_nimbus);

View File

@ -1,7 +1,7 @@
/** /**
* The fundamental widget class implementation * The fundamental widget class implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -132,9 +132,25 @@ namespace nana
virtual nana::color _m_bgcolor() const; virtual nana::color _m_bgcolor() const;
}; };
namespace detail
{
class widget_base
: public widget
{
public:
~widget_base();
window handle() const override;
private:
void _m_notify_destroy() override final;
protected:
window handle_{ nullptr };
};
}
/// Base class of all the classes defined as a widget window. Defaultly a widget_tag /// Base class of all the classes defined as a widget window. Defaultly a widget_tag
template<typename Category, typename DrawerTrigger, typename Events = ::nana::general_events, typename Scheme = ::nana::widget_colors> template<typename Category, typename DrawerTrigger, typename Events = ::nana::general_events, typename Scheme = ::nana::widget_colors>
class widget_object: public widget class widget_object: public detail::widget_base
{ {
protected: protected:
typedef DrawerTrigger drawer_trigger_t; typedef DrawerTrigger drawer_trigger_t;
@ -147,12 +163,6 @@ namespace nana
scheme_{ API::dev::make_scheme<Scheme>() } scheme_{ API::dev::make_scheme<Scheme>() }
{} {}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
event_type& events() const event_type& events() const
{ {
return *events_; return *events_;
@ -179,11 +189,6 @@ namespace nana
return (this->empty() == false); return (this->empty() == false);
} }
window handle() const override
{
return handle_;
}
widget_object& borderless(bool enable) widget_object& borderless(bool enable)
{ {
API::widget_borderless(handle_, enable); API::widget_borderless(handle_, enable);
@ -214,13 +219,7 @@ namespace nana
{ {
return *events_; return *events_;
} }
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private: private:
window handle_{nullptr};
DrawerTrigger trigger_; DrawerTrigger trigger_;
std::shared_ptr<Events> events_; std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_; std::unique_ptr<scheme_type> scheme_;
@ -228,7 +227,7 @@ namespace nana
/// Base class of all the classes defined as a non-graphics-buffer widget window. The second template parameter DrawerTrigger is always ignored.\see nana::panel /// Base class of all the classes defined as a non-graphics-buffer widget window. The second template parameter DrawerTrigger is always ignored.\see nana::panel
template<typename DrawerTrigger, typename Events, typename Scheme> template<typename DrawerTrigger, typename Events, typename Scheme>
class widget_object<category::lite_widget_tag, DrawerTrigger, Events, Scheme>: public widget class widget_object<category::lite_widget_tag, DrawerTrigger, Events, Scheme>: public detail::widget_base
{ {
protected: protected:
typedef DrawerTrigger drawer_trigger_t; typedef DrawerTrigger drawer_trigger_t;
@ -240,12 +239,6 @@ namespace nana
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() } : events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
{} {}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
event_type& events() const event_type& events() const
{ {
return *events_; return *events_;
@ -269,12 +262,7 @@ namespace nana
} }
return (this->empty() == false); return (this->empty() == false);
} }
window handle() const override
{
return handle_;
}
scheme_type& scheme() const scheme_type& scheme() const
{ {
return *scheme_; return *scheme_;
@ -284,13 +272,7 @@ namespace nana
{ {
return *events_; return *events_;
} }
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private: private:
window handle_{nullptr};
std::shared_ptr<Events> events_; std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_; std::unique_ptr<scheme_type> scheme_;
};//end class widget_object };//end class widget_object
@ -298,7 +280,7 @@ namespace nana
/// Base class of all the classes defined as a root window. \see nana::form /// Base class of all the classes defined as a root window. \see nana::form
template<typename DrawerTrigger, typename Events, typename Scheme> template<typename DrawerTrigger, typename Events, typename Scheme>
class widget_object<category::root_tag, DrawerTrigger, Events, Scheme>: public widget class widget_object<category::root_tag, DrawerTrigger, Events, Scheme>: public detail::widget_base
{ {
protected: protected:
typedef DrawerTrigger drawer_trigger_t; typedef DrawerTrigger drawer_trigger_t;
@ -324,12 +306,6 @@ namespace nana
_m_bind_and_attach(); _m_bind_and_attach();
} }
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
event_type& events() const event_type& events() const
{ {
return *events_; return *events_;
@ -340,11 +316,6 @@ namespace nana
API::activate_window(handle_); API::activate_window(handle_);
} }
window handle() const override
{
return handle_;
}
native_window_type native_handle() const native_window_type native_handle() const
{ {
return API::root(handle_); return API::root(handle_);
@ -435,13 +406,7 @@ namespace nana
{ {
return *events_; return *events_;
} }
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private: private:
window handle_;
DrawerTrigger trigger_; DrawerTrigger trigger_;
std::shared_ptr<Events> events_; std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_; std::unique_ptr<scheme_type> scheme_;
@ -453,7 +418,7 @@ namespace nana
/// Especialization. Base class of all the classes defined as a frame window. \see nana::frame /// Especialization. Base class of all the classes defined as a frame window. \see nana::frame
template<typename Events, typename Scheme> template<typename Events, typename Scheme>
class widget_object<category::frame_tag, int, Events, Scheme>: public widget class widget_object<category::frame_tag, int, Events, Scheme>: public detail::widget_base
{ {
protected: protected:
typedef int drawer_trigger_t; typedef int drawer_trigger_t;
@ -465,12 +430,6 @@ namespace nana
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() } : events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
{} {}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
event_type& events() const event_type& events() const
{ {
return *events_; return *events_;
@ -494,11 +453,6 @@ namespace nana
return (this->empty() == false); return (this->empty() == false);
} }
window handle() const override
{
return handle_;
}
scheme_type& scheme() const scheme_type& scheme() const
{ {
return *scheme_; return *scheme_;
@ -513,13 +467,7 @@ namespace nana
{ {
return *events_; return *events_;
} }
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private: private:
window handle_{nullptr};
std::shared_ptr<Events> events_; std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_; std::unique_ptr<scheme_type> scheme_;
};//end class widget_object<category::frame_tag> };//end class widget_object<category::frame_tag>

View File

@ -438,7 +438,7 @@ namespace std
namespace nana namespace nana
{ {
bool is_utf8(const char* str, unsigned len) bool is_utf8(const char* str, std::size_t len)
{ {
auto ustr = reinterpret_cast<const unsigned char*>(str); auto ustr = reinterpret_cast<const unsigned char*>(str);
auto end = ustr + len; auto end = ustr + len;
@ -474,7 +474,7 @@ namespace nana
throw std::invalid_argument("The text is not encoded in UTF8"); throw std::invalid_argument("The text is not encoded in UTF8");
} }
void throw_not_utf8(const char* text, unsigned len) void throw_not_utf8(const char* text, std::size_t len)
{ {
if (!is_utf8(text, len)) if (!is_utf8(text, len))
throw std::invalid_argument("The text is not encoded in UTF8"); throw std::invalid_argument("The text is not encoded in UTF8");

View File

@ -1,7 +1,7 @@
/* /*
* A Bedrock Platform-Independent Implementation * A Bedrock Platform-Independent Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -198,12 +198,12 @@ namespace nana
} }
} }
widget_colors& bedrock::get_scheme_template(scheme_factory_base&& factory) widget_colors& bedrock::get_scheme_template(scheme_factory_interface&& factory)
{ {
return pi_data_->scheme.scheme_template(std::move(factory)); return pi_data_->scheme.scheme_template(std::move(factory));
} }
widget_colors* bedrock::make_scheme(scheme_factory_base&& factory) widget_colors* bedrock::make_scheme(scheme_factory_interface&& factory)
{ {
return pi_data_->scheme.create(std::move(factory)); return pi_data_->scheme.create(std::move(factory));
} }

View File

@ -1,3 +1,15 @@
/*
* Color Schemes
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 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/color_schemes.cpp
*/
#include <nana/gui/detail/color_schemes.hpp> #include <nana/gui/detail/color_schemes.hpp>
#include <map> #include <map>
@ -57,7 +69,7 @@ namespace nana
//class color_schemes //class color_schemes
struct color_schemes::implement struct color_schemes::implement
{ {
std::map<scheme_factory_base::factory_identifier*, std::unique_ptr<scheme>> scheme_template; std::map<scheme_factory_interface::factory_identifier*, std::unique_ptr<scheme>> scheme_template;
}; };
color_schemes::color_schemes() color_schemes::color_schemes()
@ -70,7 +82,7 @@ namespace nana
delete impl_; delete impl_;
} }
auto color_schemes::scheme_template(scheme_factory_base&& factory) -> scheme& auto color_schemes::scheme_template(scheme_factory_interface&& factory) -> scheme&
{ {
auto & tmpl_scheme = impl_->scheme_template[factory.get_id()]; auto & tmpl_scheme = impl_->scheme_template[factory.get_id()];
@ -81,7 +93,7 @@ namespace nana
return *tmpl_scheme.get(); return *tmpl_scheme.get();
} }
widget_colors* color_schemes::create(scheme_factory_base&& factory) widget_colors* color_schemes::create(scheme_factory_interface&& factory)
{ {
return factory.create(scheme_template(std::move(factory))); return factory.create(scheme_template(std::move(factory)));
} }

View File

@ -1346,74 +1346,77 @@ namespace nana
splitter_.cursor(splitter_cursor_); splitter_.cursor(splitter_cursor_);
dragger_.trigger(splitter_); dragger_.trigger(splitter_);
splitter_.events().mouse_down.connect_unignorable([this](const arg_mouse& arg)
auto grab_fn = [this](const arg_mouse& arg)
{ {
if (false == arg.left_button) if (false == arg.left_button)
return; return;
begin_point_ = splitter_.pos(); if (event_code::mouse_down == arg.evt_code)
auto px_ptr = &nana::rectangle::width;
//Use field_area of leaf, not margin_area. Otherwise splitter would be at wrong position
auto area_left = _m_leaf_left()->field_area;
auto area_right = _m_leaf_right()->field_area;
if (nana::cursor::size_we != splitter_cursor_)
{ {
left_pos_ = area_left.y; begin_point_ = splitter_.pos();
right_pos_ = area_right.bottom();
px_ptr = &nana::rectangle::height; auto px_ptr = &nana::rectangle::width;
//Use field_area of leaf, not margin_area. Otherwise splitter would be at wrong position
auto area_left = _m_leaf_left()->field_area;
auto area_right = _m_leaf_right()->field_area;
if (nana::cursor::size_we != splitter_cursor_)
{
left_pos_ = area_left.y;
right_pos_ = area_right.bottom();
px_ptr = &nana::rectangle::height;
}
else
{
left_pos_ = area_left.x;
right_pos_ = area_right.right();
}
left_pixels_ = area_left.*px_ptr;
right_pixels_ = area_right.*px_ptr;
} }
else else if (event_code::mouse_move == arg.evt_code)
{ {
left_pos_ = area_left.x; const bool vert = (::nana::cursor::size_we != splitter_cursor_);
right_pos_ = area_right.right(); auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w();
int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x);
int total_pixels = static_cast<int>(left_pixels_ + right_pixels_);
auto left_px = static_cast<int>(left_pixels_) + delta;
if (left_px > total_pixels)
left_px = total_pixels;
else if (left_px < 0)
left_px = 0;
double imd_rate = 100.0 / area_px;
left_px = static_cast<int>(limit_px(_m_leaf_left(), left_px, area_px));
_m_leaf_left()->weight.assign_percent(imd_rate * left_px);
auto right_px = static_cast<int>(right_pixels_) - delta;
if (right_px > total_pixels)
right_px = total_pixels;
else if (right_px < 0)
right_px = 0;
right_px = static_cast<int>(limit_px(_m_leaf_right(), right_px, area_px));
_m_leaf_right()->weight.assign_percent(imd_rate * right_px);
pause_move_collocate_ = true;
div_owner->collocate(splitter_.parent());
//After the collocating, the splitter keeps the calculated weight of left division,
//and clear the weight of right division.
_m_leaf_right()->weight.reset();
pause_move_collocate_ = false;
} }
};
left_pixels_ = area_left.*px_ptr; splitter_.events().mouse_down.connect_unignorable(grab_fn);
right_pixels_ = area_right.*px_ptr; splitter_.events().mouse_move.connect_unignorable(grab_fn);
});
splitter_.events().mouse_move.connect_unignorable([this](const arg_mouse& arg)
{
if (false == arg.left_button)
return;
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w();
int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x);
int total_pixels = static_cast<int>(left_pixels_ + right_pixels_);
auto left_px = static_cast<int>(left_pixels_)+delta;
if (left_px > total_pixels)
left_px = total_pixels;
else if (left_px < 0)
left_px = 0;
double imd_rate = 100.0 / area_px;
left_px = static_cast<int>(limit_px(_m_leaf_left(), left_px, area_px));
_m_leaf_left()->weight.assign_percent(imd_rate * left_px);
auto right_px = static_cast<int>(right_pixels_)-delta;
if (right_px > total_pixels)
right_px = total_pixels;
else if (right_px < 0)
right_px = 0;
right_px = static_cast<int>(limit_px(_m_leaf_right(), right_px, area_px));
_m_leaf_right()->weight.assign_percent(imd_rate * right_px);
pause_move_collocate_ = true;
div_owner->collocate(splitter_.parent());
//After the collocating, the splitter keeps the calculated weight of left division,
//and clear the weight of right division.
_m_leaf_right()->weight.reset();
pause_move_collocate_ = false;
});
} }
auto limited_range = _m_update_splitter_range(); auto limited_range = _m_update_splitter_range();
@ -1621,7 +1624,7 @@ namespace nana
indicator_.docker->z_order(nullptr, ::nana::z_order_action::topmost); indicator_.docker->z_order(nullptr, ::nana::z_order_action::topmost);
indicator_.docker->show(); indicator_.docker->show();
indicator_.docker->events().destroy([this] indicator_.docker->events().destroy([this](const arg_destroy&)
{ {
if (indicator_.dock_area) if (indicator_.dock_area)
{ {
@ -1764,81 +1767,86 @@ namespace nana
this->bgcolor(colors::alice_blue); this->bgcolor(colors::alice_blue);
this->cursor(_m_is_vert(dir_) ? ::nana::cursor::size_ns : ::nana::cursor::size_we); this->cursor(_m_is_vert(dir_) ? ::nana::cursor::size_ns : ::nana::cursor::size_we);
this->events().mouse_down([this](const arg_mouse& arg)
auto grab_fn = [this, wd](const arg_mouse& arg)
{ {
if (arg.button != ::nana::mouse::left_button) if (event_code::mouse_down == arg.evt_code) //press mouse button
return;
bool is_vert = _m_is_vert(dir_);
API::capture_window(this->handle(), true);
auto basepos = API::cursor_position();
base_pos_.x = (is_vert ? basepos.y : basepos.x);
basepos = this->pos();
base_pos_.y = (is_vert ? basepos.y : basepos.x);
base_px_ = (is_vert ? pane_dv_->field_area.height : pane_dv_->field_area.width);
});
this->events().mouse_up([this]
{
API::capture_window(this->handle(), false);
});
this->events().mouse_move([this, wd](const arg_mouse& arg)
{
if (!arg.is_left_button())
return;
auto now_pos = API::cursor_position();
int delta = (_m_is_vert(dir_) ? now_pos.y : now_pos.x) - base_pos_.x;
int new_pos = base_pos_.y + delta;
if (new_pos < range_.x)
{ {
new_pos = range_.x; if (arg.button != ::nana::mouse::left_button)
delta = new_pos - base_pos_.y; return;
}
else if (new_pos >= range_.y)
{
new_pos = range_.y - 1;
delta = new_pos - base_pos_.y;
}
now_pos = this->pos(); bool is_vert = _m_is_vert(dir_);
if (_m_is_vert(dir_))
now_pos.y = new_pos; API::capture_window(this->handle(), true);
auto basepos = API::cursor_position();
base_pos_.x = (is_vert ? basepos.y : basepos.x);
basepos = this->pos();
base_pos_.y = (is_vert ? basepos.y : basepos.x);
base_px_ = (is_vert ? pane_dv_->field_area.height : pane_dv_->field_area.width);
}
else if (event_code::mouse_move == arg.evt_code) //hover
{
if (!arg.is_left_button())
return;
auto now_pos = API::cursor_position();
int delta = (_m_is_vert(dir_) ? now_pos.y : now_pos.x) - base_pos_.x;
int new_pos = base_pos_.y + delta;
if (new_pos < range_.x)
{
new_pos = range_.x;
delta = new_pos - base_pos_.y;
}
else if (new_pos >= range_.y)
{
new_pos = range_.y - 1;
delta = new_pos - base_pos_.y;
}
now_pos = this->pos();
if (_m_is_vert(dir_))
now_pos.y = new_pos;
else
now_pos.x = new_pos;
this->move(now_pos);
auto px = base_px_;
switch (dir_)
{
case ::nana::direction::west:
case ::nana::direction::north:
if (delta < 0)
px -= static_cast<unsigned>(-delta);
else
px += static_cast<unsigned>(delta);
break;
case ::nana::direction::east:
case ::nana::direction::south:
if (delta < 0)
px += static_cast<unsigned>(-delta);
else
px -= static_cast<unsigned>(delta);
break;
default:
break;
}
auto dock_px = (_m_is_vert(dir_) ? dock_dv_->field_area.height : dock_dv_->field_area.width);
pane_dv_->weight.assign_percent(double(px) / double(dock_px) * 100);
dock_dv_->collocate(wd);
}
else else
now_pos.x = new_pos; API::capture_window(this->handle(), false); //release mouse button
this->move(now_pos); };
auto px = base_px_; auto & evt = this->events();
switch (dir_) evt.mouse_down(grab_fn);
{ evt.mouse_up(grab_fn);
case ::nana::direction::west: evt.mouse_move(grab_fn);
case ::nana::direction::north:
if (delta < 0)
px -= static_cast<unsigned>(-delta);
else
px += static_cast<unsigned>(delta);
break;
case ::nana::direction::east:
case ::nana::direction::south:
if (delta < 0)
px += static_cast<unsigned>(-delta);
else
px -= static_cast<unsigned>(delta);
break;
default:
break;
}
auto dock_px = (_m_is_vert(dir_) ? dock_dv_->field_area.height : dock_dv_->field_area.width);
pane_dv_->weight.assign_percent(double(px) / double(dock_px) * 100);
dock_dv_->collocate(wd);
});
} }
void range(int begin, int end) void range(int begin, int end)
@ -1867,6 +1875,7 @@ namespace nana
if (i->get()->display) if (i->get()->display)
return i->get(); return i->get();
} }
return nullptr; return nullptr;
} }

View File

@ -1,7 +1,7 @@
/* /*
* Parts of Class Place * Parts of Class Place
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -233,45 +233,50 @@ namespace nana
} }
}); });
caption_.events().mouse_down([this](const arg_mouse& arg) auto grab_fn = [this](const arg_mouse& arg)
{ {
if (::nana::mouse::left_button == arg.button) if (event_code::mouse_down == arg.evt_code)
{ {
moves_.started = true; if (::nana::mouse::left_button == arg.button)
moves_.start_pos = API::cursor_position();
moves_.start_container_pos = (floating() ? container_->pos() : this->pos());
API::capture_window(caption_, true);
}
});
caption_.events().mouse_move([this](const arg_mouse& arg)
{
if (arg.left_button && moves_.started)
{
auto move_pos = API::cursor_position() - moves_.start_pos;
if (!floating())
{ {
if (std::abs(move_pos.x) > 4 || std::abs(move_pos.y) > 4) moves_.started = true;
float_away(move_pos); moves_.start_pos = API::cursor_position();
} moves_.start_container_pos = (floating() ? container_->pos() : this->pos());
else API::capture_window(caption_, true);
{
move_pos += moves_.start_container_pos;
API::move_window(container_->handle(), move_pos);
notifier_->notify_move();
} }
} }
}); else if (event_code::mouse_move == arg.evt_code)
caption_.events().mouse_up([this](const arg_mouse& arg)
{
if ((::nana::mouse::left_button == arg.button) && moves_.started)
{ {
moves_.started = false; if (arg.left_button && moves_.started)
API::capture_window(caption_, false); {
notifier_->notify_move_stopped(); auto move_pos = API::cursor_position() - moves_.start_pos;
if (!floating())
{
if (std::abs(move_pos.x) > 4 || std::abs(move_pos.y) > 4)
float_away(move_pos);
}
else
{
move_pos += moves_.start_container_pos;
API::move_window(container_->handle(), move_pos);
notifier_->notify_move();
}
}
} }
}); else if (event_code::mouse_up == arg.evt_code)
{
if ((::nana::mouse::left_button == arg.button) && moves_.started)
{
moves_.started = false;
API::capture_window(caption_, false);
notifier_->notify_move_stopped();
}
}
};
caption_.events().mouse_down(grab_fn);
caption_.events().mouse_move(grab_fn);
caption_.events().mouse_up(grab_fn);
} }
@ -293,13 +298,13 @@ namespace nana
tabbar_.reset(new tabbar_lite(*this)); tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear(); tabbar_->events().selected.clear();
tabbar_->events().selected([this] tabbar_->events().selected([this](const event_arg&)
{ {
auto handle = tabbar_->attach(tabbar_->selected()); auto handle = tabbar_->attach(tabbar_->selected());
if (handle)
caption_.caption(API::window_caption(handle)); //Set caption through a caption of window specified by handle
else //Empty if handle is null
caption_.caption(::std::string()); caption_.caption(API::window_caption(handle));
}); });
tabbar_->move({ 0, r.bottom() - 20, r.width, 20 }); tabbar_->move({ 0, r.bottom() - 20, r.width, 20 });
@ -320,7 +325,7 @@ namespace nana
if (tabbar_) if (tabbar_)
{ {
tabbar_->push_back(::nana::charset(wdg->caption())); tabbar_->push_back(wdg->caption());
tabbar_->attach(panels_.size(), wdg->handle()); tabbar_->attach(panels_.size(), wdg->handle());
} }

View File

@ -55,9 +55,9 @@ namespace API
namespace detail namespace detail
{ {
::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_base&& factory) ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_interface&& factory)
{ {
return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_base&&>(factory)); return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_interface&&>(factory));
} }
bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg) bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg)

View File

@ -1,6 +1,6 @@
/* /*
* The fundamental widget class implementation * The fundamental widget class implementation
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -370,6 +370,24 @@ namespace nana
{ {
return std::unique_ptr<widget_notifier_interface>(new widget::inner_widget_notifier(*wdg)); return std::unique_ptr<widget_notifier_interface>(new widget::inner_widget_notifier(*wdg));
} }
//class widget_base
widget_base::~widget_base()
{
if (handle_)
API::close_window(handle_);
}
window widget_base::handle() const
{
return handle_;
}
void widget_base::_m_notify_destroy()
{
handle_ = nullptr;
}
//end class widget_base
} }
}//end namespace nana }//end namespace nana