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