/*************************************************************************/ /* call_dialog.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 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 "call_dialog.h" #include "scene/gui/label.h" #include "object_type_db.h" #include "print_string.h" class CallDialogParams : public Object { GDCLASS( CallDialogParams, Object ); public: bool _set(const StringName& p_name, const Variant& p_value) { values[p_name]=p_value; return true; } bool _get(const StringName& p_name,Variant &r_ret) const { if (values.has(p_name)) { r_ret=values[p_name]; return true; } return false; } void _get_property_list( List *p_list) const { for(int i=0;ipush_back(method.arguments[i]); } MethodInfo method; HashMap values; CallDialogParams() {} }; void CallDialog::_notification(int p_what) { if (p_what==NOTIFICATION_READY) { call->connect("pressed", this,"_call"); cancel->connect("pressed", this,"_cancel"); //filter->get_path()->connect("text_changed", this,"_text_changed"); _update_method_list(); } if (p_what==NOTIFICATION_EXIT_TREE) { call->disconnect("pressed", this,"_call"); cancel->disconnect("pressed", this,"_cancel"); //filter->get_path()->connect("text_changed", this,"_text_changed"); _update_method_list(); } if (p_what==NOTIFICATION_DRAW) { RID ci = get_canvas_item(); get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); } } void CallDialog::_call() { if (!tree->get_selected()) return; TreeItem* item=tree->get_selected(); ERR_FAIL_COND(!item); int idx=item->get_metadata(0); ERR_FAIL_INDEX(idx,methods.size()); MethodInfo &m = methods[idx]; Variant args[VARIANT_ARG_MAX]; for(int i=0;i=m.arguments.size()) continue; if (call_params->values.has(m.arguments[i].name)) args[i]=call_params->values[m.arguments[i].name]; } Variant ret = object->call(m.name,args[0],args[1],args[2],args[3],args[4]); if (ret.get_type()!=Variant::NIL) return_value->set_text(ret); else return_value->set_text(""); } void CallDialog::_cancel() { hide(); } void CallDialog::_item_selected() { TreeItem* item=tree->get_selected(); ERR_FAIL_COND(!item); if (item->get_metadata(0).get_type()==Variant::NIL) { call->set_disabled(true); return; } call->set_disabled(false); int idx=item->get_metadata(0); ERR_FAIL_INDEX(idx,methods.size()); MethodInfo &m = methods[idx]; call_params->values.clear(); call_params->method=m; property_editor->edit(call_params); property_editor->update_tree(); } void CallDialog::_update_method_list() { tree->clear(); if (!object) return; TreeItem *root = tree->create_item(); List method_list; object->get_method_list(&method_list); method_list.sort(); methods.clear(); List inheritance_list; String type = object->get_class(); while(type!="") { inheritance_list.push_back( type ); type=ClassDB::get_parent_class(type); } TreeItem *selected_item=NULL; for(int i=0;i::Element *N,*E=method_list.front(); while(E) { N=E->next(); if (parent_type!="" && ClassDB::get_method(parent_type,E->get().name)!=NULL) { E=N; continue; } if (!type_item) { type_item=tree->create_item(root); type_item->set_text(0,type); if (has_icon(type,"EditorIcons")) type_item->set_icon(0,get_icon(type,"EditorIcons")); } TreeItem *method_item = tree->create_item(type_item); method_item->set_text(0,E->get().name); method_item->set_metadata(0,methods.size()); if (E->get().name==selected) selected_item=method_item; methods.push_back( E->get() ); method_list.erase(E); E=N; } } if (selected_item) selected_item->select(0); } void CallDialog::_bind_methods() { ClassDB::bind_method("_call",&CallDialog::_call); ClassDB::bind_method("_cancel",&CallDialog::_cancel); ClassDB::bind_method("_item_selected", &CallDialog::_item_selected); } void CallDialog::set_object(Object *p_object,StringName p_selected) { object=p_object; selected=p_selected; property_editor->edit(NULL); call->set_disabled(true); return_value->clear(); _update_method_list(); method_label->set_text(vformat(TTR("Method List For '%s':"),p_object->get_class())); } CallDialog::CallDialog() { object=NULL; call = memnew( Button ); call->set_anchor( MARGIN_LEFT, ANCHOR_END ); call->set_anchor( MARGIN_TOP, ANCHOR_END ); call->set_anchor( MARGIN_RIGHT, ANCHOR_END ); call->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); call->set_begin( Point2( 70, 29 ) ); call->set_end( Point2( 15, 15 ) ); call->set_text(TTR("Call")); add_child(call); cancel = memnew( Button ); cancel->set_anchor( MARGIN_TOP, ANCHOR_END ); cancel->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); cancel->set_begin( Point2( 15, 29 ) ); cancel->set_end( Point2( 70, 15 ) ); cancel->set_text(TTR("Close")); add_child(cancel); tree = memnew( Tree ); tree->set_anchor( MARGIN_RIGHT, ANCHOR_RATIO ); tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); tree->set_begin( Point2( 20,50 ) ); tree->set_margin(MARGIN_BOTTOM, 44 ); tree->set_margin(MARGIN_RIGHT, 0.5 ); tree->set_select_mode( Tree::SELECT_ROW ); add_child(tree); tree->connect("item_selected", this,"_item_selected"); tree->set_hide_root(true); property_editor = memnew( PropertyEditor ); property_editor->set_anchor_and_margin( MARGIN_RIGHT, ANCHOR_END, 15 ); property_editor->set_anchor_and_margin( MARGIN_TOP, ANCHOR_BEGIN, 50 ); property_editor->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.55 ); property_editor->set_anchor_and_margin( MARGIN_BOTTOM, ANCHOR_END, 90 ); property_editor->get_scene_tree()->set_hide_root( true ); property_editor->hide_top_label(); add_child(property_editor); method_label = memnew( Label ); method_label->set_pos( Point2( 15,25) ); method_label->set_text(TTR("Method List:")); add_child(method_label); Label *label = memnew( Label ); label->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.53 ); label->set_anchor_and_margin( MARGIN_TOP, ANCHOR_BEGIN, 25 ); label->set_text(TTR("Arguments:")); add_child(label); return_label = memnew( Label ); return_label->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.53 ); return_label->set_anchor_and_margin( MARGIN_TOP, ANCHOR_END, 85 ); return_label->set_text(TTR("Return:")); add_child(return_label); return_value = memnew( LineEdit ); return_value->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.55 ); return_value->set_anchor_and_margin( MARGIN_RIGHT, ANCHOR_END, 15 ); return_value->set_anchor_and_margin( MARGIN_TOP, ANCHOR_END, 65 ); add_child(return_value); /* label = memnew( Label ); label->set_anchor( MARGIN_TOP, ANCHOR_END ); label->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); label->set_begin( Point2( 15,54) ); label->set_end( Point2( 16,44) ); label->set_text("Parameters:"); add_child(label); */ call_params = memnew( CallDialogParams ); set_as_toplevel(true); } CallDialog::~CallDialog() { memdelete(call_params); }