| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  popup.cpp                                                            */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                    http://www.godotengine.org                         */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | #include "popup.h"
 | 
					
						
							|  |  |  | #include "os/keyboard.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::_input_event(InputEvent p_event) { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::_notification(int p_what) { | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { | 
					
						
							|  |  |  | 		if (popped_up && !is_visible()) { | 
					
						
							|  |  |  | 			popped_up=false; | 
					
						
							|  |  |  | 			notification(NOTIFICATION_POPUP_HIDE); | 
					
						
							|  |  |  | 			emit_signal("popup_hide"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::_fix_size() { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Control *window = get_window(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!window); | 
					
						
							| 
									
										
										
										
											2015-01-03 23:27:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Point2 pos = get_pos(); | 
					
						
							|  |  |  | 	Size2 size = get_size();		 | 
					
						
							|  |  |  | 	Point2 window_size = window==this ? get_parent_area_size()  :window->get_size(); | 
					
						
							| 
									
										
										
										
											2015-01-03 23:27:11 -03:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Point2 pos = get_global_pos(); | 
					
						
							|  |  |  | 	Size2 size = get_size(); | 
					
						
							|  |  |  | 	Point2 window_size = get_viewport_rect().size; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-03 23:27:11 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (pos.x+size.width > window_size.width) | 
					
						
							|  |  |  | 		pos.x=window_size.width-size.width; | 
					
						
							|  |  |  | 	if (pos.x<0) | 
					
						
							|  |  |  | 		pos.x=0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (pos.y+size.height > window_size.height) | 
					
						
							|  |  |  | 		pos.y=window_size.height-size.height; | 
					
						
							|  |  |  | 	if (pos.y<0) | 
					
						
							|  |  |  | 		pos.y=0; | 
					
						
							| 
									
										
										
										
											2015-01-03 23:27:11 -03:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (pos!=get_pos()) | 
					
						
							|  |  |  | 		set_pos(pos); | 
					
						
							| 
									
										
										
										
											2015-01-03 23:27:11 -03:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	if (pos!=get_pos()) | 
					
						
							|  |  |  | 		set_global_pos(pos); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::popup_centered_minsize(const Size2& p_minsize) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Size2 total_minsize=p_minsize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(int i=0;i<get_child_count();i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Control *c=get_child(i)->cast_to<Control>(); | 
					
						
							|  |  |  | 		if (!c) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		if (c->is_hidden()) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Size2 minsize = c->get_combined_minimum_size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(int j=0;j<2;j++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Margin m_beg = Margin(0+j); | 
					
						
							|  |  |  | 			Margin m_end = Margin(2+j); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			float margin_begin = c->get_margin(m_beg); | 
					
						
							|  |  |  | 			float margin_end = c->get_margin(m_end); | 
					
						
							|  |  |  | 			AnchorType anchor_begin = c->get_anchor(m_beg); | 
					
						
							|  |  |  | 			AnchorType anchor_end = c->get_anchor(m_end); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (anchor_begin == ANCHOR_BEGIN) | 
					
						
							|  |  |  | 				minsize[j]+=margin_begin; | 
					
						
							|  |  |  | 			if (anchor_end == ANCHOR_END) | 
					
						
							|  |  |  | 				minsize[j]+=margin_end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		print_line(String(c->get_type())+": "+minsize); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		total_minsize.width = MAX( total_minsize.width, minsize.width ); | 
					
						
							|  |  |  | 		total_minsize.height = MAX( total_minsize.height, minsize.height ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	popup_centered( total_minsize ); | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	popped_up=true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::popup_centered(const Size2& p_size) { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Control *window = get_window(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!window); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	emit_signal("about_to_show"); | 
					
						
							|  |  |  | 	Rect2 rect; | 
					
						
							|  |  |  | 	rect.size = p_size==Size2()?get_size():p_size; | 
					
						
							|  |  |  | 	Point2 window_size = window==this ? get_parent_area_size()  :window->get_size(); | 
					
						
							|  |  |  | 	rect.pos = ((window_size-rect.size)/2.0).floor(); | 
					
						
							|  |  |  | 	set_pos( rect.pos ); | 
					
						
							|  |  |  | 	set_size( rect.size ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	show_modal(exclusive); | 
					
						
							|  |  |  | 	_fix_size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Control *focusable = find_next_valid_focus(); | 
					
						
							|  |  |  | 	if (focusable) | 
					
						
							|  |  |  | 		focusable->grab_focus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_post_popup(); | 
					
						
							|  |  |  | 	notification(NOTIFICATION_POST_POPUP); | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	popped_up=true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::popup_centered_ratio(float p_screen_ratio) { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Control *window = get_window(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!window); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	emit_signal("about_to_show"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Rect2 rect; | 
					
						
							|  |  |  | 	Point2 window_size = window==this ? get_parent_area_size()  :window->get_size(); | 
					
						
							|  |  |  | 	rect.size = (window_size * p_screen_ratio).floor(); | 
					
						
							|  |  |  | 	rect.pos = ((window_size-rect.size)/2.0).floor(); | 
					
						
							|  |  |  | 	set_pos( rect.pos ); | 
					
						
							|  |  |  | 	set_size( rect.size ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	show_modal(exclusive); | 
					
						
							|  |  |  | 	_fix_size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Control *focusable = find_next_valid_focus(); | 
					
						
							|  |  |  | 	if (focusable) | 
					
						
							|  |  |  | 		focusable->grab_focus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_post_popup(); | 
					
						
							|  |  |  | 	notification(NOTIFICATION_POST_POPUP); | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	popped_up=true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::popup() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	emit_signal("about_to_show"); | 
					
						
							|  |  |  | 	show_modal(exclusive); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_fix_size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Control *focusable = find_next_valid_focus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (focusable) | 
					
						
							|  |  |  | 		focusable->grab_focus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_post_popup(); | 
					
						
							|  |  |  | 	notification(NOTIFICATION_POST_POPUP); | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	popped_up=true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::set_exclusive(bool p_exclusive) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	exclusive=p_exclusive; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Popup::is_exclusive() const  { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return exclusive; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Popup::_bind_methods() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ObjectTypeDB::bind_method(_MD("popup_centered","size"),&Popup::popup_centered,DEFVAL(Size2())); | 
					
						
							|  |  |  | 	ObjectTypeDB::bind_method(_MD("popup_centered_ratio","ratio"),&Popup::popup_centered_ratio,DEFVAL(0.75)); | 
					
						
							|  |  |  | 	ObjectTypeDB::bind_method(_MD("popup_centered_minsize","minsize"),&Popup::popup_centered_minsize,DEFVAL(Size2())); | 
					
						
							|  |  |  | 	ObjectTypeDB::bind_method(_MD("popup"),&Popup::popup); | 
					
						
							|  |  |  | 	ObjectTypeDB::bind_method(_MD("set_exclusive","enable"),&Popup::set_exclusive); | 
					
						
							|  |  |  | 	ObjectTypeDB::bind_method(_MD("is_exclusive"),&Popup::is_exclusive); | 
					
						
							|  |  |  | 	ADD_SIGNAL( MethodInfo("about_to_show") ); | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	ADD_SIGNAL( MethodInfo("popup_hide") ); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "popup/exclusive"), _SCS("set_exclusive"),_SCS("is_exclusive") ); | 
					
						
							|  |  |  | 	BIND_CONSTANT(NOTIFICATION_POST_POPUP); | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	BIND_CONSTANT(NOTIFICATION_POPUP_HIDE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Popup::Popup() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	set_as_toplevel(true); | 
					
						
							|  |  |  | 	exclusive=false; | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 	popped_up=false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	hide(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Popup::~Popup() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PopupPanel::set_child_rect(Control *p_child) { | 
					
						
							|  |  |  | 	ERR_FAIL_NULL(p_child); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Ref<StyleBox> p = get_stylebox("panel"); | 
					
						
							|  |  |  | 	p_child->set_area_as_parent_rect(); | 
					
						
							|  |  |  | 	for(int i=0;i<4;i++) { | 
					
						
							|  |  |  | 		p_child->set_margin(Margin(i),p->get_margin(Margin(i))); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PopupPanel::_notification(int p_what) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_what==NOTIFICATION_DRAW) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		get_stylebox("panel")->draw(get_canvas_item(),Rect2(Point2(),get_size())); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PopupPanel::PopupPanel() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |