some improvements, deprecated frame widget

This commit is contained in:
Jinhao 2016-06-24 00:25:26 +08:00
parent 0cd9be4641
commit 880d0becf3
24 changed files with 603 additions and 435 deletions

View File

@ -93,6 +93,9 @@
#endif #endif
#endif #endif
//This marco is defined since 1.4 and until 1.5 for deprecating frame widget.
//This marco and class frame will be removed in version 1.5
#define WIDGET_FRAME_DEPRECATED
/////////////////// ///////////////////
// Support for NANA_AUTOMATIC_GUI_TESTING // Support for NANA_AUTOMATIC_GUI_TESTING

View File

@ -56,14 +56,18 @@ namespace nana
super, super,
widget = 0x1, widget = 0x1,
lite_widget = 0x3, lite_widget = 0x3,
root = 0x5, root = 0x5
frame = 0x9 #ifndef WIDGET_FRAME_DEPRECATED
,frame = 0x9
#endif
}; };
//wait for constexpr //wait for constexpr
struct widget_tag{ static const flags value = flags::widget; }; struct widget_tag{ static const flags value = flags::widget; };
struct lite_widget_tag : public widget_tag{ static const flags value = flags::lite_widget; }; struct lite_widget_tag : public widget_tag{ static const flags value = flags::lite_widget; };
struct root_tag : public widget_tag{ static const flags value = flags::root; }; struct root_tag : public widget_tag{ static const flags value = flags::root; };
#ifndef WIDGET_FRAME_DEPRECATED
struct frame_tag : public widget_tag{ static const flags value = flags::frame; }; struct frame_tag : public widget_tag{ static const flags value = flags::frame; };
#endif
}// end namespace category }// end namespace category
using native_window_type = detail::native_window_handle_impl*; using native_window_type = detail::native_window_handle_impl*;
@ -260,6 +264,26 @@ that return a corresponding nana::appearance with predefined values.
} }
}; };
};//end namespace apper };//end namespace apper
/// Interface for caret operations
class caret_interface
{
public:
virtual ~caret_interface() = default;
virtual void disable_throw() noexcept = 0;
virtual void effective_range(const rectangle& range) = 0;
virtual void position(const point& pos) = 0;
virtual point position() const = 0;
virtual void dimension(const size& size) = 0;
virtual size dimension() const = 0;
virtual void visible(bool visibility) = 0;
virtual bool visible() const = 0;
};//end class caret_interface
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic> #include <nana/pop_ignore_diagnostic>

View File

