Merge remote-tracking branch 'nana_jinhao/hotfixes-1.0.1' into hotfixes-1.0.1
This commit is contained in:
		
						commit
						356ee07884
					
				| @ -166,7 +166,8 @@ namespace detail | ||||
| 			bool fullscreen	:1;	//When the window is maximizing whether it fit for fullscreen.
 | ||||
| 			bool borderless :1; | ||||
| 			bool make_bground_declared : 1;	//explicitly make bground for bground effects
 | ||||
| 			unsigned Reserved	:21; | ||||
| 			bool ignore_menubar_focus : 1;	//A flag indicates whether the menubar sets the focus.
 | ||||
| 			unsigned Reserved	:20; | ||||
| 			unsigned char tab;		//indicate a window that can receive the keyboard TAB
 | ||||
| 			mouse_action	action; | ||||
| 		}flags; | ||||
|  | ||||
| @ -54,13 +54,14 @@ namespace detail | ||||
| 		native_window_type root(core_window_t*); | ||||
| 
 | ||||
| 		void set_menubar_taken(core_window_t*); | ||||
| 		core_window_t* get_menubar_taken(); | ||||
| 
 | ||||
| 		//Delay Restores focus when a menu which attached to menubar is closed
 | ||||
| 		void delay_restore(int); | ||||
| 		bool close_menu_if_focus_other_window(native_window_type focus); | ||||
| 		void set_menu(native_window_type menu_window, bool is_keyboard_condition); | ||||
| 		native_window_type get_menu(native_window_type owner, bool is_keyboard_condition); | ||||
| 		native_window_type get_menu(); | ||||
| 		void remove_menu(); | ||||
| 		void empty_menu(); | ||||
| 		void erase_menu(bool try_destroy); | ||||
| 
 | ||||
| 		void get_key_state(arg_keyboard&); | ||||
| 		bool set_keyboard_shortkey(bool yes); | ||||
|  | ||||
| @ -77,6 +77,8 @@ namespace API | ||||
| 		window create_frame(window, const rectangle&, widget* attached); | ||||
| 
 | ||||
| 		paint::graphics* window_graphics(window); | ||||
| 
 | ||||
| 		void delay_restore(bool); | ||||
| 	}//end namespace dev
 | ||||
| 
 | ||||
| 
 | ||||
| @ -290,7 +292,6 @@ namespace API | ||||
| 	void register_menu_window(window, bool has_keyboard); | ||||
| 	bool attach_menubar(window menubar); | ||||
| 	void detach_menubar(window menubar); | ||||
| 	void restore_menubar_taken_window(); | ||||
| 
 | ||||
| 	bool is_window_zoomed(window, bool ask_for_max);  ///<Tests a window whether it is maximized or minimized.
 | ||||
| 
 | ||||
