diff options
author | Franco Eusébio Garcia <francoegarcia@outlook.com> | 2016-05-01 05:33:32 -0300 |
---|---|---|
committer | Rémi Verschelde <remi@verschelde.fr> | 2016-05-01 10:33:32 +0200 |
commit | a735573327d26536bd29e14350f1e5811c030b86 (patch) | |
tree | e37ff9ff7c196f66178233c292af40dd833ee9eb /tools | |
parent | ff40dcd83f7cc74446ee90a911b58c165b6e164f (diff) |
Add math/script expression evaluation in editor (#3620)
Rebase of #453
Diffstat (limited to 'tools')
-rw-r--r-- | tools/editor/property_editor.cpp | 189 | ||||
-rw-r--r-- | tools/editor/property_editor.h | 28 |
2 files changed, 184 insertions, 33 deletions
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 1340670db1..110f5bb7f5 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1313,7 +1313,10 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::REAL: { if (hint!=PROPERTY_HINT_EXP_EASING) { - v=value_editor[0]->get_text().to_double(); + if (evaluator) + evaluator->eval(value_editor[0]->get_text()); + else + v=value_editor[0]->get_text().to_double(); emit_signal("variant_changed"); } @@ -1327,8 +1330,13 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::VECTOR2: { Vector2 vec; - vec.x=value_editor[0]->get_text().to_double(); - vec.y=value_editor[1]->get_text().to_double(); + if (evaluator) { + vec.x=evaluator->eval(value_editor[0]->get_text()); + vec.y=evaluator->eval(value_editor[1]->get_text()); + } else { + vec.x=value_editor[0]->get_text().to_double(); + vec.y=value_editor[1]->get_text().to_double(); + } v=vec; emit_signal("variant_changed"); @@ -1336,10 +1344,17 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::RECT2: { Rect2 r2; - r2.pos.x=value_editor[0]->get_text().to_double(); - r2.pos.y=value_editor[1]->get_text().to_double(); - r2.size.x=value_editor[2]->get_text().to_double(); - r2.size.y=value_editor[3]->get_text().to_double(); + if (evaluator) { + r2.pos.x=evaluator->eval(value_editor[0]->get_text()); + r2.pos.y=evaluator->eval(value_editor[1]->get_text()); + r2.size.x=evaluator->eval(value_editor[2]->get_text()); + r2.size.y=evaluator->eval(value_editor[3]->get_text()); + } else { + r2.pos.x=value_editor[0]->get_text().to_double(); + r2.pos.y=value_editor[1]->get_text().to_double(); + r2.size.x=value_editor[2]->get_text().to_double(); + r2.size.y=value_editor[3]->get_text().to_double(); + } v=r2; emit_signal("variant_changed"); @@ -1348,9 +1363,15 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::VECTOR3: { Vector3 vec; - vec.x=value_editor[0]->get_text().to_double(); - vec.y=value_editor[1]->get_text().to_double(); - vec.z=value_editor[2]->get_text().to_double(); + if (evaluator) { + vec.x=evaluator->eval(value_editor[0]->get_text()); + vec.y=evaluator->eval(value_editor[1]->get_text()); + vec.z=evaluator->eval(value_editor[2]->get_text()); + } else { + vec.x=value_editor[0]->get_text().to_double(); + vec.y=value_editor[1]->get_text().to_double(); + vec.z=value_editor[2]->get_text().to_double(); + } v=vec; emit_signal("variant_changed"); @@ -1358,10 +1379,17 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::PLANE: { Plane pl; - pl.normal.x=value_editor[0]->get_text().to_double(); - pl.normal.y=value_editor[1]->get_text().to_double(); - pl.normal.z=value_editor[2]->get_text().to_double(); - pl.d=value_editor[3]->get_text().to_double(); + if (evaluator) { + pl.normal.x=evaluator->eval(value_editor[0]->get_text()); + pl.normal.y=evaluator->eval(value_editor[1]->get_text()); + pl.normal.z=evaluator->eval(value_editor[2]->get_text()); + pl.d=evaluator->eval(value_editor[3]->get_text()); + } else { + pl.normal.x=value_editor[0]->get_text().to_double(); + pl.normal.y=value_editor[1]->get_text().to_double(); + pl.normal.z=value_editor[2]->get_text().to_double(); + pl.d=value_editor[3]->get_text().to_double(); + } v=pl; emit_signal("variant_changed"); @@ -1369,10 +1397,17 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::QUAT: { Quat q; - q.x=value_editor[0]->get_text().to_double(); - q.y=value_editor[1]->get_text().to_double(); - q.z=value_editor[2]->get_text().to_double(); - q.w=value_editor[3]->get_text().to_double(); + if (evaluator) { + q.x=evaluator->eval(value_editor[0]->get_text()); + q.y=evaluator->eval(value_editor[1]->get_text()); + q.z=evaluator->eval(value_editor[2]->get_text()); + q.w=evaluator->eval(value_editor[3]->get_text()); + } else { + q.x=value_editor[0]->get_text().to_double(); + q.y=value_editor[1]->get_text().to_double(); + q.z=value_editor[2]->get_text().to_double(); + q.w=value_editor[3]->get_text().to_double(); + } v=q; emit_signal("variant_changed"); @@ -1380,14 +1415,23 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::_AABB: { Vector3 pos; - pos.x=value_editor[0]->get_text().to_double(); - pos.y=value_editor[1]->get_text().to_double(); - pos.z=value_editor[2]->get_text().to_double(); Vector3 size; - size.x=value_editor[3]->get_text().to_double(); - size.y=value_editor[4]->get_text().to_double(); - size.z=value_editor[5]->get_text().to_double(); + if (evaluator) { + pos.x=evaluator->eval(value_editor[0]->get_text()); + pos.y=evaluator->eval(value_editor[1]->get_text()); + pos.z=evaluator->eval(value_editor[2]->get_text()); + size.x=evaluator->eval(value_editor[3]->get_text()); + size.y=evaluator->eval(value_editor[4]->get_text()); + size.z=evaluator->eval(value_editor[5]->get_text()); + } else { + pos.x=value_editor[0]->get_text().to_double(); + pos.y=value_editor[1]->get_text().to_double(); + pos.z=value_editor[2]->get_text().to_double(); + size.x=value_editor[3]->get_text().to_double(); + size.y=value_editor[4]->get_text().to_double(); + size.z=value_editor[5]->get_text().to_double(); + } v=AABB(pos,size); emit_signal("variant_changed"); @@ -1396,8 +1440,11 @@ void CustomPropertyEditor::_modified(String p_string) { Matrix32 m; for(int i=0;i<6;i++) { - - m.elements[i/2][i%2]=value_editor[i]->get_text().to_double(); + if (evaluator) { + m.elements[i/2][i%2]=evaluator->eval(value_editor[i]->get_text()); + } else { + m.elements[i/2][i%2]=value_editor[i]->get_text().to_double(); + } } v=m; @@ -1409,7 +1456,11 @@ void CustomPropertyEditor::_modified(String p_string) { Matrix3 m; for(int i=0;i<9;i++) { - m.elements[i/3][i%3]=value_editor[i]->get_text().to_double(); + if (evaluator) { + m.elements[i/3][i%3]=evaluator->eval(value_editor[i]->get_text()); + } else { + m.elements[i/3][i%3]=value_editor[i]->get_text().to_double(); + } } v=m; @@ -1421,13 +1472,24 @@ void CustomPropertyEditor::_modified(String p_string) { Matrix3 basis; for(int i=0;i<9;i++) { - basis.elements[i/3][i%3]=value_editor[(i/3)*4+i%3]->get_text().to_double(); + if (evaluator) { + basis.elements[i/3][i%3]=evaluator->eval(value_editor[(i/3)*4+i%3]->get_text()); + } else { + basis.elements[i/3][i%3]=value_editor[(i/3)*4+i%3]->get_text().to_double(); + } } Vector3 origin; - origin.x=value_editor[3]->get_text().to_double(); - origin.y=value_editor[7]->get_text().to_double(); - origin.z=value_editor[11]->get_text().to_double(); + + if (evaluator) { + origin.x=evaluator->eval(value_editor[3]->get_text()); + origin.y=evaluator->eval(value_editor[7]->get_text()); + origin.z=evaluator->eval(value_editor[11]->get_text()); + } else { + origin.x=value_editor[3]->get_text().to_double(); + origin.y=value_editor[7]->get_text().to_double(); + origin.z=value_editor[11]->get_text().to_double(); + } v=Transform(basis,origin); emit_signal("variant_changed"); @@ -1736,6 +1798,8 @@ CustomPropertyEditor::CustomPropertyEditor() { add_child(menu); menu->connect("item_pressed",this,"_menu_option"); + evaluator = NULL; + spinbox = memnew ( SpinBox ); add_child(spinbox); spinbox->set_area_as_parent_rect(5); @@ -1750,7 +1814,7 @@ CustomPropertyEditor::CustomPropertyEditor() { bool PropertyEditor::_might_be_in_instance() { if (!obj) - return NULL; + return false; Node *node = obj->cast_to<Node>(); @@ -2695,8 +2759,11 @@ void PropertyEditor::update_tree() { } + if (p.hint==PROPERTY_HINT_ENUM) + item->set_cell_mode( 1, TreeItem::CELL_MODE_RANGE ); + else + item->set_cell_mode( 1, TreeItem::CELL_MODE_RANGE_EXPRESSION ); - item->set_cell_mode( 1, TreeItem::CELL_MODE_RANGE ); if (p.hint==PROPERTY_HINT_SPRITE_FRAME) { item->set_range_config(1,0,99999,1); @@ -3390,6 +3457,9 @@ void PropertyEditor::edit(Object* p_object) { } obj=p_object; + + evaluator->edit(p_object); + update_tree(); if (obj) { @@ -3719,6 +3789,10 @@ PropertyEditor::PropertyEditor() { custom_editor->connect("resource_edit_request", this,"_resource_edit_request",make_binds(),CONNECT_DEFERRED); tree->set_hide_folding(true); + evaluator = memnew (PropertyValueEvaluator); + tree->set_value_evaluator(evaluator); + custom_editor->set_value_evaluator(evaluator); + capitalize_paths=true; autoclear=false; tree->set_column_titles_visible(false); @@ -3737,6 +3811,7 @@ PropertyEditor::PropertyEditor() { PropertyEditor::~PropertyEditor() { + memdelete(evaluator); } @@ -3975,3 +4050,51 @@ SectionedPropertyEditor::~SectionedPropertyEditor() { memdelete(filter); } + +double PropertyValueEvaluator::eval(const String& p_text) { + + if (!obj) + return _default_eval(p_text); + + Ref<Script> script= Ref<Script>(script_language ->create_script()); + script->set_source_code(_build_script(p_text)); + Error err = script->reload(); + if (err) { + print_line("[PropertyValueEvaluator] Error loading script for expression: " + p_text); + return _default_eval(p_text); + } + + ScriptInstance *script_instance = script->instance_create(this); + + Variant::CallError call_err; + script_instance->call("set_this",obj); + double result = script_instance->call("e", NULL, 0, call_err ); + if (call_err.error == Variant::CallError::CALL_OK) { + return result; + } + print_line("[PropertyValueEvaluator]: Error eval! Error code: " + itos(call_err.error)); + + memdelete(script_instance); + + return _default_eval(p_text); +} + + +void PropertyValueEvaluator::edit(Object *p_obj) { + obj = p_obj; +} + +String PropertyValueEvaluator::_build_script(const String& p_text) { + String script_text = "tool\nvar this\nfunc set_this(p_this):\n\tthis=p_this\nfunc e():\n\treturn "; + script_text += p_text.strip_edges(); + script_text += "\n"; + return script_text; +} + +PropertyValueEvaluator::PropertyValueEvaluator() { + script_language = ScriptServer::get_language(0); // todo: get script language from editor setting +} + +PropertyValueEvaluator::~PropertyValueEvaluator() { + +} diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index b870a618e9..1fedb832ed 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -46,6 +46,8 @@ @author Juan Linietsky <reduzio@gmail.com> */ +class PropertyValueEvaluator; + class CustomPropertyEditor : public Popup { OBJ_TYPE( CustomPropertyEditor, Popup ); @@ -104,6 +106,8 @@ class CustomPropertyEditor : public Popup { bool updating; + PropertyValueEvaluator *evaluator; + void _text_edit_changed(); void _file_selected(String p_file); void _scroll_modified(double p_value); @@ -137,6 +141,8 @@ public: void set_read_only(bool p_read_only) { read_only=p_read_only; } + void set_value_evaluator( PropertyValueEvaluator *p_evaluator) { evaluator=p_evaluator; } + bool edit(Object* p_owner,const String& p_name,Variant::Type p_type, const Variant& p_variant,int p_hint,String p_hint_text); CustomPropertyEditor(); @@ -151,6 +157,8 @@ class PropertyEditor : public Control { //Object *object; LineEdit *search_box; + PropertyValueEvaluator *evaluator; + Object* obj; Array _prop_edited_name; @@ -283,4 +291,24 @@ public: ~SectionedPropertyEditor(); }; +class PropertyValueEvaluator : public ValueEvaluator { + OBJ_TYPE( PropertyValueEvaluator, ValueEvaluator ); + + Object *obj; + ScriptLanguage *script_language; + String _build_script(const String& p_text); + + _FORCE_INLINE_ double _default_eval(const String& p_text) { + return p_text.to_double(); + } + +public: + + void edit(Object *p_obj); + double eval(const String& p_text); + + PropertyValueEvaluator(); + ~PropertyValueEvaluator(); +}; + #endif |