@ -32,32 +32,37 @@ namespace detail
invisible, visible, displayed invisible, visible, displayed
}; };
class caret_descriptor class caret
: public caret_interface
{ {
public: public:
typedef basic_window core_window_t; caret(basic_window* owner, const size& size);
~caret();
caret_descriptor(core_window_t*, unsigned width, unsigned height); void activate(bool activity);
~caret_descriptor(); basic_window* owner() const noexcept;
void set_active(bool);
core_window_t* window() const;
void position(int x, int y);
void effective_range(::nana::rectangle);
::nana::point position() const;
void visible(bool isshow);
bool visible() const;
::nana::size size() const;
void size(const ::nana::size&);
void update(); void update();
public:
//Implement caret_interface functions
//This function is useless for class caret, see caret_proxy.
void disable_throw() noexcept override;
void effective_range(const rectangle& r) override;
void position(const point& pos) override;
nana::point position() const override;
size dimension() const override;
void dimension(const size& s);
void visible(bool visibility) override;
bool visible() const override;
private: private:
core_window_t* wd_; basic_window * owner_;
::nana::point point_; point position_;
::nana::size size_; size size_;
::nana::size paint_size_; size visual_size_;
visible_state visible_state_; visible_state visibility_{ visible_state::invisible };
bool out_of_range_; bool out_of_range_{ false };
::nana::rectangle effective_range_; rectangle effect_range_;
};//end class caret_descriptor };//end class caret
/// Define some constant about tab category, these flags can be combine with operator | /// Define some constant about tab category, these flags can be combine with operator |
struct tab_type struct tab_type
@ -70,6 +75,8 @@ namespace detail
}; };
}; };
class caret;
/// a window data structure descriptor /// a window data structure descriptor
struct basic_window struct basic_window
: public events_holder : public events_holder
@ -107,7 +114,9 @@ namespace detail
/// bind a native window and baisc_window /// bind a native window and baisc_window
void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&); void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&);
#ifndef WIDGET_FRAME_DEPRECATED
void frame_window(native_window_type); void frame_window(native_window_type);
#endif
bool is_ancestor_of(const basic_window* wd) const; bool is_ancestor_of(const basic_window* wd) const;
bool visible_parents() const; bool visible_parents() const;
@ -174,13 +183,15 @@ namespace detail
mouse_action action_before; mouse_action action_before;
}flags; }flags;
struct
{
caret_descriptor* caret;
std::shared_ptr<general_events> events_ptr;
}together;
widget_geometrics* scheme{ nullptr }; struct annex_components
{
caret* caret_ptr{ nullptr };
//The following pointers refer to the widget's object.
std::shared_ptr<general_events> events_ptr;
widget_geometrics* scheme{ nullptr };
}annex;
struct struct
{ {
@ -191,11 +202,13 @@ namespace detail
struct other_tag struct other_tag
{ {
#ifndef WIDGET_FRAME_DEPRECATED
struct attr_frame_tag struct attr_frame_tag
{ {
native_window_type container{nullptr}; native_window_type container{nullptr};
std::vector<native_window_type> attach; std::vector<native_window_type> attach;
}; };
#endif
struct attr_root_tag struct attr_root_tag
{ {
@ -223,7 +236,9 @@ namespace detail
union union
{ {
attr_root_tag * root; attr_root_tag * root;
#ifndef WIDGET_FRAME_DEPRECATED
attr_frame_tag * frame; attr_frame_tag * frame;
#endif
}attribute; }attribute;
other_tag(category::flags); other_tag(category::flags);

View File

@ -82,9 +82,7 @@ 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_geometrics& get_scheme_template(scheme_factory_interface&&); color_schemes& scheme();
widget_geometrics* make_scheme(scheme_factory_interface&&);
events_operation& evt_operation(); events_operation& evt_operation();
window_manager& wd_manager(); window_manager& wd_manager();

View File

@ -14,7 +14,6 @@
#define NANA_GUI_DETAIL_DRAWER_HPP #define NANA_GUI_DETAIL_DRAWER_HPP
#include <nana/push_ignore_diagnostic> #include <nana/push_ignore_diagnostic>
#include <vector>
#include "general_events.hpp" #include "general_events.hpp"
#include <nana/paint/graphics.hpp> #include <nana/paint/graphics.hpp>
#include <functional> #include <functional>
@ -29,14 +28,23 @@ namespace nana
} }
class drawer_trigger class drawer_trigger
: ::nana::noncopyable, ::nana::nonmovable
{ {
friend class detail::drawer; friend class detail::drawer;
//Noncopyable
drawer_trigger(const drawer_trigger&) = delete;
drawer_trigger& operator=(const drawer_trigger&) = delete;
//Nonmovable
drawer_trigger(drawer_trigger&&) = delete;
drawer_trigger& operator=(drawer_trigger&&) = delete;
public: public:
using widget_reference = widget&; using widget_reference = widget&;
using graph_reference = paint::graphics&; using graph_reference = paint::graphics&;
virtual ~drawer_trigger(); drawer_trigger() = default;
virtual ~drawer_trigger() = default;
virtual void attached(widget_reference, graph_reference); //none-const virtual void attached(widget_reference, graph_reference); //none-const
virtual void detached(); //none-const virtual void detached(); //none-const
@ -73,21 +81,11 @@ namespace nana
{ {
struct basic_window; struct basic_window;
namespace dynamic_drawing
{
//declaration
class object;
}
//@brief: Every window has a drawer, the drawer holds a drawer_trigger for //@brief: Every window has a drawer, the drawer holds a drawer_trigger for
// a widget. // a widget.
class drawer class drawer
: nana::noncopyable, nana::nonmovable : nana::noncopyable, nana::nonmovable
{ {
enum{
event_size = static_cast<int>(event_code::end)
};
enum class method_state enum class method_state
{ {
pending, pending,
@ -95,6 +93,7 @@ namespace nana
not_overrided not_overrided
}; };
public: public:
drawer();
~drawer(); ~drawer();
void bind(basic_window*); void bind(basic_window*);
@ -136,21 +135,21 @@ namespace nana
void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr) void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr)
{ {
const int pos = static_cast<int>(evt_code); const int pos = static_cast<int>(evt_code);
if (realizer_ && (method_state::not_overrided != mth_state_[pos])) if (data_impl_->realizer && (method_state::not_overrided != data_impl_->mth_state[pos]))
{ {
_m_bground_pre(); _m_bground_pre();
if (method_state::pending == mth_state_[pos]) if (method_state::pending == data_impl_->mth_state[pos])
{ {
(realizer_->*mfptr)(graphics, arg); (data_impl_->realizer->*mfptr)(graphics, arg);
//Check realizer, when the window is closed in that event handler, the drawer will be //Check realizer, when the window is closed in that event handler, the drawer will be
//detached and realizer will be a nullptr //detached and realizer will be a nullptr
if(realizer_) if (data_impl_->realizer)
mth_state_[pos] = (realizer_->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); data_impl_->mth_state[pos] = (data_impl_->realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided);
} }
else else
(realizer_->*mfptr)(graphics, arg); (data_impl_->realizer->*mfptr)(graphics, arg);
if (_m_lazy_decleared()) if (_m_lazy_decleared())
{ {
@ -162,11 +161,9 @@ namespace nana
public: public:
nana::paint::graphics graphics; nana::paint::graphics graphics;
private: private:
basic_window* core_window_{nullptr}; struct data_implement;
drawer_trigger* realizer_{nullptr};
std::vector<dynamic_drawing::object*> dynamic_drawing_objects_; data_implement * const data_impl_;
bool refreshing_{false};
method_state mth_state_[event_size];
}; };
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana

View File

@ -174,12 +174,12 @@ namespace nana{
good_r.x = good_r.y = 1; good_r.x = good_r.y = 1;
good_r.width = r.width - 2; good_r.width = r.width - 2;
good_r.height = r.height - 2; good_r.height = r.height - 2;
pixbuf.rectangle(good_r, wd->scheme->activated.get_color(), 0.95, false); pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.95, false);
good_r.x = good_r.y = 0; good_r.x = good_r.y = 0;
good_r.width = r.width; good_r.width = r.width;
good_r.height = r.height; good_r.height = r.height;
pixbuf.rectangle(good_r, wd->scheme->activated.get_color(), 0.4, false); pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.4, false);
pixbuf.pixel(0, 0, px0); pixbuf.pixel(0, 0, px0);
pixbuf.pixel(r.width - 1, 0, px1); pixbuf.pixel(r.width - 1, 0, px1);

View File

@ -94,10 +94,12 @@ namespace detail
core_window_t* create_root(core_window_t*, bool nested, rectangle, const appearance&, widget*); core_window_t* create_root(core_window_t*, bool nested, rectangle, const appearance&, widget*);
core_window_t* create_widget(core_window_t*, const rectangle&, bool is_lite, widget*); core_window_t* create_widget(core_window_t*, const rectangle&, bool is_lite, widget*);
#ifndef WIDGET_FRAME_DEPRECATED
core_window_t* create_frame(core_window_t*, const rectangle&, widget*); core_window_t* create_frame(core_window_t*, const rectangle&, widget*);
bool insert_frame(core_window_t* frame, native_window); bool insert_frame(core_window_t* frame, native_window);
bool insert_frame(core_window_t* frame, core_window_t*); bool insert_frame(core_window_t* frame, core_window_t*);
#endif
void close(core_window_t*); void close(core_window_t*);
//destroy //destroy

View File

@ -80,8 +80,9 @@ namespace API
window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached); window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached);
window create_widget(window, const rectangle&, widget* attached); window create_widget(window, const rectangle&, widget* attached);
window create_lite_widget(window, const rectangle&, widget* attached); window create_lite_widget(window, const rectangle&, widget* attached);
#ifndef WIDGET_FRAME_DEPRECATED
window create_frame(window, const rectangle&, widget* attached); window create_frame(window, const rectangle&, widget* attached);
#endif
paint::graphics* window_graphics(window); paint::graphics* window_graphics(window);
void delay_restore(bool); void delay_restore(bool);
@ -201,9 +202,12 @@ namespace API
void fullscreen(window, bool); void fullscreen(window, bool);
bool enabled_double_click(window, bool); bool enabled_double_click(window, bool);
#ifndef WIDGET_FRAME_DEPRECATED
bool insert_frame(window frame, native_window_type); bool insert_frame(window frame, native_window_type);
native_window_type frame_container(window frame); native_window_type frame_container(window frame);
native_window_type frame_element(window frame, unsigned index); native_window_type frame_element(window frame, unsigned index);
#endif
void close_window(window); void close_window(window);
void show_window(window, bool show); ///< Sets a window visible state. void show_window(window, bool show); ///< Sets a window visible state.
void restore_window(window); void restore_window(window);
@ -334,15 +338,18 @@ namespace API
color activated_color(window); color activated_color(window);
color activated_color(window, const color&); color activated_color(window, const color&);
void create_caret(window, unsigned width, unsigned height); void create_caret(window, const size&);
void destroy_caret(window); void destroy_caret(window);
void caret_effective_range(window, const rectangle&);
void caret_pos(window, const ::nana::point&); /// Opens an existing caret of a window.
nana::point caret_pos(window); /**
nana::size caret_size(window); * This function returns an object to operate caret. The object doesn't create or destroy the caret.
void caret_size(window, const size&); * When you are finished with the caret, be sure to reset the pointer.
void caret_visible(window, bool is_show); *
bool caret_visible(window); * @param window_handle A handle to a window whose caret is to be retrieved
* @return a pointer to the caret proxy. nullptr if the window doesn't have a caret.
*/
::std::unique_ptr<caret_interface> open_caret(window window_handle, bool disable_throw = false);
/// Enables that the user can give input focus to the specified window using TAB key. /// Enables that the user can give input focus to the specified window using TAB key.
void tabstop(window); void tabstop(window);

View File

@ -14,9 +14,12 @@
#define NANA_GUI_WIDGET_FORM_HPP #define NANA_GUI_WIDGET_FORM_HPP
#include "widget.hpp" #include "widget.hpp"
#include <nana/gui/place.hpp>
namespace nana namespace nana
{ {
class place;
namespace drawerbase namespace drawerbase
{ {
namespace form namespace form
@ -29,12 +32,29 @@ namespace nana
private: private:
widget* wd_{nullptr}; widget* wd_{nullptr};
}; };
class form_base
: public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension>
{
public:
form_base(window owner, bool nested, const rectangle&, const appearance&);
//place methods
place & get_place();
void div(const char* div_text);
place::field_reference operator[](const char* field_name);
void collocate() noexcept;
private:
std::unique_ptr<place> place_;
};
}//end namespace form }//end namespace form
}//end namespace drawerbase }//end namespace drawerbase
/// \brief Pop-up window. Is different from other window widgets: its default constructor create the window. /// \brief Pop-up window. Is different from other window widgets: its default constructor create the window.
/// \see nana::appearance /// \see nana::appearance
class form: public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension> class form
: public drawerbase::form::form_base
{ {
public: public:
using appear = ::nana::appear; using appear = ::nana::appear;
@ -50,7 +70,8 @@ namespace nana
void wait_for_this(); void wait_for_this();
}; };
class nested_form : public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension> class nested_form
: public drawerbase::form::form_base
{ {
public: public:
using appear = ::nana::appear; using appear = ::nana::appear;

View File

@ -16,6 +16,8 @@
#define NANA_GUI_WIDGET_FRAME_HPP #define NANA_GUI_WIDGET_FRAME_HPP
#include "widget.hpp" #include "widget.hpp"
#ifndef WIDGET_FRAME_DEPRECATED
namespace nana namespace nana
{ {
/** /**
@ -51,3 +53,4 @@ namespace nana
}; };
}//end namespace nana }//end namespace nana
#endif #endif
#endif

View File

@ -308,7 +308,8 @@ namespace nana{ namespace widgets
void _m_offset_y(int y); void _m_offset_y(int y);
unsigned _m_char_by_pixels(const wchar_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl); unsigned _m_char_by_pixels(const unicode_bidi::entity&, unsigned pos);
unsigned _m_pixels_by_char(const ::std::wstring&, std::size_t pos) const; unsigned _m_pixels_by_char(const ::std::wstring&, std::size_t pos) const;
void _handle_move_key(const arg_keyboard& arg); void _handle_move_key(const arg_keyboard& arg);
@ -316,6 +317,7 @@ namespace nana{ namespace widgets
std::unique_ptr<editor_behavior_interface> behavior_; std::unique_ptr<editor_behavior_interface> behavior_;
undoable<command> undo_; undoable<command> undo_;
nana::window window_; nana::window window_;
std::unique_ptr<caret_interface> caret_;
graph_reference graph_; graph_reference graph_;
const text_editor_scheme* scheme_; const text_editor_scheme* scheme_;
event_interface * event_handler_{ nullptr }; event_interface * event_handler_{ nullptr };

View File

@ -14,7 +14,6 @@
#define NANA_GUI_WIDGET_HPP #define NANA_GUI_WIDGET_HPP
#include <nana/push_ignore_diagnostic> #include <nana/push_ignore_diagnostic>
#include <nana/gui/place.hpp>
#include "../programming_interface.hpp" #include "../programming_interface.hpp"
#include <nana/internationalization.hpp> #include <nana/internationalization.hpp>
#include <nana/gui/detail/drawer.hpp> #include <nana/gui/detail/drawer.hpp>
@ -391,33 +390,6 @@ namespace nana
{ {
return API::window_outline_size(handle()); return API::window_outline_size(handle());
} }
place & get_place()
{
if (this->empty())
throw std::runtime_error("form::get_plac: the form has destroyed.");
if (!place_)
place_.reset(new place{ *this });
return *place_;
}
void div(const char* div_text)
{
get_place().div(div_text);
}
place::field_reference operator[](const char* field_name)
{
return get_place()[field_name];
}
void collocate() noexcept
{
if (place_)
place_->collocate();
}
protected: protected:
DrawerTrigger& get_drawer_trigger() DrawerTrigger& get_drawer_trigger()
{ {
@ -447,9 +419,9 @@ namespace nana
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_;
std::unique_ptr<place> place_;
};//end class widget_object<root_tag> };//end class widget_object<root_tag>
#ifndef WIDGET_FRAME_DEPRECATED
/// Base class of all the classes defined as a frame window. \see nana::frame /// Base class of all the classes defined as a frame window. \see nana::frame
template<typename Drawer, typename Events, typename Scheme> template<typename Drawer, typename Events, typename Scheme>
class widget_object<category::frame_tag, Drawer, Events, Scheme>: public widget{}; class widget_object<category::frame_tag, Drawer, Events, Scheme>: public widget{};
@ -509,6 +481,7 @@ namespace nana
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>
#endif
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic> #include <nana/pop_ignore_diagnostic>

View File

@ -17,188 +17,194 @@ namespace nana
{ {
namespace detail namespace detail
{ {
//class caret_descriptor //class caret
caret_descriptor::caret_descriptor(core_window_t* wd, unsigned width, unsigned height) caret::caret(basic_window* owner, const size& size):
:wd_(wd), size_(width, height), visible_state_(visible_state::invisible), out_of_range_(false) owner_(owner),
size_(size)
{} {}
caret_descriptor::~caret_descriptor() caret::~caret()
{ {
if(wd_) native_interface::caret_destroy(wd_->root); if (owner_)
native_interface::caret_destroy(owner_->root);
} }
void caret_descriptor::set_active(bool active) void caret::activate(bool activity)
{ {
if(wd_) if (owner_)
{ {
if(active) if (activity)
{ {
native_interface::caret_create(wd_->root, size_); native_interface::caret_create(owner_->root, size_);
visible_state_ = visible_state::invisible; visibility_ = visible_state::invisible;
this->position(point_.x, point_.y); this->position(position_);
} }
else else
native_interface::caret_destroy(wd_->root); native_interface::caret_destroy(owner_->root);
wd_->root_widget->other.attribute.root->ime_enabled = active; owner_->root_widget->other.attribute.root->ime_enabled = activity;
} }
} }
auto caret_descriptor::window() const ->core_window_t* basic_window* caret::owner() const noexcept
{ {
return wd_; return owner_;
} }
void caret_descriptor::position(int x, int y) void caret::update()
{ {
point_.x = x; auto pos = position_;
point_.y = y; auto size = size_;
update(); auto rect = effect_range_;
} if (0 == effect_range_.width || 0 == effect_range_.height)
void caret_descriptor::effective_range(nana::rectangle rect)
{
//Chech rect
if (rect.width && rect.height && rect.right() > 0 && rect.bottom() > 0)
{
if(rect.x < 0)
{
rect.width += rect.x;
rect.x = 0;
}
if(rect.y < 0)
{
rect.height += rect.y;
rect.y = 0;
}
if(effective_range_ != rect)
{
effective_range_ = rect;
update();
}
}
}
nana::point caret_descriptor::position() const
{
return point_;
}
void caret_descriptor::visible(bool is_show)
{
auto pre_displayed = (visible_state::displayed == visible_state_);
if (is_show)
{
visible_state_ = visible_state::visible;
if (wd_->displayed() && (! out_of_range_))
visible_state_ = visible_state::displayed;
}
else
visible_state_ = visible_state::invisible;
if (pre_displayed != (visible_state::displayed == visible_state_))
native_interface::caret_visible(wd_->root, !pre_displayed);
}
bool caret_descriptor::visible() const
{
return (visible_state::invisible != visible_state_);
}
nana::size caret_descriptor::size() const
{
return size_;
}
void caret_descriptor::size(const nana::size& s)
{
size_ = s;
update();
if (visible_state::invisible != visible_state_)
visible(true);
}
void caret_descriptor::update()
{
nana::point pos = point_;
nana::size size = size_;
nana::rectangle rect = effective_range_;
if(0 == effective_range_.width || 0 == effective_range_.height)
{ {
rect.x = rect.y = 0; rect.x = rect.y = 0;
rect = wd_->dimension; rect = owner_->dimension;
} }
else else
{ {
pos.x += effective_range_.x; pos += effect_range_.position();
pos.y += effective_range_.y;
} }
if( (pos.x + static_cast<int>(size.width) <= rect.x) || (pos.x >= rect.right()) || if ((pos.x + static_cast<int>(size.width) <= rect.x) || (pos.x >= rect.right()) ||
(pos.y + static_cast<int>(size.height) <= rect.y) || (pos.y >= rect.bottom()) (pos.y + static_cast<int>(size.height) <= rect.y) || (pos.y >= rect.bottom())
) )
{//Out of Range without overlap {//Out of Range without overlap
if(false == out_of_range_) if (false == out_of_range_)
{ {
out_of_range_ = true; out_of_range_ = true;
if (visible_state::invisible != visible_state_) if (visible_state::invisible != visibility_)
visible(false); visible(false);
} }
} }
else else
{ {
if(pos.x < rect.x) if (pos.x < rect.x)
{ {
size.width -= (rect.x - pos.x); size.width -= (rect.x - pos.x);
pos.x = rect.x; pos.x = rect.x;
} }
else if(pos.x + static_cast<int>(size.width) > rect.right()) else if (pos.x + static_cast<int>(size.width) > rect.right())
{ {
size.width -= pos.x + size.width - rect.right(); size.width -= pos.x + size.width - rect.right();
} }
if(pos.y < rect.y) if (pos.y < rect.y)
{ {
size.width -= (rect.y - pos.y); size.width -= (rect.y - pos.y);
pos.y = rect.y; pos.y = rect.y;
} }
else if(pos.y + static_cast<int>(size.height) > rect.bottom()) else if (pos.y + static_cast<int>(size.height) > rect.bottom())
size.height -= pos.y + size.height - rect.bottom(); size.height -= pos.y + size.height - rect.bottom();
if(out_of_range_) if (out_of_range_)
{ {
if (paint_size_ == size) if (visual_size_ == size)
visible(true); visible(true);
out_of_range_ = false; out_of_range_ = false;
} }
if(paint_size_ != size) if (visual_size_ != size)
{ {
bool vs = (visible_state::invisible != visible_state_); bool vs = (visible_state::invisible != visibility_);
native_interface::caret_destroy(wd_->root); native_interface::caret_destroy(owner_->root);
native_interface::caret_create(wd_->root, size); native_interface::caret_create(owner_->root, size);
visible_state_ = visible_state::invisible; visibility_ = visible_state::invisible;
if (vs) if (vs)
visible(true); visible(true);
paint_size_ = size; visual_size_ = size;
} }
native_interface::caret_pos(wd_->root, wd_->pos_root + pos); native_interface::caret_pos(owner_->root, owner_->pos_root + pos);
} }
} }
//end class caret_descriptor
//Implement caret_interface functions
void caret::disable_throw() noexcept
{
//This function is useless for class caret, see caret_proxy.
}
void caret::effective_range(const rectangle& r)
{
auto range = r;
//Chech rect
if (range.width && range.height && range.right() > 0 && range.bottom() > 0)
{
if (range.x < 0)
{
range.width += range.x;
range.x = 0;
}
if (range.y < 0)
{
range.height += range.y;
range.y = 0;
}
if (effect_range_ != range)
{
effect_range_ = range;
update();
}
}
}
void caret::position(const point& pos)
{
position_ = pos;
update();
}
point caret::position() const
{
return position_;
}
size caret::dimension() const
{
return size_;
}
void caret::dimension(const size& s)
{
size_ = s;
update();
if (visible_state::invisible != visibility_)
visible(true);
}
void caret::visible(bool visibility)
{
auto pre_displayed = (visible_state::displayed == visibility_);
if (visibility)
{
visibility_ = visible_state::visible;
if (owner_->displayed() && (!out_of_range_))
visibility_ = visible_state::displayed;
}
else
visibility_ = visible_state::invisible;
if (pre_displayed != (visible_state::displayed == visibility_))
native_interface::caret_visible(owner_->root, !pre_displayed);
}
bool caret::visible() const
{
return (visible_state::invisible != visibility_);
}
//end class caret
//struct basic_window //struct basic_window
//struct basic_window::other_tag //struct basic_window::other_tag
@ -210,9 +216,11 @@ namespace nana
case category::flags::root: case category::flags::root:
attribute.root = new attr_root_tag; attribute.root = new attr_root_tag;
break; break;
#ifndef WIDGET_FRAME_DEPRECATED
case category::flags::frame: case category::flags::frame:
attribute.frame = new attr_frame_tag; attribute.frame = new attr_frame_tag;
break; break;
#endif
default: default:
attribute.root = nullptr; attribute.root = nullptr;
} }
@ -220,6 +228,7 @@ namespace nana
basic_window::other_tag::~other_tag() basic_window::other_tag::~other_tag()
{ {
#ifndef WIDGET_FRAME_DEPRECATED
switch(category) switch(category)
{ {
case category::flags::root: case category::flags::root:
@ -230,6 +239,9 @@ namespace nana
break; break;
default: break; default: break;
} }
#endif
if (category::flags::root == category)
delete attribute.root;
} }
//end struct basic_window::other_tag //end struct basic_window::other_tag
@ -245,8 +257,8 @@ namespace nana
basic_window::~basic_window() basic_window::~basic_window()
{ {
delete together.caret; delete annex.caret_ptr;
together.caret = nullptr; annex.caret_ptr = nullptr;
delete effect.bground; delete effect.bground;
effect.bground = nullptr; effect.bground = nullptr;
@ -268,11 +280,13 @@ namespace nana
} }
} }
#ifndef WIDGET_FRAME_DEPRECATED
void basic_window::frame_window(native_window_type wd) void basic_window::frame_window(native_window_type wd)
{ {
if(category::flags::frame == this->other.category) if(category::flags::frame == this->other.category)
other.attribute.frame->container = wd; other.attribute.frame->container = wd;
} }
#endif
bool basic_window::is_ancestor_of(const basic_window* wd) const bool basic_window::is_ancestor_of(const basic_window* wd) const
{ {
@ -312,7 +326,7 @@ namespace nana
const basic_window* get_child_caret(const basic_window* wd, bool this_is_a_child) const basic_window* get_child_caret(const basic_window* wd, bool this_is_a_child)
{ {
if (this_is_a_child && wd->together.caret) if (this_is_a_child && wd->annex.caret_ptr)
return wd; return wd;
for (auto child : wd->children) for (auto child : wd->children)
@ -412,8 +426,6 @@ namespace nana
effect.bground = nullptr; effect.bground = nullptr;
effect.bground_fade_rate = 0; effect.bground_fade_rate = 0;
together.caret = nullptr;
extra_width = extra_height = 0; extra_width = extra_height = 0;
//The window must keep its thread_id same as its parent if it is a child. //The window must keep its thread_id same as its parent if it is a child.
@ -425,15 +437,15 @@ namespace nana
bool basic_window::set_events(const std::shared_ptr<general_events>& p) bool basic_window::set_events(const std::shared_ptr<general_events>& p)
{ {
if (together.events_ptr) if (annex.events_ptr)
return false; return false;
together.events_ptr = p; annex.events_ptr = p;
return true; return true;
} }
general_events * basic_window::get_events() const general_events * basic_window::get_events() const
{ {
return together.events_ptr.get(); return annex.events_ptr.get();
} }
//end struct basic_window //end struct basic_window
}//end namespace detail }//end namespace detail

View File

@ -129,16 +129,16 @@ namespace nana
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = reinterpret_cast<window>(wd);
if (emit(event_code::expose, wd, arg, false, get_thread_context())) if (emit(event_code::expose, wd, arg, false, get_thread_context()))
{ {
const core_window_t * caret_wd = (wd->together.caret ? wd : wd->child_caret()); const core_window_t * caret_wd = (wd->annex.caret_ptr ? wd : wd->child_caret());
if (caret_wd) if (caret_wd)
{ {
if (exposed) if (exposed)
{ {
if (wd->root_widget->other.attribute.root->focus == caret_wd) if (wd->root_widget->other.attribute.root->focus == caret_wd)
caret_wd->together.caret->visible(true); caret_wd->annex.caret_ptr->visible(true);
} }
else else
caret_wd->together.caret->visible(false); caret_wd->annex.caret_ptr->visible(false);
} }
if (!exposed) if (!exposed)
@ -148,8 +148,10 @@ namespace nana
//find an ancestor until it is not a lite_widget //find an ancestor until it is not a lite_widget
wd = wd->seek_non_lite_widget_ancestor(); wd = wd->seek_non_lite_widget_ancestor();
} }
#ifndef WIDGET_FRAME_DEPRECATED
else if (category::flags::frame == wd->other.category) else if (category::flags::frame == wd->other.category)
wd = wd_manager().find_window(wd->root, wd->pos_root.x, wd->pos_root.y); wd = wd_manager().find_window(wd->root, wd->pos_root.x, wd->pos_root.y);
#endif
} }
wd_manager().refresh_tree(wd); wd_manager().refresh_tree(wd);
@ -201,24 +203,21 @@ namespace nana
{ {
if (root_wd->flags.enabled && root_wd->flags.take_active) if (root_wd->flags.enabled && root_wd->flags.take_active)
{ {
if (focused && focused->together.caret) if (focused && focused->annex.caret_ptr)
focused->together.caret->set_active(true); focused->annex.caret_ptr->activate(true);
if (!emit(event_code::focus, focused, arg, true, get_thread_context())) if (!emit(event_code::focus, focused, arg, true, get_thread_context()))
this->wd_manager().set_focus(root_wd, true, arg_focus::reason::general); this->wd_manager().set_focus(root_wd, true, arg_focus::reason::general);
} }
} }
else else if (root_wd->other.attribute.root->focus)
{ {
if (root_wd->other.attribute.root->focus) if (emit(event_code::focus, focused, arg, true, get_thread_context()))
{ {
if (emit(event_code::focus, focused, arg, true, get_thread_context())) if (focused->annex.caret_ptr)
{ focused->annex.caret_ptr->activate(false);
if (focused->together.caret)
focused->together.caret->set_active(false);
}
close_menu_if_focus_other_window(receiver);
} }
close_menu_if_focus_other_window(receiver);
} }
} }
@ -353,19 +352,14 @@ namespace nana
return pi_data_->shortkey_occurred; return pi_data_->shortkey_occurred;
} }
widget_geometrics& bedrock::get_scheme_template(scheme_factory_interface&& factory) color_schemes& bedrock::scheme()
{ {
return pi_data_->scheme.scheme_template(std::move(factory)); return pi_data_->scheme;
}
widget_geometrics* bedrock::make_scheme(scheme_factory_interface&& factory)
{
return pi_data_->scheme.create(std::move(factory));
} }
void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg) void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg)
{ {
auto retain = wd->together.events_ptr; auto retain = wd->annex.events_ptr;
auto evts_ptr = retain.get(); auto evts_ptr = retain.get();
switch (evt_code) switch (evt_code)

View File

@ -385,7 +385,7 @@ namespace detail
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->together.events_ptr->mouse_dropfiles.emit(arg, reinterpret_cast<window>(msgwd)); msgwd->annex.events_ptr->mouse_dropfiles.emit(arg, reinterpret_cast<window>(msgwd));
brock.wd_manager().do_lazy_refresh(msgwd, false); brock.wd_manager().do_lazy_refresh(msgwd, false);
} }
break; break;
@ -594,7 +594,7 @@ namespace detail
} }
} }
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
context.event_window = msgwnd; context.event_window = msgwnd;
pressed_wd = nullptr; pressed_wd = nullptr;
@ -632,7 +632,7 @@ namespace detail
nana::point mspos{xevent.xbutton.x, xevent.xbutton.y}; nana::point mspos{xevent.xbutton.x, xevent.xbutton.y};
while(msgwnd) while(msgwnd)
{ {
if(msgwnd->together.events_ptr->mouse_wheel.length() != 0) if(msgwnd->annex.events_ptr->mouse_wheel.length() != 0)
{ {
mspos -= msgwnd->pos_root; mspos -= msgwnd->pos_root;
arg_wheel arg; arg_wheel arg;
@ -653,7 +653,7 @@ namespace detail
msgwnd->set_action(mouse_action::normal); msgwnd->set_action(mouse_action::normal);
if(msgwnd->flags.enabled) if(msgwnd->flags.enabled)
{ {
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
::nana::arg_mouse arg; ::nana::arg_mouse arg;
assign_arg(arg, msgwnd, message, xevent); assign_arg(arg, msgwnd, message, xevent);
@ -682,7 +682,7 @@ namespace detail
if(hit) if(hit)
msgwnd->set_action(mouse_action::hovered); msgwnd->set_action(mouse_action::hovered);
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
auto evt_ptr = retain.get(); auto evt_ptr = retain.get();
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
@ -698,7 +698,7 @@ namespace detail
} }
} }
else if(click_arg.window_handle) else if(click_arg.window_handle)
msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
@ -895,7 +895,7 @@ namespace detail
msgwnd->set_action(mouse_action::pressed); msgwnd->set_action(mouse_action::pressed);
pressed_wd_space = msgwnd; pressed_wd_space = msgwnd;
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
draw_invoker(&drawer::mouse_down, msgwnd, arg, &context); draw_invoker(&drawer::mouse_down, msgwnd, arg, &context);
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
@ -987,7 +987,7 @@ namespace detail
arg.evt_code = event_code::key_char; arg.evt_code = event_code::key_char;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = reinterpret_cast<window>(msgwnd);
brock.get_key_state(arg); brock.get_key_state(arg);
msgwnd->together.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd));
if(arg.ignore == false && wd_manager.available(msgwnd)) if(arg.ignore == false && wd_manager.available(msgwnd))
draw_invoker(&drawer::key_char, msgwnd, arg, &context); draw_invoker(&drawer::key_char, msgwnd, arg, &context);
} }
@ -1031,7 +1031,7 @@ namespace detail
click_arg.mouse_args = nullptr; click_arg.mouse_args = nullptr;
click_arg.window_handle = reinterpret_cast<window>(msgwnd); click_arg.window_handle = reinterpret_cast<window>(msgwnd);
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) if (brock.emit(event_code::click, msgwnd, click_arg, true, &context))
{ {
arg_mouse arg; arg_mouse arg;

View File

@ -947,7 +947,7 @@ namespace detail
assign_arg(arg, msgwnd, message, pmdec); assign_arg(arg, msgwnd, message, pmdec);
msgwnd->set_action(mouse_action::pressed); msgwnd->set_action(mouse_action::pressed);
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
if (brock.emit(event_code::mouse_down, msgwnd, arg, true, &context)) if (brock.emit(event_code::mouse_down, msgwnd, arg, true, &context))
{ {
//If a root_window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event. //If a root_window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event.
@ -986,7 +986,7 @@ namespace detail
msgwnd->set_action(mouse_action::normal); msgwnd->set_action(mouse_action::normal);
if(msgwnd->flags.enabled) if(msgwnd->flags.enabled)
{ {
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
::nana::arg_mouse arg; ::nana::arg_mouse arg;
assign_arg(arg, msgwnd, message, pmdec); assign_arg(arg, msgwnd, message, pmdec);
@ -1121,7 +1121,7 @@ namespace detail
auto evt_wd = scrolled_wd; auto evt_wd = scrolled_wd;
while (evt_wd) while (evt_wd)
{ {
if (evt_wd->together.events_ptr->mouse_wheel.length() != 0) if (evt_wd->annex.events_ptr->mouse_wheel.length() != 0)
{ {
def_window_proc = false; def_window_proc = false;
nana::point mspos{ scr_pos.x, scr_pos.y }; nana::point mspos{ scr_pos.x, scr_pos.y };
@ -1198,7 +1198,7 @@ namespace detail
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 = reinterpret_cast<window>(msgwnd);
msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast<window>(msgwnd));
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
} }
@ -1422,7 +1422,7 @@ namespace detail
msgwnd->set_action(mouse_action::pressed); msgwnd->set_action(mouse_action::pressed);
pressed_wd_space = msgwnd; pressed_wd_space = msgwnd;
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
draw_invoker(&drawer::mouse_down, msgwnd, arg, &context); draw_invoker(&drawer::mouse_down, msgwnd, arg, &context);
wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
@ -1468,7 +1468,7 @@ namespace detail
brock.get_key_state(arg); brock.get_key_state(arg);
arg.ignore = false; arg.ignore = false;
msgwnd->together.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(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);
@ -1496,7 +1496,7 @@ namespace detail
click_arg.mouse_args = nullptr; click_arg.mouse_args = nullptr;
click_arg.window_handle = reinterpret_cast<window>(msgwnd); click_arg.window_handle = reinterpret_cast<window>(msgwnd);
auto retain = msgwnd->together.events_ptr; auto retain = msgwnd->annex.events_ptr;
if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) if (brock.emit(event_code::click, msgwnd, click_arg, true, &context))
{ {
arg_mouse arg; arg_mouse arg;

View File

@ -26,7 +26,6 @@ namespace nana
typedef detail::edge_nimbus_renderer<detail::bedrock::core_window_t> edge_nimbus_renderer_t; typedef detail::edge_nimbus_renderer<detail::bedrock::core_window_t> edge_nimbus_renderer_t;
//class drawer_trigger //class drawer_trigger
drawer_trigger::~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
void drawer_trigger::typeface_changed(graph_reference){} void drawer_trigger::typeface_changed(graph_reference){}
@ -136,23 +135,43 @@ namespace nana
typedef bedrock bedrock_type; typedef bedrock bedrock_type;
//class drawer //class drawer
enum{
event_size = static_cast<int>(event_code::end)
};
struct drawer::data_implement
{
bool refreshing{ false };
basic_window* window_handle{ nullptr };
drawer_trigger* realizer{ nullptr };
method_state mth_state[event_size];
std::vector<dynamic_drawing::object*> draws;
};
drawer::drawer()
: data_impl_{ new data_implement }
{}
drawer::~drawer() drawer::~drawer()
{ {
for(auto p : dynamic_drawing_objects_) for(auto p : data_impl_->draws)
{ {
delete p; delete p;
} }
delete data_impl_;
} }
void drawer::bind(basic_window* cw) void drawer::bind(basic_window* cw)
{ {
core_window_ = cw; data_impl_->window_handle = cw;
} }
void drawer::typeface_changed() void drawer::typeface_changed()
{ {
if(realizer_) if(data_impl_->realizer)
realizer_->typeface_changed(graphics); data_impl_->realizer->typeface_changed(graphics);
} }
void drawer::click(const arg_click& arg) void drawer::click(const arg_click& arg)
@ -245,7 +264,7 @@ namespace nana
if(wd) if(wd)
{ {
auto iwd = reinterpret_cast<bedrock_type::core_window_t*>(wd); auto iwd = reinterpret_cast<bedrock_type::core_window_t*>(wd);
bool owns_caret = (iwd->together.caret) && (iwd->together.caret->visible()); bool owns_caret = (iwd->annex.caret_ptr) && (iwd->annex.caret_ptr->visible());
//The caret in X11 is implemented by Nana, it is different from Windows' //The caret in X11 is implemented by Nana, it is different from Windows'
//the caret in X11 is asynchronous, it is hard to hide and show the caret //the caret in X11 is asynchronous, it is hard to hide and show the caret
@ -254,7 +273,7 @@ namespace nana
if(owns_caret) if(owns_caret)
{ {
#ifndef NANA_X11 #ifndef NANA_X11
iwd->together.caret->visible(false); iwd->annex.caret_ptr->visible(false);
#else #else
owns_caret = nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, false); owns_caret = nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, false);
#endif #endif
@ -265,7 +284,7 @@ namespace nana
if(owns_caret) if(owns_caret)
{ {
#ifndef NANA_X11 #ifndef NANA_X11
iwd->together.caret->visible(true); iwd->annex.caret_ptr->visible(true);
#else #else
nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, true); nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, true);
#endif #endif
@ -275,39 +294,39 @@ namespace nana
void drawer::refresh() void drawer::refresh()
{ {
if(realizer_ && (refreshing_ == false)) if (data_impl_->realizer && !data_impl_->refreshing)
{ {
refreshing_ = true; data_impl_->refreshing = true;
_m_bground_pre(); _m_bground_pre();
realizer_->refresh(graphics); data_impl_->realizer->refresh(graphics);
_m_draw_dynamic_drawing_object(); _m_draw_dynamic_drawing_object();
_m_bground_end(); _m_bground_end();
graphics.flush(); graphics.flush();
refreshing_ = false; data_impl_->refreshing = false;
} }
} }
drawer_trigger* drawer::realizer() const drawer_trigger* drawer::realizer() const
{ {
return realizer_; return data_impl_->realizer;
} }
void drawer::attached(widget& wd, drawer_trigger& realizer) void drawer::attached(widget& wd, drawer_trigger& realizer)
{ {
for (auto i = std::begin(mth_state_), end = std::end(mth_state_); i != end; ++i) for (auto i = std::begin(data_impl_->mth_state), end = std::end(data_impl_->mth_state); i != end; ++i)
*i = method_state::pending; *i = method_state::pending;
realizer_ = &realizer; data_impl_->realizer = &realizer;
realizer._m_reset_overrided(); realizer._m_reset_overrided();
realizer.attached(wd, graphics); realizer.attached(wd, graphics);
} }
drawer_trigger* drawer::detached() drawer_trigger* drawer::detached()
{ {
if(realizer_) if (data_impl_->realizer)
{ {
auto rmp = realizer_; auto rmp = data_impl_->realizer;
realizer_ = nullptr; data_impl_->realizer = nullptr;
rmp->detached(); rmp->detached();
return rmp; return rmp;
} }
@ -317,7 +336,7 @@ namespace nana
void drawer::clear() void drawer::clear()
{ {
std::vector<dynamic_drawing::object*> then; std::vector<dynamic_drawing::object*> then;
for(auto p : dynamic_drawing_objects_) for (auto p : data_impl_->draws)
{ {
if(p->diehard()) if(p->diehard())
then.push_back(p); then.push_back(p);
@ -325,7 +344,7 @@ namespace nana
delete p; delete p;
} }
then.swap(dynamic_drawing_objects_); then.swap(data_impl_->draws);
} }
void* drawer::draw(std::function<void(paint::graphics&)> && f, bool diehard) void* drawer::draw(std::function<void(paint::graphics&)> && f, bool diehard)
@ -333,7 +352,7 @@ namespace nana
if(f) if(f)
{ {
auto p = new dynamic_drawing::user_draw_function(std::move(f), diehard); auto p = new dynamic_drawing::user_draw_function(std::move(f), diehard);
dynamic_drawing_objects_.push_back(p); data_impl_->draws.push_back(p);
return (diehard ? p : nullptr); return (diehard ? p : nullptr);
} }
return nullptr; return nullptr;
@ -343,11 +362,11 @@ namespace nana
{ {
if(p) if(p)
{ {
for (auto i = dynamic_drawing_objects_.begin(); i != dynamic_drawing_objects_.end(); ++i) for (auto i = data_impl_->draws.begin(); i != data_impl_->draws.end(); ++i)
if (*i == p) if (*i == p)
{ {
delete (*i); delete (*i);
dynamic_drawing_objects_.erase(i); data_impl_->draws.erase(i);
break; break;
} }
} }
@ -355,25 +374,25 @@ namespace nana
void drawer::_m_bground_pre() void drawer::_m_bground_pre()
{ {
if(core_window_->effect.bground && core_window_->effect.bground_fade_rate < 0.01) if (data_impl_->window_handle->effect.bground && data_impl_->window_handle->effect.bground_fade_rate < 0.01)
core_window_->other.glass_buffer.paste(graphics, 0, 0); data_impl_->window_handle->other.glass_buffer.paste(graphics, 0, 0);
} }
void drawer::_m_bground_end() void drawer::_m_bground_end()
{ {
if(core_window_->effect.bground && core_window_->effect.bground_fade_rate >= 0.01) if (data_impl_->window_handle->effect.bground && data_impl_->window_handle->effect.bground_fade_rate >= 0.01)
core_window_->other.glass_buffer.blend(::nana::rectangle{ core_window_->other.glass_buffer.size() }, graphics, nana::point(), core_window_->effect.bground_fade_rate); data_impl_->window_handle->other.glass_buffer.blend(::nana::rectangle{ data_impl_->window_handle->other.glass_buffer.size() }, graphics, nana::point(), data_impl_->window_handle->effect.bground_fade_rate);
} }
void drawer::_m_draw_dynamic_drawing_object() void drawer::_m_draw_dynamic_drawing_object()
{ {
for(auto * dw : dynamic_drawing_objects_) for (auto * dw : data_impl_->draws)
dw->draw(graphics); dw->draw(graphics);
} }
bool drawer::_m_lazy_decleared() const bool drawer::_m_lazy_decleared() const
{ {
return (basic_window::update_state::refresh == core_window_->other.upd_state); return (basic_window::update_state::refresh == data_impl_->window_handle->other.upd_state);
} }
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana

View File

@ -66,6 +66,7 @@ namespace nana
nana::point p_src; nana::point p_src;
for (auto & el : blocks) for (auto & el : blocks)
{ {
#ifndef WIDGET_FRAME_DEPRECATED
if (category::flags::frame == el.window->other.category) if (category::flags::frame == el.window->other.category)
{ {
native_window_type container = el.window->other.attribute.frame->container; native_window_type container = el.window->other.attribute.frame->container;
@ -73,6 +74,7 @@ namespace nana
graph.bitblt(el.r, container); graph.bitblt(el.r, container);
} }
else else
#endif
{ {
p_src.x = el.r.x - el.window->pos_root.x; p_src.x = el.r.x - el.window->pos_root.x;
p_src.y = el.r.y - el.window->pos_root.y; p_src.y = el.r.y - el.window->pos_root.y;

View File

@ -237,7 +237,7 @@ namespace detail
switch(evtid) switch(evtid)
{ {
case event_code::mouse_drop: case event_code::mouse_drop:
wd->flags.dropable = (is_make || (0 != wd->together.events_ptr->mouse_dropfiles.length())); wd->flags.dropable = (is_make || (0 != wd->annex.events_ptr->mouse_dropfiles.length()));
break; break;
default: default:
break; break;
@ -277,8 +277,12 @@ namespace detail
if (owner->flags.destroying) if (owner->flags.destroying)
throw std::runtime_error("the specified owner is destory"); throw std::runtime_error("the specified owner is destory");
#ifndef WIDGET_FRAME_DEPRECATED
native = (category::flags::frame == owner->other.category ? native = (category::flags::frame == owner->other.category ?
owner->other.attribute.frame->container : owner->root_widget->root); owner->other.attribute.frame->container : owner->root_widget->root);
#else
native = owner->root_widget->root;
#endif
r.x += owner->pos_root.x; r.x += owner->pos_root.x;
r.y += owner->pos_root.y; r.y += owner->pos_root.y;
} }
@ -311,8 +315,10 @@ namespace detail
wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph); wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph);
impl_->wd_register.insert(wd, wd->thread_id); impl_->wd_register.insert(wd, wd->thread_id);
#ifndef WIDGET_FRAME_DEPRECATED
if (owner && (category::flags::frame == owner->other.category)) if (owner && (category::flags::frame == owner->other.category))
insert_frame(owner, wd); insert_frame(owner, wd);
#endif
bedrock::inc_window(wd->thread_id); bedrock::inc_window(wd->thread_id);
this->icon(wd, impl_->default_icon_small, impl_->default_icon_big); this->icon(wd, impl_->default_icon_small, impl_->default_icon_big);
@ -321,6 +327,7 @@ namespace detail
return nullptr; return nullptr;
} }
#ifndef WIDGET_FRAME_DEPRECATED
window_manager::core_window_t* window_manager::create_frame(core_window_t* parent, const rectangle& r, widget* wdg) window_manager::core_window_t* window_manager::create_frame(core_window_t* parent, const rectangle& r, widget* wdg)
{ {
//Thread-Safe Required! //Thread-Safe Required!
@ -337,6 +344,7 @@ namespace detail
return (wd); return (wd);
} }
bool window_manager::insert_frame(core_window_t* frame, native_window wd) bool window_manager::insert_frame(core_window_t* frame, native_window wd)
{ {
if(frame) if(frame)
@ -367,6 +375,7 @@ namespace detail
} }
return false; return false;
} }
#endif
window_manager::core_window_t* window_manager::create_widget(core_window_t* parent, const rectangle& r, bool is_lite, widget* wdg) window_manager::core_window_t* window_manager::create_widget(core_window_t* parent, const rectangle& r, bool is_lite, widget* wdg)
{ {
@ -461,7 +470,11 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd) == false) return; if (impl_->wd_register.available(wd) == false) return;
#ifndef WIDGET_FRAME_DEPRECATED
if((category::flags::root == wd->other.category) || (category::flags::frame != wd->other.category)) if((category::flags::root == wd->other.category) || (category::flags::frame != wd->other.category))
#else
if (category::flags::root == wd->other.category)
#endif
{ {
impl_->misc_register.erase(wd->root); impl_->misc_register.erase(wd->root);
impl_->wd_register.remove(wd); impl_->wd_register.remove(wd);
@ -498,6 +511,7 @@ namespace detail
if(visible != wd->visible) if(visible != wd->visible)
{ {
#ifndef WIDGET_FRAME_DEPRECATED
native_window_type nv = nullptr; native_window_type nv = nullptr;
switch(wd->other.category) switch(wd->other.category)
{ {
@ -508,6 +522,9 @@ namespace detail
default: //category::widget_tag, category::lite_widget_tag default: //category::widget_tag, category::lite_widget_tag
break; break;
} }
#else
auto nv = (category::flags::root == wd->other.category ? wd->root : nullptr);
#endif
if(visible && wd->effect.bground) if(visible && wd->effect.bground)
window_layer::make_bground(wd); window_layer::make_bground(wd);
@ -717,12 +734,14 @@ namespace detail
if(false == passive) if(false == passive)
native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)); native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height));
} }
#ifndef WIDGET_FRAME_DEPRECATED
else if(category::flags::frame == wd->other.category) else if(category::flags::frame == wd->other.category)
{ {
native_interface::window_size(wd->other.attribute.frame->container, sz); native_interface::window_size(wd->other.attribute.frame->container, sz);
for(auto natwd : wd->other.attribute.frame->attach) for(auto natwd : wd->other.attribute.frame->attach)
native_interface::window_size(natwd, sz); native_interface::window_size(natwd, sz);
} }
#endif
else else
{ {
//update the bground buffer of glass window. //update the bground buffer of glass window.
@ -943,8 +962,8 @@ namespace detail
if (impl_->wd_register.available(prev_focus)) if (impl_->wd_register.available(prev_focus))
{ {
if(prev_focus->together.caret) if(prev_focus->annex.caret_ptr)
prev_focus->together.caret->set_active(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 = reinterpret_cast<window>(prev_focus);
@ -961,8 +980,8 @@ namespace detail
return prev_focus; //no new focus_window return prev_focus; //no new focus_window
if(wd->together.caret) if(wd->annex.caret_ptr)
wd->together.caret->set_active(true); wd->annex.caret_ptr->activate(true);
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = reinterpret_cast<window>(wd);
arg.getting = true; arg.getting = true;
@ -1446,6 +1465,7 @@ namespace detail
} }
} }
#ifndef WIDGET_FRAME_DEPRECATED
if (category::flags::frame == wd->other.category) if (category::flags::frame == wd->other.category)
{ {
//remove the frame handle from the WM frames manager. //remove the frame handle from the WM frames manager.
@ -1454,6 +1474,7 @@ namespace detail
if (established) if (established)
pa_root_attr->frames.push_back(wd); pa_root_attr->frames.push_back(wd);
} }
#endif
if (established) if (established)
{ {
@ -1507,11 +1528,11 @@ namespace detail
wd->flags.destroying = true; wd->flags.destroying = true;
if(wd->together.caret) if(wd->annex.caret_ptr)
{ {
//The deletion of caret wants to know whether the window is destroyed under SOME platform. Such as X11 //The deletion of caret wants to know whether the window is destroyed under SOME platform. Such as X11
delete wd->together.caret; delete wd->annex.caret_ptr;
wd->together.caret = nullptr; wd->annex.caret_ptr = nullptr;
} }
arg_destroy arg; arg_destroy arg;
@ -1552,6 +1573,7 @@ namespace detail
wd->drawer.detached(); wd->drawer.detached();
wd->widget_notifier->destroy(); wd->widget_notifier->destroy();
#ifndef WIDGET_FRAME_DEPRECATED
if(category::flags::frame == wd->other.category) if(category::flags::frame == wd->other.category)
{ {
//The frame widget does not have an owner, and close their element windows without activating owner. //The frame widget does not have an owner, and close their element windows without activating owner.
@ -1561,6 +1583,7 @@ namespace detail
native_interface::close_window(wd->other.attribute.frame->container); native_interface::close_window(wd->other.attribute.frame->container);
} }
#endif
if(wd->other.category != category::flags::root) //Not a root window if(wd->other.category != category::flags::root) //Not a root window
impl_->wd_register.remove(wd); impl_->wd_register.remove(wd);
@ -1571,13 +1594,18 @@ namespace detail
if(category::flags::root != wd->other.category) //A root widget always starts at (0, 0) and its childs are not to be changed if(category::flags::root != wd->other.category) //A root widget always starts at (0, 0) and its childs are not to be changed
{ {
wd->pos_root += delta; wd->pos_root += delta;
#ifndef WIDGET_FRAME_DEPRECATED
if (category::flags::frame != wd->other.category) if (category::flags::frame != wd->other.category)
{ {
if (wd->together.caret && wd->together.caret->visible()) if (wd->annex.caret_ptr && wd->annex.caret_ptr->visible())
wd->together.caret->update(); wd->annex.caret_ptr->update();
} }
else else
native_interface::move_window(wd->other.attribute.frame->container, wd->pos_root.x, wd->pos_root.y); native_interface::move_window(wd->other.attribute.frame->container, wd->pos_root.x, wd->pos_root.y);
#else
if (wd->annex.caret_ptr && wd->annex.caret_ptr->visible())
wd->annex.caret_ptr->update();
#endif
if (wd->displayed() && wd->effect.bground) if (wd->displayed() && wd->effect.bground)
window_layer::make_bground(wd); window_layer::make_bground(wd);

View File

@ -57,7 +57,7 @@ namespace API
{ {
::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&& factory) ::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&& factory)
{ {
return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_interface&&>(factory)); return restrict::bedrock.scheme().create(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)
@ -89,7 +89,7 @@ namespace API
if (!restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd))) if (!restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd)))
return nullptr; return nullptr;
return reinterpret_cast<basic_window*>(wd)->together.events_ptr.get(); return reinterpret_cast<basic_window*>(wd)->annex.events_ptr.get();
} }
}//end namespace detail }//end namespace detail
@ -200,14 +200,14 @@ namespace API
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(iwd)) if (restrict::wd_manager().available(iwd))
iwd->scheme = wdg_geom; iwd->annex.scheme = wdg_geom;
} }
widget_geometrics* get_scheme(window wd) widget_geometrics* get_scheme(window wd)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock; internal_scope_guard lock;
return (restrict::wd_manager().available(iwd) ? iwd->scheme : nullptr); return (restrict::wd_manager().available(iwd) ? iwd->annex.scheme : nullptr);
} }
void attach_drawer(widget& wd, drawer_trigger& dr) void attach_drawer(widget& wd, drawer_trigger& dr)
@ -217,7 +217,7 @@ namespace API
if(restrict::wd_manager().available(iwd)) if(restrict::wd_manager().available(iwd))
{ {
iwd->drawer.graphics.make(iwd->dimension); iwd->drawer.graphics.make(iwd->dimension);
iwd->drawer.graphics.rectangle(true, iwd->scheme->background.get_color()); iwd->drawer.graphics.rectangle(true, iwd->annex.scheme->background.get_color());
iwd->drawer.attached(wd, dr); iwd->drawer.attached(wd, dr);
iwd->drawer.refresh(); //Always redrawe no matter it is visible or invisible. This can make the graphics data correctly. iwd->drawer.refresh(); //Always redrawe no matter it is visible or invisible. This can make the graphics data correctly.
} }
@ -266,10 +266,12 @@ namespace API
return reinterpret_cast<window>(restrict::wd_manager().create_widget(reinterpret_cast<basic_window*>(parent), r, true, wdg)); return reinterpret_cast<window>(restrict::wd_manager().create_widget(reinterpret_cast<basic_window*>(parent), r, true, wdg));
} }
#ifndef WIDGET_FRAME_DEPRECATED
window create_frame(window parent, const rectangle& r, widget* wdg) window create_frame(window parent, const rectangle& r, widget* wdg)
{ {
return reinterpret_cast<window>(restrict::wd_manager().create_frame(reinterpret_cast<basic_window*>(parent), r, wdg)); return reinterpret_cast<window>(restrict::wd_manager().create_frame(reinterpret_cast<basic_window*>(parent), r, wdg));
} }
#endif
paint::graphics* window_graphics(window wd) paint::graphics* window_graphics(window wd)
{ {
@ -546,6 +548,7 @@ namespace API
reinterpret_cast<basic_window*>(wd)->flags.fullscreen = v; reinterpret_cast<basic_window*>(wd)->flags.fullscreen = v;
} }
#ifndef WIDGET_FRAME_DEPRECATED
bool insert_frame(window frame, native_window_type native_window) bool insert_frame(window frame, native_window_type native_window)
{ {
return restrict::wd_manager().insert_frame(reinterpret_cast<basic_window*>(frame), native_window); return restrict::wd_manager().insert_frame(reinterpret_cast<basic_window*>(frame), native_window);
@ -571,6 +574,7 @@ namespace API
} }
return nullptr; return nullptr;
} }
#endif
void close_window(window wd) void close_window(window wd)
{ {
@ -1022,7 +1026,7 @@ namespace API
{ {
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd))) if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd)))
return reinterpret_cast<basic_window*>(wd)->scheme->foreground.get_color(); return reinterpret_cast<basic_window*>(wd)->annex.scheme->foreground.get_color();
return{}; return{};
} }
@ -1032,10 +1036,10 @@ namespace API
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(iwd)) if (restrict::wd_manager().available(iwd))
{ {
auto prev = iwd->scheme->foreground.get_color(); auto prev = iwd->annex.scheme->foreground.get_color();
if (prev != clr) if (prev != clr)
{ {
iwd->scheme->foreground = clr; iwd->annex.scheme->foreground = clr;
restrict::wd_manager().update(iwd, true, false); restrict::wd_manager().update(iwd, true, false);
} }
return prev; return prev;
@ -1047,7 +1051,7 @@ namespace API
{ {
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd))) if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd)))
return reinterpret_cast<basic_window*>(wd)->scheme->background.get_color(); return reinterpret_cast<basic_window*>(wd)->annex.scheme->background.get_color();
return{}; return{};
} }
@ -1057,10 +1061,10 @@ namespace API
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(iwd)) if (restrict::wd_manager().available(iwd))
{ {
auto prev = iwd->scheme->background.get_color(); auto prev = iwd->annex.scheme->background.get_color();
if (prev != clr) if (prev != clr)
{ {
iwd->scheme->background = clr; iwd->annex.scheme->background = clr;
//If the bground mode of this window is basic, it should remake the background //If the bground mode of this window is basic, it should remake the background
if (iwd->effect.bground && iwd->effect.bground_fade_rate < 0.01) // fade rate < 0.01 means it is basic mode if (iwd->effect.bground && iwd->effect.bground_fade_rate < 0.01) // fade rate < 0.01 means it is basic mode
@ -1077,7 +1081,7 @@ namespace API
{ {
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd))) if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd)))
return reinterpret_cast<basic_window*>(wd)->scheme->activated.get_color(); return reinterpret_cast<basic_window*>(wd)->annex.scheme->activated.get_color();
return{}; return{};
} }
@ -1087,10 +1091,10 @@ namespace API
internal_scope_guard lock; internal_scope_guard lock;
if (restrict::wd_manager().available(iwd)) if (restrict::wd_manager().available(iwd))
{ {
auto prev = iwd->scheme->activated.get_color(); auto prev = iwd->annex.scheme->activated.get_color();
if (prev != clr) if (prev != clr)
{ {
iwd->scheme->activated = clr; iwd->annex.scheme->activated = clr;
restrict::wd_manager().update(iwd, true, false); restrict::wd_manager().update(iwd, true, false);
} }
return prev; return prev;
@ -1099,12 +1103,99 @@ namespace API
return{}; return{};
} }
void create_caret(window wd, unsigned width, unsigned height) class caret_proxy
: public caret_interface
{
public:
caret_proxy(basic_window* wd)
: window_{ wd }
{}
void disable_throw() noexcept override
{
throw_ = false;
}
void effective_range(const rectangle& range) override
{
internal_scope_guard lock;
auto caret = _m_caret();
if (caret)
caret->effective_range(range);
}
void position(const point& pos) override
{
internal_scope_guard lock;
auto caret = _m_caret();
if (caret)
caret->position(pos);
}
point position() const override
{
internal_scope_guard lock;
auto caret = _m_caret();
if (caret)
return caret->position();
return{};
}
void dimension(const size& size) override
{
internal_scope_guard lock;
auto caret = _m_caret();
if (caret)
caret->dimension(size);
}
size dimension() const override
{
internal_scope_guard lock;
auto caret = _m_caret();
if (caret)
return caret->dimension();
return{};
}
void visible(bool visibility) override
{
internal_scope_guard lock;
auto caret = _m_caret();
if (caret)
caret->visible(visibility);
}
bool visible() const override
{
internal_scope_guard lock;
auto caret = _m_caret();
return (caret && caret->visible());
}
private:
caret_interface* _m_caret() const
{
if (restrict::wd_manager().available(window_) && window_->annex.caret_ptr)
return window_->annex.caret_ptr;
if (throw_)
throw std::runtime_error("nana.api: access invalid caret");
return nullptr;
}
private:
basic_window* const window_;
bool throw_{ true };
};
void create_caret(window wd, const size& caret_size)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock; internal_scope_guard lock;
if(restrict::wd_manager().available(iwd) && (nullptr == iwd->together.caret)) if (restrict::wd_manager().available(iwd) && !(iwd->annex.caret_ptr))
iwd->together.caret = new ::nana::detail::caret_descriptor(iwd, width, height); iwd->annex.caret_ptr = new ::nana::detail::caret(iwd, caret_size);
} }
void destroy_caret(window wd) void destroy_caret(window wd)
@ -1113,72 +1204,19 @@ namespace API
internal_scope_guard lock; internal_scope_guard lock;
if(restrict::wd_manager().available(iwd)) if(restrict::wd_manager().available(iwd))
{ {
auto p = iwd->together.caret; auto p = iwd->annex.caret_ptr;
iwd->together.caret = nullptr; iwd->annex.caret_ptr = nullptr;
delete p; delete p;
} }
} }
void caret_pos(window wd, const point& pos) std::unique_ptr<caret_interface> open_caret(window window_handle, bool disable_throw)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto p = new caret_proxy{ reinterpret_cast<basic_window*>(window_handle) };
internal_scope_guard lock; if (disable_throw)
if(restrict::wd_manager().available(iwd) && iwd->together.caret) p->disable_throw();
iwd->together.caret->position(pos.x, pos.y);
}
nana::point caret_pos(window wd) return std::unique_ptr<caret_interface>{ p };
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if(restrict::wd_manager().available(iwd) && iwd->together.caret)
return iwd->together.caret->position();
return{};
}
void caret_effective_range(window wd, const nana::rectangle& rect)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if(restrict::wd_manager().available(iwd) && iwd->together.caret)
iwd->together.caret->effective_range(rect);
}
void caret_size(window wd, const nana::size& sz)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard isg;
if(restrict::wd_manager().available(iwd) && iwd->together.caret)
iwd->together.caret->size(sz);
}
nana::size caret_size(window wd)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if(restrict::wd_manager().available(iwd) && iwd->together.caret)
return iwd->together.caret->size();
return{};
}
void caret_visible(window wd, bool is_show)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if(restrict::wd_manager().available(iwd) && iwd->together.caret)
iwd->together.caret->visible(is_show);
}
bool caret_visible(window wd)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if(restrict::wd_manager().available(iwd) && iwd->together.caret)
return iwd->together.caret->visible();
return false;
} }
void tabstop(window wd) void tabstop(window wd)

View File

@ -28,27 +28,61 @@ namespace nana
{ {
graph.rectangle(true, API::bgcolor(*wd_)); graph.rectangle(true, API::bgcolor(*wd_));
} }
//end class trigger
//class form_base
form_base::form_base(window owner, bool nested, const rectangle& r, const appearance& app)
: widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension>(owner, nested, r, app)
{}
place & form_base::get_place()
{
if (this->empty())
throw std::runtime_error("form::get_plac: the form has destroyed.");
if (!place_)
place_.reset(new place{ *this });
return *place_;
}
void form_base::div(const char* div_text)
{
get_place().div(div_text);
}
place::field_reference form_base::operator[](const char* field_name)
{
return get_place()[field_name];
}
void form_base::collocate() noexcept
{
if (place_)
place_->collocate();
}
//end class form_base
}//end namespace form }//end namespace form
}//end namespace drawerbase }//end namespace drawerbase
//class form //class form
typedef widget_object<category::root_tag, drawerbase::form::trigger, ::nana::detail::events_root_extension> form_base_t; using form_base = drawerbase::form::form_base;
form::form(const form& fm, const ::nana::size& sz, const appearance& apr) form::form(const form& fm, const ::nana::size& sz, const appearance& apr)
: form_base_t(fm.handle(), false, API::make_center(fm.handle(), sz.width, sz.height), apr) : form_base(fm.handle(), false, API::make_center(fm.handle(), sz.width, sz.height), apr)
{ {
} }
form::form(const rectangle& r, const appearance& apr) form::form(const rectangle& r, const appearance& apr)
: form_base_t(nullptr, false, r, apr) : form_base(nullptr, false, r, apr)
{} {}
form::form(window owner, const ::nana::size& sz, const appearance& apr) form::form(window owner, const ::nana::size& sz, const appearance& apr)
: form_base_t(owner, false, API::make_center(owner, sz.width, sz.height), apr) : form_base(owner, false, API::make_center(owner, sz.width, sz.height), apr)
{} {}
form::form(window owner, const rectangle& r, const appearance& apr) form::form(window owner, const rectangle& r, const appearance& apr)
: form_base_t(owner, false, r, apr) : form_base(owner, false, r, apr)
{} {}
void form::modality() const void form::modality() const
@ -64,21 +98,21 @@ namespace nana
//class nested_form //class nested_form
nested_form::nested_form(const form& fm, const rectangle& r, const appearance& apr) nested_form::nested_form(const form& fm, const rectangle& r, const appearance& apr)
: form_base_t(fm.handle(), true, r, apr) : form_base(fm.handle(), true, r, apr)
{ {
} }
nested_form::nested_form(const nested_form& fm, const rectangle& r, const appearance& apr) nested_form::nested_form(const nested_form& fm, const rectangle& r, const appearance& apr)
: form_base_t(fm.handle(), true, r, apr) : form_base(fm.handle(), true, r, apr)
{ {
} }
nested_form::nested_form(window owner, const appearance& apr) nested_form::nested_form(window owner, const appearance& apr)
: form_base_t(owner, true, rectangle(), apr) : form_base(owner, true, rectangle(), apr)
{} {}
nested_form::nested_form(window owner, const rectangle& r, const appearance& apr) nested_form::nested_form(window owner, const rectangle& r, const appearance& apr)
: form_base_t(owner, true, r, apr) : form_base(owner, true, r, apr)
{} {}
//end nested_form //end nested_form
}//end namespace nana }//end namespace nana

View File

@ -13,6 +13,8 @@
#include <nana/gui/widgets/frame.hpp> #include <nana/gui/widgets/frame.hpp>
#ifndef WIDGET_FRAME_DEPRECATED
namespace nana namespace nana
{ {
//class frame:: public widget_object<category::frame_tag> //class frame:: public widget_object<category::frame_tag>
@ -45,3 +47,5 @@ namespace nana
//end class frame //end class frame
}//end namespace nana }//end namespace nana
#endif

View File

@ -376,9 +376,7 @@ namespace nana{ namespace widgets
auto str_px = static_cast<int>(editor_._m_text_extent_size(ent.begin, len).width); auto str_px = static_cast<int>(editor_._m_text_extent_size(ent.begin, len).width);
if (scrpos.x < str_px) if (scrpos.x < str_px)
{ {
std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]); res.x = editor_._m_char_by_pixels(ent, static_cast<unsigned>(scrpos.x));
res.x = editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, is_right_text(ent));
res.x += static_cast<unsigned>(ent.begin - lnstr.data()); res.x += static_cast<unsigned>(ent.begin - lnstr.data());
return res; return res;
} }
@ -837,9 +835,7 @@ namespace nana{ namespace widgets
auto str_px = static_cast<int>(editor_._m_text_extent_size(ent.begin, len).width); auto str_px = static_cast<int>(editor_._m_text_extent_size(ent.begin, len).width);
if (scrpos.x < str_px) if (scrpos.x < str_px)
{ {
std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]); res.x += editor_._m_char_by_pixels(ent, scrpos.x);
res.x += editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, is_right_text(ent));
res.x += static_cast<unsigned>(ent.begin - str); res.x += static_cast<unsigned>(ent.begin - str);
return res; return res;
} }
@ -1281,7 +1277,9 @@ namespace nana{ namespace widgets
//class text_editor //class text_editor
text_editor::text_editor(window wd, graph_reference graph, const text_editor_scheme* schm) text_editor::text_editor(window wd, graph_reference graph, const text_editor_scheme* schm)
: behavior_(new behavior_normal(*this)), : behavior_(new behavior_normal(*this)),
window_(wd), graph_(graph), window_(wd),
caret_(API::open_caret(wd, true)),
graph_(graph),
scheme_(schm), keywords_(new keywords) scheme_(schm), keywords_(new keywords)
{ {
text_area_.area = graph.size(); text_area_.area = graph.size();
@ -1295,7 +1293,7 @@ namespace nana{ namespace widgets
select_.mode_selection = selection::mode::no_selected; select_.mode_selection = selection::mode::no_selected;
select_.ignore_press = false; select_.ignore_press = false;
API::create_caret(wd, 1, line_height()); API::create_caret(wd, { 1, line_height() });
API::bgcolor(wd, colors::white); API::bgcolor(wd, colors::white);
API::fgcolor(wd, colors::black); API::fgcolor(wd, colors::black);
@ -1864,18 +1862,17 @@ namespace nana{ namespace widgets
{ {
visible = true; visible = true;
if (line_bottom > _m_end_pos(false)) if (line_bottom > _m_end_pos(false))
API::caret_size(window_, nana::size(1, line_pixels - (line_bottom - _m_end_pos(false)))); caret_->dimension(nana::size(1, line_pixels - (line_bottom - _m_end_pos(false))));
else if (API::caret_size(window_).height != line_pixels) else if (caret_->dimension().height != line_pixels)
reset_caret_pixels(); reset_caret_pixels();
} }
if(!attributes_.editable) if(!attributes_.editable)
visible = false; visible = false;
API::caret_visible(window_, visible); caret_->visible(visible);
if(visible) if(visible)
API::caret_pos(window_, pos); caret_->position(pos);
} }
void text_editor::move_caret_end() void text_editor::move_caret_end()
@ -1887,7 +1884,7 @@ namespace nana{ namespace widgets
void text_editor::reset_caret_pixels() const void text_editor::reset_caret_pixels() const
{ {
API::caret_size(window_, nana::size(1, line_height())); caret_->dimension({ 1, line_height() });
} }
void text_editor::reset_caret() void text_editor::reset_caret()
@ -1898,7 +1895,7 @@ namespace nana{ namespace widgets
void text_editor::show_caret(bool isshow) void text_editor::show_caret(bool isshow)
{ {
if(isshow == false || API::is_focus_ready(window_)) if(isshow == false || API::is_focus_ready(window_))
API::caret_visible(window_, isshow); caret_->visible(isshow);
} }
bool text_editor::selected() const bool text_editor::selected() const
@ -2004,7 +2001,7 @@ namespace nana{ namespace widgets
if (attributes_.line_wrapped) if (attributes_.line_wrapped)
exclude_px = text_area_.vscroll; exclude_px = text_area_.vscroll;
else else
exclude_px = API::caret_size(window_).width; exclude_px = caret_->dimension().width;
return (text_area_.area.width > exclude_px ? text_area_.area.width - exclude_px : 0); return (text_area_.area.width > exclude_px ? text_area_.area.width - exclude_px : 0);
} }
@ -3452,42 +3449,48 @@ namespace nana{ namespace widgets
points_.offset.y = y; points_.offset.y = y;
} }
unsigned text_editor::_m_char_by_pixels(const wchar_t* str, std::size_t len, unsigned * pxbuf, int str_px, int pixels, bool is_rtl) unsigned text_editor::_m_char_by_pixels(const unicode_bidi::entity& ent, unsigned pos)
{ {
if (graph_.glyph_pixels(str, len, pxbuf)) unsigned len = ent.end - ent.begin;
{
if (is_rtl)
{ //RTL
for (std::size_t u = 0; u < len; ++u)
{
auto px = static_cast<int>(pxbuf[u]);
auto chbeg = str_px - px;
if (chbeg <= pixels && pixels < str_px)
{
if ((px < 2) || (pixels <= chbeg + (px >> 1)))
return static_cast<unsigned>(u + 1);
return static_cast<unsigned>(u); std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
if (graph_.glyph_pixels(ent.begin, len, pxbuf.get()))
{
const auto px_end = pxbuf.get() + len;
if (is_right_text(ent))
{
auto total_px = std::accumulate(pxbuf.get(), px_end, static_cast<unsigned>(0));
for (auto p = pxbuf.get(); p != px_end; ++p)
{
auto chpos = total_px - *p;
if ((chpos <= pos) && (pos < total_px))
{
if ((*p < 2) || (pos <= chpos + (*p >> 1)))
return static_cast<unsigned>(p - pxbuf.get()) + 1;
return static_cast<unsigned>(p - pxbuf.get());
} }
str_px = chbeg; total_px = chpos;
} }
} }
else else
{ {
//LTR for (auto p = pxbuf.get(); p != px_end; ++p)
for (std::size_t u = 0; u < len; ++u)
{ {
auto px = static_cast<int>(pxbuf[u]); if (pos < *p)
if (pixels < px)
{ {
if ((px > 1) && (pixels > (px >> 1))) if ((*p > 1) && (pos >(*p >> 1)))
return static_cast<unsigned>(u + 1); return static_cast<unsigned>(p - pxbuf.get()) + 1;
return static_cast<unsigned>(u); return static_cast<unsigned>(p - pxbuf.get());
} }
pixels -= px;
pos -= *p;
} }
} }
} }
return 0; return 0;
} }

View File

@ -48,6 +48,7 @@ namespace nana{ namespace paint
struct pixel_buffer::pixel_buffer_storage struct pixel_buffer::pixel_buffer_storage
: private nana::noncopyable : private nana::noncopyable
{ {
pixel_buffer_storage(const pixel_buffer_storage& other) = delete;
pixel_buffer_storage& operator=(const pixel_buffer_storage&) = delete; pixel_buffer_storage& operator=(const pixel_buffer_storage&) = delete;
bool _m_alloc() bool _m_alloc()
@ -112,18 +113,6 @@ namespace nana{ namespace paint
} }
}img_pro; }img_pro;
pixel_buffer_storage(const pixel_buffer_storage& other) :
drawable{ other.drawable },
valid_r{ other.valid_r },
pixel_size{ other.pixel_size },
bytes_per_line{ other.bytes_per_line },
alpha_channel{ other.alpha_channel },
img_pro{ other.img_pro }
{
if (_m_alloc())
std::memcpy(raw_pixel_buffer, other.raw_pixel_buffer, pixel_size.width * pixel_size.height);
}
pixel_buffer_storage(std::size_t width, std::size_t height) pixel_buffer_storage(std::size_t width, std::size_t height)
: drawable(nullptr), : drawable(nullptr),
valid_r(0, 0, static_cast<unsigned>(width), static_cast<unsigned>(height)), valid_r(0, 0, static_cast<unsigned>(width), static_cast<unsigned>(height)),