Merge remote-tracking branch 'cnjinhao/develop-1.7' into cmake-dev
This commit is contained in:
		
						commit
						65d2440e26
					
				@ -211,10 +211,10 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#undef _nana_std_optional
 | 
			
		||||
#if ((defined(_MSC_VER) && (_MSC_VER >= 1912) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201703))) ||	\
 | 
			
		||||
	((__cplusplus < 201703L) || \
 | 
			
		||||
#if ((defined(_MSC_VER) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201703))) ||	\
 | 
			
		||||
	((!defined(_MSC_VER)) && ((__cplusplus < 201703L) || \
 | 
			
		||||
		(defined(__clang__) && (__clang_major__ * 100 + __clang_minor__ < 400)) ||				\
 | 
			
		||||
		(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 701))	\
 | 
			
		||||
		(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 701)))	\
 | 
			
		||||
	)
 | 
			
		||||
#	define _nana_std_optional
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 *	An Animation Implementation
 | 
			
		||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
			
		||||
 *	Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *	Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *
 | 
			
		||||
 *	Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 *	(See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@ -49,24 +49,18 @@ namespace nana
 | 
			
		||||
		
 | 
			
		||||
		struct impl;
 | 
			
		||||
		class performance_manager;
 | 
			
		||||
 | 
			
		||||
		/// Non-copyable
 | 
			
		||||
		animation(const animation&) = delete;
 | 
			
		||||
		animation& operator=(const animation&) = delete;
 | 
			
		||||
	public:
 | 
			
		||||
		animation(std::size_t fps = 23);
 | 
			
		||||
		~animation();
 | 
			
		||||
 | 
			
		||||
		void push_back(frameset frms);
 | 
			
		||||
		/*
 | 
			
		||||
		void branch(const std::string& name, const frameset& frms)
 | 
			
		||||
		{
 | 
			
		||||
			impl_->branches[name].frames = frms;
 | 
			
		||||
		}
 | 
			
		||||
		animation(animation&&);
 | 
			
		||||
		animation& operator=(animation&&);
 | 
			
		||||
 | 
			
		||||
		void branch(const std::string& name, const frameset& frms, std::function<std::size_t(const std::string&, std::size_t, std::size_t&)> condition)
 | 
			
		||||
		{
 | 
			
		||||
			auto & br = impl_->branches[name];
 | 
			
		||||
			br.frames = frms;
 | 
			
		||||
			br.condition = condition;
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
		void push_back(frameset frms);
 | 
			
		||||
 | 
			
		||||
		void looped(bool enable);       ///< Enables or disables the animation repeating playback.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 *	A Menubar implementation
 | 
			
		||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
			
		||||
 *	Copyright(C) 2009-2017 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *	Copyright(C) 2009-2018 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *
 | 
			
		||||
 *	Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 *	(See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@ -34,26 +34,6 @@ namespace nana
 | 
			
		||||
				color_proxy border_highlight{ colors::highlight };
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			class item_renderer
 | 
			
		||||
			{
 | 
			
		||||
			public:
 | 
			
		||||
				enum class state
 | 
			
		||||
				{
 | 
			
		||||
					normal, highlighted, selected
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				using graph_reference = paint::graphics&;
 | 
			
		||||
				using scheme = ::nana::drawerbase::menubar::scheme;
 | 
			
		||||
 | 
			
		||||
				item_renderer(window, graph_reference);
 | 
			
		||||
				virtual void background(const point&, const ::nana::size&, state);
 | 
			
		||||
				virtual void caption(const point&, const native_string_type&);
 | 
			
		||||
				scheme *scheme_ptr() const { return scheme_ptr_; };
 | 
			
		||||
			private:
 | 
			
		||||
				graph_reference graph_;
 | 
			
		||||
				scheme *scheme_ptr_;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			class trigger
 | 
			
		||||
				: public drawer_trigger
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
@ -87,13 +87,15 @@ namespace nana
 | 
			
		||||
			class trigger
 | 
			
		||||
				:public drawer_trigger
 | 
			
		||||
			{
 | 
			
		||||
				template<typename Renderer>
 | 
			
		||||
				struct basic_implement;
 | 
			
		||||
				//template<typename Renderer>
 | 
			
		||||
				//struct basic_implement;	//deprecated
 | 
			
		||||
 | 
			
		||||
				class item_renderer;
 | 
			
		||||
				class implementation;
 | 
			
		||||
 | 
			
		||||
				//class item_renderer;	//deprecated
 | 
			
		||||
				class item_locator;
 | 
			
		||||
 | 
			
		||||
				typedef basic_implement<item_renderer> implement;
 | 
			
		||||
				//typedef basic_implement<item_renderer> implement;	//deprecated
 | 
			
		||||
			public:
 | 
			
		||||
				struct treebox_node_type
 | 
			
		||||
				{
 | 
			
		||||
@ -116,27 +118,30 @@ namespace nana
 | 
			
		||||
				trigger();
 | 
			
		||||
				~trigger();
 | 
			
		||||
 | 
			
		||||
				implement * impl() const;
 | 
			
		||||
				implementation * impl() const;
 | 
			
		||||
 | 
			
		||||
				void check(node_type*, checkstate);
 | 
			
		||||
 | 
			
		||||
				void renderer(::nana::pat::cloneable<renderer_interface>&&);
 | 
			
		||||
				const ::nana::pat::cloneable<renderer_interface>& renderer() const;
 | 
			
		||||
				pat::cloneable<renderer_interface>& renderer() const;
 | 
			
		||||
 | 
			
		||||
				//void renderer(::nana::pat::cloneable<renderer_interface>&&);
 | 
			
		||||
				//const ::nana::pat::cloneable<renderer_interface>& renderer() const;	//deprecated
 | 
			
		||||
				void placer(::nana::pat::cloneable<compset_placer_interface>&&);
 | 
			
		||||
				const ::nana::pat::cloneable<compset_placer_interface>& placer() const;
 | 
			
		||||
 | 
			
		||||
				node_type* insert(node_type*, const std::string& key, std::string&&);
 | 
			
		||||
				node_type* insert(const std::string& path, std::string&&);
 | 
			
		||||
 | 
			
		||||
				node_type * selected() const;
 | 
			
		||||
				void selected(node_type*);
 | 
			
		||||
				//node_type * selected() const;	//deprecated
 | 
			
		||||
				//void selected(node_type*);
 | 
			
		||||
 | 
			
		||||
				node_image_tag& icon(const ::std::string&) const;
 | 
			
		||||
				node_image_tag& icon(const ::std::string&);
 | 
			
		||||
				void icon_erase(const ::std::string&);
 | 
			
		||||
				void node_icon(node_type*, const ::std::string& id);
 | 
			
		||||
				unsigned node_width(const node_type*) const;
 | 
			
		||||
 | 
			
		||||
				bool rename(node_type*, const char* key, const char* name);
 | 
			
		||||
 | 
			
		||||
			private:
 | 
			
		||||
				//Overrides drawer_trigger methods
 | 
			
		||||
				void attached(widget_reference, graph_reference)		override;
 | 
			
		||||
@ -152,7 +157,7 @@ namespace nana
 | 
			
		||||
				void key_press(graph_reference, const arg_keyboard&)	override;
 | 
			
		||||
				void key_char(graph_reference, const arg_keyboard&)	override;
 | 
			
		||||
			private:
 | 
			
		||||
				implement * const impl_;
 | 
			
		||||
				implementation * const impl_;
 | 
			
		||||
			}; //end class trigger
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -171,11 +176,11 @@ namespace nana
 | 
			
		||||
 | 
			
		||||
				/// Append a child with a specified value (user object.).
 | 
			
		||||
				template<typename T>
 | 
			
		||||
				item_proxy append(const ::std::string& key, ::std::string name, const T&t)
 | 
			
		||||
				item_proxy append(const ::std::string& key, ::std::string name, T&& t)
 | 
			
		||||
				{
 | 
			
		||||
					item_proxy ip = append(key, std::move(name));
 | 
			
		||||
					if(false == ip.empty())
 | 
			
		||||
						ip.value(t);
 | 
			
		||||
						ip.value(std::forward<T>(t));
 | 
			
		||||
					return ip;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@ -291,17 +296,19 @@ namespace nana
 | 
			
		||||
					return *p;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/*
 | 
			
		||||
				template<typename T>
 | 
			
		||||
				item_proxy & value(const T& t)
 | 
			
		||||
				item_proxy & value(const T& t)	//deprecated
 | 
			
		||||
				{
 | 
			
		||||
					_m_value() = t;
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				*/
 | 
			
		||||
 | 
			
		||||
				template<typename T>
 | 
			
		||||
				item_proxy & value(T&& t)
 | 
			
		||||
				{
 | 
			
		||||
					_m_value() = std::move(t);
 | 
			
		||||
					_m_value() = std::forward<T>(t);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@ -378,7 +385,7 @@ namespace nana
 | 
			
		||||
		template<typename ItemRenderer>
 | 
			
		||||
		treebox & renderer(const ItemRenderer & rd) ///< set user-defined node renderer
 | 
			
		||||
		{
 | 
			
		||||
			get_drawer_trigger().renderer(::nana::pat::cloneable<renderer_interface>(rd));
 | 
			
		||||
			get_drawer_trigger().renderer() = ::nana::pat::cloneable<renderer_interface>{rd};
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -403,6 +410,23 @@ namespace nana
 | 
			
		||||
		/// @param enable bool  whether to enable.
 | 
			
		||||
		void auto_draw(bool enable);
 | 
			
		||||
 | 
			
		||||
		/// Prevents drawing during execution.
 | 
			
		||||
		template<typename Function>
 | 
			
		||||
		void avoid_drawing(Function fn)
 | 
			
		||||
		{
 | 
			
		||||
			this->auto_draw(false);
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				fn();
 | 
			
		||||
			}
 | 
			
		||||
			catch (...)
 | 
			
		||||
			{
 | 
			
		||||
				this->auto_draw(true);
 | 
			
		||||
				throw;
 | 
			
		||||
			}
 | 
			
		||||
			this->auto_draw(true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// \brief  Enable the checkboxs for each item of the widget.
 | 
			
		||||
		/// @param enable bool  indicates whether to show or hide the checkboxs.
 | 
			
		||||
		treebox & checkable(bool enable);
 | 
			
		||||
@ -419,8 +443,9 @@ namespace nana
 | 
			
		||||
        /// These states are 'normal', 'hovered' and 'expanded'. 
 | 
			
		||||
        /// If 'hovered' or 'expanded' are not set, it uses 'normal' state image for these 2 states.
 | 
			
		||||
        /// See also in [documentation](http://nanapro.org/en-us/help/widgets/treebox.htm)
 | 
			
		||||
		node_image_type& icon(const ::std::string& id ///< the name of an icon scheme. If the name is not existing, it creates a new scheme for the name.
 | 
			
		||||
                               ) const;
 | 
			
		||||
		/// @param id The name of an icon scheme. If the name is not existing, it creates a new scheme for the name.
 | 
			
		||||
		/// @return The reference of node image scheme correspending with the specified id.
 | 
			
		||||
		node_image_type& icon(const ::std::string& id);
 | 
			
		||||
 | 
			
		||||
		void icon_erase(const ::std::string& id);
 | 
			
		||||
 | 
			
		||||
@ -445,6 +470,19 @@ namespace nana
 | 
			
		||||
 | 
			
		||||
		item_proxy selected() const; ///< returns the selected node
 | 
			
		||||
 | 
			
		||||
		/// Scrolls a specified item into view.
 | 
			
		||||
		/**
 | 
			
		||||
		 * @param item An item to be requested.
 | 
			
		||||
		 * @param bearing The position where the item to be positioned in the view.
 | 
			
		||||
		 */
 | 
			
		||||
		void scroll_into_view(item_proxy item, align_v bearing);
 | 
			
		||||
 | 
			
		||||
		/// Scrolls a specified item into view.
 | 
			
		||||
		/**
 | 
			
		||||
		 * @param item An item to be requested.
 | 
			
		||||
		 */
 | 
			
		||||
		void scroll_into_view(item_proxy item);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -658,21 +658,31 @@ namespace detail
 | 
			
		||||
		platform_scope_guard lock;
 | 
			
		||||
		if(umake_owner(wd))
 | 
			
		||||
		{
 | 
			
		||||
			auto & wd_manager = detail::bedrock::instance().wd_manager();
 | 
			
		||||
 | 
			
		||||
			std::vector<native_window_type> owned_children;
 | 
			
		||||
 | 
			
		||||
			auto i = wincontext_.find(wd);
 | 
			
		||||
			if(i != wincontext_.end())
 | 
			
		||||
			{
 | 
			
		||||
				if(i->second.owned)
 | 
			
		||||
				{
 | 
			
		||||
					set_error_handler();
 | 
			
		||||
					auto & wd_manager = detail::bedrock::instance().wd_manager();
 | 
			
		||||
					for(auto u = i->second.owned->rbegin(); u != i->second.owned->rend(); ++u)
 | 
			
		||||
						wd_manager.close(wd_manager.root(*u));
 | 
			
		||||
 | 
			
		||||
					rev_error_handler();
 | 
			
		||||
 | 
			
		||||
					delete i->second.owned;
 | 
			
		||||
					for(auto child : *i->second.owned)
 | 
			
		||||
						owned_children.push_back(child);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			//Closing a child will erase the wd from the table wincontext_, so the 
 | 
			
		||||
			//iterator i can't be reused after children closed.
 | 
			
		||||
			set_error_handler();
 | 
			
		||||
			for(auto u = owned_children.rbegin(); u != owned_children.rend(); ++u)
 | 
			
		||||
				wd_manager.close(wd_manager.root(*u));
 | 
			
		||||
			rev_error_handler();
 | 
			
		||||
 | 
			
		||||
			i = wincontext_.find(wd);
 | 
			
		||||
			if(i != wincontext_.end())
 | 
			
		||||
			{
 | 
			
		||||
				delete i->second.owned;
 | 
			
		||||
				wincontext_.erase(i);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 *	An Animation Implementation
 | 
			
		||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
			
		||||
 *	Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *	Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *
 | 
			
		||||
 *	Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 *	(See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@ -571,6 +571,25 @@ namespace nana
 | 
			
		||||
			delete impl_;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		animation::animation(animation&& rhs)
 | 
			
		||||
			: impl_(rhs.impl_)
 | 
			
		||||
		{
 | 
			
		||||
			rhs.impl_ = new impl(23);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		animation& animation::operator=(animation&& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			if (this != &rhs)
 | 
			
		||||
			{
 | 
			
		||||
				auto imp = new impl{ 23 };
 | 
			
		||||
 | 
			
		||||
				delete impl_;
 | 
			
		||||
				impl_ = rhs.impl_;
 | 
			
		||||
				rhs.impl_ = imp;
 | 
			
		||||
			}
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void animation::push_back(frameset frms)
 | 
			
		||||
		{
 | 
			
		||||
			impl_->framesets.emplace_back(std::move(frms));
 | 
			
		||||
 | 
			
		||||
@ -973,7 +973,12 @@ namespace detail
 | 
			
		||||
			case Expose:
 | 
			
		||||
				if(msgwnd->visible && (msgwnd->root_graph->empty() == false))
 | 
			
		||||
				{
 | 
			
		||||
					nana::detail::platform_scope_guard lock;
 | 
			
		||||
					nana::internal_scope_guard lock;
 | 
			
		||||
					//Don't lock this scope using platform-scope-guard. Because it would cause the platform-scope-lock to be locked
 | 
			
		||||
					//before the internal-scope-guard, and the order of locking would cause dead-lock.
 | 
			
		||||
					//
 | 
			
		||||
					//Locks this scope using internal-scope-guard is correct and safe. In the scope, the Xlib functions aren't called
 | 
			
		||||
					//directly.
 | 
			
		||||
					if(msgwnd->is_draw_through())
 | 
			
		||||
					{
 | 
			
		||||
						msgwnd->other.attribute.root->draw_through();
 | 
			
		||||
 | 
			
		||||
@ -371,6 +371,8 @@ namespace nana{
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Window parent = (owner ? reinterpret_cast<Window>(owner) : restrict::spec.root_window());
 | 
			
		||||
 | 
			
		||||
			//The position passed to XCreateWindow is a screen coordinate.
 | 
			
		||||
			nana::point pos(r.x, r.y);
 | 
			
		||||
			if((false == nested) && owner)
 | 
			
		||||
			{
 | 
			
		||||
@ -396,7 +398,9 @@ namespace nana{
 | 
			
		||||
				{
 | 
			
		||||
					auto origin_owner = (owner ? owner : reinterpret_cast<native_window_type>(restrict::spec.root_window()));
 | 
			
		||||
					restrict::spec.make_owner(origin_owner, reinterpret_cast<native_window_type>(handle));
 | 
			
		||||
					exposed_positions[handle] = pos;
 | 
			
		||||
 | 
			
		||||
					//The exposed_position is a relative position to its owner/parent.
 | 
			
		||||
					exposed_positions[handle] = r.position();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				XChangeWindowAttributes(disp, handle, attr_mask, &win_attr);
 | 
			
		||||
@ -945,13 +949,14 @@ namespace nana{
 | 
			
		||||
				auto fm_extents = window_frame_extents(wd);
 | 
			
		||||
				origin.x = -fm_extents.left;
 | 
			
		||||
				origin.y = -fm_extents.top;
 | 
			
		||||
 | 
			
		||||
#if 0	//deprecated
 | 
			
		||||
				if(reinterpret_cast<Window>(coord_wd) != restrict::spec.root_window())
 | 
			
		||||
				{
 | 
			
		||||
					fm_extents = window_frame_extents(coord_wd);
 | 
			
		||||
					origin.x += fm_extents.left;
 | 
			
		||||
					origin.y += fm_extents.top;
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				coord_wd = get_window(wd, window_relationship::parent);
 | 
			
		||||
@ -1010,8 +1015,14 @@ namespace nana{
 | 
			
		||||
			if(owner && (owner != reinterpret_cast<native_window_type>(restrict::spec.root_window())))
 | 
			
		||||
			{
 | 
			
		||||
				auto origin = window_position(owner);
 | 
			
		||||
#if 0
 | 
			
		||||
				x += origin.x;
 | 
			
		||||
				y += origin.y;
 | 
			
		||||
#else
 | 
			
		||||
				auto owner_extents = window_frame_extents(owner);
 | 
			
		||||
				x += origin.x + owner_extents.left;
 | 
			
		||||
				y += origin.y + owner_extents.top;
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			::XMoveWindow(disp, reinterpret_cast<Window>(wd), x, y);
 | 
			
		||||
@ -1099,8 +1110,14 @@ namespace nana{
 | 
			
		||||
			if(owner && (owner != reinterpret_cast<native_window_type>(restrict::spec.root_window())))
 | 
			
		||||
			{
 | 
			
		||||
				auto origin = window_position(owner);
 | 
			
		||||
#if 0
 | 
			
		||||
				x += origin.x;
 | 
			
		||||
				y += origin.y;
 | 
			
		||||
#else
 | 
			
		||||
				auto owner_extents = window_frame_extents(owner);
 | 
			
		||||
				x += origin.x + owner_extents.left;
 | 
			
		||||
				y += origin.y + owner_extents.top;
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height);
 | 
			
		||||
@ -1580,14 +1597,21 @@ namespace nana{
 | 
			
		||||
				pos.y = point.y;
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			return false;
 | 
			
		||||
#elif defined(NANA_X11)
 | 
			
		||||
			nana::detail::platform_scope_guard psg;
 | 
			
		||||
			int x = pos.x, y = pos.y;
 | 
			
		||||
			Window child;
 | 
			
		||||
			return (True == ::XTranslateCoordinates(restrict::spec.open_display(),
 | 
			
		||||
													reinterpret_cast<Window>(wd), restrict::spec.root_window(), x, y, &pos.x, &pos.y, &child));
 | 
			
		||||
			if(True == ::XTranslateCoordinates(restrict::spec.open_display(),
 | 
			
		||||
													reinterpret_cast<Window>(wd), restrict::spec.root_window(), x, y, &pos.x, &pos.y, &child))
 | 
			
		||||
			{
 | 
			
		||||
				//deprecated
 | 
			
		||||
				//auto fm_extents = window_frame_extents(wd);
 | 
			
		||||
				//pos.x += fm_extents.left;
 | 
			
		||||
				//pos.y += fm_extents.top;
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool native_interface::calc_window_point(native_window_type wd, nana::point& pos)
 | 
			
		||||
@ -1600,14 +1624,21 @@ namespace nana{
 | 
			
		||||
				pos.y = point.y;
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			return false;
 | 
			
		||||
#elif defined(NANA_X11)
 | 
			
		||||
			nana::detail::platform_scope_guard psg;
 | 
			
		||||
			int x = pos.x, y = pos.y;
 | 
			
		||||
			Window child;
 | 
			
		||||
			return (True == ::XTranslateCoordinates(restrict::spec.open_display(),
 | 
			
		||||
													restrict::spec.root_window(), reinterpret_cast<Window>(wd), x, y, &pos.x, &pos.y, &child));
 | 
			
		||||
			if(True == ::XTranslateCoordinates(restrict::spec.open_display(), restrict::spec.root_window(), reinterpret_cast<Window>(wd), x, y, &pos.x, &pos.y, &child))
 | 
			
		||||
			{
 | 
			
		||||
				//deprecated
 | 
			
		||||
				//Now the origin of pos is the left-top corner of the window(including titlebar and border)
 | 
			
		||||
				//auto fm_extents = window_frame_extents(wd);
 | 
			
		||||
				//pos.x += fm_extents.left;
 | 
			
		||||
				//pos.y += fm_extents.top;
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		native_window_type native_interface::find_window(int x, int y)
 | 
			
		||||
 | 
			
		||||
@ -303,7 +303,7 @@ namespace nana
 | 
			
		||||
							extent_size.width = width_px;
 | 
			
		||||
 | 
			
		||||
						for (auto & vsline : rs.vslines)
 | 
			
		||||
							extent_size.height += vsline.extent_height_px;
 | 
			
		||||
							extent_size.height += static_cast<size::value_type>(vsline.extent_height_px);
 | 
			
		||||
 | 
			
		||||
						content_lines.emplace_back(std::move(rs.vslines));
 | 
			
		||||
 | 
			
		||||
@ -311,7 +311,8 @@ namespace nana
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (allowed_width_px < extent_size.width)
 | 
			
		||||
					//The width is not restricted if the allowed_width_px is zero.
 | 
			
		||||
					if (allowed_width_px && (allowed_width_px < extent_size.width))
 | 
			
		||||
						extent_size.width = allowed_width_px;
 | 
			
		||||
 | 
			
		||||
					if (transient_.current_font != pre_font)
 | 
			
		||||
@ -445,6 +446,10 @@ namespace nana
 | 
			
		||||
								unsigned sub_text_px = 0;
 | 
			
		||||
								auto sub_text_len = _m_fit_text(graph, data->text().substr(text_begin), rs.allowed_width, sub_text_px);
 | 
			
		||||
 | 
			
		||||
								//At least one character must be displayed no matter whether the width is enough or not.
 | 
			
		||||
								if (0 == sub_text_len)
 | 
			
		||||
									sub_text_len = 1;
 | 
			
		||||
 | 
			
		||||
								if (text_begin + sub_text_len < data->text().size())
 | 
			
		||||
								{
 | 
			
		||||
									//make a new visual line
 | 
			
		||||
@ -886,7 +891,8 @@ namespace nana
 | 
			
		||||
			if(graph_ptr->empty())
 | 
			
		||||
			{
 | 
			
		||||
				graph_ptr = &substitute;
 | 
			
		||||
				graph_ptr->make({ 10, 10 });
 | 
			
		||||
				substitute.make({ 10, 10 });
 | 
			
		||||
				substitute.typeface(this->typeface());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return impl->renderer.measure(*graph_ptr, limited, impl->text_align, impl->text_align_v);
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
*	A Menubar implementation
 | 
			
		||||
*	Nana C++ Library(http://www.nanapro.org)
 | 
			
		||||
*	Copyright(C) 2009-2017 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
*	Copyright(C) 2009-2018 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
*
 | 
			
		||||
*	Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
*	(See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@ -215,6 +215,26 @@ namespace nana
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			//class item_renderer
 | 
			
		||||
			class item_renderer
 | 
			
		||||
			{
 | 
			
		||||
			public:
 | 
			
		||||
				enum class state
 | 
			
		||||
				{
 | 
			
		||||
					normal, highlighted, selected
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				using graph_reference = paint::graphics&;
 | 
			
		||||
				using scheme = ::nana::drawerbase::menubar::scheme;
 | 
			
		||||
 | 
			
		||||
				item_renderer(window, graph_reference);
 | 
			
		||||
				virtual void background(const point&, const ::nana::size&, state);
 | 
			
		||||
				virtual void caption(const point&, const native_string_type&);
 | 
			
		||||
				scheme *scheme_ptr() const { return scheme_ptr_; };
 | 
			
		||||
			private:
 | 
			
		||||
				graph_reference graph_;
 | 
			
		||||
				scheme *scheme_ptr_;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			item_renderer::item_renderer(window wd, graph_reference graph)
 | 
			
		||||
				:graph_(graph), scheme_ptr_(static_cast<scheme*>(API::dev::get_scheme(wd)))
 | 
			
		||||
			{}
 | 
			
		||||
@ -250,7 +270,6 @@ namespace nana
 | 
			
		||||
			void item_renderer::caption(const point& pos, const native_string_type& text)
 | 
			
		||||
			{
 | 
			
		||||
				graph_.string(pos, text, scheme_ptr_->text_fgcolor);
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			//end class item_renderer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -180,13 +180,13 @@ namespace nana
 | 
			
		||||
				}
 | 
			
		||||
			};//end class tooltip_window
 | 
			
		||||
 | 
			
		||||
			//item_locator should be defined before the definition of basic_implement
 | 
			
		||||
			//item_locator should be defined before the definition of implementation
 | 
			
		||||
			class trigger::item_locator
 | 
			
		||||
			{
 | 
			
		||||
			public:
 | 
			
		||||
				using node_type = tree_cont_type::node_type;
 | 
			
		||||
 | 
			
		||||
				item_locator(implement * impl, int item_pos, int x, int y);
 | 
			
		||||
				item_locator(implementation * impl, int item_pos, int x, int y);
 | 
			
		||||
				int operator()(node_type &node, int affect);
 | 
			
		||||
				node_type * node() const;
 | 
			
		||||
				component what() const;
 | 
			
		||||
@ -194,7 +194,7 @@ namespace nana
 | 
			
		||||
 | 
			
		||||
				nana::rectangle text_pos() const;
 | 
			
		||||
			private:
 | 
			
		||||
				trigger::implement * impl_;
 | 
			
		||||
				implementation * const impl_;
 | 
			
		||||
				nana::point item_pos_;
 | 
			
		||||
				const nana::point pos_;		//Mouse pointer position
 | 
			
		||||
				component	what_;
 | 
			
		||||
@ -212,11 +212,89 @@ namespace nana
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			//struct implement
 | 
			
		||||
			//struct implementation
 | 
			
		||||
			//@brief:	some data for treebox trigger
 | 
			
		||||
			template<typename Renderer>
 | 
			
		||||
			struct trigger::basic_implement
 | 
			
		||||
			class trigger::implementation
 | 
			
		||||
			{
 | 
			
		||||
				class item_rendering_director
 | 
			
		||||
					: public compset_interface
 | 
			
		||||
				{
 | 
			
		||||
				public:
 | 
			
		||||
					using node_type = tree_cont_type::node_type;
 | 
			
		||||
 | 
			
		||||
					item_rendering_director(implementation * impl, const nana::point& pos):
 | 
			
		||||
						impl_(impl),
 | 
			
		||||
						pos_(pos)
 | 
			
		||||
					{
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					//affect
 | 
			
		||||
					//0 = Sibling, the last is a sibling of node
 | 
			
		||||
					//1 = Owner, the last is the owner of node
 | 
			
		||||
					//>=2 = Children, the last is a child of a node that before this node.
 | 
			
		||||
					int operator()(const node_type& node, int affect)
 | 
			
		||||
					{
 | 
			
		||||
						iterated_node_ = &node;
 | 
			
		||||
						switch (affect)
 | 
			
		||||
						{
 | 
			
		||||
						case 1:
 | 
			
		||||
							pos_.x += impl_->shape.indent_pixels;
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							if (affect >= 2)
 | 
			
		||||
								pos_.x -= impl_->shape.indent_pixels * (affect - 1);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						auto & comp_placer = impl_->data.comp_placer;
 | 
			
		||||
 | 
			
		||||
						impl_->assign_node_attr(node_attr_, iterated_node_);
 | 
			
		||||
						node_r_.x = node_r_.y = 0;
 | 
			
		||||
						node_r_.width = comp_placer->item_width(*impl_->data.graph, node_attr_);
 | 
			
		||||
						node_r_.height = comp_placer->item_height(*impl_->data.graph);
 | 
			
		||||
 | 
			
		||||
						auto renderer = impl_->data.renderer;
 | 
			
		||||
						renderer->begin_paint(*impl_->data.widget_ptr);
 | 
			
		||||
						renderer->bground(*impl_->data.graph, this);
 | 
			
		||||
						renderer->expander(*impl_->data.graph, this);
 | 
			
		||||
						renderer->crook(*impl_->data.graph, this);
 | 
			
		||||
						renderer->icon(*impl_->data.graph, this);
 | 
			
		||||
						renderer->text(*impl_->data.graph, this);
 | 
			
		||||
 | 
			
		||||
						pos_.y += node_r_.height;
 | 
			
		||||
 | 
			
		||||
						if (pos_.y > static_cast<int>(impl_->data.graph->height()))
 | 
			
		||||
							return 0;
 | 
			
		||||
 | 
			
		||||
						return (node.child && node.value.second.expanded ? 1 : 2);
 | 
			
		||||
					}
 | 
			
		||||
				private:
 | 
			
		||||
					//Overrides compset_interface
 | 
			
		||||
					virtual const item_attribute_t& item_attribute() const override
 | 
			
		||||
					{
 | 
			
		||||
						return node_attr_;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					virtual bool comp_attribute(component_t comp, comp_attribute_t& attr) const override
 | 
			
		||||
					{
 | 
			
		||||
						attr.area = node_r_;
 | 
			
		||||
						if (impl_->data.comp_placer->locate(comp, node_attr_, &attr.area))
 | 
			
		||||
						{
 | 
			
		||||
							attr.mouse_pointed = node_attr_.mouse_pointed;
 | 
			
		||||
							attr.area.x += pos_.x;
 | 
			
		||||
							attr.area.y += pos_.y;
 | 
			
		||||
							return true;
 | 
			
		||||
						}
 | 
			
		||||
						return false;
 | 
			
		||||
					}
 | 
			
		||||
				private:
 | 
			
		||||
					implementation * const impl_;
 | 
			
		||||
					::nana::point pos_;
 | 
			
		||||
					const node_type * iterated_node_;
 | 
			
		||||
					item_attribute_t node_attr_;
 | 
			
		||||
					::nana::rectangle node_r_;
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
			public:
 | 
			
		||||
				using node_type = trigger::node_type;
 | 
			
		||||
 | 
			
		||||
				struct rep_tag
 | 
			
		||||
@ -271,7 +349,7 @@ namespace nana
 | 
			
		||||
					nana::timer timer;
 | 
			
		||||
				}adjust;
 | 
			
		||||
			public:
 | 
			
		||||
				basic_implement()
 | 
			
		||||
				implementation()
 | 
			
		||||
				{
 | 
			
		||||
					data.graph			= nullptr;
 | 
			
		||||
					data.widget_ptr		= nullptr;
 | 
			
		||||
@ -353,6 +431,11 @@ namespace nana
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				static constexpr unsigned margin_top_bottom()
 | 
			
		||||
				{
 | 
			
		||||
					return 1;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				bool draw(bool reset_scroll, bool ignore_update = false, bool ignore_auto_draw = false)
 | 
			
		||||
				{
 | 
			
		||||
					if(data.graph && (false == data.stop_drawing))
 | 
			
		||||
@ -368,7 +451,7 @@ namespace nana
 | 
			
		||||
								data.graph->rectangle(true, data.widget_ptr->bgcolor());
 | 
			
		||||
 | 
			
		||||
							//Draw tree
 | 
			
		||||
							attr.tree_cont.for_each(shape.first, Renderer(this, nana::point(static_cast<int>(attr.tree_cont.indent_size(shape.first) * shape.indent_pixels) - shape.offset_x, 1)));
 | 
			
		||||
							attr.tree_cont.for_each(shape.first, item_rendering_director(this, nana::point(static_cast<int>(attr.tree_cont.indent_size(shape.first) * shape.indent_pixels) - shape.offset_x, margin_top_bottom())));
 | 
			
		||||
 | 
			
		||||
							if (!ignore_update)
 | 
			
		||||
								API::update_window(data.widget_ptr->handle());
 | 
			
		||||
@ -460,6 +543,129 @@ namespace nana
 | 
			
		||||
					return nullptr;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				node_type* last(bool ignore_folded_children) const
 | 
			
		||||
				{
 | 
			
		||||
					auto p = attr.tree_cont.get_root();
 | 
			
		||||
 | 
			
		||||
					while (true)
 | 
			
		||||
					{
 | 
			
		||||
						while (p->next)
 | 
			
		||||
							p = p->next;
 | 
			
		||||
 | 
			
		||||
						if (p->child)
 | 
			
		||||
						{
 | 
			
		||||
							if (p->value.second.expanded || !ignore_folded_children)
 | 
			
		||||
							{
 | 
			
		||||
								p = p->child;
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					return p;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				std::size_t screen_capacity(bool completed) const
 | 
			
		||||
				{
 | 
			
		||||
					auto const item_px = data.comp_placer->item_height(*data.graph);
 | 
			
		||||
					auto screen_px = data.graph->size().height - (margin_top_bottom() << 1);
 | 
			
		||||
					
 | 
			
		||||
					if (completed || ((screen_px % item_px) == 0))
 | 
			
		||||
						return screen_px / item_px;
 | 
			
		||||
 | 
			
		||||
					return screen_px / item_px + 1;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				bool scroll_into_view(node_type* node, bool use_bearing, align_v bearing)
 | 
			
		||||
				{
 | 
			
		||||
					auto & tree = attr.tree_cont;
 | 
			
		||||
 | 
			
		||||
					auto parent = node->owner;
 | 
			
		||||
 | 
			
		||||
					std::vector<node_type*> parent_path;
 | 
			
		||||
					while (parent)
 | 
			
		||||
					{
 | 
			
		||||
						parent_path.push_back(parent);
 | 
			
		||||
						parent = parent->owner;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					bool has_expanded = false;
 | 
			
		||||
 | 
			
		||||
					//Expands the shrinked nodes which are ancestors of node
 | 
			
		||||
					for (auto i = parent_path.rbegin(); i != parent_path.rend(); ++i)
 | 
			
		||||
					{
 | 
			
		||||
						if (!(*i)->value.second.expanded)
 | 
			
		||||
						{
 | 
			
		||||
							has_expanded = true;
 | 
			
		||||
							(*i)->value.second.expanded = true;
 | 
			
		||||
							item_proxy iprx(data.trigger_ptr, *i);
 | 
			
		||||
							data.widget_ptr->events().expanded.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, true }, data.widget_ptr->handle());
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					auto pos = tree.distance_if(node, pred_allow_child{});
 | 
			
		||||
					auto last_pos = tree.distance_if(last(true), pred_allow_child{});
 | 
			
		||||
 | 
			
		||||
					auto const capacity = screen_capacity(true);
 | 
			
		||||
					auto const item_px = data.comp_placer->item_height(*data.graph);
 | 
			
		||||
 | 
			
		||||
					//If use_bearing is false, it calculates a bearing depending on the current
 | 
			
		||||
					//position of the requested item.
 | 
			
		||||
					if (!use_bearing)
 | 
			
		||||
					{
 | 
			
		||||
						auto first_pos = tree.distance_if(shape.first, pred_allow_child{});
 | 
			
		||||
 | 
			
		||||
						if (pos < first_pos)
 | 
			
		||||
							bearing = align_v::top;
 | 
			
		||||
						else if (pos >= first_pos + capacity)
 | 
			
		||||
							bearing = align_v::bottom;
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							//The item is already in the view.
 | 
			
		||||
							//Returns true if a draw operation is needed
 | 
			
		||||
							return has_expanded;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (align_v::top == bearing)
 | 
			
		||||
					{
 | 
			
		||||
						if (last_pos - pos + 1 < capacity)
 | 
			
		||||
						{
 | 
			
		||||
							if (last_pos + 1 >= capacity)
 | 
			
		||||
								pos = last_pos + 1 - capacity;
 | 
			
		||||
							else
 | 
			
		||||
								pos = 0;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else if (align_v::center == bearing)
 | 
			
		||||
					{
 | 
			
		||||
						auto const short_side = (std::min)(pos, last_pos - pos);
 | 
			
		||||
						if (short_side >= capacity / 2)
 | 
			
		||||
							pos -= capacity / 2;
 | 
			
		||||
						else if (short_side == pos || (last_pos + 1 < capacity))
 | 
			
		||||
							pos = 0;
 | 
			
		||||
						else
 | 
			
		||||
							pos = last_pos + 1 - capacity;
 | 
			
		||||
					}
 | 
			
		||||
					else if (align_v::bottom == bearing)
 | 
			
		||||
					{
 | 
			
		||||
						if (pos + 1 >= capacity)
 | 
			
		||||
							pos = pos + 1 - capacity;
 | 
			
		||||
						else
 | 
			
		||||
							pos = 0;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					auto prv_first = shape.first;
 | 
			
		||||
					shape.first = attr.tree_cont.advance_if(nullptr, pos, drawerbase::treebox::pred_allow_child{});
 | 
			
		||||
 | 
			
		||||
					//Update the position of scroll
 | 
			
		||||
					show_scroll();
 | 
			
		||||
 | 
			
		||||
					return has_expanded || (prv_first != shape.first);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				bool make_adjust(node_type * node, int reason)
 | 
			
		||||
				{
 | 
			
		||||
					if(!node) return false;
 | 
			
		||||
@ -1356,7 +1562,7 @@ namespace nana
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			//class trigger::item_locator
 | 
			
		||||
				trigger::item_locator::item_locator(implement * impl, int item_pos, int x, int y)
 | 
			
		||||
				trigger::item_locator::item_locator(implementation * impl, int item_pos, int x, int y)
 | 
			
		||||
					:	impl_(impl),
 | 
			
		||||
						item_pos_(item_pos, 1),
 | 
			
		||||
						pos_(x, y),
 | 
			
		||||
@ -1439,86 +1645,6 @@ namespace nana
 | 
			
		||||
					return{node_text_r_.x + item_pos_.x, node_text_r_.y + item_pos_.y, node_text_r_.width, node_text_r_.height};
 | 
			
		||||
				}
 | 
			
		||||
			//end class item_locator
 | 
			
		||||
 | 
			
		||||
			class trigger::item_renderer
 | 
			
		||||
				: public compset_interface
 | 
			
		||||
			{
 | 
			
		||||
			public:
 | 
			
		||||
				typedef tree_cont_type::node_type node_type;
 | 
			
		||||
 | 
			
		||||
				item_renderer(implement * impl, const nana::point& pos)
 | 
			
		||||
					:	impl_(impl),
 | 
			
		||||
						pos_(pos)
 | 
			
		||||
				{
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				//affect
 | 
			
		||||
				//0 = Sibling, the last is a sibling of node
 | 
			
		||||
				//1 = Owner, the last is the owner of node
 | 
			
		||||
				//>=2 = Children, the last is a child of a node that before this node.
 | 
			
		||||
				int operator()(const node_type& node, int affect)
 | 
			
		||||
				{
 | 
			
		||||
					implement * draw_impl = impl_;
 | 
			
		||||
 | 
			
		||||
					iterated_node_ = &node;
 | 
			
		||||
					switch(affect)
 | 
			
		||||
					{
 | 
			
		||||
					case 1:
 | 
			
		||||
						pos_.x += draw_impl->shape.indent_pixels;
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						if(affect >= 2)
 | 
			
		||||
							pos_.x -= draw_impl->shape.indent_pixels * (affect - 1);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					auto & comp_placer = impl_->data.comp_placer;
 | 
			
		||||
 | 
			
		||||
					impl_->assign_node_attr(node_attr_, iterated_node_);
 | 
			
		||||
					node_r_.x = node_r_.y = 0;
 | 
			
		||||
					node_r_.width = comp_placer->item_width(*impl_->data.graph, node_attr_);
 | 
			
		||||
					node_r_.height = comp_placer->item_height(*impl_->data.graph);
 | 
			
		||||
 | 
			
		||||
					auto renderer = draw_impl->data.renderer;
 | 
			
		||||
					renderer->begin_paint(*draw_impl->data.widget_ptr);
 | 
			
		||||
					renderer->bground(*draw_impl->data.graph, this);
 | 
			
		||||
					renderer->expander(*draw_impl->data.graph, this);
 | 
			
		||||
					renderer->crook(*draw_impl->data.graph, this);
 | 
			
		||||
					renderer->icon(*draw_impl->data.graph, this);
 | 
			
		||||
					renderer->text(*draw_impl->data.graph, this);
 | 
			
		||||
 | 
			
		||||
					pos_.y += node_r_.height;
 | 
			
		||||
 | 
			
		||||
					if(pos_.y > static_cast<int>(draw_impl->data.graph->height()))
 | 
			
		||||
						return 0;
 | 
			
		||||
 | 
			
		||||
					return (node.child && node.value.second.expanded ? 1 : 2);
 | 
			
		||||
				}
 | 
			
		||||
			private:
 | 
			
		||||
				//Overrides compset_interface
 | 
			
		||||
				virtual const item_attribute_t& item_attribute() const override
 | 
			
		||||
				{
 | 
			
		||||
					return node_attr_;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				virtual bool comp_attribute(component_t comp, comp_attribute_t& attr) const override
 | 
			
		||||
				{
 | 
			
		||||
					attr.area = node_r_;
 | 
			
		||||
					if (impl_->data.comp_placer->locate(comp, node_attr_, &attr.area))
 | 
			
		||||
					{
 | 
			
		||||
						attr.mouse_pointed = node_attr_.mouse_pointed;
 | 
			
		||||
						attr.area.x += pos_.x;
 | 
			
		||||
						attr.area.y += pos_.y;
 | 
			
		||||
						return true;
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
			private:
 | 
			
		||||
				trigger::implement * impl_;
 | 
			
		||||
				::nana::point pos_;
 | 
			
		||||
				const node_type * iterated_node_;
 | 
			
		||||
				item_attribute_t node_attr_;
 | 
			
		||||
				::nana::rectangle node_r_;
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//Treebox Implementation
 | 
			
		||||
@ -1548,7 +1674,7 @@ namespace nana
 | 
			
		||||
				//end struct treebox_node_type
 | 
			
		||||
 | 
			
		||||
				trigger::trigger()
 | 
			
		||||
					:	impl_(new implement)
 | 
			
		||||
					:	impl_(new implementation)
 | 
			
		||||
				{
 | 
			
		||||
					impl_->data.trigger_ptr = this;
 | 
			
		||||
					impl_->data.renderer = nana::pat::cloneable<renderer_interface>(internal_renderer());
 | 
			
		||||
@ -1615,7 +1741,7 @@ namespace nana
 | 
			
		||||
					delete impl_;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				trigger::implement * trigger::impl() const
 | 
			
		||||
				trigger::implementation * trigger::impl() const
 | 
			
		||||
				{
 | 
			
		||||
					return impl_;
 | 
			
		||||
				}
 | 
			
		||||
@ -1687,6 +1813,7 @@ namespace nana
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/*	//deprecated
 | 
			
		||||
				void trigger::renderer(::nana::pat::cloneable<renderer_interface>&& r)
 | 
			
		||||
				{
 | 
			
		||||
					impl_->data.renderer = std::move(r);
 | 
			
		||||
@ -1696,6 +1823,12 @@ namespace nana
 | 
			
		||||
				{
 | 
			
		||||
					return impl_->data.renderer;
 | 
			
		||||
				}
 | 
			
		||||
				*/
 | 
			
		||||
 | 
			
		||||
				::nana::pat::cloneable<renderer_interface>& trigger::renderer() const
 | 
			
		||||
				{
 | 
			
		||||
					return impl_->data.renderer;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				void trigger::placer(::nana::pat::cloneable<compset_placer_interface>&& r)
 | 
			
		||||
				{
 | 
			
		||||
@ -1729,18 +1862,22 @@ namespace nana
 | 
			
		||||
					return x;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				trigger::node_type* trigger::selected() const
 | 
			
		||||
				/*
 | 
			
		||||
				trigger::node_type* trigger::selected() const	//deprecated
 | 
			
		||||
				{
 | 
			
		||||
					return impl_->node_state.selected;
 | 
			
		||||
				}
 | 
			
		||||
				*/
 | 
			
		||||
 | 
			
		||||
				void trigger::selected(node_type* node)
 | 
			
		||||
				/*
 | 
			
		||||
				void trigger::selected(node_type* node)	//deprecated
 | 
			
		||||
				{
 | 
			
		||||
					if(impl_->attr.tree_cont.verify(node) && impl_->set_selected(node))
 | 
			
		||||
						impl_->draw(true);
 | 
			
		||||
				}
 | 
			
		||||
				*/
 | 
			
		||||
 | 
			
		||||
				node_image_tag& trigger::icon(const std::string& id) const
 | 
			
		||||
				node_image_tag& trigger::icon(const std::string& id)
 | 
			
		||||
				{
 | 
			
		||||
					auto i = impl_->shape.image_table.find(id);
 | 
			
		||||
					if(i != impl_->shape.image_table.end())
 | 
			
		||||
@ -2167,7 +2304,7 @@ namespace nana
 | 
			
		||||
				impl->draw(true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		treebox::node_image_type& treebox::icon(const std::string& id) const
 | 
			
		||||
		treebox::node_image_type& treebox::icon(const std::string& id)
 | 
			
		||||
		{
 | 
			
		||||
			return get_drawer_trigger().icon(id);
 | 
			
		||||
		}
 | 
			
		||||
@ -2233,7 +2370,24 @@ namespace nana
 | 
			
		||||
 | 
			
		||||
		treebox::item_proxy treebox::selected() const
 | 
			
		||||
		{
 | 
			
		||||
			return item_proxy(const_cast<drawer_trigger_t*>(&get_drawer_trigger()), get_drawer_trigger().selected());
 | 
			
		||||
			//return item_proxy(const_cast<drawer_trigger_t*>(&get_drawer_trigger()), get_drawer_trigger().selected());	//deprecated
 | 
			
		||||
			auto dw = &get_drawer_trigger();
 | 
			
		||||
			return item_proxy(const_cast<drawer_trigger_t*>(dw), dw->impl()->node_state.selected);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void treebox::scroll_into_view(item_proxy item, align_v bearing)
 | 
			
		||||
		{
 | 
			
		||||
			internal_scope_guard lock;
 | 
			
		||||
			if(get_drawer_trigger().impl()->scroll_into_view(item._m_node(), true, bearing))
 | 
			
		||||
				API::refresh_window(*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void treebox::scroll_into_view(item_proxy item)
 | 
			
		||||
		{
 | 
			
		||||
			internal_scope_guard lock;
 | 
			
		||||
			//The third argument for scroll_into_view is ignored if the second argument is false.
 | 
			
		||||
			if(get_drawer_trigger().impl()->scroll_into_view(item._m_node(), false, align_v::center))
 | 
			
		||||
				API::refresh_window(*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		std::shared_ptr<scroll_operation_interface> treebox::_m_scroll_operation()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user