improve dockpane factory
This commit is contained in:
		
							parent
							
								
									44a067fd51
								
							
						
					
					
						commit
						5d2127e613
					
				| @ -127,15 +127,16 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 		/// Add a panel factory
 | 		/// Add a panel factory
 | ||||||
| 		template<typename Panel, typename ...Args> | 		template<typename Panel, typename ...Args> | ||||||
| 		void dock(const std::string& dockname, Args&& ... args) | 		place& dock(const std::string& dockname, const std::string& factory_name, Args&& ... args) | ||||||
| 		{ | 		{ | ||||||
| 			dock(dockname, std::bind([](window parent, Args & ... args) | 			return dock(dockname, factory_name, std::bind([](window parent, Args & ... args) | ||||||
| 			{ | 			{ | ||||||
| 				return std::unique_ptr<widget>(new Panel(parent, std::forward<Args>(args)...)); | 				return std::unique_ptr<widget>(new Panel(parent, std::forward<Args>(args)...)); | ||||||
| 			}, std::placeholders::_1, args...)); | 			}, std::placeholders::_1, args...)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void dock(const std::string& dockname, std::function<std::unique_ptr<widget>(window)> factory); | 		place& dock(const std::string& dockname, std::string factory_name, std::function<std::unique_ptr<widget>(window)> factory); | ||||||
|  | 		place& dock_create(const std::string& factory); | ||||||
| 	private: | 	private: | ||||||
| 		implement * impl_; | 		implement * impl_; | ||||||
| 	}; | 	}; | ||||||
|  | |||||||
| @ -450,6 +450,7 @@ namespace nana | |||||||
| 		std::unique_ptr<division> root_division; | 		std::unique_ptr<division> root_division; | ||||||
| 		std::map<std::string, field_gather*> fields; | 		std::map<std::string, field_gather*> fields; | ||||||
| 		std::map<std::string, field_dock*> docks; | 		std::map<std::string, field_dock*> docks; | ||||||
|  | 		std::map<std::string, field_dock*> dock_factoris; | ||||||
| 
 | 
 | ||||||
| 		//A temporary pointer used to refer to a specified div object which
 | 		//A temporary pointer used to refer to a specified div object which
 | ||||||
| 		//will be deleted in modification process.
 | 		//will be deleted in modification process.
 | ||||||
| @ -598,7 +599,8 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		div_dockpane * attached{ nullptr };					//attached div object
 | 		div_dockpane * attached{ nullptr };					//attached div object
 | ||||||
| 		place_parts::dockarea dockarea;	//the dockable widget
 | 		std::unique_ptr<place_parts::dockarea> dockarea;	//the dockable widget
 | ||||||
|  | 		std::map<std::string, std::function<std::unique_ptr<widget>(window)>> factories;	//factories for dockpane
 | ||||||
| 	};//end class field_dock
 | 	};//end class field_dock
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -1559,13 +1561,14 @@ namespace nana | |||||||
| 				impl_ptr_{impl} | 				impl_ptr_{impl} | ||||||
| 		{ | 		{ | ||||||
| 			dir = pane_dir; | 			dir = pane_dir; | ||||||
|  | 			this->display = false; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		~div_dockpane() | 		~div_dockpane() | ||||||
| 		{ | 		{ | ||||||
| 			if (dockable_field) | 			if (dockable_field) | ||||||
| 			{ | 			{ | ||||||
| 				dockable_field->dockarea.close(); | 				dockable_field->dockarea.reset(); | ||||||
| 				dockable_field->attached = nullptr; | 				dockable_field->attached = nullptr; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @ -1586,6 +1589,8 @@ namespace nana | |||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			auto & dockarea = dockable_field->dockarea; | 			auto & dockarea = dockable_field->dockarea; | ||||||
|  | 
 | ||||||
|  | 			/*
 | ||||||
| 			if (!created_) | 			if (!created_) | ||||||
| 			{ | 			{ | ||||||
| 				created_ = true; | 				created_ = true; | ||||||
| @ -1594,6 +1599,10 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 			if (!dockarea.empty() && !dockarea.floating()) | 			if (!dockarea.empty() && !dockarea.floating()) | ||||||
| 				dockarea.move(this->field_area); | 				dockarea.move(this->field_area); | ||||||
|  | 			*/ | ||||||
|  | 
 | ||||||
|  | 			if (dockarea && !dockarea->floating()) | ||||||
|  | 				dockarea->move(this->field_area); | ||||||
| 		} | 		} | ||||||
| 	private: | 	private: | ||||||
| 		//Implement dock_notifier_interface
 | 		//Implement dock_notifier_interface
 | ||||||
| @ -1710,8 +1719,8 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 		void notify_move_stopped() | 		void notify_move_stopped() | ||||||
| 		{ | 		{ | ||||||
| 			if (_m_dockable() && dockable_field) | 			if (_m_dockable() && dockable_field && dockable_field->dockarea) | ||||||
| 				dockable_field->dockarea.dock(); | 				dockable_field->dockarea->dock(); | ||||||
| 
 | 
 | ||||||
| 			indicator_.docker.reset(); | 			indicator_.docker.reset(); | ||||||
| 		} | 		} | ||||||
| @ -2514,7 +2523,7 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 		for (auto& e : docks_to_be_closed) | 		for (auto& e : docks_to_be_closed) | ||||||
| 		{ | 		{ | ||||||
| 			e.second->dockarea.close(); | 			e.second->dockarea.reset(); | ||||||
| 			e.second->attached->dockable_field = nullptr; | 			e.second->attached->dockable_field = nullptr; | ||||||
| 			e.second->attached = nullptr; | 			e.second->attached = nullptr; | ||||||
| 		} | 		} | ||||||
| @ -2747,7 +2756,7 @@ namespace nana | |||||||
| 		return field(name); | 		return field(name); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void place::dock(const std::string& name, std::function<std::unique_ptr<widget>(window)> factory) | 	place& place::dock(const std::string& name, std::string factory_name, std::function<std::unique_ptr<widget>(window)> factory) | ||||||
| 	{ | 	{ | ||||||
| 		//check the name, it throws std::invalid_argument
 | 		//check the name, it throws std::invalid_argument
 | ||||||
| 		//if name violate the naming convention.
 | 		//if name violate the naming convention.
 | ||||||
| @ -2757,7 +2766,16 @@ namespace nana | |||||||
| 		if (!dock_ptr) | 		if (!dock_ptr) | ||||||
| 			dock_ptr = new implement::field_dock; | 			dock_ptr = new implement::field_dock; | ||||||
| 
 | 
 | ||||||
| 		dock_ptr->dockarea.add_factory(std::move(factory)); | 		//Register the factory if it has a name
 | ||||||
|  | 		if (!factory_name.empty()) | ||||||
|  | 		{ | ||||||
|  | 			auto i = impl_->dock_factoris.find(factory_name); | ||||||
|  | 			if (i != impl_->dock_factoris.end()) | ||||||
|  | 				throw std::invalid_argument("nana::place - the specified factory name(" + factory_name + ") already exists"); | ||||||
|  | 
 | ||||||
|  | 			impl_->dock_factoris[factory_name] = dock_ptr; | ||||||
|  | 			dock_ptr->factories[factory_name].swap(factory); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		auto div = dynamic_cast<implement::div_dockpane*>(impl_->search_div_name(impl_->root_division.get(), name)); | 		auto div = dynamic_cast<implement::div_dockpane*>(impl_->search_div_name(impl_->root_division.get(), name)); | ||||||
| 		if (div) | 		if (div) | ||||||
| @ -2765,6 +2783,45 @@ namespace nana | |||||||
| 			dock_ptr->attached = div; | 			dock_ptr->attached = div; | ||||||
| 			div->dockable_field = dock_ptr; | 			div->dockable_field = dock_ptr; | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		//Create the pane if it has not a name
 | ||||||
|  | 		if (factory_name.empty()) | ||||||
|  | 		{ | ||||||
|  | 			dock_ptr->attached->set_display(true); | ||||||
|  | 			impl_->collocate(); | ||||||
|  | 
 | ||||||
|  | 			if (!dock_ptr->dockarea) | ||||||
|  | 			{ | ||||||
|  | 				dock_ptr->dockarea.reset(new ::nana::place_parts::dockarea); | ||||||
|  | 				dock_ptr->dockarea->create(impl_->window_handle, dock_ptr->attached); | ||||||
|  | 				dock_ptr->dockarea->move(dock_ptr->attached->field_area); | ||||||
|  | 			} | ||||||
|  | 			dock_ptr->dockarea->add_pane(factory); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	place& place::dock_create(const std::string& factory) | ||||||
|  | 	{ | ||||||
|  | 		auto i = impl_->dock_factoris.find(factory); | ||||||
|  | 		if (i == impl_->dock_factoris.end()) | ||||||
|  | 			throw std::invalid_argument("nana::place - invalid factory name(" + factory + ")"); | ||||||
|  | 
 | ||||||
|  | 		auto dock_ptr = i->second; | ||||||
|  | 		dock_ptr->attached->set_display(true); | ||||||
|  | 		impl_->collocate(); | ||||||
|  | 
 | ||||||
|  | 		if (!dock_ptr->dockarea) | ||||||
|  | 		{ | ||||||
|  | 			dock_ptr->dockarea.reset(new ::nana::place_parts::dockarea); | ||||||
|  | 			dock_ptr->dockarea->create(impl_->window_handle, dock_ptr->attached); | ||||||
|  | 			dock_ptr->dockarea->move(dock_ptr->attached->field_area); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		dock_ptr->dockarea->add_pane(i->second->factories[factory]); | ||||||
|  | 
 | ||||||
|  | 		return *this; | ||||||
| 	} | 	} | ||||||
| 	//end class place
 | 	//end class place
 | ||||||
| }//end namespace nana
 | }//end namespace nana
 | ||||||
|  | |||||||
| @ -148,12 +148,7 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 			struct panel | 			struct panel | ||||||
| 			{ | 			{ | ||||||
| 				factory factory_fn; |  | ||||||
| 				std::unique_ptr<widget> widget_ptr; | 				std::unique_ptr<widget> widget_ptr; | ||||||
| 
 |  | ||||||
| 				panel(factory && fn) |  | ||||||
| 					: factory_fn(std::move(fn)) |  | ||||||
| 				{} |  | ||||||
| 			}; | 			}; | ||||||
| 		public: | 		public: | ||||||
| 			void create(window parent, place_parts::dock_notifier_interface* notifier) | 			void create(window parent, place_parts::dock_notifier_interface* notifier) | ||||||
| @ -229,29 +224,49 @@ namespace nana | |||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 
 | 
 | ||||||
| 				if (panels_.size() > 1) | 			} | ||||||
|  | 
 | ||||||
|  | 			void add_pane(factory & fn) | ||||||
|  | 			{ | ||||||
|  | 				rectangle r{ point(), this->size()}; | ||||||
|  | 
 | ||||||
|  | 				//get a rectangle excluding caption
 | ||||||
|  | 				r.y = 20; | ||||||
|  | 				if (r.height > 20) | ||||||
|  | 					r.height -= 20; | ||||||
|  | 				else | ||||||
|  | 					r.height = 0; | ||||||
|  | 
 | ||||||
|  | 				if (!tabbar_ && panels_.size() > 0) | ||||||
|  | 				{ | ||||||
| 					tabbar_.reset(new tabbar_lite(*this)); | 					tabbar_.reset(new tabbar_lite(*this)); | ||||||
|  | 					tabbar_->move({ 0, r.bottom() - 20, r.width, 20 }); | ||||||
|  | 					r.height -= 20; | ||||||
| 
 | 
 | ||||||
| 					std::size_t pos = 0; | 					std::size_t pos = 0; | ||||||
| 					for (auto & pn : panels_) | 					for (auto & pn : panels_) | ||||||
| 				{ |  | ||||||
| 					if (!pn.widget_ptr) |  | ||||||
| 					{ |  | ||||||
| 						pn.widget_ptr = pn.factory_fn(*this); |  | ||||||
| 						if (tabbar_) |  | ||||||
| 					{ | 					{ | ||||||
| 						tabbar_->push_back(::nana::charset(pn.widget_ptr->caption())); | 						tabbar_->push_back(::nana::charset(pn.widget_ptr->caption())); | ||||||
| 							tabbar_->attach(pos++, pn.widget_ptr->handle()); | 						tabbar_->attach(pos++, *pn.widget_ptr); | ||||||
| 							//tabbar_->push_back(pn.widget_ptr->caption());
 |  | ||||||
| 							//tabbar_->relate(pos++, pn.widget_ptr->handle());
 |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 			void add_factory(factory && fn) | 				auto wdg = fn(*this); | ||||||
|  | 
 | ||||||
|  | 				if (tabbar_) | ||||||
| 				{ | 				{ | ||||||
| 				panels_.emplace_back(std::move(fn)); | 					tabbar_->push_back(::nana::charset(wdg->caption())); | ||||||
|  | 					tabbar_->attach(panels_.size(), *wdg); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				panels_.emplace_back(); | ||||||
|  | 				panels_.back().widget_ptr.swap(wdg); | ||||||
|  | 
 | ||||||
|  | 				for (auto & pn : panels_) | ||||||
|  | 				{ | ||||||
|  | 					if (pn.widget_ptr) | ||||||
|  | 						pn.widget_ptr->move(r); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			void float_away(const ::nana::point& move_pos) | 			void float_away(const ::nana::point& move_pos) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinhao
						Jinhao