array_property_edit.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "array_property_edit.h"
  2. #include "editor_node.h"
  3. #define ITEMS_PER_PAGE 100
  4. Variant ArrayPropertyEdit::get_array() const{
  5. Object*o = ObjectDB::get_instance(obj);
  6. if (!o)
  7. return Array();
  8. Variant arr=o->get(property);
  9. if (!arr.is_array()) {
  10. Variant::CallError ce;
  11. arr=Variant::construct(default_type,NULL,0,ce);
  12. }
  13. return arr;
  14. }
  15. void ArrayPropertyEdit::_notif_change() {
  16. _change_notify();
  17. }
  18. void ArrayPropertyEdit::_notif_changev(const String& p_v) {
  19. _change_notify(p_v.utf8().get_data());
  20. }
  21. void ArrayPropertyEdit::_set_size(int p_size) {
  22. Variant arr = get_array();
  23. arr.call("resize",p_size);
  24. Object*o = ObjectDB::get_instance(obj);
  25. if (!o)
  26. return;
  27. o->set(property,arr);
  28. }
  29. void ArrayPropertyEdit::_set_value(int p_idx,const Variant& p_value) {
  30. Variant arr = get_array();
  31. arr.set(p_idx,p_value);
  32. Object*o = ObjectDB::get_instance(obj);
  33. if (!o)
  34. return;
  35. o->set(property,arr);
  36. }
  37. bool ArrayPropertyEdit::_set(const StringName& p_name, const Variant& p_value){
  38. String pn=p_name;
  39. if (pn.begins_with("array/")) {
  40. if (pn=="array/size") {
  41. Variant arr = get_array();
  42. int size = arr.call("size");
  43. int newsize=p_value;
  44. if (newsize==size)
  45. return true;
  46. UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
  47. ur->create_action("Resize Array");
  48. ur->add_do_method(this,"_set_size",newsize);
  49. ur->add_undo_method(this,"_set_size",size);
  50. if (newsize<size) {
  51. for(int i=newsize;i<size;i++) {
  52. ur->add_undo_method(this,"_set_value",i,arr.get(i));
  53. }
  54. } else if (newsize>size && size) {
  55. Variant init;
  56. Variant::CallError ce;
  57. init = Variant::construct(arr.get(size-1).get_type(),NULL,0,ce);
  58. for(int i=size;i<newsize;i++) {
  59. ur->add_do_method(this,"_set_value",i,init);
  60. }
  61. }
  62. ur->add_do_method(this,"_notif_change");
  63. ur->add_undo_method(this,"_notif_change");
  64. ur->commit_action();
  65. return true;
  66. }
  67. if (pn=="array/page") {
  68. page=p_value;
  69. _change_notify();
  70. return true;
  71. }
  72. } else if (pn.begins_with("indices")) {
  73. if (pn.find("_")!=-1) {
  74. //type
  75. int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int();
  76. int type = p_value;
  77. Variant arr = get_array();
  78. Variant value = arr.get(idx);
  79. if (value.get_type()!=type && type>=0 && type<Variant::VARIANT_MAX) {
  80. Variant::CallError ce;
  81. Variant new_value=Variant::construct(Variant::Type(type),NULL,0,ce);
  82. UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
  83. ur->create_action("Change Array Value Type");
  84. ur->add_do_method(this,"_set_value",idx,new_value);
  85. ur->add_undo_method(this,"_set_value",idx,value);
  86. ur->add_do_method(this,"_notif_change");
  87. ur->add_undo_method(this,"_notif_change");
  88. ur->commit_action();
  89. }
  90. return true;
  91. } else {
  92. int idx=pn.get_slicec('/',1).to_int();
  93. Variant arr = get_array();
  94. Variant value = arr.get(idx);
  95. UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
  96. ur->create_action("Change Array Value");
  97. ur->add_do_method(this,"_set_value",idx,p_value);
  98. ur->add_undo_method(this,"_set_value",idx,value);
  99. ur->add_do_method(this,"_notif_changev",p_name);
  100. ur->add_undo_method(this,"_notif_changev",p_name);
  101. ur->commit_action();
  102. return true;
  103. }
  104. }
  105. return false;
  106. }
  107. bool ArrayPropertyEdit::_get(const StringName& p_name,Variant &r_ret) const {
  108. Variant arr = get_array();
  109. //int size = arr.call("size");
  110. String pn=p_name;
  111. if (pn.begins_with("array/")) {
  112. if (pn=="array/size") {
  113. r_ret=arr.call("size");
  114. return true;
  115. }
  116. if (pn=="array/page") {
  117. r_ret=page;
  118. return true;
  119. }
  120. } else if (pn.begins_with("indices")) {
  121. if (pn.find("_")!=-1) {
  122. //type
  123. int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int();
  124. bool valid;
  125. r_ret=arr.get(idx,&valid);
  126. if (valid)
  127. r_ret=r_ret.get_type();
  128. return valid;
  129. } else {
  130. int idx=pn.get_slicec('/',1).to_int();
  131. bool valid;
  132. r_ret=arr.get(idx,&valid);
  133. return valid;
  134. }
  135. }
  136. return false;
  137. }
  138. void ArrayPropertyEdit::_get_property_list( List<PropertyInfo> *p_list) const{
  139. Variant arr = get_array();
  140. int size = arr.call("size");
  141. p_list->push_back( PropertyInfo(Variant::INT,"array/size",PROPERTY_HINT_RANGE,"0,100000,1") );
  142. int pages = size/ITEMS_PER_PAGE;
  143. if (pages>0)
  144. p_list->push_back( PropertyInfo(Variant::INT,"array/page",PROPERTY_HINT_RANGE,"0,"+itos(pages)+",1") );
  145. int offset=page*ITEMS_PER_PAGE;
  146. int items=MIN(size-offset,ITEMS_PER_PAGE);
  147. for(int i=0;i<items;i++) {
  148. Variant v=arr.get(i+offset);
  149. if (arr.get_type()==Variant::ARRAY) {
  150. p_list->push_back(PropertyInfo(Variant::INT,"indices/"+itos(i+offset)+"_type",PROPERTY_HINT_ENUM,vtypes));
  151. }
  152. if (arr.get_type()!=Variant::ARRAY || v.get_type()!=Variant::NIL) {
  153. PropertyInfo pi(v.get_type(),"indices/"+itos(i+offset));
  154. if (v.get_type()==Variant::OBJECT) {
  155. pi.hint=PROPERTY_HINT_RESOURCE_TYPE;
  156. pi.hint_string="Resource";
  157. }
  158. p_list->push_back(pi);
  159. }
  160. }
  161. }
  162. void ArrayPropertyEdit::edit(Object* p_obj,const StringName& p_prop,Variant::Type p_deftype) {
  163. page=0;
  164. property=p_prop;
  165. obj=p_obj->get_instance_ID();
  166. default_type=p_deftype;
  167. }
  168. Node *ArrayPropertyEdit::get_node() {
  169. Object *o = ObjectDB::get_instance(obj);
  170. if (!o)
  171. return NULL;
  172. return o->cast_to<Node>();
  173. }
  174. void ArrayPropertyEdit::_bind_methods() {
  175. ObjectTypeDB::bind_method(_MD("_set_size"),&ArrayPropertyEdit::_set_size);
  176. ObjectTypeDB::bind_method(_MD("_set_value"),&ArrayPropertyEdit::_set_value);
  177. ObjectTypeDB::bind_method(_MD("_notif_change"),&ArrayPropertyEdit::_notif_change);
  178. ObjectTypeDB::bind_method(_MD("_notif_changev"),&ArrayPropertyEdit::_notif_changev);
  179. }
  180. ArrayPropertyEdit::ArrayPropertyEdit()
  181. {
  182. page=0;
  183. for(int i=0;i<Variant::VARIANT_MAX;i++) {
  184. if (i>0)
  185. vtypes+=",";
  186. vtypes+=Variant::get_type_name( Variant::Type(i) );
  187. }
  188. default_type=Variant::NIL;
  189. }