|  | ||||
| @ -24,12 +24,16 @@ namespace nana | ||||
| 			class item_renderer | ||||
| 			{ | ||||
| 			public: | ||||
| 				enum state_t{state_normal, state_highlight, state_selected}; | ||||
| 				typedef nana::paint::graphics& graph_reference; | ||||
| 				enum class state | ||||
| 				{ | ||||
| 					normal, highlighted, selected | ||||
| 				}; | ||||
| 
 | ||||
| 				using graph_reference = paint::graphics&; | ||||
| 
 | ||||
| 				item_renderer(window, graph_reference); | ||||
| 				virtual void background(const nana::point& pos, const nana::size& size, state_t); | ||||
| 				virtual void caption(int x, int y, const nana::string& text); | ||||
| 				virtual void background(const point&, const ::nana::size&, state); | ||||
| 				virtual void caption(const point&, const ::nana::string&); | ||||
| 			private: | ||||
| 				window	handle_; | ||||
| 				graph_reference graph_; | ||||
| @ -59,9 +63,8 @@ namespace nana | ||||
| 			private: | ||||
| 				void _m_move(bool to_left); | ||||
| 				bool _m_popup_menu(); | ||||
| 				void _m_total_close(bool try_restore); | ||||
| 				void _m_total_close(); | ||||
| 				bool _m_close_menu(); | ||||
| 				void _m_unload_menu_window(); | ||||
| 				std::size_t _m_item_by_pos(const ::nana::point&); | ||||
| 				bool _m_track_mouse(const ::nana::point&); | ||||
| 				void _m_draw(); | ||||
| @ -90,11 +93,6 @@ namespace nana | ||||
| 
 | ||||
| 					nana::menu *menu; | ||||
| 					nana::point mouse_pos; | ||||
| 
 | ||||
| 					//The menu will restore the focus of taken window. But the restoring during
 | ||||
| 					//key_press and key_release resets the focus to the taken window, it causes
 | ||||
| 					//the taken window to receive a key_char which should be received by menubar.
 | ||||
| 					bool delay_restore; | ||||
| 				}state_; | ||||
| 			}; | ||||
| 		}//end namespace menubar
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| /*
 | ||||
|  *	Platform Specification Implementation | ||||
|  *	Nana C++ Library(http://www.nanapro.org)
 | ||||
|  *	Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) | ||||
|  *	Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) | ||||
|  * | ||||
|  *	Distributed under the Nana Software License, Version 1.0. | ||||
|  *	(See accompanying file LICENSE_1_0.txt or copy at | ||||
| @ -841,7 +841,10 @@ namespace detail | ||||
| 						if((attr.your_event_mask & addr->input_context_event_mask) == addr->input_context_event_mask) | ||||
| 						{ | ||||
| 							XSetWindowAttributes new_attr; | ||||
| 							new_attr.event_mask = (attr.your_event_mask & ~addr->input_context_event_mask); | ||||
| 
 | ||||
| 							//Don't remove the KeyPress and KeyRelease mask(0x3), otherwise the window will not receive
 | ||||
| 							//Keyboard events after destroying caret 
 | ||||
| 							new_attr.event_mask = (attr.your_event_mask & ~(addr->input_context_event_mask & (~0x3))); | ||||
| 							::XChangeWindowAttributes(display_, reinterpret_cast<Window>(wd), CWEventMask, &new_attr); | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| @ -347,6 +347,7 @@ namespace nana | ||||
| 				flags.destroying = false; | ||||
| 				flags.borderless = false; | ||||
| 				flags.make_bground_declared = false; | ||||
| 				flags.ignore_menubar_focus = false; | ||||
| 
 | ||||
| 				visible = false; | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| /*
 | ||||
|  *	Bedrock Selector | ||||
|  *	Nana C++ Library(http://www.nanapro.org)
 | ||||
|  *	Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) | ||||
|  *	Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) | ||||
|  * | ||||
|  *	Distributed under the Nana Software License, Version 1.0. | ||||
|  *	(See accompanying file LICENSE_1_0.txt or copy at | ||||
|  | ||||
| @ -102,27 +102,18 @@ namespace detail | ||||
| 		{ | ||||
| 			struct thread_context_cache | ||||
| 			{ | ||||
| 				unsigned tid; | ||||
| 				thread_context *object; | ||||
| 				unsigned tid{ 0 }; | ||||
| 				thread_context *object{ nullptr }; | ||||
| 			}tcontext; | ||||
| 
 | ||||
| 			cache_type() | ||||
| 			{ | ||||
| 				tcontext.tid = 0; | ||||
| 				tcontext.object = nullptr; | ||||
| 			} | ||||
| 		}cache; | ||||
| 
 | ||||
| 		struct menu_tag | ||||
| 		{ | ||||
| 			menu_tag() | ||||
| 				:taken_window(nullptr), window(nullptr), owner(nullptr), has_keyboard(false) | ||||
| 			{} | ||||
| 
 | ||||
| 			core_window_t*	taken_window; | ||||
| 			native_window_type window; | ||||
| 			native_window_type owner; | ||||
| 			bool has_keyboard; | ||||
| 			core_window_t*	taken_window{ nullptr }; | ||||
| 			bool			delay_restore{ false }; | ||||
| 			native_window_type window{ nullptr }; | ||||
| 			native_window_type owner{ nullptr }; | ||||
| 			bool	has_keyboard{ false }; | ||||
| 		}menu; | ||||
| 
 | ||||
| 		struct keyboard_tracking_state_tag | ||||
| @ -282,14 +273,39 @@ namespace detail | ||||
| 
 | ||||
| 	void bedrock::set_menubar_taken(core_window_t* wd) | ||||
| 	{ | ||||
| 		auto pre = impl_->menu.taken_window; | ||||
| 		impl_->menu.taken_window = wd; | ||||
| 
 | ||||
| 		//assigning of a nullptr taken window is to restore the focus of pre taken
 | ||||
| 		if ((!wd) && pre) | ||||
| 		{ | ||||
| 			internal_scope_guard lock; | ||||
| 			wd_manager.set_focus(pre, false); | ||||
| 			wd_manager.update(pre, true, false); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	bedrock::core_window_t* bedrock::get_menubar_taken() | ||||
| 	//0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying
 | ||||
| 	void bedrock::delay_restore(int state) | ||||
| 	{ | ||||
| 		core_window_t* wd = impl_->menu.taken_window; | ||||
| 		impl_->menu.taken_window = nullptr; | ||||
| 		return wd; | ||||
| 		switch (state) | ||||
| 		{ | ||||
| 		case 0:	//Enable
 | ||||
| 			break; | ||||
| 		case 1: //Cancel
 | ||||
| 			break; | ||||
| 		case 2:	//Restore if key released
 | ||||
| 			//restores the focus when menu is closed by pressing keyboard
 | ||||
| 			if (!impl_->menu.window) | ||||
| 				set_menubar_taken(nullptr); | ||||
| 			break; | ||||
| 		case 3:	//Restores if destroying
 | ||||
| 			//when the menu is destroying, restores the focus if delay restore is not declared
 | ||||
| 			if (!impl_->menu.delay_restore) | ||||
| 				set_menubar_taken(nullptr); | ||||
| 		} | ||||
| 
 | ||||
| 		impl_->menu.delay_restore = (0 == state); | ||||
| 	} | ||||
| 
 | ||||
| 	bool bedrock::close_menu_if_focus_other_window(native_window_type wd) | ||||
| @ -304,7 +320,7 @@ namespace detail | ||||
| 				else | ||||
| 					return false; | ||||
| 			} | ||||
| 			remove_menu(); | ||||
| 			erase_menu(true); | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| @ -314,7 +330,7 @@ namespace detail | ||||
| 	{ | ||||
| 		if(menu_window && impl_->menu.window != menu_window) | ||||
| 		{ | ||||
| 			remove_menu(); | ||||
| 			erase_menu(true); | ||||
| 			impl_->menu.window = menu_window; | ||||
| 			impl_->menu.owner = native_interface::get_owner_window(menu_window); | ||||
| 			impl_->menu.has_keyboard = has_keyboard; | ||||
| @ -338,21 +354,13 @@ namespace detail | ||||
| 		return impl_->menu.window; | ||||
| 	} | ||||
| 
 | ||||
| 	void bedrock::remove_menu() | ||||
| 	void bedrock::erase_menu(bool try_destroy) | ||||
| 	{ | ||||
| 		if(impl_->menu.window) | ||||
| 		if (impl_->menu.window) | ||||
| 		{ | ||||
| 			native_window_type delwin = impl_->menu.window; | ||||
| 			impl_->menu.window = impl_->menu.owner = nullptr; | ||||
| 			impl_->menu.has_keyboard = false; | ||||
| 			native_interface::close_window(delwin); | ||||
| 		} | ||||
| 	} | ||||
| 			if (try_destroy) | ||||
| 				native_interface::close_window(impl_->menu.window); | ||||
| 
 | ||||
| 	void bedrock::empty_menu() | ||||
| 	{ | ||||
| 		if(impl_->menu.window) | ||||
| 		{ | ||||
| 			impl_->menu.window = impl_->menu.owner = nullptr; | ||||
| 			impl_->menu.has_keyboard = false; | ||||
| 		} | ||||
| @ -372,6 +380,11 @@ namespace detail | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	bool bedrock::whether_keyboard_shortkey() const | ||||
| 	{ | ||||
| 		return impl_->keyboard_tracking_state.has_shortkey_occured; | ||||
| 	} | ||||
| 
 | ||||
| 	element_store& bedrock::get_element_store() const | ||||
| 	{ | ||||
| 		return impl_->estore; | ||||
| @ -700,8 +713,8 @@ namespace detail | ||||
| 				msgwnd = brock.wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); | ||||
| 				if(nullptr == msgwnd) break; | ||||
| 					 | ||||
| 				if((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) | ||||
| 					brock.remove_menu(); | ||||
| 				if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) | ||||
| 					brock.erase_menu(true); | ||||
| 				else | ||||
| 					brock.close_menu_if_focus_other_window(msgwnd->root); | ||||
| 
 | ||||
| @ -719,7 +732,7 @@ namespace detail | ||||
| 						if(kill_focus != new_focus) | ||||
| 							brock.wd_manager.do_lazy_refresh(kill_focus, false); | ||||
| 					} | ||||
| 					auto retain = msgwnd->together.event_ptr; | ||||
| 					auto retain = msgwnd->together.events_ptr; | ||||
| 					msgwnd->root_widget->other.attribute.root->context.focus_changed = false; | ||||
| 					context.event_window = msgwnd; | ||||
| 
 | ||||
| @ -773,7 +786,7 @@ namespace detail | ||||
| 					msgwnd->flags.action = mouse_action::normal; | ||||
| 					if(msgwnd->flags.enabled) | ||||
| 					{ | ||||
| 						auto retain = msgwnd->together.event_ptr; | ||||
| 						auto retain = msgwnd->together.events_ptr; | ||||
| 
 | ||||
| 						arg_mouse arg; | ||||
| 						assign_arg(arg, msgwnd, message, xevent); | ||||
| @ -829,8 +842,11 @@ namespace detail | ||||
| 					if(brock.wd_manager.available(msgwnd)) | ||||
| 					{ | ||||
| 						//The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window().
 | ||||
| 						if(msgwnd->root == brock.get_menu()) | ||||
| 							brock.empty_menu(); | ||||
| 						if (msgwnd->root == brock.get_menu()) | ||||
| 						{ | ||||
| 							brock.erase_menu(false); | ||||
| 							brock.delay_restore(3);	//Restores if delay_restore not decleared
 | ||||
| 						} | ||||
| 
 | ||||
| 						spec.remove(native_window); | ||||
| 						brock.wd_manager.destroy(msgwnd); | ||||
| @ -929,6 +945,9 @@ namespace detail | ||||
| 				nana::detail::platform_spec::instance().write_keystate(xevent.xkey); | ||||
| 				if(msgwnd->flags.enabled) | ||||
| 				{ | ||||
| 					if (brock.get_menu()) | ||||
| 						brock.delay_restore(0);	//Enable delay restore
 | ||||
| 
 | ||||
| 					if(msgwnd->root != brock.get_menu()) | ||||
| 						msgwnd = brock.focus(); | ||||
| 
 | ||||
| @ -1011,12 +1030,31 @@ namespace detail | ||||
| 							else if(keyboard::alt == keychar) | ||||
| 							{ | ||||
| 								context.is_alt_pressed = true; | ||||
| 								if (brock.whether_keyboard_shortkey() == false) | ||||
| 								{ | ||||
| 									msgwnd = msgwnd->root_widget->other.attribute.root->menubar; | ||||
| 									if (msgwnd) | ||||
| 									{ | ||||
| 										bool focused = (brock.focus() == msgwnd); | ||||
| 										arg_keyboard arg; | ||||
| 										arg.evt_code = event_code::key_press; | ||||
| 										arg.window_handle = reinterpret_cast<window>(msgwnd); | ||||
| 										arg.ignore = false; | ||||
| 										arg.key = static_cast<nana::char_t>(keychar); | ||||
| 										brock.get_key_state(arg); | ||||
| 										brock.emit(event_code::key_press, msgwnd, arg, true, &context); | ||||
| 
 | ||||
| 										msgwnd->root_widget->flags.ignore_menubar_focus = (focused && (brock.focus() != msgwnd)); | ||||
| 									} | ||||
| 									else | ||||
| 										brock.erase_menu(true); | ||||
| 								} | ||||
| 							} | ||||
| 							else if(keychar) | ||||
| 							else | ||||
| 							{ | ||||
| 								arg_keyboard arg; | ||||
| 								arg.ignore = false; | ||||
| 								arg.key = keychar; | ||||
| 								arg.key = keychar ? keychar : xevent.xkey.keycode; | ||||
| 								arg.evt_code = event_code::key_press; | ||||
| 								brock.get_key_state(arg); | ||||
| 								arg.window_handle = reinterpret_cast<window>(msgwnd); | ||||
| @ -1093,11 +1131,35 @@ namespace detail | ||||
| 						brock.get_key_state(arg); | ||||
| 						brock.emit(event_code::key_release, msgwnd, arg, true, &context); | ||||
| 					} | ||||
| 					brock.delay_restore(2);	//Restores while key release
 | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					context.is_alt_pressed = false; | ||||
| 					brock.set_keyboard_shortkey(false); | ||||
| 					if (brock.set_keyboard_shortkey(false) == false) | ||||
| 					{ | ||||
| 						msgwnd = msgwnd->root_widget->other.attribute.root->menubar; | ||||
| 						if (msgwnd) | ||||
| 						{ | ||||
| 							bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); | ||||
| 							if (set_focus) | ||||
| 								brock.wd_manager.set_focus(msgwnd, false); | ||||
| 
 | ||||
| 							arg_keyboard arg; | ||||
| 							arg.evt_code = event_code::key_release; | ||||
| 							arg.window_handle = reinterpret_cast<window>(msgwnd); | ||||
| 							arg.ignore = false; | ||||
| 							arg.key = static_cast<nana::char_t>(context.platform.keychar); | ||||
| 							brock.get_key_state(arg); | ||||
| 							brock.emit(event_code::key_release, msgwnd, arg, true, &context); | ||||
| 
 | ||||
| 							if (!set_focus) | ||||
| 							{ | ||||
| 								brock.set_menubar_taken(nullptr); | ||||
| 								msgwnd->root_widget->flags.ignore_menubar_focus = false; | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				break; | ||||
| 			default: | ||||
|  | ||||
| @ -580,27 +580,30 @@ namespace nana{ | ||||
| 			//event, when the client receives the event, the specified window has been already
 | ||||
| 			//destroyed. This is a feature which is different from Windows. So the following
 | ||||
| 			//works should be handled before calling XDestroyWindow.
 | ||||
| 			auto & bedrock = bedrock::instance(); | ||||
| 			if(wd == bedrock.get_menu()) | ||||
| 				bedrock.empty_menu(); | ||||
| 			auto & brock = bedrock::instance(); | ||||
| 			if(wd == brock.get_menu()) | ||||
| 			{ | ||||
| 				brock.erase_menu(false); | ||||
| 				brock.delay_restore(3);	//Restores if delay_restore is not decleard
 | ||||
| 			} | ||||
| 
 | ||||
| 			Display* disp = restrict::spec.open_display(); | ||||
| 			restrict::spec.remove(wd); | ||||
| 			auto iwd = bedrock.wd_manager.root(wd); | ||||
| 			auto iwd = brock.wd_manager.root(wd); | ||||
| 			if(iwd) | ||||
| 			{ | ||||
| 				{ | ||||
| 					//Before calling window_manager::destroy, make sure the window is invisible.
 | ||||
| 					//It is a behavior like Windows.
 | ||||
| 					nana::detail::platform_scope_guard psg; | ||||
| 					nana::detail::platform_scope_guard lock; | ||||
| 					restrict::spec.set_error_handler(); | ||||
| 					::XUnmapWindow(disp, reinterpret_cast<Window>(wd)); | ||||
| 					::XFlush(disp); | ||||
| 					restrict::spec.rev_error_handler(); | ||||
| 				} | ||||
| 				bedrock.wd_manager.destroy(iwd); | ||||
| 				bedrock.rt_manager.remove_if_exists(iwd); | ||||
| 				bedrock.wd_manager.destroy_handle(iwd); | ||||
| 				brock.wd_manager.destroy(iwd); | ||||
| 				brock.rt_manager.remove_if_exists(iwd); | ||||
| 				brock.wd_manager.destroy_handle(iwd); | ||||
| 			} | ||||
| 
 | ||||
| 			nana::detail::platform_scope_guard psg; | ||||
|  | ||||
| @ -185,17 +185,18 @@ namespace detail | ||||
| 		{ | ||||
| 			struct thread_context_cache | ||||
| 			{ | ||||
| 				unsigned tid = 0; | ||||
| 				thread_context *object = nullptr; | ||||
| 				unsigned tid{ 0 }; | ||||
| 				thread_context *object{ nullptr }; | ||||
| 			}tcontext; | ||||
| 		}cache; | ||||
| 
 | ||||
| 		struct menu_tag | ||||
| 		{ | ||||
| 			core_window_t*	taken_window	= nullptr; | ||||
| 			native_window_type window		= nullptr; | ||||
| 			native_window_type owner		= nullptr; | ||||
| 			bool has_keyboard	= false; | ||||
| 			core_window_t*	taken_window{ nullptr }; | ||||
| 			bool			delay_restore{ false }; | ||||
| 			native_window_type window{ nullptr }; | ||||
| 			native_window_type owner{ nullptr }; | ||||
| 			bool	has_keyboard{false}; | ||||
| 		}menu; | ||||
| 
 | ||||
| 		struct keyboard_tracking_state_tag | ||||
| @ -921,8 +922,8 @@ namespace detail | ||||
| 				if(nullptr == msgwnd)	break; | ||||
| 
 | ||||
| 				//if event on the menubar, just remove the menu if it is not associating with the menubar
 | ||||
| 				if((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) | ||||
| 					brock.remove_menu(); | ||||
| 				if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) | ||||
| 					brock.erase_menu(true); | ||||
| 				else | ||||
| 					brock.close_menu_if_focus_other_window(msgwnd->root); | ||||
| 
 | ||||
| @ -1322,13 +1323,12 @@ namespace detail | ||||
| 				def_window_proc = true; | ||||
| 				break; | ||||
| 			case WM_SYSKEYDOWN: | ||||
| 				if(brock.whether_keyboard_shortkey() == false) | ||||
| 				if (brock.whether_keyboard_shortkey() == false) | ||||
| 				{ | ||||
| 					msgwnd = msgwnd->root_widget->other.attribute.root->menubar; | ||||
| 					if(msgwnd) | ||||
| 					if (msgwnd) | ||||
| 					{ | ||||
| 						brock.wd_manager.set_focus(msgwnd, false); | ||||
| 
 | ||||
| 						bool focused = (brock.focus() == msgwnd); | ||||
| 						arg_keyboard arg; | ||||
| 						arg.evt_code = event_code::key_press; | ||||
| 						arg.window_handle = reinterpret_cast<window>(msgwnd); | ||||
| @ -1336,9 +1336,11 @@ namespace detail | ||||
| 						arg.key = static_cast<nana::char_t>(wParam); | ||||
| 						brock.get_key_state(arg); | ||||
| 						brock.emit(event_code::key_press, msgwnd, arg, true, &context); | ||||
| 
 | ||||
| 						msgwnd->root_widget->flags.ignore_menubar_focus = (focused && (brock.focus() != msgwnd)); | ||||
| 					} | ||||
| 					else if(brock.get_menu()) | ||||
| 						brock.remove_menu(); | ||||
| 					else | ||||
| 						brock.erase_menu(true); | ||||
| 				} | ||||
| 				def_window_proc = true; | ||||
| 				break; | ||||
| @ -1348,6 +1350,10 @@ namespace detail | ||||
| 					msgwnd = msgwnd->root_widget->other.attribute.root->menubar; | ||||
| 					if(msgwnd) | ||||
| 					{ | ||||
| 						bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); | ||||
| 						if (set_focus) | ||||
| 							brock.wd_manager.set_focus(msgwnd, false); | ||||
| 
 | ||||
| 						arg_keyboard arg; | ||||
| 						arg.evt_code = event_code::key_release; | ||||
| 						arg.window_handle = reinterpret_cast<window>(msgwnd); | ||||
| @ -1355,6 +1361,12 @@ namespace detail | ||||
| 						arg.key = static_cast<nana::char_t>(wParam); | ||||
| 						brock.get_key_state(arg); | ||||
| 						brock.emit(event_code::key_release, msgwnd, arg, true, &context); | ||||
| 
 | ||||
| 						if (!set_focus) | ||||
| 						{ | ||||
| 							brock.set_menubar_taken(nullptr); | ||||
| 							msgwnd->root_widget->flags.ignore_menubar_focus = false; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				def_window_proc = true; | ||||
| @ -1362,6 +1374,9 @@ namespace detail | ||||
| 			case WM_KEYDOWN: | ||||
| 				if(msgwnd->flags.enabled) | ||||
| 				{ | ||||
| 					if (brock.get_menu()) | ||||
| 						brock.delay_restore(0);	//Enable delay restore
 | ||||
| 
 | ||||
| 					if(msgwnd->root != brock.get_menu()) | ||||
| 						msgwnd = brock.focus(); | ||||
| 
 | ||||
| @ -1431,6 +1446,8 @@ namespace detail | ||||
| 				} | ||||
| 				else | ||||
| 					brock.set_keyboard_shortkey(false); | ||||
| 
 | ||||
| 				brock.delay_restore(2);	//Restores while key release
 | ||||
| 				break; | ||||
| 			case WM_CLOSE: | ||||
| 			{ | ||||
| @ -1448,8 +1465,12 @@ namespace detail | ||||
| 				break; | ||||
| 			} | ||||
| 			case WM_DESTROY: | ||||
| 				if(msgwnd->root == brock.get_menu()) | ||||
| 					brock.empty_menu(); | ||||
| 				if (msgwnd->root == brock.get_menu()) | ||||
| 				{ | ||||
| 					brock.erase_menu(false); | ||||
| 					brock.delay_restore(3);	//Restores if delay_restore not decleared
 | ||||
| 				} | ||||
| 
 | ||||
| 				brock.wd_manager.destroy(msgwnd); | ||||
| 
 | ||||
| 				nana::detail::platform_spec::instance().release_window_icon(msgwnd->root); | ||||
| @ -1512,14 +1533,39 @@ namespace detail | ||||
| 
 | ||||
| 	void bedrock::set_menubar_taken(core_window_t* wd) | ||||
| 	{ | ||||
| 		auto pre = impl_->menu.taken_window; | ||||
| 		impl_->menu.taken_window = wd; | ||||
| 
 | ||||
| 		//assigning of a nullptr taken window is to restore the focus of pre taken
 | ||||
| 		if ((!wd) && pre) | ||||
| 		{ | ||||
| 			internal_scope_guard lock; | ||||
| 			wd_manager.set_focus(pre, false); | ||||
| 			wd_manager.update(pre, true, false); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	bedrock::core_window_t* bedrock::get_menubar_taken() | ||||
| 	//0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying
 | ||||
| 	void bedrock::delay_restore(int state) | ||||
| 	{ | ||||
| 		core_window_t* wd = impl_->menu.taken_window; | ||||
| 		impl_->menu.taken_window = nullptr; | ||||
| 		return wd; | ||||
| 		switch (state) | ||||
| 		{ | ||||
| 		case 0:	//Enable
 | ||||
| 			break; | ||||
| 		case 1: //Cancel
 | ||||
| 			break; | ||||
| 		case 2:	//Restore if key released
 | ||||
| 			//restores the focus when menu is closed by pressing keyboard
 | ||||
| 			if (!impl_->menu.window) | ||||
| 				set_menubar_taken(nullptr); | ||||
| 			break; | ||||
| 		case 3:	//Restores if destroying
 | ||||
| 			//when the menu is destroying, restores the focus if delay restore is not declared
 | ||||
| 			if (!impl_->menu.delay_restore) | ||||
| 				set_menubar_taken(nullptr); | ||||
| 		} | ||||
| 
 | ||||
| 		impl_->menu.delay_restore = (0 == state); | ||||
| 	} | ||||
| 
 | ||||
| 	bool bedrock::close_menu_if_focus_other_window(native_window_type wd) | ||||
| @ -1534,7 +1580,7 @@ namespace detail | ||||
| 				else | ||||
| 					return false; | ||||
| 			} | ||||
| 			remove_menu(); | ||||
| 			erase_menu(true); | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| @ -1544,7 +1590,7 @@ namespace detail | ||||
| 	{ | ||||
| 		if(menu_wd && impl_->menu.window != menu_wd) | ||||
| 		{ | ||||
| 			remove_menu(); | ||||
| 			erase_menu(true); | ||||
| 
 | ||||
| 			impl_->menu.window = menu_wd; | ||||
| 			impl_->menu.owner = native_interface::get_owner_window(menu_wd); | ||||
| @ -1568,21 +1614,13 @@ namespace detail | ||||
| 		return impl_->menu.window; | ||||
| 	} | ||||
| 
 | ||||
| 	void bedrock::remove_menu() | ||||
| 	void bedrock::erase_menu(bool try_destroy) | ||||
| 	{ | ||||
| 		if(impl_->menu.window) | ||||
| 		{ | ||||
| 			auto delwin = impl_->menu.window; | ||||
| 			impl_->menu.window = impl_->menu.owner = nullptr; | ||||
| 			impl_->menu.has_keyboard = false; | ||||
| 			native_interface::close_window(delwin); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void bedrock::empty_menu() | ||||
| 	{ | ||||
| 		if(impl_->menu.window) | ||||
| 		if (impl_->menu.window) | ||||
| 		{ | ||||
| 			if (try_destroy) | ||||
| 				native_interface::close_window(impl_->menu.window); | ||||
| 			 | ||||
| 			impl_->menu.window = impl_->menu.owner = nullptr; | ||||
| 			impl_->menu.has_keyboard = false; | ||||
| 		} | ||||
|  | ||||
| @ -884,7 +884,8 @@ namespace detail | ||||
| 				if (wd == wd->root_widget->other.attribute.root->menubar) | ||||
| 					wd = prev_focus; | ||||
| 
 | ||||
| 				brock.set_menubar_taken(wd); | ||||
| 				if (wd != wd->root_widget->other.attribute.root->menubar) | ||||
| 					brock.set_menubar_taken(wd); | ||||
| 			} | ||||
| 			return prev_focus; | ||||
| 		} | ||||
|  | ||||
| @ -240,6 +240,11 @@ namespace API | ||||
| 				return &reinterpret_cast<restrict::core_window_t*>(wd)->drawer.graphics; | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 
 | ||||
| 		void delay_restore(bool enable) | ||||
| 		{ | ||||
| 			restrict::bedrock.delay_restore(enable ? 0 : 1); | ||||
| 		} | ||||
| 	}//end namespace dev
 | ||||
| 
 | ||||
| 	//exit
 | ||||
| @ -1203,17 +1208,6 @@ namespace API | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void restore_menubar_taken_window() | ||||
| 	{ | ||||
| 		auto wd = restrict::bedrock.get_menubar_taken(); | ||||
| 		if(wd) | ||||
| 		{ | ||||
| 			internal_scope_guard lock; | ||||
| 			restrict::window_manager.set_focus(wd, false); | ||||
| 			restrict::window_manager.update(wd, true, false); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	bool is_window_zoomed(window wd, bool ask_for_max) | ||||
| 	{ | ||||
| 		auto const iwd = reinterpret_cast<restrict::core_window_t*>(wd); | ||||
|  | ||||
| @ -37,21 +37,25 @@ namespace nana | ||||
| 						::nana::color clr{ 0xaf, 0xc7, 0xe3 }; | ||||
| 						graph.rectangle(r, false, clr); | ||||
| 
 | ||||
| 						auto right = r.right() - 1; | ||||
| 						auto bottom = r.bottom() - 1; | ||||
| 						graph.set_color(colors::white); | ||||
| 						graph.set_pixel(r.x, r.y); | ||||
| 						graph.set_pixel(r.x + r.width - 1, r.y); | ||||
| 						graph.set_pixel(r.x, r.y + r.height - 1); | ||||
| 						graph.set_pixel(r.x + r.width - 1, r.y + r.height - 1); | ||||
| 						graph.set_pixel(right, r.y); | ||||
| 						graph.set_pixel(r.x, bottom); | ||||
| 						graph.set_pixel(right, bottom); | ||||
| 
 | ||||
| 						--right; | ||||
| 						--bottom; | ||||
| 						graph.set_color(clr); | ||||
| 						graph.set_pixel(r.x + 1, r.y + 1); | ||||
| 						graph.set_pixel(r.x + r.width - 2, r.y + 1); | ||||
| 						graph.set_pixel(r.x + 1, r.y + r.height - 2); | ||||
| 						graph.set_pixel(r.x + r.width - 2, r.y + r.height - 2); | ||||
| 						graph.set_pixel(right, r.y + 1); | ||||
| 						graph.set_pixel(r.x + 1, bottom); | ||||
| 						graph.set_pixel(right, bottom); | ||||
| 
 | ||||
| 						nana::rectangle po_r(r); | ||||
| 						graph.rectangle(po_r.pare_off(1), false, { 0xEB, 0xF4, 0xFB }); | ||||
| 						graph.gradual_rectangle(po_r.pare_off(1), { 0xDD, 0xEC, 0xFD }, { 0xC2, 0xDC, 0xFD }, true); | ||||
| 						graph.rectangle(po_r.pare_off(1), false, static_cast<color_rgb>(0xEBF4FB)); | ||||
| 						graph.gradual_rectangle(po_r.pare_off(1), static_cast<color_rgb>(0xDDECFD), static_cast<color_rgb>(0xC2DCFD), true); | ||||
| 					} | ||||
| 					else | ||||
| 						graph.rectangle(r, true, colors::white); | ||||
| @ -113,13 +117,8 @@ namespace nana | ||||
| 			class drawer_impl | ||||
| 			{ | ||||
| 			public: | ||||
| 				typedef widget& widget_reference; | ||||
| 				typedef nana::paint::graphics& graph_reference; | ||||
| 
 | ||||
| 				drawer_impl() | ||||
| 					:	widget_(nullptr), graph_(nullptr), image_pixels_(16), | ||||
| 						ignore_first_mouseup_(true), module_(nullptr) | ||||
| 				{} | ||||
| 				using widget_reference = widget&; | ||||
| 				using graph_reference = paint::graphics&; | ||||
| 
 | ||||
| 				void clear_state() | ||||
| 				{ | ||||
| @ -151,25 +150,19 @@ namespace nana | ||||
| 				{ | ||||
| 					if(scrollbar_.empty()) return; | ||||
| 
 | ||||
| 					bool update = false; | ||||
| 					const auto before_change = state_.offset_y; | ||||
| 					if(upwards) | ||||
| 					{ | ||||
| 						if(state_.offset_y) | ||||
| 						{ | ||||
| 						if (before_change) | ||||
| 							--(state_.offset_y); | ||||
| 							update = true; | ||||
| 						} | ||||
| 					} | ||||
| 					else  | ||||
| 					{ | ||||
| 						if((state_.offset_y + module_->max_items) < module_->items.size()) | ||||
| 						{ | ||||
| 						if ((before_change + module_->max_items) < module_->items.size()) | ||||
| 							++(state_.offset_y); | ||||
| 							update = true; | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					if(update) | ||||
| 					if(before_change != state_.offset_y) | ||||
| 					{ | ||||
| 						draw(); | ||||
| 						scrollbar_.value(state_.offset_y); | ||||
| @ -323,8 +316,7 @@ namespace nana | ||||
| 							state_.renderer->image(_m_image_enabled(), image_pixels_); | ||||
| 							for(std::size_t i = state_.offset_y; i < items; ++i) | ||||
| 							{ | ||||
| 								item_renderer::state_t state = item_renderer::StateNone; | ||||
| 								if(i == state_.index) state = item_renderer::StateHighlighted; | ||||
| 								auto state = (i != state_.index ? item_renderer::StateNone : item_renderer::StateHighlighted); | ||||
| 
 | ||||
| 								state_.renderer->render(*widget_, *graph_, item_r, module_->items[i].get(), state); | ||||
| 								item_r.y += item_pixels; | ||||
| @ -384,20 +376,20 @@ namespace nana | ||||
| 						scrollbar_.close(); | ||||
| 				} | ||||
| 			private: | ||||
| 				widget * widget_; | ||||
| 				nana::paint::graphics * graph_; | ||||
| 				unsigned image_pixels_;		//Define the width pixels of the image area
 | ||||
| 				widget * widget_{nullptr}; | ||||
| 				nana::paint::graphics * graph_{nullptr}; | ||||
| 				unsigned image_pixels_{16};		//Define the width pixels of the image area
 | ||||
| 
 | ||||
| 				bool ignore_first_mouseup_; | ||||
| 				bool ignore_first_mouseup_{true}; | ||||
| 				struct state_type | ||||
| 				{ | ||||
| 					std::size_t offset_y; | ||||
| 					std::size_t index;			//The index of the selected item.
 | ||||
| 					std::size_t offset_y{0}; | ||||
| 					std::size_t index{npos};			//The index of the selected item.
 | ||||
| 
 | ||||
| 					item_renderer * const orig_renderer; | ||||
| 					item_renderer * renderer; | ||||
| 
 | ||||
| 					state_type(): offset_y(0), index(npos), orig_renderer(new def_item_renderer), renderer(orig_renderer){} | ||||
| 					state_type(): orig_renderer(new def_item_renderer), renderer(orig_renderer){} | ||||
| 					~state_type() | ||||
| 					{ | ||||
| 						delete orig_renderer; | ||||
| @ -405,7 +397,7 @@ namespace nana | ||||
| 				}state_; | ||||
| 				nana::scroll<true> scrollbar_; | ||||
| 
 | ||||
| 				const module_def* module_; | ||||
| 				const module_def* module_{nullptr}; | ||||
| 			}; | ||||
| 
 | ||||
| 			//class drawer_impl;
 | ||||
|  | ||||
| @ -588,8 +588,6 @@ namespace nana | ||||
| 
 | ||||
| 				std::pair<std::size_t, std::size_t> _m_locate(dstream::linecontainer::iterator& i, std::size_t pos) | ||||
| 				{ | ||||
| 					//std::pair<std::size_t, std::size_t> r;	//deprecated
 | ||||
| 
 | ||||
| 					std::size_t n = i->data_ptr->text().length(); | ||||
| 					while(pos >= n) | ||||
| 					{ | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| /*
 | ||||
| *	A Menu implementation | ||||
| *	Nana C++ Library(http://www.nanapro.org)
 | ||||
| *	Copyright(C) 2009-2014 Jinhao(cnjinhao@hotmail.com) | ||||
| *	Copyright(C) 2009-2015 Jinhao(cnjinhao@hotmail.com) | ||||
| * | ||||
| *	Distributed under the Boost Software License, Version 1.0. | ||||
| *	(See accompanying file LICENSE_1_0.txt or copy at | ||||
| @ -151,7 +151,7 @@ namespace nana | ||||
| 
 | ||||
| 				void item_text(graph_reference graph, const nana::point& pos, const nana::string& text, unsigned text_pixels, const attr& at) | ||||
| 				{ | ||||
| 					graph.set_color(at.enabled ? colors::black : colors::gray_border); | ||||
| 					graph.set_text_color(at.enabled ? colors::black : colors::gray_border); | ||||
| 					nana::paint::text_renderer tr(graph); | ||||
| 					tr.render(pos, text.c_str(), text.length(), text_pixels, true); | ||||
| 				} | ||||
|  | ||||
| @ -58,16 +58,6 @@ namespace nana | ||||
| 					cont_.push_back(new item_type(text, shortkey)); | ||||
| 				} | ||||
| 
 | ||||
| 				nana::menu* get_menu(std::size_t index) const | ||||
| 				{ | ||||
| 					return (index < cont_.size() ? &(cont_[index]->menu_obj) : nullptr); | ||||
| 				} | ||||
| 
 | ||||
| 				const item_type& at(std::size_t index) const | ||||
| 				{ | ||||
| 					return *cont_.at(index); | ||||
| 				} | ||||
| 
 | ||||
| 				std::size_t find(unsigned long shortkey) const | ||||
| 				{ | ||||
| 					if(shortkey) | ||||
| @ -98,19 +88,19 @@ namespace nana | ||||
| 					:handle_(wd), graph_(graph) | ||||
| 				{} | ||||
| 
 | ||||
| 				void item_renderer::background(const nana::point& pos, const nana::size& size, state_t state) | ||||
| 				void item_renderer::background(const nana::point& pos, const nana::size& size, state item_state) | ||||
| 				{ | ||||
| 					auto bground = API::fgcolor(handle_); | ||||
| 					::nana::color border, body, corner; | ||||
| 
 | ||||
| 					switch(state) | ||||
| 					switch (item_state) | ||||
| 					{ | ||||
| 					case item_renderer::state_highlight: | ||||
| 					case state::highlighted: | ||||
| 						border = colors::highlight; | ||||
| 						body.from_rgb(0xC0, 0xDD, 0xFC); | ||||
| 						corner = body.blend(bground, 0.5); | ||||
| 						break; | ||||
| 					case item_renderer::state_selected: | ||||
| 					case state::selected: | ||||
| 						border = colors::dark_border; | ||||
| 						body = colors::white; | ||||
| 						corner = body.blend(bground, 0.5); | ||||
| @ -132,9 +122,9 @@ namespace nana | ||||
| 					graph_.rectangle(r.pare_off(1), true, body); | ||||
| 				} | ||||
| 
 | ||||
| 				void item_renderer::caption(int x, int y, const nana::string& text) | ||||
| 				void item_renderer::caption(const point& pos, const nana::string& text) | ||||
| 				{ | ||||
| 					graph_.string({ x, y }, text, colors::black); | ||||
| 					graph_.string(pos, text, colors::black); | ||||
| 				} | ||||
| 			//end class item_renderer
 | ||||
| 
 | ||||
| @ -150,22 +140,26 @@ namespace nana | ||||
| 
 | ||||
| 				nana::menu* trigger::push_back(const ::nana::string& text) | ||||
| 				{ | ||||
| 					::nana::string::value_type shkey; | ||||
| 					::nana::char_t shkey; | ||||
| 					API::transform_shortkey_text(text, shkey, nullptr); | ||||
| 
 | ||||
| 					if(shkey) | ||||
| 						API::register_shortkey(widget_->handle(), shkey); | ||||
| 
 | ||||
| 					auto i = items_->cont().size(); | ||||
| 					auto pos = items_->cont().size(); | ||||
| 					items_->append(text, shkey); | ||||
| 					_m_draw(); | ||||
| 					API::update_window(*widget_); | ||||
| 					return items_->get_menu(i); | ||||
| 
 | ||||
| 					return at(pos); | ||||
| 				} | ||||
| 
 | ||||
| 				nana::menu* trigger::at(std::size_t index) const | ||||
| 				nana::menu* trigger::at(std::size_t pos) const | ||||
| 				{ | ||||
| 					return items_->get_menu(index); | ||||
| 					if (pos < items_->cont().size()) | ||||
| 						return &(items_->cont()[pos]->menu_obj); | ||||
| 
 | ||||
| 					return nullptr; | ||||
| 				} | ||||
| 
 | ||||
| 				std::size_t trigger::size() const | ||||
| @ -222,22 +216,17 @@ namespace nana | ||||
| 				void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) | ||||
| 				{ | ||||
| 					state_.nullify_mouse = false; | ||||
| 
 | ||||
| 					state_.active = _m_item_by_pos(arg.pos); | ||||
| 					if(state_.menu_active == false) | ||||
| 
 | ||||
| 					if (npos != state_.active) | ||||
| 					{ | ||||
| 						if(state_.active != npos) | ||||
| 						{ | ||||
| 						if (!state_.menu_active) | ||||
| 							state_.menu_active = true; | ||||
| 							_m_popup_menu(); | ||||
| 						} | ||||
| 						else | ||||
| 							_m_total_close(true); | ||||
| 					} | ||||
| 					else if(npos == state_.active) | ||||
| 						_m_total_close(true); | ||||
| 					else | ||||
| 
 | ||||
| 						_m_popup_menu(); | ||||
| 					} | ||||
| 					else | ||||
| 						_m_total_close(); | ||||
| 
 | ||||
| 					_m_draw(); | ||||
| 					API::lazy_refresh(); | ||||
| @ -255,11 +244,10 @@ namespace nana | ||||
| 					else | ||||
| 					{ | ||||
| 						state_.behavior = state_.behavior_none; | ||||
| 						_m_total_close(true); | ||||
| 						_m_total_close(); | ||||
| 						_m_draw(); | ||||
| 						API::lazy_refresh(); | ||||
| 					} | ||||
| 
 | ||||
| 				} | ||||
| 
 | ||||
| 				void trigger::focus(graph_reference, const arg_focus& arg) | ||||
| @ -284,10 +272,10 @@ namespace nana | ||||
| 						switch(arg.key) | ||||
| 						{ | ||||
| 						case keyboard::os_arrow_down: | ||||
| 							state_.menu->goto_next(true);  break; | ||||
| 						case keyboard::backspace: | ||||
| 						case keyboard::os_arrow_up: | ||||
| 							state_.menu->goto_next(false); break; | ||||
| 							state_.menu->goto_next(keyboard::os_arrow_down == arg.key); | ||||
| 							break; | ||||
| 						case keyboard::os_arrow_right: | ||||
| 							if(state_.menu->goto_submen() == false) | ||||
| 								_m_move(false); | ||||
| @ -305,19 +293,14 @@ namespace nana | ||||
| 							} | ||||
| 							break; | ||||
| 						case keyboard::enter: | ||||
| 							state_.delay_restore = true; | ||||
| 							state_.menu->pick(); | ||||
| 							break; | ||||
| 						default: | ||||
| 							if(2 != state_.menu->send_shortkey(arg.key)) | ||||
| 							if (2 != state_.menu->send_shortkey(arg.key)) | ||||
| 							{ | ||||
| 								if (state_.active != npos) | ||||
| 								{ | ||||
| 									state_.delay_restore = true; | ||||
| 									_m_total_close(false); | ||||
| 									if (arg.key == 18) //ALT
 | ||||
| 										state_.behavior = state_.behavior_focus; | ||||
| 								} | ||||
| 								_m_total_close(); | ||||
| 								if (arg.key == 18) //ALT
 | ||||
| 									state_.behavior = state_.behavior_focus; | ||||
| 							} | ||||
| 							else | ||||
| 								state_.menu->goto_submen(); | ||||
| @ -328,18 +311,15 @@ namespace nana | ||||
| 						switch(arg.key) | ||||
| 						{ | ||||
| 						case keyboard::os_arrow_right: | ||||
| 							_m_move(false); | ||||
| 							break; | ||||
| 						case keyboard::backspace: | ||||
| 						case keyboard::os_arrow_left: | ||||
| 							_m_move(true); | ||||
| 							_m_move(keyboard::os_arrow_right != arg.key); | ||||
| 							break; | ||||
| 						case keyboard::escape: | ||||
| 							if(state_.behavior == state_.behavior_focus) | ||||
| 							{ | ||||
| 								state_.active= npos; | ||||
| 								state_.behavior = state_.behavior_none; | ||||
| 								API::restore_menubar_taken_window(); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| @ -369,12 +349,6 @@ namespace nana | ||||
| 						_m_draw(); | ||||
| 						API::lazy_refresh(); | ||||
| 					} | ||||
| 
 | ||||
| 					if (state_.delay_restore) | ||||
| 					{ | ||||
| 						API::restore_menubar_taken_window(); | ||||
| 						state_.delay_restore = false; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				void trigger::shortkey(graph_reference graph, const arg_keyboard& arg) | ||||
| @ -430,33 +404,44 @@ namespace nana | ||||
| 
 | ||||
| 				bool trigger::_m_popup_menu() | ||||
| 				{ | ||||
| 					if(state_.menu_active && (state_.menu != items_->get_menu(state_.active))) | ||||
| 					{ | ||||
| 						std::size_t index = state_.active; | ||||
| 						_m_close_menu(); | ||||
| 						state_.active = index; | ||||
| 					auto& items = items_->cont(); | ||||
| 
 | ||||
| 						state_.menu = items_->get_menu(state_.active); | ||||
| 						if(state_.menu) | ||||
| 					auto pos = state_.active; | ||||
| 					if (pos >= items.size()) | ||||
| 						return false; | ||||
| 
 | ||||
| 					if(state_.menu_active && (state_.menu != &(items[pos]->menu_obj))) | ||||
| 					{ | ||||
| 						API::dev::delay_restore(true); | ||||
| 						_m_close_menu(); | ||||
| 						API::dev::delay_restore(false); | ||||
| 						state_.active = pos; | ||||
| 
 | ||||
| 						auto & m = items[pos]; | ||||
| 						state_.menu = &(m->menu_obj); | ||||
| 						state_.menu->destroy_answer([this] | ||||
| 						{ | ||||
| 							const item_type &m = items_->at(state_.active); | ||||
| 							state_.menu->destroy_answer(std::bind(&trigger::_m_unload_menu_window, this)); | ||||
| 							menu_accessor::popup(*state_.menu, widget_->handle(), m.pos.x, m.pos.y + m.size.height); | ||||
| 							return true; | ||||
| 						} | ||||
| 							state_.menu = nullptr; | ||||
| 							if (state_.passive_close) | ||||
| 							{ | ||||
| 								_m_total_close(); | ||||
| 
 | ||||
| 								_m_draw(); | ||||
| 								API::update_window(widget_->handle()); | ||||
| 							} | ||||
| 						}); | ||||
| 						menu_accessor::popup(*state_.menu, *widget_, m->pos.x, m->pos.y + static_cast<int>(m->size.height)); | ||||
| 						return true; | ||||
| 					} | ||||
| 					return false; | ||||
| 				} | ||||
| 
 | ||||
| 				void trigger::_m_total_close(bool try_restore) | ||||
| 				void trigger::_m_total_close() | ||||
| 				{ | ||||
| 					_m_close_menu(); | ||||
| 					state_.menu_active = false; | ||||
| 					state_.behavior = state_.behavior_none; | ||||
| 
 | ||||
| 					if (try_restore) | ||||
| 						API::restore_menubar_taken_window(); | ||||
| 
 | ||||
| 					auto pos = API::cursor_position(); | ||||
| 					API::calc_window_point(widget_->handle(), pos); | ||||
| 					state_.active = _m_item_by_pos(pos); | ||||
| @ -475,18 +460,6 @@ namespace nana | ||||
| 					return false; | ||||
| 				} | ||||
| 
 | ||||
| 				void trigger::_m_unload_menu_window() | ||||
| 				{ | ||||
| 					state_.menu = nullptr; | ||||
| 					if(state_.passive_close) | ||||
| 					{ | ||||
| 						_m_total_close(false); | ||||
| 
 | ||||
| 						_m_draw(); | ||||
| 						API::update_window(widget_->handle()); | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				std::size_t trigger::_m_item_by_pos(const ::nana::point& pos) | ||||
| 				{ | ||||
| 					if((2 <= pos.x) && (2 <= pos.y) && (pos.y < 25)) | ||||
| @ -534,9 +507,9 @@ namespace nana | ||||
| 					for(auto i : items_->cont()) | ||||
| 					{ | ||||
| 						//Transform the text if it contains the hotkey character
 | ||||
| 						nana::string::value_type hotkey; | ||||
| 						nana::string::size_type hotkey_pos; | ||||
| 						nana::string text = API::transform_shortkey_text(i->text, hotkey, &hotkey_pos); | ||||
| 						::nana::char_t hotkey; | ||||
| 						::nana::string::size_type hotkey_pos; | ||||
| 						auto text = API::transform_shortkey_text(i->text, hotkey, &hotkey_pos); | ||||
| 
 | ||||
| 						nana::size text_s = graph_->text_extent_size(text); | ||||
| 
 | ||||
| @ -545,10 +518,11 @@ namespace nana | ||||
| 						i->pos = item_pos; | ||||
| 						i->size = item_s; | ||||
| 
 | ||||
| 						item_renderer::state_t state = (index != state_.active ? ird.state_normal : (state_.menu_active ? ird.state_selected : ird.state_highlight)); | ||||
| 						ird.background(item_pos, item_s, state); | ||||
| 						using state = item_renderer::state; | ||||
| 						state item_state = (index != state_.active ? state::normal : (state_.menu_active ? state::selected : state::highlighted)); | ||||
| 						ird.background(item_pos, item_s, item_state); | ||||
| 
 | ||||
| 						if(state == ird.state_selected) | ||||
| 						if (state::selected == item_state) | ||||
| 						{ | ||||
| 							int x = item_pos.x + item_s.width; | ||||
| 							int y1 = item_pos.y + 2, y2 = item_pos.y + item_s.height - 1; | ||||
| @ -558,7 +532,7 @@ namespace nana | ||||
| 
 | ||||
| 						//Draw text, the text is transformed from orignal for hotkey character
 | ||||
| 						int text_top_off = (item_s.height - text_s.height) / 2; | ||||
| 						ird.caption(item_pos.x + 8, item_pos.y + text_top_off, text); | ||||
| 						ird.caption({ item_pos.x + 8, item_pos.y + text_top_off }, text); | ||||
| 
 | ||||
| 						if(hotkey) | ||||
| 						{ | ||||
| @ -584,8 +558,7 @@ namespace nana | ||||
| 							menu_active(false), | ||||
| 							passive_close(true), | ||||
| 							nullify_mouse(false), | ||||
| 							menu(nullptr), | ||||
| 							delay_restore(false) | ||||
| 							menu(nullptr) | ||||
| 					{} | ||||
| 				//end struct state_type
 | ||||
| 			//end class trigger
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 qPCR4vir
						qPCR4vir